wince系統對於鉤子技術的支援,顯然不及windows。有一些技術文檔乾脆說wince不支援鉤子。其實,不盡然。我們還是可以從coredll.dll中,得到一些有用的介面,來實現攔截一些簡單的鍵盤或滑鼠的動作。
還是代碼最有說服力:
#define WH_JOURNALRECORD 0
#define WH_JOURNALPLAYBACK 1
#define WH_KEYBOARD_LL 20
#define HC_ACTION 0
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
typedef HHOOK (WINAPI *_SetWindowsHookExW)(int, HOOKPROC, HINSTANCE, DWORD);
typedef LRESULT (WINAPI *_CallNextHookEx)(HHOOK, int, WPARAM, LPARAM);
typedef LRESULT (WINAPI *_UnhookWindowsHookEx)(HHOOK);
static _SetWindowsHookExW SetHook;
static _UnhookWindowsHookEx UnhookHook;
static _CallNextHookEx CallNextHook;
HINSTANCE g_hHookApiDll = NULL;
HHOOK g_hKbdHook = NULL;
HHOOK g_hMouseHook = NULL;
LRESULT CALLBACK KbdHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
BOOL ActivateHook(HINSTANCE hInstance, HOOKPROC HookCallback);
BOOL DeactivateHook();
BOOL ActivateHook(HINSTANCE hInstance, HOOKPROC hookProc)
{
SetHook = NULL;
CallNextHook = NULL;
UnhookHook = NULL;
EVENTMSG msg = {HC_ACTION};
g_hMouseHook = QASetWindowsJournalHook(WH_JOURNALRECORD, MouseHookCallback, &msg);//這個是針對滑鼠的
if(NULL == g_hMouseHook )
{
return FALSE;
}
g_hHookApiDll = LoadLibrary(_T("coredll.dll"));
if(NULL == g_hHookApiDll)
{
return FALSE;
}
SetHook = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDll, _T("SetWindowsHookExW"));
if(NULL == SetHook)
{
return FALSE;
}
g_hKbdHook = SetHook(WH_KEYBOARD_LL, hookProc, hInstance, 0);
if(NULL == g_hKbdHook)
{
return FALSE;
}
CallNextHook = (_CallNextHookEx)GetProcAddress(g_hHookApiDll, _T("CallNextHookEx"));
if(NULL == CallNextHook)
{
return FALSE;
}
UnhookHook = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDll, _T("UnhookWindowsHookEx"));
if(NULL == UnhookHook)
{
return FALSE;
}
return TRUE;
}
BOOL DeactivateHook()
{
if(g_hMouseHook != NULL)
{
QAUnhookWindowsJournalHook(WH_JOURNALRECORD);
g_hMouseHook = NULL;
}
if(g_hKbdHook != NULL)
{
UnhookHook(g_hKbdHook);
g_hKbdHook = NULL;
}
if(g_hHookApiDll != NULL)
{
FreeLibrary(g_hHookApiDll);
g_hHookApiDll = NULL;
}
return TRUE;
}
LRESULT CALLBACK KbdHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode >= HC_ACTION)
{
if(wParam == WM_KEYUP)
{
DWORD dwKey = ((KBDLLHOOKSTRUCT*)lParam)->vkCode;
if(dwKey == VK_UP || dwKey == VK_DOWN || dwKey == VK_LEFT || dwKey == VK_RIGHT)
{
//Do Something
}
}
}
return CallNextHook(g_hKbdHook, nCode, wParam, lParam);
}
LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode >= HC_ACTION)
{
PEVENTMSGMSG pMsg = (PEVENTMSGMSG)lParam;
if(pMsg)
{
if(pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_LBUTTONUP)
{
//Do Something
}
}
}
return CallNextHook( g_hMouseHook, nCode, wParam, lParam );
}
如果在一個程式中啟動了鉤子,其他的程式使用鉤子將無效。
由於使用了微軟未公開的函數,可能會有潛在的問題,建議慎用。另,據說WM6.5以上,已經不支援滑鼠鉤子。