вентилятор
Хорошего настроения!

Создаём программу-прикол *убегающая кнопка Пуск* на C#



Привет! Сегодня Хэллоуин (31 октября), и мы сделаем программу-прикол "Убегающая кнопка Пуск".


С помощью данной программы вы можете кого-нибудь разыграть. Когда пользователь подведёт курсор мышки к кнопке Пуск, она начнёт от него убегать! В этот момент мы спрячем данную кнопку, а наша форма программы появится в случайном месте экрана, и на ней будет нарисована кнопка Пуск. Таким образом, получится эффект, что данная кнопка взбунтовалась и просто убегает.


При попытке навести курсор на форму, она снова будет убегать. Остановить шутку можно, если пользователь ещё раз подведёт курсор к законному месту кнопки Пуск, тогда наша программа закроется.


Воспользоваться уже готовой программой можно по ссылке. Эта программа ещё немного усовершенствована в некоторых мелочах.





Идея была взята из книги Михаила Фленова С++ глазами хакера. Но реализацию мы будем делать по-своему на языке С#.


Результат работы программы *убегающая кнопка Пуск*

Выбираем проект Windows Forms (.NET Framework). Главная форма будет прозрачной, программу будет видно только в трее.


В настройках нашей программы организатору розыгрыша нужно будет добавить изображение кнопки Пуск для текущей версии Windows на данном компьютере. Её легко сделать с помощью какого-нибудь графического редактора и скришота экрана. Здесь вам рекомендую воспользоваться мои скриншотером, который может сохранить указанную область экрана сразу в файл.





Свойства главной формы: Opacity: 0% (делаем форму прозрачной), ShowInTaskbar: Fasle (убираем программу из панели задач), FormBorderStyle: None (убираем рамку вокруг окна).


Чтобы программу было видно в трее кинем на форму элемент NotifyIcon. Добавим в ресурсы проекта иконку для этого элемента. Переходим Обозреватель решений->Свойства (Проекта)->Ресурсы.


Обозреватель решений

Выбираем в верхнем выпадающем меню Значки.


Возле кнопки Добавить ресурс нажимаем чёрный треугольник и выбираем "добавить существующий файл". Выберем изображение формата .ico с разрешением 150 на 150 пикселей.


Теперь можно обратится в коде к этому ресурсу. Напишем в классе главной формы внутри функции public Form1() после инициализации:


notifyIcon1.Icon = Properties.Resources._1;

_1 - это название иконки.





Зададим свойства для notifyIcon1. Text: Программа-прикол "убегающая кнопка Пуск" (этот текст будет всплывать при наведении на иконку в трее).


Добавим для элемента notifyIcon1 контекстное меню. Кинем элемент contextMenuStrip1 на главную форму. Добавим в свойство ContextMenuStrip для notifyIcon1 имя контекстного меню.


Добавим две позиции в контекстное меню.

Контекстное меню

Кликним два раза по каждому пункту и получим функции, которые будут вызываться, когда пользователь будет нажимать на них.


Для выхода пропишем:


Выход из программы

Перейдём к главной форме. Нажмём F7. Напишем в начале класса Form1.

public string FileImg = "";

Это переменная будет хранить путь к файлу изображения кнопки Пуск. Сделали эту переменную публичной. Мы к ней будем обращаться из формы настроек.





При клике на пункт Настройки должно появится окно с параметрами. В нём пользователь должен указать на изображение кнопки Пуск в формате jpg для данного компьютера, где будет происходит розыгрыш. Добавим ещё одну форму.


В обозревателе решений кликнем правой кнопкой мыши по названию проекта. Выберем Добавить-> Форма -> Добавить.


Пропишем свойства новой формы. Text: Настройки "Убегающая кнопка Пуск" (Название окна); StartPosition: CenterScreen (окно должно появляться по центру экрана); FormBorderStyle: FixedSingle (окно нельзя будет растягивать), MaximizeBox: False (убираем возможность развернуть окно).


Кинем на новую форму элемент Label. Сделаем для него свойства. Font: Размер 14 пт, Text: "Добавьте изображение для кнопки пуск". Размести этот элемент примерно посередине.


Кинем на форму элемент TextBox. Чтобы изменить высоту данного элемента, нужно изменить свойство Font. Поставим Font: 12 пт, установим свойство ReadOnly: True (запретим редактирование текстового поля).




Добавим на новую форму ещё две кнопки Button, чтобы в итоге она выглядела примерно так:


Настройки для программы-прикола убегающая кнопка Пуск

Для контекстного меню настройки пропишем:


Делаем видимой форму настроек




Здесь создаётся объект формы настроек. И эта форма становится видимой.


Перейдём на вторую форму. Нажмём F7 и пропишем в начале класса Form2:

string FileName = "";

Кинем ещё один элемент OpenFileDialog на вторую форму. Выделим первую кнопку ("Выбрать изображение"). Настроим обработчик события нажатия этой кнопки. Перейдём на окно События (иконка в виде молнии).


Иконка События

Найдём событие Click и кликнем два раза по ячейке справа. Пропишем в обработчике события:


Обработчик события Click для выбора изображения

Здесь вызывается файловый диалог, чтобы пользователь указал файл изображения кнопки пуск. В функции проверяется расширение выбранного файла. Расширение должно быть jpg. Путь до этого файла записывается в текстовое поле textBox1. Если путь превышает 23 символа, то эта строка обрезается и добавляется к ней троеточие.


Чтобы передать путь до изображения в главную форму, сделаем следующие манипуляции. Пропишем в начале класса Form2:

Form1 Prt;

И изменим функцию public Form2():


Конструктор Form2

Тогда и в коде для первой формы в функции настройкиToolStripMenuItem_Click изменим создание объекта для формы настроек:

Form2 FormSitting = new Form2(this);




Таким образом, мы сможет передать путь до изображения кнопки Пуск из формы настроек в главное окно программы.


Пропишем обработчик события Click для второй кнопки окна настроек (кнопки ОК).


Обработчик события для кнопки ОК

Здесь мы проверяем, чтобы файл был именно формата jpg. Если всё нормально - передаём главному окну путь до изображения кнопки Пуск и закрываем окно настроек.


Вернёмся к коду главной формы Form1. Кинем на форму ещё элемент таймер (Timer). Таймер будет запускать функцию каждые 100 миллисекунд. Эта функция будет проверять находится ли курсор мышки над кнопкой Пуск. Пропишем в функции public Form1() внизу:


Настройки для Таймера

Именно функция Timer1_Tick будет запускаться каждые 100 миллисекунд.





Добавим в начале класса Form1 переменную-индикатор:

bool move = false;

Эта переменная будет равна true, если наша кнопка уже убегает от пользователя.


Добавим так же очень важные для нашей программы функции из WinAPI в начале класса Form1.


[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string ClassName, string WindowName);

[DllImport("user32.dll")]
static extern IntPtr WindowFromPoint(Point p);

[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point lpPoint);

[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("User32.Dll")]
public static extern long SetCursorPos(int x, int y);

[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
private const UInt32 SWP_NOSIZE = 0x0001;
private const UInt32 SWP_NOMOVE = 0x0002;
private const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;




Теперь реализуем функцию Timer1_Tick, которую будет запускать таймер каждые 100 миллисекунд.


private void Timer1_Tick(object sender, EventArgs e)
{
    Point p;
    Image img;

    int x, y;

    GetCursorPos(out p);

    // Получим дескриптор кнопки ПУСК
    IntPtr startWnd = FindWindow("Button", null);
    IntPtr  W = WindowFromPoint(p);

    if (startWnd == W)
    {

        if (move)
        {
            Thread.Sleep(400);
            this.Close();
        }

        if (FileImg != "")
        {
            img = Bitmap.FromFile(FileImg);
            this.Opacity = 100;
            this.Size = new Size(img.Width, img.Height);

            if (move == false)
            {
                Rectangle resolution = Screen.PrimaryScreen.Bounds;
                Random rnd = new Random();

                x = rnd.Next(Convert.ToInt32(resolution.Width*0.2), Convert.ToInt32(resolution.Width * 0.3));
                y = rnd.Next(Convert.ToInt32(resolution.Height * 0.7), Convert.ToInt32(resolution.Height * 0.8));

                this.Location = new Point(x, y);
                this.BackgroundImage = img;

                SetCursorPos(x-20, y+80);

                Thread.Sleep(150);

                ShowWindow(startWnd, 0);

                SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);
            }

            move = true;
         }
     }
}

