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以上,已经不支持鼠标钩子。