Share via


SetWindowsHookExA 函式 (winuser.h)

將應用程式定義的攔截程式安裝到勾點鏈結中。 您會安裝攔截程式來監視系統是否有特定類型的事件。 這些事件與特定線程或與呼叫線程位於相同桌面上的所有線程相關聯。

語法

HHOOK SetWindowsHookExA(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);

參數

[in] idHook

類型: int

要安裝的攔截程序類型。 此參數可以是下列其中一個值。

意義
WH_CALLWNDPROC
4

安裝攔截程式,在系統將訊息傳送至目的地視窗程式之前監視訊息。 如需詳細資訊,請參閱 CallWndProc 攔截程式。

WH_CALLWNDPROCRET
12
安裝攔截程式,以監視目的地視窗程序處理訊息之後的訊息。 如需詳細資訊,請參閱 [HOOKPROC 回呼函式] (nc-winuser-hookproc.md) 攔截程式。
WH_CBT
5
安裝攔截程式,以接收對 CBT 應用程式有用的通知。 如需詳細資訊,請參閱 CBTProc 攔截程式。
WH_DEBUG
9

安裝用於偵錯其他攔截程式的攔截程式。 如需詳細資訊,請參閱 DebugProc 攔截程式。

WH_FOREGROUNDIDLE
11

安裝會在應用程式的前景線程即將變成閑置時呼叫的攔截程式。 此勾點適用於在空閒時間執行低優先順序工作。 如需詳細資訊,請參閱 ForegroundIdleProc 攔截程式。

WH_GETMESSAGE
3

安裝攔截程式,以監視張貼至消息佇列的訊息。 如需詳細資訊,請參閱 GetMsgProc 攔截程式。

WH_JOURNALPLAYBACK
1

警告

Windows 11 和更新版本:不支援日誌攔截 API。 建議改用 SendInput TextInput API。

安裝攔截程式,此攔截程式會張貼先前由 WH_JOURNALRECORD 攔截程序記錄的訊息。 如需詳細資訊,請參閱 JournalPlaybackProc 攔截程式。

WH_JOURNALRECORD
0

警告

Windows 11 和更新版本:不支援日誌攔截 API。 建議改用 SendInput TextInput API。

安裝攔截程式,以記錄張貼至系統消息佇列的輸入訊息。 此勾點適用於錄製宏。 如需詳細資訊,請參閱 JournalRecordProc 攔截程式。

WH_KEYBOARD
2

安裝可監視擊鍵訊息的攔截程式。 如需詳細資訊,請參閱 KeyboardProc 攔截程式。

WH_KEYBOARD_LL
13
安裝可監視低階鍵盤輸入事件的攔截程式。 如需詳細資訊,請參閱 [LowLevelKeyboardProc] (/windows/win32/winmsg/lowlevelkeyboardproc) 攔截程式。
WH_MOUSE
7

安裝可監視滑鼠訊息的攔截程式。 如需詳細資訊,請參閱 MouseProc 攔截程式。

WH_MOUSE_LL
14

安裝可監視低階滑鼠輸入事件的攔截程式。 如需詳細資訊,請參閱 LowLevelMouseProc 攔截程式。

WH_MSGFILTER
-1

安裝攔截程式,以監視對話框、消息框、功能表或滾動條中輸入事件所產生的訊息。 如需詳細資訊,請參閱 MessageProc 攔截程式。

WH_SHELL
10
安裝攔截程式,以接收殼層應用程式有用的通知。 如需詳細資訊,請參閱 ShellProc 攔截程式。
WH_SYSMSGFILTER
6

安裝攔截程式,以監視對話框、消息框、功能表或滾動條中輸入事件所產生的訊息。 攔截程式會監視與呼叫線程相同桌面上所有應用程式的這些訊息。 如需詳細資訊,請參閱 SysMsgProc 攔截程式。

[in] lpfn

類型: HOOKPROC

攔截程式的指標。 如果 dwThreadId 參數為零,或指定由不同進程建立的線程標識碼, lpfn 參數必須指向 DLL 中的攔截程式。 否則, lpfn 可以指向與目前進程相關聯之程式代碼中的攔截程式。

[in] hmod

類型: HINSTANCE

DLL 的句柄,其中包含 lpfn 參數所指向的攔截程式。 如果 dwThreadId 參數指定目前進程所建立的線程,而且攔截程式是在與目前進程相關聯的程式代碼內,則 hMod 參數必須設定為 NULL

[in] dwThreadId

類型: DWORD

要與攔截程式相關聯之線程的標識碼。 針對傳統型應用程式,如果此參數為零,攔截程式會與在呼叫線程相同的桌面上執行的所有現有線程相關聯。 針對 Windows 市集應用程式,請參閱一節。

傳回值

類型: HHOOK

如果函式成功,傳回值就是攔截程式的句柄。

如果函式失敗,傳回值為 NULL。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

備註

SetWindowsHookEx 可用來將 DLL 插入另一個進程。 32 位 DLL 無法插入 64 位進程,而 64 位 DLL 無法插入 32 位進程。 如果應用程式需要在其他進程中使用攔截,則需要 32 位應用程式呼叫 SetWindowsHookEx ,將 32 位 DLL 插入 32 位進程,而 64 位應用程式呼叫 SetWindowsHookEx 將 64 位 DLL 插入 64 位進程。 32 位和 64 位 DLL 必須有不同的名稱。

