...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∞.
|