Программирование >>  Арифметические и логические операции 

1 ... 32 33 34 [ 35 ] 36 37 38 ... 53


Всё это реализует примерно такой код:

LRESULT CALLBACK KeyboardHook(int nCode,WPARAM wParam,LPARAM lParam)

{ Ловушка клав. - биканье при перекл. раскладки if((lParam 31)&1) Если клавиша нажата... switch(wParam)

{ Определяем какая именно

case VK SHIFT: {iShiftKey=UP; break};

case VK CONTROL: {iCtrlKey=UP; break};

case VK MENU: {iAltKey=UP; break};

else Если была отпущена...

switch(wParam)

{ Определяем какая именно

case VK SHIFT: {iShiftKey=DOWN; break};

case VK CONTROL: {iCtrlKey=DOWN; break};

case VK MENU: {iAltKey=DOWN; break};

--------------

switch(KEYBLAY) В зависимости от способа переключения раскладки

case 1: Alt+Shift

if(iAltKey==DOWN && iShiftKey==UP)

vfBeep(); iShiftKey=RESET;

if(iAltKey==UP && iShiftKey==DOWN)

vfBeep(); iAltKey=RESET;

((iAltKey==UP && iShiftKey==RESET)(iAltKey==RESET &&

iShiftKey==UP))

iAltKey=RESET; iShiftKey=RESET;

break;

------------------------------------case 2: Ctrl+Shift

if(iCtrlKey==DOWN && iShiftKey==UP)

vfBeep(); iShiftKey=RESET;

if(iCtrlKey==UP && iShiftKey==DOWN)

vfBeep(); iCtrlKey=RESET;

if((iCtrlKey==UP && iShiftKey==RESET)(iCtrlKey==RESET && iShiftKey==UP))

iCtrlKey=RESET; iShiftKey=RESET;

return 0;

Звуковой сигнал выдаётся такой небольшой функцией:

void vfBeep()

{ Биканье

MessageBeep(-1);

MessageBeep(-1); Два раза - для отчётливости

Функция ловушки мыши

Эта функция отслеживает движение курсора мыши, получает его координаты и сравнивает их с координатами правого верхнего угла экрана (0,0). Если эти координаты совпадают, то вызывается хранитель экрана. Для отслеживания движения анализируется значение параметра wParam, а для отслеживания координат значение, находящееся в структуре типа MOUSEHOOKSTRUCT, на которую указывает lParam. Код, реализующий вышесказанное, примерно такой:

LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam) { Ловушка мыши - включает хранитель когда в углу if(wParam==WM MOUSEMOVE wParam==WM NCMOUSEMOVE)



psMouseHook=(MOUSEHOOKSTRUCT*)(lParam); if(psMouseHook->pt.x==0 && psMouseHook->pt.y==0) if(bSCRSAVEACTIVE)

PostMessage(psMouseHook->hwnd,WM SYSCOMMAND,

SC SCREENSAVE,0);

return 0;

Обратите внимание, что команда на активизацию хранителя посылается в окно, получающее сообщения от мыши:

PostMessage(psMouseHook->hwnd,WM SYSCOMMAND, SC SCREENSAVE ,0).

Теперь, когда функции ловушек написаны, надо сделать так, чтобы они были доступны из процессов, подключающих эту библиотеку. Для этого перед функцией входа следует добавить такой код:

extern C declspec(dllexport) LRESULT CALLBACK

KeyboardHook(int,WPARAM,LPARAM);

extern C declspec(dllexport) LRESULT CALLBACK

MouseHook(int,WPARAM,LPARAM);

Написание приложения, устанавливающего ловушку

Создание пустого приложения

Для создания пустого приложения воспользоваться встроенным мастером. Для этого надо использовать пункт меню File * New: В появившемся окне необходимо выбрать Console Wizard и нажать кнопку Ok . В новом диалоге в разделе Source Type следует оставить значение по умолчанию - C++ . Во втором разделе надо снять все флажки. По нажатию Ок приложение создаётся.

Создание главного окна

Следующий этап - это создание главного окна приложения. Сначала надо зарегистрировать класс окна. После этого создать окно. Всё это делает следующий код (описатель окна MainWnd определён глобально):

BOOL InitApplication(HINSTANCE hinstance,int nCmdShow) { Создание главного окна WNDCLASS wcx; Класс окна

wcx.style=NULL;

wcx.lpfnWndProc=MainWndProc;

wcx.cbClsExtra=0;

wcx.cbWndExtra=0;

wcx.hInstance=hinstance; wcx.hIcon=LoadIcon(hinstance, MAINICON ); wcx.hCursor=LoadCursor(NULL,IDC ARROW); wcx.hbrBackground=(HBRUSH)(COLOR APPWORKSPACE);

wcx.lpszMenuName=NULL;

wcx.lpszClassName= HookWndClass ; if(RegisterClass(&wcx)) Регистрируем класс

MainWnd=CreateWindow( HookWndClass , SSHook , /* Создаём окно */

WS OVERLAPPEDWINDOW, CW USEDEFAULT,CW USEDEFAULT, CW USEDEFAULT,CW USEDEFAULT,

NULL,NULL,hinstance,NULL);

if(!MainWnd) return FALSE;

return TRUE;

return false;

Обратите внимание на то, каким образом был получен значок класса:

wcx.hIcon=LoadIcon(hinstance, MAINICON );

Для того, чтобы это получилось надо включить в проект файл ресурсов (*.res), в котором должен находиться значок с именем MAINI-

CON .

Это окно никогда не появится на экране, поэтому оно имеет размеры и координаты, устанавливаемые по умолчанию. Оконная процедура такого окна необычайно проста:

LRESULT CALLBACK MainWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,

LPARAM lParam) { Оконная процедура switch (uMsg)

case WM DESTROY:{PostQuitMessage(0); break;} case MYWM NOTIFY:

if(lParam==WM RBUTTONUP) PostQuitMessage(0);

break; Правый щелчок на значке - завершаем



default:

return DefWindowProc(hwnd,uMsg,wParam,lParam);

return 0;

Размещение значка в системной области

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

void vfSetTrayIcon(HINSTANCE hInst) { Значок в Tray

char* pszTip= Хранитель экрана и раскладка ; Это просто Hint

NotIconD.cbSize=sizeof(NOTIFYICONDATA);

NotIconD.hWnd=MainWnd;

NotIconD.uID=IDC MYICON;

NotIconD.uFlags=NIF MESSAGENIF ICONNIF TIP; NotIconD.uCallbackMessage=MYWM NOTIFY;

NotIconD.hIcon=LoadIcon(hInst, MAINICON ); lstrcpyn(NotIconD.szTip,pszTip,sizeof(NotIconD.szTip)); Shell NotifyIcon(NIM ADD,&NotIconD);

Для корректной работы функции предварительно нужно определить уникальный номер значка (параметр NotIconD.uID) и его сообщение (параметр NotlconD.uCallbackMessage). Делаем это в области определения глобальных переменных:

#define MYWM NOTIFY (WM APP+100) #define IDC MYICON 1006

Сообщение значка будет обрабатываться в оконной процедуре главного окна (NotIconD.hWnd=MainWnd):

case MYWM NOTIFY:

if(lParam==WM RBUTTONUP) PostQuitMessage(0); break; Правый щелчок на значке

завершаем

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

При завершении работы значок надо удалить:

void vfResetTrayIcon() { Удаляем значок

Shell NotifyIcon(NIM DELETE,&NotIconD);

Установка и снятие ловушек

Для получения доступа в функциям ловушки надо определить указатели на эти функции:

LRESULT CALLBACK ( stdcall *pKeybHook)(int,WPARAM,LPARAM); LRESULT CALLBACK ( stdcall *pMouseHook)(int,WPARAM,LPARAM);

После этого спроецируем написанную DLL на адресное пространство процесса:

hLib=LoadLibrary( SSHook.dll ); (hLib описан как HINSTANCE hLib)

После этого мы должны получить доступ к функциям ловушек:

(void*)pKeybHook=GetProcAddress(hLib, KeyboardHook ); (void*)pMouseHook=GetProcAddress(hLib, MouseHook );

Теперь всё готово к постановке ловушек. Устанавливаются они с помощью функции SetWindowsHookEx:

hKeybHook=SetWindowsHookEx(WH KEYBOARD,(HOOKPROC)(pKeybHook),hLib,

hMouseHook=SetWindowsHookEx(WH MOUSE,(HOOKPROC)(pMouseHook),

hLib,0);

(hKeybHook и hMouseHook описаны как HHOOK hKeybHook; HOOK

hMouseHook;)

Первый параметр - тип ловушки (в данном случае первая ловушка для клавиатуры, вторая - для мыши). Второй - адрес процедуры ловушки. Третий - описатель DLL-библиотеки. Последний параметр - идентификатор потока, для которого будет установлена ловушка. Если этот параметр равен нулю (как в нашем случае), то ловушка устанавливается для всех потоков.

После установки ловушек они начинают работать. При завершении работы приложения следует их снять и отключить DLL. Делается это так:

UnhookWindowsHookEx(hKeybHook); UnhookWindowsHookEx(hMouseHook); Завершаем FreeLibrary(hLib);



1 ... 32 33 34 [ 35 ] 36 37 38 ... 53

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика