Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Ein Hook ist ein Mechanismus, mit dem eine Anwendung Ereignisse wie Nachrichten, Mausaktionen und Tastaturanschläge abfangen kann. Eine Funktion, die einen bestimmten Ereignistyp abfangen kann, wird als Hook-Prozedur bezeichnet. Eine Hook-Prozedur kann auf jedes empfangene Ereignis reagieren und dann das Ereignis ändern oder verwerfen.
Im Folgenden finden Sie einige Beispiele für die Verwendung von Hooks:
- Überwachen von Nachrichten für Debuggingzwecke
- Bereitstellen von Unterstützung für die Aufzeichnung und Wiedergabe von Makros
- Unterstützung für eine Hilfeschlüssel (F1) bereitstellen
- Simulieren von Maus- und Tastatureingaben
- Implementieren einer computerbasierten Schulung (CBT)-Anwendung
Hinweis
Hooks neigen dazu, das System zu verlangsamen, da sie die Verarbeitung des Systems für jede Nachricht erhöhen müssen. Sie sollten einen Hook nur bei Bedarf installieren und so bald wie möglich entfernen.
In diesem Abschnitt wird Folgendes erläutert:
Hook-Ketten
Das System unterstützt viele verschiedene Arten von Haken; jeder Typ bietet Zugriff auf einen anderen Aspekt des Nachrichtenbehandlungsmechanismus. Beispielsweise kann eine Anwendung den WH_MOUSE Hook verwenden, um den Nachrichtendatenverkehr für Mausnachrichten zu überwachen.
Das System verwaltet eine separate Hakenkette für jeden Hakentyp. Eine Hookchain ist eine Liste von Zeigern auf spezielle, anwendungsdefinierte Rückruffunktionen, die als Hook-Prozeduren bezeichnet werden. Wenn eine Nachricht auftritt, die einem bestimmten Hooktyp zugeordnet ist, übergibt das System die Nachricht an jede Hookprozedur, auf die in der Hookkette verwiesen wird, eine nach der anderen. Die Aktion, die eine Hook-Prozedur ausführen kann, hängt von der Art des beteiligten Hooks ab. Die Hook-Prozeduren für einige Arten von Hooks können nur Nachrichten überwachen; andere können Nachrichten ändern oder ihren Fortschritt durch die Kette unterbrechen, sodass diese das nächste Hook-Verfahren oder das Zielfenster nicht erreichen.
Hook-Prozeduren
Um eine bestimmte Art von Hook zu nutzen, stellt der Entwickler ein Hook-Verfahren bereit und verwendet die SetWindowsHookEx-Funktion , um ihn in der Kette zu installieren, die dem Hook zugeordnet ist. Eine Hook-Prozedur muss die folgende Syntax aufweisen:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
// process event
...
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
HookProc ist ein Platzhalter für einen anwendungsdefinierten Namen.
Der nCode-Parameter ist ein Hook-Code, den die Hook-Prozedur verwendet, um die auszuführende Aktion zu bestimmen. Der Wert des Hook-Codes hängt vom Typ des Hooks ab; jeder Typ verfügt über einen eigenen Merkmalssatz von Hookcodes. Die Werte der Parameter "wParam" und "lParam" hängen vom Hookcode ab, enthalten jedoch in der Regel Informationen zu einer gesendeten oder geposteten Nachricht.
Die Funktion SetWindowsHookEx installiert immer eine Hook-Prozedur am Anfang einer Hook-Kette. Wenn ein Ereignis auftritt, das von einer bestimmten Art von Hook überwacht wird, ruft das System die Prozedur zu Beginn der Hook-Kette auf, die dem Hook zugeordnet ist. Jede Hook-Prozedur in der Kette bestimmt, ob das Ereignis an die nächste Prozedur weitergegeben werden soll. Eine Hook-Prozedur übergibt ein Ereignis an die nächste Prozedur, indem die CallNextHookEx-Funktion aufgerufen wird.
Beachten Sie, dass die Hook-Prozeduren für einige Typen von Hooks nur Nachrichten überwachen können. Das System übergibt Nachrichten an jede Hook-Prozedur, unabhängig davon, ob eine bestimmte Prozedur CallNextHookEx aufruft.
Ein globaler Hook überwacht Nachrichten für alle Threads auf demselben Desktop wie der aufrufende Thread. Ein threadspezifischer Hook überwacht Nachrichten nur für einen einzelnen Thread. Eine globale Hook-Prozedur kann im Kontext einer beliebigen Anwendung auf demselben Desktop wie der aufrufende Thread aufgerufen werden, daher muss sich die Prozedur in einem separaten DLL-Modul befinden. Eine threadspezifische Hook-Prozedur wird nur im Kontext des zugeordneten Threads aufgerufen. Wenn eine Anwendung eine Hook-Prozedur für einen ihrer eigenen Threads installiert, kann sich die Hook-Prozedur entweder im gleichen Modul wie der restliche Code der Anwendung oder in einer DLL befinden. Wenn die Anwendung eine Hook-Prozedur für einen Thread einer anderen Anwendung installiert, muss sich die Prozedur in einer DLL-Datei befindet. Weitere Informationen finden Sie unter Dynamic-Link Bibliotheken.
Hinweis
Sie sollten globale Hooks nur für Debuggingzwecke verwenden; andernfalls sollten Sie sie vermeiden. Globale Hooks verletzen die Systemleistung und verursachen Konflikte mit anderen Anwendungen, die dieselbe Art von globalen Hook implementieren.
Hakenarten
Jede Art von Hook ermöglicht es einer Anwendung, einen anderen Aspekt des Nachrichtenbehandlungsmechanismus des Systems zu überwachen. In den folgenden Abschnitten werden die verfügbaren Hooks beschrieben.
- WH_CALLWNDPROC und WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER und WH_SYSMSGFILTER
- WH_SHELL
WH_CALLWNDPROC und WH_CALLWNDPROCRET
Mit den WH_CALLWNDPROC - und WH_CALLWNDPROCRET-Hooks können Sie Nachrichten überwachen, die an Fensterprozeduren gesendet werden. Das System ruft eine WH_CALLWNDPROC Hook-Prozedur auf, bevor die Nachricht an die empfangende Fensterprozedur übergeben wird, und ruft die WH_CALLWNDPROCRET Hook-Prozedur auf, nachdem die Fensterprozedur die Nachricht verarbeitet hat.
Der WH_CALLWNDPROCRET Hook übergibt einen Zeiger auf eine CWPRETSTRUCT-Struktur an die Hook-Prozedur. Die Struktur enthält den Rückgabewert aus der Fensterprozedur, die die Nachricht verarbeitet hat, sowie die Nachrichtenparameter, die der Nachricht zugeordnet sind. Die Unterklassifizierung des Fensters funktioniert nicht für Nachrichten, die zwischen Prozessen festgelegt sind.
Weitere Informationen finden Sie in den CallWndProc - und CallWndRetProc-Rückruffunktionen .
WH_CBT
Das System ruft eine WH_CBT Hook-Prozedur auf, bevor ein Fenster aktiviert, erstellt, zerstört, minimiert, maximiert, bewegt oder verkleinert wird; vor Abschluss eines Systembefehls; vor dem Entfernen eines Maus- oder Tastaturereignisses aus der Systemnachrichtenwarteschlange; vor dem Festlegen des Eingabefokus; oder bevor Sie die Synchronisierung mit der Systemnachrichtenwarteschlange ausführen. Der Wert, den die Hook-Prozedur zurückgibt, bestimmt, ob das System einen dieser Vorgänge zulässt oder verhindert. Der WH_CBT Hook ist in erster Linie für computerbasierte Schulungsanwendungen (CBT) vorgesehen.
Weitere Informationen finden Sie in der CBTProc-Rückruffunktion .
Weitere Informationen finden Sie unter WinEvents.
WH_DEBUG
Das System ruft eine WH_DEBUG Hook-Prozedur auf, bevor Hook-Prozeduren aufgerufen werden, die anderen Hooks im System zugeordnet sind. Sie können diesen Hook verwenden, um zu bestimmen, ob das System Hook-Prozeduren aufrufen kann, die anderen Arten von Hooks zugeordnet sind.
Weitere Informationen finden Sie in der DebugProc-Rückruffunktion .
WH_FOREGROUNDIDLE
Mit dem WH_FOREGROUNDIDLE-Hook können Sie Aufgaben mit niedriger Priorität in Zeiten ausführen, in denen sich der Vordergrundthread im Leerlauf befindet. Das System ruft eine WH_FOREGROUNDIDLE-Hook-Prozedur auf, wenn der Vordergrundthread der Anwendung kurz davor steht, in den Leerlauf zu gehen.
Weitere Informationen finden Sie in der ForegroundIdleProc-Rückruffunktion .
WH_GETMESSAGE
Der WH_GETMESSAGE-Hook ermöglicht es einer Anwendung, Nachrichten zu überwachen, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden. Sie können den WH_GETMESSAGE-Hook verwenden, um Maus- und Tastatureingaben und andere Nachrichten zu überwachen, die in der Nachrichtenwarteschlange gepostet wurden.
Weitere Informationen finden Sie in der GetMsgProc-Rückruffunktion .
WH_JOURNALPLAYBACK
Warnung
Journaling-Hooks-APIs werden ab Windows 11 nicht mehr unterstützt und in einem zukünftigen Release entfernt. Aus diesem Grund empfehlen wir dringend, stattdessen die SendInput TextInput-API aufzurufen.
Der WH_JOURNALPLAYBACK-Hook ermöglicht es einer Anwendung, Nachrichten in die Systemnachrichtenwarteschlange einzufügen. Sie können diesen Hook verwenden, um eine Reihe von Maus- und Tastaturereignissen wiederzugeben, die zuvor mithilfe von WH_JOURNALRECORD aufgezeichnet wurden. Die normale Maus- und Tastatureingabe ist deaktiviert, solange ein WH_JOURNALPLAYBACK Haken installiert ist. Ein WH_JOURNALPLAYBACK Hook ist ein globaler Hook– er kann nicht als threadspezifischer Hook verwendet werden.
Der WH_JOURNALPLAYBACK Hook gibt einen Timeoutwert zurück. Dieser Wert gibt dem System an, wie viele Millisekunden warten müssen, bevor die aktuelle Nachricht aus dem Wiedergabehaken verarbeitet wird. Damit kann der Hook das Timing der Ereignisse steuern, die er widerspiegelt.
Weitere Informationen finden Sie in der JournalPlaybackProc-Rückruffunktion .
WH_JOURNALRECORD
Warnung
Journaling-Hooks-APIs werden ab Windows 11 nicht mehr unterstützt und in einem zukünftigen Release entfernt. Aus diesem Grund empfehlen wir dringend, stattdessen die SendInput TextInput-API aufzurufen.
Mit dem WH_JOURNALRECORD Hook können Sie Eingabeereignisse überwachen und aufzeichnen. In der Regel verwenden Sie diesen Hook, um eine Sequenz von Maus- und Tastaturereignissen aufzuzeichnen, um später mithilfe von WH_JOURNALPLAYBACK wiederzugeben. Der WH_JOURNALRECORD Hook ist ein globaler Hook, der nicht als threadspezifischer Hook verwendet werden kann.
Weitere Informationen finden Sie in der JournalRecordProc-Rückruffunktion .
WH_KEYBOARD_LL
Mit dem WH_KEYBOARD_LL Hook können Sie Tastatureingabeereignisse überwachen, die in einer Threadeingabewarteschlange gepostet werden sollen.
Weitere Informationen finden Sie in der LowLevelKeyboardProc-Rückruffunktion .
WH_KEYBOARD
Der WH_KEYBOARD-Hook ermöglicht es einer Anwendung, den Nachrichtendatenverkehr für WM_KEYDOWN zu überwachen, und WM_KEYUP Nachrichten, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden sollen. Sie können den WH_KEYBOARD-Hook verwenden, um die tastatureingaben zu überwachen, die in einer Nachrichtenwarteschlange gepostet wurden.
Weitere Informationen finden Sie in der KeyboardProc-Rückruffunktion .
WH_MOUSE_LL
Mit dem WH_MOUSE_LL Hook können Sie Mauseingabeereignisse überwachen, die in einer Threadeingabewarteschlange gepostet werden sollen.
Weitere Informationen finden Sie in der LowLevelMouseProc-Rückruffunktion .
WH_MOUSE
Mit dem WH_MOUSE Hook können Sie Mausnachrichten überwachen, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden sollen. Sie können den WH_MOUSE-Hook verwenden, um mauseingaben zu überwachen, die in eine Nachrichtenwarteschlange gepostet wurden.
Weitere Informationen finden Sie in der MouseProc-Rückruffunktion .
WH_MSGFILTER und WH_SYSMSGFILTER
Mit den WH_MSGFILTER - und WH_SYSMSGFILTER-Hooks können Sie Nachrichten überwachen, die von einem Menü, einer Bildlaufleiste, einem Meldungsfeld oder einem Dialogfeld verarbeitet werden. Außerdem können Sie erkennen, wann ein anderes Fenster aufgrund der Tastenkombination ALT+TAB oder ALT+ESC aktiviert werden soll. Der WH_MSGFILTER Hook kann nur Nachrichten überwachen, die an ein Menü, eine Bildlaufleiste, ein Meldungsfeld oder ein Dialogfeld übergeben werden, das von der Anwendung erstellt wurde, die die Hookprozedur installiert hat. Der WH_SYSMSGFILTER Hook überwacht solche Meldungen für alle Anwendungen.
Mit den WH_MSGFILTER und WH_SYSMSGFILTER-Hooks können Sie Nachrichten filtern während modaler Schleifen, was der Filterung in der Hauptnachrichtenschleife entspricht. Zum Beispiel untersucht eine Anwendung oft eine neue Nachricht in der Hauptschleife zwischen dem Zeitpunkt, zu dem sie die Nachricht aus der Warteschlange abruft, und dem Zeitpunkt, zu dem sie die Nachricht weiterleitet und dabei falls erforderlich eine spezielle Verarbeitung durchführt. Während einer modalen Schleife ruft das System Nachrichten jedoch ab und verteilt sie, ohne einer Anwendung die Möglichkeit zu geben, die Nachrichten in der Hauptnachrichtenschleife zu filtern. Wenn eine Anwendung eine WH_MSGFILTER- oder WH_SYSMSGFILTER-Hook-Prozedur installiert, ruft das System die Prozedur während der modalen Schleife auf.
Eine Anwendung kann den WH_MSGFILTER Hook direkt aufrufen, indem die CallMsgFilter-Funktion aufgerufen wird. Mithilfe dieser Funktion kann die Anwendung denselben Code verwenden, um Nachrichten während modaler Schleifen zu filtern, wie sie in der Hauptnachrichtenschleife verwendet wird. Kapseln Sie dazu die Filtervorgänge in einer WH_MSGFILTER Hook-Prozedur, und rufen Sie CallMsgFilter zwischen den Aufrufen der GetMessage- und DispatchMessage-Funktionen auf.
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
if (!CallMsgFilter(&qmsg, 0))
DispatchMessage(&qmsg);
}
Das letzte Argument von CallMsgFilter wird einfach an die Hook-Prozedur übergeben. Sie können einen beliebigen Wert eingeben. Die Hook-Prozedur kann durch Definieren einer Konstante wie MSGF_MAINLOOP diesen Wert verwenden, um zu bestimmen, wo die Prozedur aufgerufen wurde.
Weitere Informationen finden Sie zu den Callback-Funktionen MessageProc und SysMsgProc.
WH_SHELL
Eine Shellanwendung kann den WH_SHELL Hook verwenden, um wichtige Benachrichtigungen zu empfangen. Das System ruft eine WH_SHELL Hook-Prozedur auf, wenn die Shellanwendung aktiviert werden soll und wenn ein Fenster auf oberster Ebene erstellt oder zerstört wird.
Beachten Sie, dass benutzerdefinierte Shellanwendungen keine WH_SHELL Nachrichten empfangen. Daher muss jede Anwendung, die sich als Standardshell registriert, die SystemParametersInfo-Funktion aufrufen, bevor sie (oder eine andere Anwendung) WH_SHELL Nachrichten empfangen kann. Diese Funktion muss mit SPI_SETMINIMIZEDMETRICS und einer MINIMIZEDMETRICS-Struktur aufgerufen werden. Legen Sie das iArrange-Element dieser Struktur auf ARW_HIDE fest.
Weitere Informationen finden Sie in der ShellProc-Rückruffunktion .