C++ Windows键盘钩子

一、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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_君莫笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值