22.2.9 屏蔽键盘Power键
通过回调函数,可以屏蔽系统按键的处理。本节介绍通过底层键盘钩子的回调函数屏蔽POWER键的方法。键盘钩子是当有键盘事件发生时,系统会执行的操作,操作执行的内容可以定义在回调函数中。用户可以通过挂上相应的钩子自定义的操作。由于POWER键是底层键盘按键,因此需要使用底层键盘钩子回调函数。其原型为:
- LRESULT CALLBACK LowLevelKeyboardProc
( int nCode, // 指定钩子处理代码 - WPARAM wParam, // 指定键盘消息的标识符
- LPARAM lParam); // 指向KBDLLHOOKSTRUCT
结构的指针,其中存储按下的按键的信息
如果nCode参数为HC_ACTION,则在wParam和lParam参数中包含与键盘消息相关的信息。如果nCode小于0,则钩子处理函数必须通过CallNextHookEx()函数将消息传递给下一个钩子。wParam参数用于指定键盘消息的标识符,取值为WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN或WM_SYSKEYUP,分别表示按键按下、按键抬起、系统按键按下、系统按键抬起。如果按下的按键是要屏蔽的按键,则返回true,否则,返回CallNextHookEx()函数。代码如下:
- LRESULT CALLBACK LowLevelKeyboardProc(int nCode,
WPARAM wParam, LPARAM lParam) - {// 底层键盘钩子回调函数
- if (nCode == HC_ACTION)
// 禁用键盘的某个按键 - {
- KBDLLHOOKSTRUCT* pHookStruct =
(KBDLLHOOKSTRUCT*)lParam; -
// 取出钩子结构 - LPDWORD tmpVirKey = m_lpdwVirtualKey;
// 取出要屏蔽的键的列表指针 - for (int i = 0; i < m_nLength; i++)
// 依次处理要屏蔽的按键 - {
- if (*m_lpdwContentKey++ == 1)
- {
- DWORD dwAltKey = 32;
- if ((pHookStruct->vkCode ==
*tmpVirKey++)&& (pHook Struct-) - >flags == dwAltKey))return true;
- }
- if (pHookStruct->vkCode ==
*tmpVirKey++) return true; - }
- }
- return CallNextHookEx(m_hHook, nCode, wParam, lParam);
-
// 传给系统中的下一个钩子 - }
上面的代码是底层键盘钩子的回调函数。判断按下的功能组合键和按键是否与禁用的按键相同,如果是要屏蔽的按键,则返回true,终止向下一个钩子函数传递,从而屏蔽到此按键的事件。如果不是要屏蔽的按键,则返回CallNextHookEx,将消息传递给下一个钩子。为了使得功能可以重复使用,因此,将此功能封装在DLL中,而需要屏蔽的程序只需要调用DLL即可。以下代码是屏蔽按键的处理过程。
- SHIELDKEYBORDSAMPLE_API bool StartShieldKey
(LPDWORD lpdwVirtualKey, - LPDWORD lpdwContentKey, int nLength)
// 屏蔽按键处理 - {
- if (m_hHook != NULL) return StopShieldKey();
// 执行停止按键处理函数 - m_lpdwVirtualKey = (LPDWORD)malloc
(sizeof(DWORD) * nLength); - m_lpdwContentKey = (LPDWORD)malloc
(sizeof(DWORD) * nLength); - LPDWORD tmpVirKey = m_lpdwVirtualKey;
// 要屏蔽的底层键盘 - LPDWORD tmpConKey = m_lpdwContentKey;
// 要屏蔽的底层键盘组合键 - for (int i = 0; i < nLength; i++)
- {
- *tmpVirKey++ = *lpdwVirtualKey++;
- *tmpConKey++ = *lpdwContentKey++;
- }
- m_nLength = nLength;
- m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc, - m_hInstance, NULL);
// 安装底层键盘钩子 - if (m_hHook == NULL) return false;
- return true;
- }
- SHIELDKEYBORDSAMPLE_API bool StopShieldKey() // 卸载按键钩子
- {
- if (UnhookWindowsHookEx(m_hHook) == 0) return false;
- m_hHook = NULL;
- return true;
- }
在上面代码中,StartShieldKey()函数用于安装钩子。首先将传入的要屏蔽的按键的数组传入DLL中,并保存为全局变量。然后调用SetWindowsHookEx()函数安装钩子,并指定钩子的回调函数为LowLevelKeyboardProc()。StopShieldKey()函数用于卸载钩子。调用UnhookWindowsHookEx()函数卸载指定的钩子。下面的代码就是在调用的程序中,调用函数安装屏蔽Power键的钩子。
- Void CDLLAppSampleDlg::OnButtonDisablePower()
// 屏蔽Power按键 - {
- DWORD dwVerKey[] = {0x00000001};
// 定义按键集合 - DWORD dwConKey[] = {0};
- int nLength = sizeof(dwVerKey)
/ sizeof(DWORD); // 计算长度 - if (StartShieldKey(dwVerKey,
dwConKey, nLength)) WriteLog("已经屏蔽 - Power键");
- else WriteLog("屏蔽Power键失败");
- }
因为POWER键的按键代码是1,因此将其传入DLL中的StartShieldKey()函数,屏蔽POWER按键。