|
Программирование >> Арифметические и логические операции
Всё это реализует примерно такой код: 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);
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |