Hlavnφ
Hlavnφ strana
Seznam Φlßnk∙
NejΦten∞jÜφ Φlßnky
Progres e-mailem
Visual C++ FAQ

Serißly
COM
ISAPI

banner1.gif (2545 bytes)

Nenechte si ujφt
NeobdΘlnφkovß okna
Tisk bez Preview
MFC a DLL
Logo v MDI ploÜe
Kouzla s kombo-boxem
V²jimky v C++

banner.gif (3305 bytes)

Hook - monitorovßnφ zprßv II. Jan Odvßrko
12.11.1999
[Hlavnφ strßnka]  |  [Rubrika]  |  [Download]

...pokraΦovßnφ a dokonΦenφ Φlßnku z p°edchozφ Φßsti.

4. Monitorovßnφ zprßv od myÜi
V nßsledujφcφm p°φkladu pou₧ijeme mechanismu hookovßnφ pro monitorovßnφ vÜech zprßv od myÜi. P°ipome≥me jen, ₧e reagovßnφm v okΘnkovΘ procedu°e, odchytßvßme tyto zprßvy pouze tehdy, nachßzφ-li se myÜ nad p°φsluÜn²m oknem. To samoz°ejm∞ nemusφ v n∞kter²ch p°φpadech postaΦovat. Proto₧e budeme vytvß°et globßlnφ hook, musφme monitorovacφ proceduru umφstit do DLL knihovny. Tato knihovna se pak bude automaticky nahrßvat do dalÜφch proces∙.

4.1 DLL knihovna
V tΘto DLL knihovn∞ vytvo°φme dv∞ globßlnφ prom∞nnΘ. Prvnφ z nich je theInstance, kterß bude obsahovat handle DLL knihovny a druhß ghMouseHook, kterß bude obsahovat handle hookovacφ procedury. Jejich definice je nßsledujφcφ.

HINSTANCE theInstance = NULL;
HHOOK ghMouseHook = NULL;

Prvnφ dv∞ funkce, kterΘ implementujeme jsou HookMouse a UnhookMouse. Jako v₧dy se nejd°φve podφvßme na jejich zdrojov² k≤d.

BOOL HookMouse()
{
 ghMouseHook = ::SetWindowsHookEx(WH_MOUSE, (HOOKPROC) MouseHookCallback,
    theInstance, 0);
  return (ghMouseHook != NULL);
}

BOOL UnhookMouse()
{
  return UnhookWindowsHookEx(ghMouseHook);
}

Funkce HookMouse zajiÜ¥uje instalaci hookovacφ procedury a inicializuje globßlnφ prom∞nnou ghMouseHook. Funkce UnhookMouse tuto proceduru jednoduÜe odinstaluje. Ob∞ dv∞ funkce musφ b²t z DLL knihovny exportovßny. Export t∞chto funkcφ zajistφme hlaviΦkov²m souborem, kter² bude spoleΦn²  pro DLL knihovnu i pro aplikaci (tzn. musφme jej vlo₧it do DLL i do EXE). Jeho obsah je nßsledujφcφ.

__declspec(dllexport) BOOL HookMouse();
__declspec(dllexport) BOOL UnhookMouse();

Poslednφ funkcφ v knihovn∞ je samotnß monitorovacφ procedura.

LRESULT CALLBACK MouseHookCallback( int nCode, WPARAM wParam,
  LPARAM lParam )
{
  if (nCode < 0)
    return CallNextHookEx(ghMouseHook, nCode, wParam, lParam);

  if (wParam == WM_MOUSEMOVE || wParam == WM_NCMOUSEMOVE)
  {
    LPMOUSEHOOKSTRUCT mhs = (LPMOUSEHOOKSTRUCT) lParam;

    CWnd* poWnd = CWnd::FindWindow(NULL, "MouseHook");
    if (poWnd != NULL)
    {
      poWnd->PostMessage((UINT) wParam, 0,
        MAKELPARAM(mhs->pt.x, mhs->pt.y));
    }
  }
  return CallNextHookEx(ghMouseHook, nCode, wParam, lParam);
}

V prvnφm parametru nCode obdr₧φ funkce k≤d, kter² specifikuje zp∙sob zpracovßnφ zprßvy. Pokud je tento parametr nastaven na hodnotu HC_ACTION nebo HC_NOREMOVE je jistΘ, ₧e v parametrech wParam a lParam jsou dalÜφ informace. Hodnota HC_NOREMOVE dßle °φkß, ₧e zprßva nebude vyjmuta z fronty (aplikace volala PeekMessage s p°φznakem PM_NOREMOVE). Pokud je parametr menÜφ ne₧ 0 musφme funkci okam₧it∞ ukonΦit volßnφm CallNextHookEx.V parametru wParam obdr₧φ tato metoda k≤d zprßvy od myÜi a v parametru lParam ukazatel na strukturu MOUSEHOOKSTRUCT, kterß obsahuje dalÜφ informace (nap°. sou°adnice myÜi). Nßsledujφcφ zdrojov² k≤d ukazuje ΦlenskΘ prom∞nnΘ tΘto struktury.

V p°φpad∞, ₧e byla odchycena zprßva WM_MOUSEMOVE, nebo WM_NCMOUSEMOVE pokusφme se pomocφ metody FindWindow vyhledat okno s aplikacφ a zaslat mu zprßvu o pohybu myÜi. Tato metoda ve svΘm druhΘm parametru oΦekßvß jmΘno okna.

4.2 Aplikace
Nynφ vytvo°φme aplikaci, kterß bude p°ijφmat zprßvy od hookovacφ procedury a bude zobrazovat aktußlnφ polohu myÜi. Pro nßÜ p°φklad zvolφme jednoduch² model dialog-based aplikace. V okam₧iku vytvo°enφ dialogu (v reakci na zprßvu WM_CREATE) nainstalujeme hook volßnφm exportovanΘ funkce HookMouse a p°i zavφrßnφ dialogu (v reakci na WM_DESTROY), tzn. p°i ukonΦovßnφ aplikace, zavolßme druhou exportovanou funkci UnhookMouse a proceduru odinstalujeme.

int CMouseHookDlgAPP::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
  if (CDialog::OnCreate(lpCreateStruct) == -1)
    return -1;
  
  if (!HookMouse())
    return -1;

  return 0;
}

void CMouseHookDlgAPP
::OnDestroy() 
{
  UnhookMouse();
  CDialog::OnDestroy();
}

Poslednφ reakce bude na zprßvy WM_MOUSEMOVE a WM_NCMOUSEMOVE, ve kter²ch budeme nastavovat statick² text v dialogu tak, aby zobrazoval aktußlnφ sou°adnice. Podφvejme se na zdrojov² k≤d t∞chto funkcφ.

void CMouseHookDlgAPP::OnMouseMove(UINT nFlags, CPoint point) 
{
  m_sMousePosition.Format("Pozice myÜi x:%d, y:%d", point.x, point.y);
  UpdateData(FALSE);
  CDialog::OnMouseMove(nFlags, point);
}

void CMouseHookDlgAPP::OnNcMouseMove(UINT nHitTest, CPoint point) 
{
  m_sMousePosition.Format("Pozice myÜi x:%d, y:%d", point.x, point.y);
  UpdateData(FALSE);
  CDialog::OnNcMouseMove(nHitTest, point);
}

Prom∞nnß m_sMousePosition je typu CString a je "namapovanß" na statick² text v dialogovΘ Üablon∞.

jo_11111999_mousehook_obr1.gif (1294 bytes)

 


PodobnΘ Φlßnky: MFC a DLL, dφl 1.,

<<P°edchozφ
Hook - monitorovßnφ zprßv I.
╚lßnek je za°azen do serißlu  

Kdo Otßzka nebo p°ipomφnka

Prohlφ₧enφ p°φsp∞vk∙ nebo nov² p°φsp∞vek

O firm∞... Kontakt ;