Клавиатурный и мышиный хук
От: lexer_lx Украина  
Дата: 24.05.05 05:52
Оценка:
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) {
                  .........
        }
}


При запуске приложения есть реакция на нажатия клавиш, от мыши ничего не приходит.
Если убрать фокус с окна приложения, то и от клавы ничего не приходит.
И если потом вернуть его, то тоже не приходит ничего.

В чем моя ошибка ?
И плз, не отсылайет меня в хелпам =)
Благодарен за любые советы, кроме отсылания к хелпам )
Re: Клавиатурный и мышиный хук
От: dpisarciuc  
Дата: 24.05.05 08:08
Оценка:
Здравствуйте, 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
Re: Клавиатурный и мышиный хук
От: Игорь Вартанов Ниоткуда  
Дата: 24.05.05 09:34
Оценка:
Здравствуйте, 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, но статьи сайта-то можно было прочесть? Или имеет место классическая ситуация "не читатель — писатель"?

Здесь я давал пример написания системного хука. Там и хук-длль, и запускающий процесс — все упрощено до безобразия. Единственное отличие — другой тип хука, но твои проблемы пока не в этом.
---
С уважением,
Игорь
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.