MS VC++ 6.0 MFC Dialog Based App
Нужно поставить хуки глобальной области видимости, т.е., реализованные в dll.
Они должны отсылать главному окну приложения сообщения при нажатии на клавижи или движении мышью.
Хэлпов по этой теме достаточно, но, тем не менее у меня ничего не работает.
Вот код dll:
#define WM_RETURNIDLE (WM_USER + 155)
HWND NSWindow;
HHOOK KeyboardHook,MouseHook;
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
HMODULE ThisDll;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:NSWindow=FindWindow(NULL,"Program");
ThisDll=GetModuleHandle(NULL);
KeyboardHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookProc,ThisDll,NULL);
MouseHook=SetWindowsHookEx(WH_MOUSE,MouseHookProc,ThisDll,NULL);
break;
case DLL_PROCESS_DETACH:if (KeyboardHook) UnhookWindowsHookEx(KeyboardHook);
if (MouseHook) UnhookWindowsHookEx(MouseHook);
}
return true;
}
exported LRESULT CALLBACK KeyboardHookProc(int iCode,WPARAM wParam,LPARAM lParam)
{
if (iCode>=0) {
if (NSWindow) PostMessage(NSWindow,WM_RETURNIDLE,0,0);
}
return CallNextHookEx(KeyboardHook,iCode,wParam,lParam);
}
exported LRESULT CALLBACK MouseHookProc(int iCode,WPARAM wParam,LPARAM lParam)
{
if (iCode>=0) {
if (NSWindow) PostMessage(NSWindow,WM_RETURNIDLE,0,0);
}
return CallNextHookEx(MouseHook,iCode,wParam,lParam);
}
Код приложения:
BOOL CDlg::OnInitDialog() {
HMODULE hHookDll = LoadLibrary("nslib.dll");
}
LRESULT CDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
if (message == WM_RETURNIDLE) {
.........
}
}
При запуске приложения есть реакция на нажатия клавиш, от мыши ничего не приходит.
Если убрать фокус с окна приложения, то и от клавы ничего не приходит.
И если потом вернуть его, то тоже не приходит ничего.
В чем моя ошибка ?
И плз, не отсылайет меня в хелпам =)
Благодарен за любые советы, кроме отсылания к хелпам )
Здравствуйте, lexer_lx, Вы писали:
_>MS VC++ 6.0 MFC Dialog Based App
_>Нужно поставить хуки глобальной области видимости, т.е., реализованные в dll.
_>Они должны отсылать главному окну приложения сообщения при нажатии на клавижи или движении мышью.
_>Хэлпов по этой теме достаточно, но, тем не менее у меня ничего не работает.
_>Вот код dll:
_>_>#define WM_RETURNIDLE (WM_USER + 155)
_>HWND NSWindow;
_>HHOOK KeyboardHook,MouseHook;
_>BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
_> {
_> HMODULE ThisDll;
_> switch (ul_reason_for_call)
_> {
_> case DLL_PROCESS_ATTACH:NSWindow=FindWindow(NULL,"Program");
_> ThisDll=GetModuleHandle(NULL);
_> KeyboardHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookProc,ThisDll,NULL);
_> MouseHook=SetWindowsHookEx(WH_MOUSE,MouseHookProc,ThisDll,NULL);
_> break;
_> case DLL_PROCESS_DETACH:if (KeyboardHook) UnhookWindowsHookEx(KeyboardHook);
_> if (MouseHook) UnhookWindowsHookEx(MouseHook);
_> }
_> return true;
_> }
_>exported LRESULT CALLBACK KeyboardHookProc(int iCode,WPARAM wParam,LPARAM lParam)
_> {
_> if (iCode>=0) {
_> if (NSWindow) PostMessage(NSWindow,WM_RETURNIDLE,0,0);
_> }
_> return CallNextHookEx(KeyboardHook,iCode,wParam,lParam);
_> }
_>exported LRESULT CALLBACK MouseHookProc(int iCode,WPARAM wParam,LPARAM lParam)
_> {
_> if (iCode>=0) {
_> if (NSWindow) PostMessage(NSWindow,WM_RETURNIDLE,0,0);
_> }
_> return CallNextHookEx(MouseHook,iCode,wParam,lParam);
_> }
_>
_>Код приложения:
_>_>BOOL CDlg::OnInitDialog() {
_> HMODULE hHookDll = LoadLibrary("nslib.dll");
_>}
_>LRESULT CDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
_> if (message == WM_RETURNIDLE) {
_> .........
_> }
_>}
_>
_>При запуске приложения есть реакция на нажатия клавиш, от мыши ничего не приходит.
_>Если убрать фокус с окна приложения, то и от клавы ничего не приходит.
_>И если потом вернуть его, то тоже не приходит ничего.
_>В чем моя ошибка ?
_>И плз, не отсылайет меня в хелпам =)
_>Благодарен за любые советы, кроме отсылания к хелпам )
Oshibka v tom chito pri DLL_PROCESS_ATTACH ty pytaeshisea naiti okno tvoego prilojeniya, kotoraya eschio ne suschestvuet (DLL-ki zagrujaiutsya do vhoda v functsiu Main/WinMain prolojeniya).
Moi sovet: sdelati escio 2 exportiruemye functsii (InstallHooks i UninstallHooks) i v OnInitDialog vizivaeshi InstallHooks a v OnDestroy/OnNcDestroy — vyzyvaeshi UninstallHooks.
P.S. Ya dumaya chito ponyatno chito vpisati v eti 2 functsii...
i conechino ubiraeshi vse iz DLL_PROCESS_ATTACH i DLL_PROCESS_DETACH
I eschio, KeyboardHookProc i MoseHookProc mojno ne exportirovati. oni "vneshemu miru" ne interesny
Здравствуйте, lexer_lx, Вы писали:
_>Хэлпов по этой теме достаточно, но, тем не менее у меня ничего не работает.
Хэлпов, действительно, достаточно. Но, похоже, они тебе без особой пользы.
_>HWND NSWindow;
_>HHOOK KeyboardHook,MouseHook;
Во-первых, эти данные нужны во всех экземплярах дллей, но заполняются они один-единственный раз — а именно, при постановке хука. Доставка во все остальные инстансы обеспечивается помещением данных в шареную секцию. Чтобы не имет дополнительного геморроя (просто поверь на слово), их нужно инициализировать.
_>BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
_> {
_> HMODULE ThisDll;
_> switch (ul_reason_for_call)
_> {
_> case DLL_PROCESS_ATTACH:NSWindow=FindWindow(NULL,"Program");
_> ThisDll=GetModuleHandle(NULL);
_> KeyboardHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardHookProc,ThisDll,NULL);
_> MouseHook=SetWindowsHookEx(WH_MOUSE,MouseHookProc,ThisDll,NULL);
_> break;
_> case DLL_PROCESS_DETACH:if (KeyboardHook) UnhookWindowsHookEx(KeyboardHook);
_> if (MouseHook) UnhookWindowsHookEx(MouseHook);
_> }
_> return true;
_> }
Вот здесь написан полный бред. По этому коду видно, что писатель совершенно не понимает механику работы хуков. Каждый аттач к процессу предполагает постановку
нового хука. Спрашивается — нафига?
Следующий момент — ThisDll=GetModuleHandle(NULL);
Чудесный по своей наивности код. GetModuleHandle(NULL)
всегда возвращает инстанс экзешника, для которого создавался процесс. Т.е. это никак не может быть ThisDll. Хук, поставленный на экзешник, не может быть глобальным
_>При запуске приложения есть реакция на нажатия клавиш, от мыши ничего не приходит.
_>Если убрать фокус с окна приложения, то и от клавы ничего не приходит.
_>И если потом вернуть его, то тоже не приходит ничего.
Смотри выше.
_>В чем моя ошибка ?
Которая из? Про шареную секцию я уже сказал, хук ставить на инстанс длии, а не экзешника. Хук-хэндлы тоже надо заполнить вовремя, чтобы всплывшая в чужом процессе длль сразу имела правильные хэндлы.
_>И плз, не отсылайет меня в хелпам =)
_>Благодарен за любые советы, кроме отсылания к хелпам )
Несмотря на то, что я никогда не ругаюсь матом, при виде фразы "не отсылайте меня к хелпам" я всегда испытываю острое желание нарушить собственные правила. А почему, собственно, не отсылать? Ладно — MSDN многие не любят по причине poor English, но статьи сайта-то можно было прочесть? Или имеет место классическая ситуация "не читатель — писатель"?
Здесь я давал пример написания системного хука. Там и хук-длль, и запускающий процесс — все упрощено до безобразия. Единственное отличие — другой тип хука, но твои проблемы пока не в этом.