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

         

Начните работу с кнопки Пуск


Если вы сами устанавливали Windows, то после первого запуска, неверно, видели сообщение ОС типа "Начните работу с этой кнопки" и стрелку, указывающую на кнопку Пуск. Я достаточно долго работал администратором сети, и мне наскучило отвечать пользователям на вопрос: "А где у меня программа XXX". После очередного вопроса я написал программу, которая постоянно открывает меню, появляющееся по нажатию кнопки Пуск. Сейчас нам предстоит написать подобный пример.

Создайте новое приложение Win32 Project. Я назвал новый проект CrazyStart, но вы можете назвать и по-другому. В данном примере имя проекта не будет использоваться, и путаницы в понимании не будет.

Откройте файл с кодом вашего проекта, он должен иметь имя вашего проекта и расширение срр (у меня это CrazyStart.cpp). Найдите функцию _tWinMain и доведите ее до вида как в листинге 2.4. По комментариям, которые указаны в листинге, вы легко можете определить, что нужно добавить.

Листинг 2.4. Функция _tWinMain
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. MSG msg; HACCEL hAccelTable;

// Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_CRAZYSTART, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance);

// Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; }

hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_CRAZYSTART);

// Main message loop: // Необходимо добавить в свой код следующие три строки: HWND hTaskBar, hButton;

hTaskBar= FindWindow("Shell_TrayWnd",NULL); hButton= GetWindow(hTaskBar, GW_CHILD);

while (GetMessage(msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, msg)) { TranslateMessage(msg); DispatchMessage(msg); } // Hажать кнопку "Пуск" // Необходимо добавить в свой код следующие две строки: SendMessage(hButton, WM_LBUTTONDOWN, 0, 0); Sleep(1000); }


return (int) msg.wParam; }



Сначала мы объявляем две переменные hTaskBar и hButton типа HWND. Это уже знакомый нам тип, который используется для ссылки на окна. Потом мы выполняем функцию FindWindow, которая ищет окно по заданным двум параметрам:

имя класса окна — это имя используется при регистрации окна в системе;

имя заголовка окна — текст, который указан в заголовке.

Кнопка Пуск расположена на Панели задач, которая является окном, и именно его мы хотим найти. Класс этого окна — Shell_TrayWnd, что мы и указываем в первом параметре. Заголовка нет, поэтому и имени окна не будет, так что второй параметр пустой и равен NULL.

На Панели задач есть только одна кнопка — Пуск, поэтому мы можем получить на нее ссылку с помощью вызова функции GetWindow. Эта функция имеет два параметра:

указатель на окно;

"родственные связи" искомого окна и указанного. У нас кнопка находится на окне, поэтому окно является для нее родителем, а сама кнопка — подчиненным, и мы должны указать флаг GW_CHILD.

Таким образом, мы получим указатель на кнопку и сохраним его в переменной hButton. В цикле обработчика сообщений мы посылаем кнопке Пуск сообщение с помощью функции SendMessage со следующими параметрами:

окно, сообщение которому мы хотим послать, — указатель на кнопку Пуск;

сообщение, которое надо послать, — отсылаем WM_LBUTTONDOWN, что равносильно нажатию левой кнопки мыши.

Кнопка Пуск, получив наше сообщение, будет думать, что по ней щелкнули левой кнопкой мыши, и отобразит меню.

После этого вызывается функция Sleep, которая делает задержку в заданное количество миллисекунд. У нас указано 1000, что равносильно одной секунде. Эта функция останавливает выполнение программы, но, в отличие от использованного ранее метода с функцией WaitForsingleObject, эта помимо задержки больше загружает систему. Таким образом, когда пользователь захочет закрыть наше окно, он поведет мышкой по окну, и в этот момент будет сгенерировано множество сообщений от мышки. Задержка от функции Sleep будет настолько большой, что закрыть окно будет сложно.

Примечание
Исходный код и запускаемый файл этого примера вы можете найти на компакт - диске в каталоге \Demo\Chapter2\CrazyStart.

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