由於攔截會在應用程式的內容中執行,因此它們必須符合應用程式的「位」。 如果 32 位應用程式在 64 位 Windows 上安裝全域攔截,則會將 32 位勾點插入每個 32 位進程, (套用一般安全性界限) 。 在64位進程中,線程仍會標示為「攔截」。不過,因為32位應用程式必須執行攔截程式代碼,所以系統會在勾點應用程式的內容中執行勾點;具體而言,在稱為 SetWindowsHookEx 的線程上。 這表示勾點應用程式必須繼續提取訊息,或者它可能會封鎖64位進程的正常運作。

如果64位應用程式在64位 Windows 上安裝全域攔截,則會將64位勾點插入每個64位進程,而所有32位進程都會使用攔截應用程式的回呼。

若要攔截 64 位 Windows 安裝桌面上的所有應用程式,請安裝 32 位全域勾點和 64 位全域攔截,每個鏈接程式皆來自適當的進程,而且請務必在攔截應用程式中保留幫浦訊息,以避免封鎖正常運作。 如果您已經有 32 位的全域勾點應用程式,而且不需要在每個應用程式的內容中執行,您可能不需要建立 64 位版本。

如果 hMod 參數為 NULLdwThreadId 參數為零,或指定另一個進程所建立之線程的標識符,可能會發生錯誤。

呼叫 CallNextHookEx 函 式以鏈結至下一個攔截程式是選擇性的,但強烈建議您這麼做;否則,具有已安裝勾點的其他應用程式將不會收到攔截通知,而且可能會因為結果而不正確。 除非您絕對需要防止其他應用程式看到通知,否則您應該呼叫 CallNextHookEx

在終止之前,應用程式必須呼叫 UnhookWindowsHookEx 函式 ,以釋放與勾點相關聯的系統資源。

勾點的範圍取決於勾點類型。 某些勾點只能設定全域範圍;其他線程也可以設定為特定線程,如下表所示。

勾點 範圍
WH_CALLWNDPROC 線程或全域
WH_CALLWNDPROCRET 線程或全域
WH_CBT 線程或全域
WH_DEBUG 線程或全域
WH_FOREGROUNDIDLE 線程或全域
WH_GETMESSAGE 線程或全域
WH_JOURNALPLAYBACK 僅限全域
WH_JOURNALRECORD 僅限全域
WH_KEYBOARD 線程或全域
WH_KEYBOARD_LL 僅限全域
WH_MOUSE 線程或全域
WH_MOUSE_LL 僅限全域
WH_MSGFILTER 線程或全域
WH_SHELL 線程或全域
WH_SYSMSGFILTER 僅限全域

針對指定的攔截類型,會先呼叫線程勾點,然後再呼叫全域攔截。 請注意,WH_MOUSE、WH_KEYBOARD、WH_JOURNAL*、WH_SHELL和低階勾點可以在安裝攔截的線程上呼叫,而不是處理攔截的線程。 針對這些勾點,如果 32 位和 64 位勾點在攔截鏈結中 64 位攔截之前,可能會呼叫 32 位攔截。

全域勾點是共用資源,安裝一個鏈接會影響與呼叫線程相同的桌面中的所有應用程式。 所有全域攔截函式都必須位於連結庫中。 全域勾點應限制為特殊用途應用程式,或在應用程式偵錯期間作為開發輔助。 不再需要勾點的連結庫應該移除其攔截程式。

Windows 市集應用程式開發如果 dwThreadId 為零,則除非 UIAccess 進程 (輔助功能工具) 安裝 windows 市集應用程式進程和 Windows 執行階段 代理程式進程,否則不會載入視窗勾點 DLL。 這些勾點的通知會在安裝程式的線程上傳遞:

  • WH_JOURNALPLAYBACK
  • WH_JOURNALRECORD
  • WH_KEYBOARD
  • WH_KEYBOARD_LL
  • WH_MOUSE
  • WH_MOUSE_LL
此行為類似於當勾點 DLL 與目標應用程式進程之間有架構不符的情況,例如,當勾點 DLL 為 32 位和應用程式進程 64 位時。

範例

如需範例,請參閱 安裝和釋放攔截程式

注意

winuser.h 標頭會根據 UNICODE 預處理器常數的定義,將 SetWindowsHookEx 定義為別名,自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱 函式原型的慣例

規格需求

需求
最低支援的用戶端 Windows 2000 專業版 [僅限傳統型應用程式]
最低支援的伺服器 Windows 2000 Server [僅限傳統型應用程式]
目標平台 Windows
標頭 winuser.h (包括 Windows.h)
程式庫 User32.lib
Dll User32.dll
API 集合 ext-ms-win-ntuser-window-l1-1-0 (於 Windows 8)

另請參閱

CallNextHookEx 函式

CallWindowProc 函式

UnhookWindowsHookEx 函式

CBTProc

CallWndProc

CallWndRetProc

DebugProc

ForegroundIdleProc

GetMsgProc

JournalPlaybackProc

JournalRecordProc

KeyboardProc

LowLevelKeyboardProc

LowLevelMouseProc

MessageProc

MouseProc

ShellProc

SysMsgProc

概念

勾點