一、KeyBoardHookDll.h
class KeyBoardHookDll
{
public:
KeyBoardHookDll();
~KeyBoardHookDll();
VOID SetVKCode(DWORD dVirtualkey, DWORD dContentKey);
BOOL StartShieldKey(LPDWORD lpdwVirtualKey, LPDWORD lpdwContentKey, int nLength);
BOOL StopShieldKey();
};
二、KeyBoardHookDll.cpp
#include "KeyBoardHookDll.h"
#include <vector>
#include <mutex>
#include <algorithm>
static HHOOK g_hHook = NULL; //定义HOOK句柄
HINSTANCE g_hInst = NULL; //实例句柄
std::vector<DWORD> g_vecVirtualKeyHook; //要屏蔽的底层键盘
std::vector<DWORD> g_vecContentKeyHook; //要屏蔽的底层键盘组合键
std::mutex mx;
int g_nLength = 0;
KeyBoardHookDll::KeyBoardHookDll()
{
}
KeyBoardHookDll::~KeyBoardHookDll()
{
}
VOID KeyBoardHookDll::SetVKCode(DWORD dVirtualkey, DWORD dContentKey)
{
mx.lock();
g_vecVirtualKeyHook.push_back(dVirtualkey);
mx.unlock();
mx.lock();
g_vecContentKeyHook.push_back(dContentKey);
mx.unlock();
}
//底层键盘钩子回掉函数
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//禁用键盘的某个按键
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT* pHookStruct = (KBDLLHOOKSTRUCT*)lParam;
//取出钩子结构
for (int i = 0; i < g_nLength; i++)
{
if (g_vecContentKeyHook.at(i) == 1)
{
DWORD dwAltKey = 32;
if ((pHookStruct->vkCode == g_vecVirtualKeyHook.at(i)) &&
(pHookStruct->flags == dwAltKey))
{
return true;
}
}
if (pHookStruct->vkCode == g_vecVirtualKeyHook.at(i))
{
return true;
}
}
}
//传递给下一个键盘钩子
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
BOOL KeyBoardHookDll::StartShieldKey(LPDWORD lpdwVirtualKey, LPDWORD lpdwContentKey, int nLength)
{
// 此处为普通函数体
if (g_hHook != NULL)
{
return /*StopShieldKey()*/FALSE;
}
for (int i = 0; i < nLength; i++)
{
DWORD dVirtualKey = *(lpdwVirtualKey++);
DWORD dContentKey = *(lpdwContentKey++);
SetVKCode(dVirtualKey, dContentKey);
}
g_nLength = nLength;
//安装底层键盘钩子
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, g_hInst, NULL);
if (g_hHook == NULL)
{
return FALSE;
}
return TRUE;
}
BOOL KeyBoardHookDll::StopShieldKey()
{
if (UnhookWindowsHookEx(g_hHook) == 0)
{
return FALSE;
}
g_vecContentKeyHook.clear();
g_vecVirtualKeyHook.clear();
g_hHook = NULL;
return TRUE;
}
三、调用
void CTestKeyBoardDllDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
std::vector<DWORD> vecValue;
vecValue.push_back(VK_LWIN);
vecValue.push_back(VK_RWIN);
vecValue.push_back(VK_SNAPSHOT);
vecValue.push_back(VK_ESCAPE);
DWORD dwVerKey[256] = { 0 };
DWORD dwConKey[256] = { 0 };
for (unsigned int i = 0; i < vecValue.size(); i++)
{
dwVerKey[i] = vecValue.at(i);
dwConKey[i] = 0;
}
if (DllStartShieldKey(dwVerKey, dwConKey, vecValue.size()))
{
AfxMessageBox(_T("禁用WIN、截屏键、空格键成功!"));
}
else
{
AfxMessageBox(_T("禁用WIN、截屏键、空格键失败!"));
}
}
按键消息:
WM_CHAR、WM_KEYDOWN、WM_SYSKEYDOWN都是键盘消息;
WM_CHAR是由WM_KEYDOWN消息Translate()之后产生的,然后再发给窗口过程。
WM_SYSKEYDOWN是接受快捷键或系统命令按键的,像是Alt键就是。所以捕获Alt键时,在WM_KEYDOWN下是无效的,要在WM_SYSKEYDOWN中。
ctrl和shift都不属于WM_SYSKEYDOWN