// KEY Begin
/*
通常我们捕获键盘消息会在WindowProc函数种用一个switch来监听WM_KEYUP和WM_KEYDOWN消息,当按下键盘时程序就会收到这个消息。但是,有一个前提是当焦点是在当前窗口时,这个WM_KEYUP和WM_KEYDOWN消息才会被捕获到。如果我们需要在任何情况下使用这个应用程序捕获到键盘的动作就需要使用钩子。
// 第四步:创建一个函数ActivateKBHook在这个函数中来使用钩子,当然也可以不在这个函数中使用,创建函数只是为了使代码可读性好一些。具体代码如下:
HINSTANCE g_hHookApiDLL = NULL;
HHOOK g_hInstalledLLKBDhook = NULL;
BOOL ActivateKBHook(HINSTANCE hInstance, HOOKPROC LLKeyboardHookCallbackFunction)
{
RETAILMSG(DEBUG_CODE,(L"ActivateKBHook\r\n"));
//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;
//now load the coredll.dll
g_hHookApiDLL = LoadLibrary(_T("coredll.dll"));
if(g_hHookApiDLL == NULL)
{
//something is awfully wrong
//the dll has to be present
RETAILMSG(DEBUG_CODE,(L"coredll.dll failure\r\n"));
return false;
}
else
{
//load the SetWindowsHookEx API call
//the SetWindowsHookEx function installs an application-defined hook procedure into a hook chain.
//You would install a hook procedure to monitor the system for certain types of events.
//here we use use the hook to monitor kyeboard events
SetWindowsHookEx = (_SetWindowsHookExW)GetProcAddress(g_hHookApiDLL, _T("SetWindowsHookExW"));
if(SetWindowsHookEx == NULL)
{
//this means that MS has really stopped supporting this API in WinCE
RETAILMSG(DEBUG_CODE,(L"SetWindowsHookExW failure\r\n"));
return false;
}
else
{
//install the KB hook
//the hande needs to be saved for default processing of the events and to uninstall the hook, once we are done with it
g_hInstalledLLKBDhook = SetWindowsHookEx(WH_KEYBOARD_LL, LLKeyboardHookCallbackFunction, g_hHookApiDLL, 0); // ZSC 091218 Modify WH_KEYBOARD_LL => WH_KEYBOARD
if(g_hInstalledLLKBDhook == NULL)
{
int re;
re=GetLastError();
RETAILMSG(DEBUG_CODE,(L"SetWindowsHookEx failure %d \r\n",re));
return false;
}
}
//load CallNextHookEx() API call
//the CallNextHookEx function passes the hook information to the next hook procedure in the current hook chain.
//we use this call for default processing of events.
CallNextHookEx = (_CallNextHookEx)GetProcAddress(g_hHookApiDLL, _T("CallNextHookEx"));
if(CallNextHookEx == NULL)
{
RETAILMSG(DEBUG_CODE,(L" _CallNextHookEx failure \r\n"));
return false;
}
//load UnhookWindowsHookEx() API
//the UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.
//we use this call to unistall the hook.
UnhookWindowsHookEx = (_UnhookWindowsHookEx)GetProcAddress(g_hHookApiDLL, _T("UnhookWindowsHookEx"));
if(UnhookWindowsHookEx == NULL)
{
RETAILMSG(DEBUG_CODE,(L"_UnhookWindowsHookEx failure\r\n"));
return false;
}
}
//all the APIs are loaded and the application is hooked
return true;
INT_PTR CALLBACK TESTKEY(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
RECT rectChild, rectParent;
int DlgWidth, DlgHeight; // dialog width and height in pixel units
int NewPosX, NewPosY;
// trying to center the About dialog
if (GetWindowRect(hDlg, &rectChild))
{
GetClientRect(GetParent(hDlg), &rectParent);
DlgWidth = rectChild.right - rectChild.left;
DlgHeight = rectChild.bottom - rectChild.top ;
NewPosX = (rectParent.right - rectParent.left - DlgWidth) / 2;
NewPosY = (rectParent.bottom - rectParent.top - DlgHeight) / 2;
// if the About box is larger than the physical screen
if (NewPosX < 0) NewPosX = 0;
if (NewPosY < 0) NewPosY = 0;
SetWindowPos(hDlg, 0, NewPosX, NewPosY,
0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
return (INT_PTR)TRUE;
case WM_COMMAND:
{
// 调用程序
switch(LOWORD(wParam))
{
case IDOK:
{
BOOL bRet = FALSE;
bRet = ActivateKBHook(g_hInst, LowLevelKeyboardProc); RETAILMSG(1, (TEXT("[TESTKEY] GET ActivateKBHook %d\r\n"), bRet));
break;
}
case IDCANCEL:
{
//EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
}
break;
}
case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;