鉤子程序必須置於 DLL 中以實現系統級攔截。以下為核心導出函數:
__declspec(dllexport) BOOL SetMyHook(HWND hWndServer)
{
if (hWndServer == NULL) return FALSE;
hWndServer = hWnd; // 全域變數儲存接收視窗
hook = SetWindowsHookEx(WH_GETMESSAGE, MsgHook, hInst, 0);
return (hook != NULL);
}
__declspec(dllexport) BOOL ClearMyHook(HWND hWnd)
{
if (hWnd != hWndServer) return FALSE;
BOOL unhooked = UnhookWindowsHookEx(hook);
if (unhooked) hWndServer = NULL;
return unhooked;
}
static LRESULT CALLBACK MsgHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode < 0) // 必須傳遞給下一個鉤子
return CallNextHookEx(hook, nCode, wParam, lParam);
LPMSG msg = (LPMSG)lParam; // WH_GETMESSAGE: lParam 指向 MSG 結構
// 攔截滑鼠移動訊息(客戶區與非客戶區)
if (msg->message == WM_MOUSEMOVE || msg->message == WM_NCMOUSEMOVE)
{
// 使用 PostMessage 非同步通知主視窗,避免阻塞鉤子鏈
PostMessage(hWndServer, UWM_MOUSEMOVE, 0, 0);
}
return CallNextHookEx(hook, nCode, wParam, lParam);
}
// 標頭檔
#define UWM_MOUSEMOVE_MSG "MyApp_MouseMove"
UINT UWM_MOUSEMOVE = ::RegisterWindowMessage(UWM_MOUSEMOVE_MSG);
BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
ON_REGISTERED_MESSAGE(UWM_MOUSEMOVE, OnMyMouseMove)
END_MESSAGE_MAP()
LRESULT CMyApp::OnMyMouseMove(WPARAM, LPARAM)
{
CPoint pt;
GetCursorPos(&pt);
// 這裡處理滑鼠座標,如更新 UI、追蹤軌跡等
return 0;
}
示範程式建立全域 WH_GETMESSAGE 鉤子,攔截滑鼠移動,主視窗接收通知後移動「貓」的圖片追蹤滑鼠「老鼠」。當距離足夠近時觸發捕捉動畫。

__declspec(dllexport) 讓 EXE 可呼叫安裝/移除函數。#pragma data_seg("SHARED") 讓 hWndServer、hook 在所有載入 DLL 的進程間共享。PostMessage 非同步通知,SendMessage 會阻塞導致系統卡頓。ClipCursor 限制滑鼠範圍、SetCapture 捕捉滑鼠、區域裁剪、雙緩衝繪圖等輔助技巧。WH_KEYBOARD_LL、WH_MOUSE_LL)不需 DLL,但延遲較高;全域鉤子(WH_GETMESSAGE、WH_KEYBOARD)需 DLL 且目標進程必須有訊息迴圈。掌握鉤子與 DLL 協作模式,即可實現全域熱鍵、滑鼠手勢、自動化測試、螢幕錄製等系統級功能。