Программирование на C++ глазами хакера

Дрожь в ногах


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

Создайте в Visual C++ новый проект типа Win32 Project. Добавьте пуню-меню для вызова команды дрожания, потом найдите в исходном коде функцию WndProc, где обрабатываются все события окна. Между дрожаниями понадобится задержка, чтобы пользователь успел увидеть изменения, но они не казались слишком частыми, поэтому в начале функции объявляется переменная типа HANDLE, которая инициализируется функцией CreateEvent:

HANDLE h;
h = CreateEvent(0, true, false, "et ");

Теперь обработчик события будет выглядеть следующим образом:

case ID_MYCOMMAND_VIBRATION: while (TRUE) { EnumWindows(EnumWindowsWnd, 0); WaitForSingleObject(h, 10); // Задержка в 500 миллисекунд }

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

Самое интересное скрывается в функции EnumWindowsWnd, код которой вы можете увидеть в листинге 3.1.

Листинг 3.1. Код функции EnumWindowsWnd

BOOL CALLBACK EnumWindowsWnd( HWND hwnd, // handle to parent window LPARAM lParam // application-defined value ) { if (IsWindowVisible(hwnd)==FALSE) return TRUE;



RECT rect; GetWindowRect(hwnd, rect);

int index=rand()%2; if (index==0) { rect.top=rect.top+3; rect.left=rect.left+3; } else { rect.top=rect.top-3; rect.left=rect.left-3; }

MoveWindow(hwnd, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);

return TRUE; }

Теперь посмотрим на функцию-ловушку EnumWindowsWnd, которая будет вызываться каждый раз, когда найдено окно. Тут первой запускается функция IsWindowVisible, которая проверяет, является ли найденное окно видимым. Если нет, то возвращается значение TRUE, происходит выход из ловушки, и поиск следующего окна будет продолжен, иначе он остановится, и следующее окно не будет найдено. Если окно невидимо, то нет смысла его двигать или изменять размер.


После этого вызывается функция GetWindowRect. Этой функции передается в первом параметре идентификатор найденного окна, а она возвращает во втором параметре размеры этого окна в структуре RECT, описывающей прямоугольную область на экране с параметрами left, top, bottom, right.

После получения величины окна генерируется случайное число от 0 до 1 с помощью функции rand. После этого необходимо проверить, если сгенерированное число равно 0, то увеличиваем свойства top и left структуры rect на 3 пиксела, иначе эти значения уменьшаем.

Изменив значения переменных структуры, в которой хранились размеры найденного окна, перемещаем это окно с помощью функции MoveWindow. Эта функция имеет следующие параметры:

идентификатор окна, позицию которого надо изменить (h);

новая позиция левого края (rect.left);

новая позиция верхнего края (rect.top);

новая ширина (rect.right-rect.left);

новая высота (rect.bottom-rect.top).

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

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

Примечание
Исходный код этого примера вы можете найти на компакт - диске в каталоге \Demo\Chapter3\Vibration.

Содержание раздела