共用方式為


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](/windows/win32/winmsg/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 攔截程式。
WH_MOUSE
7

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

WH_MOUSE_LL
14

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

WH_MSGFILTER
-1

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

WH_SHELL
10
安裝攔截程式,以接收對殼層應用程式有用的通知。 如需詳細資訊,請參閱 [ShellProc](/windows/win32/winmsg/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 參數 NULL且 dwThreadId 參數為零,或指定另一個進程所建立之線程的標識符,就可能發生錯誤。

呼叫 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 位攔截之前,可能會呼叫 32 位和 64 位攔截。

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

Windows 市集應用程式開發 如果 dwThreadId 為零,則 Windows 市集應用程式進程和 Windows 執行時間訊息代理程式不會在進程內載入視窗勾點 DLL,除非它們是由 UIAccess 行程安裝(輔助功能工具)。 這些攔截的通知會在安裝程式的線程上傳遞:

  • 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 Professional [僅限傳統型應用程式]
支援的最低伺服器 Windows 2000 Server [僅限傳統型應用程式]
目標平臺 窗戶
標頭 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

概念