您的位置:首页 > 其它

[zz]Windows Mobile 上使用键盘钩子

2008-11-17 15:10 288 查看
转自:http://tech.it168.com/msoft/2008-01-03/200801031715485.shtml
【IT168 技术文档】

最近做的项目涉及Wince 按键的Hook操作,需要屏蔽挂机键和一些系统按键。

在Windows中,设置键盘钩子很多人都做过,但是在windows Mobile系统中并没有直接的函数支持。但是我们可以通过使用undocument api来实现。

首先定义一些参数
#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);

typedef struct ...{
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;

static _SetWindowsHookExW SetWindowsHookEx;
static _UnhookWindowsHookEx UnhookWindowsHookEx;
static _CallNextHookEx CallNextHookEx;

然后是实现的代码,LLKeyboardHookCallbackFunction就是回调函数
BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)
...{
//we need to manually load these standard Win32 API calls
//MSDN states that these aren't supported in WinCE

SetWindowsHookEx = NULL;
CallNextHookEx = NULL;
UnhookWindowsHookEx = NULL;

//从 coredll.dll 获取我们需要的函数

g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));
if(g_hHookApiDLL == NULL)
...{
return FALSE;
}
else
...{

SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));
if(SetWindowsHookEx == NULL)
...{

return FALSE;
}
else
...{

g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, hInstance, 0);
if(g_hInstalledLLKBDhook == NULL)
...{

return FALSE;
}
}

CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T("CallNextHookEx"));
if(CallNextHookEx == NULL)
...{

return FALSE;
}

UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T("UnhookWindowsHookEx"));
if(UnhookWindowsHookEx == NULL)
...{
return FALSE;
}
}

return TRUE;
}

BOOL DeactivateKBHook()
...{
//unload the hook
if(g_hInstalledLLKBDhook != NULL)
...{
UnhookWindowsHookEx(g_hInstalledLLKBDhook);
g_hInstalledLLKBDhook = NULL;
}

//unload the coredll.dll
if(g_hHookApiDLL != NULL)
...{
FreeLibrary(g_hHookApiDLL);
g_hHookApiDLL = NULL;
}

//we have terminated gracefully
return TRUE;
}

一般的回调函数是这么写的,BlockKeyList是需要屏蔽的按键列表

int CLoginDlg::BlockKeyList[] = {VK_TBACK,VK_TTALK,VK_TEND,VK_THOME};

LRESULT CALLBACK CLoginDlg::LLKeyboardHookCallbackFunction(int nCode, WPARAM wParam, LPARAM lParam)
...{
if(nCode >= HC_ACTION)
...{
if(wParam == WM_KEYDOWN || wParam == WM_KEYUP || wParam == WM_LBUTTONDOWN)
...{

int countKeyList = ARRAY_SIZEOF(BlockKeyList);

for(int i=0;i<countKeyList;i++)
...{
if((((KBDLLHOOKSTRUCT*)lParam)->vkCode) == BlockKeyList[i])
...{
return TRUE;
}
}

}
}

return CallNextHookEx(g_hInstalledLLKBDhook, nCode, wParam, lParam);
}

最后还有关键的一点,网上有人说WH_KEYBOARD_LL不需要用DLL就能实现全局钩子,但是我发觉至少在windows mobile的机器上不行,还是要用DLL来实现键盘钩子。

以上的方法在windows mobile 5.0以及6.0上都可以正常使用,如果你只是要屏蔽所有按键的话可以简单的使用EnableHardwareKeyboard函数来实现。

相关例子源码下载:http://www.codeproject.com/KB/mobile/wincekbhook.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: