Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
hak to mechanizm, za pomocą którego aplikacja może przechwytywać zdarzenia, takie jak komunikaty, ruchy myszy i naciśnięcia. Funkcja, która przechwytuje określony typ zdarzenia, jest nazywana procedurą haka . Procedura haka może działać na każdym odbieranym zdarzeniu, a następnie zmodyfikować lub odrzucić zdarzenie.
Niektóre zastosowania dla haków to:
- Monitorowanie komunikatów na potrzeby debugowania
- Zapewnianie obsługi rejestrowania i odtwarzania makr
- Obsługa klawisza pomocy (F1)
- Symulowanie danych wejściowych myszy i klawiatury
- Implementowanie aplikacji szkoleniowej opartej na komputerze (CBT)
Notatka
Hooki spowalniają system, ponieważ zwiększają ilość przetwarzania, którą system musi wykonać dla każdego komunikatu. Należy zainstalować punkt zaczepienia tylko wtedy, gdy jest to konieczne, i usunąć go tak szybko, jak to możliwe.
W tej sekcji omówiono następujące zagadnienia:
Łańcuchy haków
System obsługuje wiele różnych typów haków; każdy typ zapewnia dostęp do innego aspektu mechanizmu obsługi komunikatów. Na przykład aplikacja może użyć haka WH_MOUSE, aby monitorować ruch komunikatów pod kątem komunikatów myszy.
System utrzymuje oddzielny łańcuch haków dla każdego typu haka. Łańcuch zaczepienia to lista wskaźników do specjalnych, zdefiniowanych przez aplikację funkcji wywołania zwrotnego zwanych procedurami zaczepienia . Gdy wystąpi komunikat skojarzony z określonym typem uchwytu, system przekazuje komunikat do każdej procedury uchwytu, do której odwołuje się łańcuch uchwytu, jeden po drugim. Działanie, które może podjąć procedura, zależy od typu haka. Procedury haków dla niektórych typów haków mogą monitorować tylko komunikaty; inne mogą modyfikować komunikaty lub zatrzymywać ich postęp w łańcuchu, uniemożliwiając dotarcie do następnej procedury haka lub okna docelowego.
Procedury hakowania
Aby skorzystać z określonego typu haka, deweloper udostępnia procedurę haka i używa funkcji SetWindowsHookEx, aby zainstalować ją w łańcuchu skojarzonym z hakiem. Procedura haka musi mieć następującą składnię:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
// process event
...
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
HookProc jest symbolem zastępczym nazwy zdefiniowanej przez aplikację.
Parametr nCode jest kodem zaczepienia używanym przez procedurę zaczepienia w celu określenia działania do podjęcia. Wartość kodu haka zależy od typu haka; każdy typ ma własny zestaw kodów haków. Wartości parametrów wParam i lParam zależą od kodu hook, ale zazwyczaj zawierają informacje o wiadomości, która została wysłana lub opublikowana.
Funkcja SetWindowsHookEx zawsze instaluje procedurę zaczepu na początku łańcucha zaczepów. Gdy wystąpi zdarzenie monitorowane przez określony typ uchwytu, system wywołuje procedurę na początku łańcucha związanego z uchwytem. Każda procedura haka w łańcuchu określa, czy należy przekazać zdarzenie do następnej procedury. Procedura zaczepienia przekazuje zdarzenie do następnej procedury przez wywołanie funkcji CallNextHookEx.
Należy pamiętać, że procedury zaczepów dla pewnych typów zaczepów mogą monitorować tylko komunikaty. System przekazuje komunikaty do każdej procedury haka, niezależnie od tego, czy określona procedura wywołuje funkcję CallNextHookEx.
Globalny hak monitoruje komunikaty dla wszystkich wątków na tym samym pulpicie co wątek wywołujący. Hak specyficzny dla wątku monitoruje komunikaty tylko dla pojedynczego wątku. Globalna procedura haka może być wywoływana w kontekście dowolnej aplikacji na tym samym pulpicie co wątek wywołujący, więc procedura musi znajdować się w osobnym module DLL. Procedura haka specyficzna dla wątku jest wywoływana tylko w kontekście skojarzonego wątku. Jeśli aplikacja instaluje procedurę haka dla jednego z własnych wątków, procedura haka może znajdować się w tym samym module co pozostała część kodu aplikacji lub w pliku DLL. Jeśli aplikacja instaluje procedurę haka dla wątku innej aplikacji, procedura musi znajdować się w dll. Aby uzyskać informacje, zobacz Dynamic-Link Biblioteki.
Notatka
Należy używać globalnych punktów zaczepienia tylko do celów debugowania; w przeciwnym razie należy ich unikać. Globalne haki szkodzą wydajności systemu i powodują konflikty z innymi aplikacjami, które implementują ten sam typ haka globalnego.
Typy punktów zaczepienia
Każdy typ zaczepienia umożliwia aplikacji monitorowanie innego aspektu mechanizmu obsługi komunikatów systemu. W poniższych sekcjach opisano dostępne haczyki.
- WH_CALLWNDPROC i WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KLAWIATURA
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER i WH_SYSMSGFILTER
- WH_SHELL
WH_CALLWNDPROC i WH_CALLWNDPROCRET
Haki WH_CALLWNDPROC i WH_CALLWNDPROCRET umożliwiają monitorowanie wiadomości wysyłanych do procedur okiennych. System wywołuje procedurę zaczepu WH_CALLWNDPROC przed przekazaniem komunikatu do procedury okna odbierającego i wywołuje procedurę zaczepu WH_CALLWNDPROCRET po tym, jak procedura okna przetworzy komunikat.
Hak WH_CALLWNDPROCRET przekazuje wskaźnik do struktury CWPRETSTRUCT do procedury haka. Struktura zawiera wartość zwracaną z procedury okna, która przetworzyła komunikat, a także parametry komunikatu skojarzone z komunikatem. Podklasowanie okna nie działa w przypadku komunikatów ustawionych między procesami.
Aby uzyskać więcej informacji, zobacz CallWndProc i CallWndRetProc funkcji wywołania zwrotnego.
WH_CBT
System wywołuje procedurę zaczepu WH_CBT przed aktywowaniem, tworzeniem, niszczeniem, minimalizowaniem, maksymalizowaniem, przenoszeniem lub zmianą rozmiaru okna; przed ukończeniem polecenia systemowego; przed usunięciem zdarzenia myszy lub klawiatury z kolejki komunikatów systemowych; przed ustawieniem fokusu wejściowego; lub przed zsynchronizowaniem z kolejką komunikatów systemowych. Wartość zwracana przez procedurę punktów zaczepienia określa, czy system zezwala na wykonywanie jednej z tych operacji, czy też uniemożliwia wykonywanie jednej z tych operacji. Hak WH_CBT jest przeznaczony głównie dla aplikacji szkoleniowych opartych na komputerach (CBT).
Aby uzyskać więcej informacji, zobacz funkcję callback CBTProc.
Aby uzyskać informacje, zobacz WinEvents.
WH_DEBUG
System wywołuje procedurę haka WH_DEBUG przed wywołaniem procedur haka skojarzonych z innym hakiem w systemie. Możesz użyć tego uchwytu, aby określić, czy umożliwić systemowi wywoływanie procedur skojarzonych z innymi typami uchwytów.
Aby uzyskać więcej informacji, zapoznaj się z funkcją wywołania zwrotnego DebugProc.
WH_FOREGROUNDIDLE
Hak WH_FOREGROUNDIDLE umożliwia wykonywanie zadań o niskim priorytecie, gdy wątek pierwszego planu jest bezczynny. System wywołuje procedurę haka WH_FOREGROUNDIDLE, gdy wątek aplikacji w pierwszym planie staje się bezczynny.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego ForegroundIdleProc.
WH_GETMESSAGE
Hak WH_GETMESSAGE umożliwia aplikacji monitorowanie komunikatów, które mają być zwracane przez funkcję GetMessage lub PeekMessage. Możesz użyć haka WH_GETMESSAGE do monitorowania wprowadzania myszy i klawiatury oraz innych komunikatów opublikowanych w kolejce komunikatów.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego GetMsgProc.
WH_JOURNALPLAYBACK
Ostrzeżenie
Interfejsy API dzienników punktów zaczepienia nie są obsługiwane począwszy od systemu Windows 11 i zostaną usunięte w przyszłej wersji. W związku z tym zdecydowanie zalecamy wywołanie API SendInput TextInput.
Hak WH_JOURNALPLAYBACK umożliwia aplikacji wstawianie komunikatów do kolejki komunikatów systemowych. Możesz użyć tego hooka, aby odtworzyć serię wcześniej zarejestrowanych zdarzeń myszy i klawiatury za pomocą WH_JOURNALRECORD. Zwykłe wejście myszy i klawiatury jest wyłączone, jeśli jest zainstalowana procedura hakowa WH_JOURNALPLAYBACK. Hak WH_JOURNALPLAYBACK jest globalnym hakiem — nie można go używać jako haka specyficznego dla wątku.
Punkt zaczepienia WH_JOURNALPLAYBACK zwraca wartość limitu czasu. Ta wartość informuje system o tylu milisekundach oczekiwania przed przetworzeniem bieżącego komunikatu z punktu zaczepienia odtwarzania. To umożliwia hakowi kontrolowanie czasu i przebiegu zdarzeń.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego JournalPlaybackProc.
WH_JOURNALRECORD
Ostrzeżenie
Interfejsy API dzienników punktów zaczepienia nie są obsługiwane począwszy od systemu Windows 11 i zostaną usunięte w przyszłej wersji. W związku z tym zdecydowanie zalecamy wywołanie API SendInput TextInput.
Hak WH_JOURNALRECORD umożliwia monitorowanie i rejestrowanie zdarzeń wejściowych. Zazwyczaj ten hak służy do rejestrowania sekwencji zdarzeń myszy i klawiatury do odtwarzania później przy użyciu WH_JOURNALPLAYBACK. Hak WH_JOURNALRECORD jest globalnym hakiem — nie można go używać jako haka specyficznego dla wątku.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego JournalRecordProc.
WH_KEYBOARD_LL
Hak WH_KEYBOARD_LL umożliwia monitorowanie zdarzeń związanych z wejściem klawiatury, które mają być umieszczane w kolejce wejściowej dla wątku.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego LowLevelKeyboardProc.
WH_KLAWIATURA
Hak WH_KEYBOARD umożliwia aplikacji monitorowanie przepływu komunikatów dla WM_KEYDOWN i WM_KEYUP komunikatów, które mają być zwracane przez funkcję GetMessage lub PeekMessage. Możesz użyć haka WH_KEYBOARD do monitorowania danych wejściowych klawiatury, które trafiają do kolejki komunikatów.
Aby uzyskać więcej informacji, zobacz funkcję wywołania zwrotnego KeyboardProc.
WH_MOUSE_LL
Hak WH_MOUSE_LL umożliwia monitorowanie zdarzeń wejściowych myszy, które mają być publikowane w kolejce wejściowej wątku.
Aby uzyskać więcej informacji, zobacz procedurę wywołania zwrotnego LowLevelMouseProc.
WH_MOUSE
Hak WH_MOUSE umożliwia monitorowanie komunikatów myszy, które mają być zwracane przez funkcję GetMessage lub PeekMessage. Możesz użyć haka WH_MOUSE do monitorowania danych wejściowych myszy opublikowanych w kolejce komunikatów.
Aby uzyskać więcej informacji, zapoznaj się z funkcją wywołania zwrotnego MouseProc.
WH_MSGFILTER i WH_SYSMSGFILTER
Haki WH_MSGFILTER i WH_SYSMSGFILTER umożliwiają monitorowanie komunikatów, które mają być przetworzone przez menu, pasek przewijania, okno komunikatu lub okno dialogowe, a także wykrywanie, kiedy inne okno ma zostać aktywowane w wyniku naciśnięcia kombinacji klawiszy ALT+TAB lub ALT+ESC. Hak WH_MSGFILTER może monitorować komunikaty przekazywane tylko do menu, paska przewijania, okna komunikatu lub okna dialogowego utworzonego przez aplikację, która zainstalowała procedurę haka. Hak WH_SYSMSGFILTER monitoruje takie komunikaty dla wszystkich aplikacji.
Haki WH_MSGFILTER i WH_SYSMSGFILTER umożliwiają przeprowadzanie filtrowania komunikatów podczas pętli modalnych, co odpowiada filtrowaniu wykonywanemu w głównej pętli komunikatów. Na przykład aplikacja często analizuje nowy komunikat w pętli głównej między czasem pobierania komunikatu z kolejki a czasem wysyłania komunikatu, wykonując specjalne przetwarzanie zgodnie z potrzebami. Jednak podczas pętli modalnej system pobiera i wysyła komunikaty bez zezwalania aplikacji na filtrowanie komunikatów w głównej pętli komunikatów. Jeśli aplikacja instaluje procedurę haka WH_MSGFILTER lub WH_SYSMSGFILTER, system wywołuje tę procedurę podczas pętli modalnej.
Aplikacja może wywołać punkt zaczepienia WH_MSGFILTER bezpośrednio, wywołując funkcję CallMsgFilter. Korzystając z tej funkcji, aplikacja może używać tego samego kodu do filtrowania komunikatów podczas modalnych pętli, jaki jest używany w głównej pętli komunikatów. W tym celu hermetyzuj operacje filtrowania w procedurze WH_MSGFILTER haka i wywołaj CallMsgFilter między wywołaniami funkcji GetMessage i DispatchMessage.
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
if (!CallMsgFilter(&qmsg, 0))
DispatchMessage(&qmsg);
}
Ostatni argument CallMsgFilter jest po prostu przekazywany do procedury hooka. Można wprowadzić dowolną wartość. Procedura haka, definiując stałą, taką jak MSGF_MAINLOOP, może użyć tej wartości, aby określić, skąd została wywołana procedura.
Aby uzyskać więcej informacji, zobacz funkcje wywołania zwrotnego MessageProc i SysMsgProc.
WH_SHELL
Aplikacja powłoki może używać haka WH_SHELL do odbierania ważnych powiadomień. System wywołuje procedurę hook WH_SHELL, gdy aplikacja powłoki ma zostać aktywowana oraz gdy zostanie utworzone lub zniszczone okno najwyższego poziomu.
Należy pamiętać, że niestandardowe aplikacje powłoki nie otrzymują komunikatów WH_SHELL. W związku z tym każda aplikacja, która rejestruje się jako powłoka domyślna, musi wywołać funkcję SystemParametersInfo, zanim ona sama (lub inna aplikacja) będzie mogła odbierać komunikaty WH_SHELL. Ta funkcja musi być wywoływana przy użyciu SPI_SETMINIMIZEDMETRICS i struktury MINIMIZEDMETRICS. Ustaw element iArrange tej struktury na ARW_HIDE.
Aby uzyskać więcej informacji, zobacz funkcję ShellProc wywołania zwrotnego.