Код DLL: Код (Text): #pragma data_seg(".SHRDATA") HWND hWndMain = NULL; #pragma data_seg() HHOOK hook; HINSTANCE hInstance; __declspec(dllexport) LRESULT CALLBACK KeyboardProc(UINT nCode, WPARAM wParam, LPARAM lParam) { MessageBox(NULL,"Hook","Hook",MB_OK); return CallNextHookEx(hook, nCode, wParam, lParam); } __declspec(dllexport) void InstallHook(HWND hWnd,int iTKey) { hook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, hInstance, NULL); } bool APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hInstance = (HINSTANCE)hModule; break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: UnInstallHook(hWndMain); break; } return TRUE; } А это код приложения: Код (Text): #pragma comment (lib, "keyshook.lib") __declspec(dllimport) void InstallHook(HWND hWnd, int iTKey); __declspec(dllimport) void UnInstallHook(HWND hWnd); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { InitCommonControls(); hDlg=CreateDialog(hInst, MAKEINTRESOURCE(ID_MDIALOG), 0, (DLGPROC) DlgProc); while ((GetMessage(&Msg, NULL, 0, 0)) != 0) { if (!IsWindow(hDlg) || !IsDialogMessage(hDlg, &Msg)) { TranslateMessage(&Msg); DispatchMessage(&Msg); } } } .............. BOOL CALLBACK DlgProc(HWND hWndDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: InstallHook(hWndDlg, dwTypeKey); break; case WM_MOUSEHOOK: break; } ....... }
Так вроде все верно, но есть одно подозрительное место. Не мешало бы показать код UnInstallHook(). Вот смотри - ты загрузил ДЛЛ в свой основной процесс, вызвал InstallHook(). Система добавила соответсвующую структуру tagHOOK в цепочку хуков данного типа. В другом процессе, при обработке сообщения от клавы, система видит, что есть хук, процедуру которого надо вызвать. Если ДЛЛ еще не подгружена, система загружает ее и вызывает процедуру. Т.е. тут все ок. А теперь представь, что уже "похуканный" процесс завершает свою работу. Т.е. во всех ДЛЛ в этом процессе (и нашей ДЛЛ с callback-функцией хука) вызывается DllMain с флагом DLL_PROCESS_DETACH. А у тебя в обработчике DLL_PROCESS_DETACH стоит UnInstallHook(). Так как хэндл хука глобален (по аналогии с hWnd), то вызвав UnInstallHook() в другом процессе ты вообще снимешь свой хук. Может я и ошибся в рассуждениях, но это первое, что бросилось в глаза. А почему хук работает внутри одного процесса (точнее было бы сказать для одного потока) я не знаю - возможно ты ошибся.
Все заработало. Поставил DllMain(HINSTANCE hInst, DWORD ul_reason_for_call, LPVOID lpReserved) вместо DllMain(HANDLE hModule... Странно все таки как-то.
Странно, конечно, но MSDN говорит ставить именно HINSTANCE: Код (Text): BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved );
Вот пришло в хук сообщение WM_KEYDOWN к примеру. А как сделать чтобы сообщение не долшо приложению или вообще поменять на другой мессаж???
что бы сообщение не дошло до адресата убираешь CallNextHookEx и вставляешь return 1 Поменять на другой мессаж? смотря на какой. Нужно курить структуры, на которые ссылается lParam. Соответственно сформировать свою структуру сообщения, и занести ее в lParam и вызвать return CallNextHookEx(NULL, nCode, wParam, lParam);.
Пытаюсь вставить определенный текст в позицию курсора. Но сообщение не всегда срабатывает. Может есть другие способы как это сделать? Код (Text): //обработка мессажа от хука WM_HOOK OpenClipboard(hWndDlg); EmptyClipboard(); hglbCopy = GlobalAlloc(GMEM_MOVEABLE,strlen(stData[wParam].szData)+1); GlobalLock(hglbCopy); lptstrCopy = (LPTSTR)GlobalLock(hglbCopy); memcpy(lptstrCopy,&stData[wParam].szData, strlen(stData[wParam].szData)+1); GlobalUnlock(hglbCopy); SetClipboardData(CF_TEXT, hglbCopy); CloseClipboard(); GetCursorPos(&pt); hW=WindowFromPoint(pt); SendMessage(hW,WM_PASTE,0,0);