Шутки с мышкой

Мышка тоже может быть объектом насмешек. Например, можно заставить ее беспорядочно бегать по монитору или ограничить движение маленьким квадратом. А можно вообще остановить указатель в определенной точке, создав видимость его зависания. Как показывает практика, игры с мышкой производят на пользователя большее впечатление, особенно на начинающего, потому что он больше работает с ней, а не с клавиатурой.

Безумная мышка

Как сделать мышку безумной? Очень даже просто:

for (int i=0; i<20; i++)
{
SetCursorPos(rand()%640, rand()%480);
Sleep (100);
}

Здесь запускается цикл от 0 до 20, в котором указатель мышки переносится в случайную позицию с помощью функции SetCursorPos, которой нужно передать два параметра X и Y в виде целых чисел — координаты новой позиции курсора. Параметры формируются с помощью функции rand() в диапазоне от нуля до числа, указанного после знака %. В реальной программе желательно определять разрешение экрана (ширину и высоту) с помощью функции GetSystemMetrics с параметрами SM_CYSCREEN и SM_CXSCREEN, но в примередля наглядности я ограничился разрешением 640x480.

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

Летающие объекты

В разд. 2.2 мы рассматривали пример, в котором программно щелкали по кнопке Пуск. Тогда это было определенное окно, поэтому задача упрощалась. Поставим задачу шире — щелкнуть в любой области экрана. Для этого потребуется определить, какое в этом месте окно. Этот вопрос тоже решается достаточно просто:

for (int i=0; i<20; i++)
{
POINT pt = {rand()%800, rand()%600};
SetCursorPos(pt.x, pt.y);
Sleep(100);

HWND hPointWnd = WindowFromPoint(pt);
SendMessage(hPointWnd, WM_LBUTTONDOWN, MK_LBUTTON,
MAKELONG(pt.x,pt.y));
SendMessage(hPointWnd, WM_LBUTTONUP, 0,
MAKELONG(pt.x,pt.y));
}

В этом примере, как и в задаче с мышкой, мы случайным образом генерируем две координаты и сохраняем их в параметрах х и у структуры pt. Потом изменяем положение курсора в соответствии с полученными координатами.

На следующем шаге определяем окно, которое находится в этой позиции. Для этого существует функция WindowFromPoint, которой нужно передать один параметр — структуру типа POINT с хранящимися в ней координатами искомой точки. Функция вернет указатель на это окно.

Теперь отправляем два сообщения уже знакомым способом. В первом случае второй параметр равен WM_LBUTTONDOWN (когда нажата левая кнопка мыши), а во втором — WM_LBUTTONUP (когда отпущена). Почему здесь два события? Если кнопка Пуск реагирует на нажатия, то программы чаще всего обрабатывают полное нажатие (Click) или событие, когда отпущена кнопка. Поэтому желательно отправлять оба события.

В качестве последнего параметра функции SendMessage мы передаем координаты точки, где щелкнул пользователь. Для этого обе координаты собираются в одно большое число с помощью макроса MAKELONG (макрос похож по своему принципу работы на функцию).

Можно сразу немного изменить пример:

for (int i =0; i <20; i ++)
{
// Устанавливаем случайную позицию курсора
POINT pt = {rand()%800, rand()%600};
SetCursorPos(pt.x, pt.y);
Sleep(100);

// Посылаем сообщение о нажатии кнопки мыши
HWND hPointWnd = WindowFromPoint(pt);
SendMessage(hPointWnd, WM_LBUTTONDOWN, MK_LBUTTON,
MAKELONG(pt.x,pt.y));

// Изменение позиции курсора
POINT pt1 = {rand()%800, rand()%600};
SetCursorPos(pt1.x, pt1.y);

SendMessage(hPointWnd, WM_MOUSEMOVE, 0,
MAKELONG(pt1.x, pt1.y));

// Отпускаем кнопку мышки
SendMessage(hPointWnd, WM_LBUTTONUP, 0,
MAKELONG(pt1.x, pt1.y));
}

Здесь между событиями нажатия и отпускания кнопки мы генерируем новые координаты, перемещаем туда мышку и отпускаем ее. Перед тем как послать сообщение о том, что кнопка отпущена, мы отправляем сообщение WM_MOUSEMOVE, которое заставляет программу отработать перемещение указателя мыши. Таким образом, нажали в одном месте, а отпустили в другом. И если в месте нажатия был объект, который можно перетащить, то он перелетит в новое место (получается программный Drag & Drop).

Мышка в клетке

Очень интересным примером является ограничение свободы перемещения мышки. Посмотрите на следующий код:

RECT r;
r.left=10;
r.top=10;
r.bottom=100;
r.right=100;
CiipCursor(&r);

Определим переменную r типа RECT. Это структура, которая состоит из четырех числовых переменных, описывающих прямоугольник. Переменные структуры имеют следующие имена: left, top, bottom и right (левая, верхняя, нижняя и правая координаты прямоугольника).

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

Попробуйте выполнить следующий код:

RECT r;
r.left=0;
r.top=0;
r.bottom=1;
r.right=1;
CiipCursor(&r);

Здесь размер области передвижения равен 1 пикселу по горизонтали и вертикали, поэтому мышка окажется запертой в клетке.

Изменчивый указатель

Есть такая интересная WinAPI-функция — SetSystemCursor. У нее есть два параметра:

И сразу приведу небольшой пример изменения текущего курсора:

SetSystemCursor(GetCursor(), OCR_CROSS);

Этот код изменяет текущий курсор на крестик, который используется при графическом выделении.

free-templates.ru
Сайт управляется системой uCoz