Переменная img - она будет содержать картинку кнопки Пуск, которую загрузил пользователь. Функция GetCursorPos будет получать координаты курсора мышки в переменную p.





С помощью функции FindWindow определяем дескриптор кнопки Пуск. С помощью функции WindowFromPoint определяем дескриптор окна для точки p. Таким образом, если у нас эти дескрипторы равны, то курсор мышки находится над кнопкой Пуск. Пора действовать!


Если переменная FileImg не пуста, то значит, пользователь уже настроил изображение для кнопки Пуск. Загружаем изображение в переменную img. Для основной формы возвращаем непрозрачность на 100%. Делаем размер окна таким же, как и изображение для кнопки Пуск.


Если этот механизм сработал первый раз (переменная move всё ещё равна false), то узнаём размеры экрана (переменная resolution) и делаем случайные координаты x, y для Form1 (с изображением кнопки) вблизи левого нижнего угла (где примерно и находится кнопка Пуск). Тем самым достигается эффект того, что кнопка ускользнула от пользователя.


Курсор мышки устанавливаем рядом с новым изображением кнопки Пуск (с Form1) c помощью функции SetCursorPos. Скрываем настоящую кнопку Пуск с помощью функции ShowWindow. Задержку в 150 миллисекунд делаем для более плавной работы.


Функция SetWindowPos помогает муляж кнопки Пуск разместить поверх всех окон.


Так же в этой функции написано условие:

if (move)
{
    Thread.Sleep(400);
    this.Close();
}



Оно написано для того, чтобы завершить работу программы, если пользователь подведёт курсор мышки к настоящей кнопке Пуск (при move=true, т.е. при уже блуждающем Пуске). Всё равно в этом случае в Windows 10 настоящая кнопка Пуск становится опять видимой, и наша шутка как бы на этом заканчивается. Т.е, чтобы завершить блуждание кнопки, нужно догадаться подвести мышку к месту постоянной дислокации кнопки Пуск.


Запрограммируем убегание муляжа кнопки Пуск (Form1) при наведении на него курсора. Для главной формы настроим обработчик события MouseMove.

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    Rectangle resolution = Screen.PrimaryScreen.Bounds;
    Random rnd = new Random();
    this.Location = new Point(rnd.Next(10, resolution.Width - 100), rnd.Next(10, resolution.Height - 100));
}




Этот код похож на фрагмент из функции Timer1_Tick. Здесь случайно вычисляются новые координаты для главной формы (муляжа кнопки Пуск). Уже существенно расширен диапазон для переменных x и y. Делаем небольшие отступы от краёв экрана, чтобы картинка не ушла за поле зрения пользователя.

На сегодня всё! Счастливого программирования! ))


Скачать результат данной статьи с небольшими усовершенствованиями можно по ссылке ниже.




Программа JokeProgramm







26-10-2022 в 20:11:42





Поддержать сайт:


Похожая статья:

Получить изображение с веб-камеры в форме на C#

В этой статье мы получить изображение с веб-камеры на C#...

Категория: C#  Подкатегория: -
Дата: 08-05-2023 в 13:11:16 1



Оставить коментарий:



Напишите email, чтобы получать сообщения о новых комментариях (необязательно):


Задача против робота. Расположите картинки горизонтально:




Нажимая кнопку Отправить, Вы соглашаетесь с политикой конфиденциальности сайта.