C++ 在C+中,如何正确使用键盘挂钩来按组合键以阻止某个键,并再次按组合键以取消阻止该键+;
在以下代码中,我没有得到生成错误,但在运行时未打印消息“密钥A被阻止”:C++ 在C+中,如何正确使用键盘挂钩来按组合键以阻止某个键,并再次按组合键以取消阻止该键+;,c++,winapi,keyboard,hook,C++,Winapi,Keyboard,Hook,在以下代码中,我没有得到生成错误,但在运行时未打印消息“密钥A被阻止”: #include "stdafx.h" #include <iostream> #include <conio.h> #include <Windows.h> #include <sstream> #define _WIN32_WINNT 0x050 using namespace std; string intToHexString(int intV
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <Windows.h>
#include <sstream>
#define _WIN32_WINNT 0x050
using namespace std;
string intToHexString(int intValue) {
string hexStr;
/// integer value to hex-string
stringstream sstream;
sstream << "0x" << hex << (int)intValue;
hexStr = sstream.str();
sstream.clear(); //clears out the stream-string
return hexStr;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
BOOL locked = FALSE;
PKBDLLHOOKSTRUCT hookStruct;
if (nCode == HC_ACTION) {
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
hookStruct = (PKBDLLHOOKSTRUCT)lParam;
/**
* this is where the problem is
*/
//ctrl+alt+n
if (hookStruct->vkCode == 0x11 && hookStruct->vkCode == 0x12 && hookStruct->vkCode == 0x4E
&& !locked) {
locked = TRUE;
if (hookStruct->vkCode == 0x41) {
cout << "The key A is blocked" << endl;
return 1;
}
}
else if (hookStruct->vkCode == 0x11 && hookStruct->vkCode == 0x12 && hookStruct->vkCode == 0x4E) {
locked = FALSE;
BlockInput(locked);
cout << "The key is unblocked" << endl;
}
else {
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
char key_pressed;
int ascii_value;
string key_press_special;
HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, 0, 0);
cout << "press any key to see it's Character, ASCII and Scan Code" << endl;
cout << "Press ESC key to Exit" << endl;
while(1) {
key_pressed = _getch();
if (key_pressed == 13) {
key_press_special = "Enter";
cout << "Character: " << key_press_special << endl;
}
else if (key_pressed == 9) {
key_press_special = "Tab";
cout << "Character: " << key_press_special << endl;
}
else if (key_pressed == 27) {
key_press_special = "ESC";
cout << "Character: " << key_press_special << endl;
}
else {
cout << "Character: " << key_pressed << endl;
}
ascii_value = key_pressed;
cout << "The ASCII Value is: " << ascii_value << endl;
int scan = MapVirtualKey(ascii_value, 0);
string scanCode = intToHexString(scan);
cout << "Scan Code is: " << scanCode << endl;
if (key_pressed == 27) {
break;
}
else {
continue;
}
}
UnhookWindowsHookEx(hhkLowLevelKybd);
return 0;
}
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#定义_WIN32_WINNT 0x050
使用名称空间std;
字符串intToHexString(int intValue){
字符串hextr;
///整数值转换为十六进制字符串
溪流;
sstream vkCode==0x4E
&&!已锁定){
锁定=真;
if(hookStruct->vkCode==0x41){
cout vkCode==0x12&&hookStruct->vkCode==0x4E){
锁定=错误;
块输入(锁定);
cout您的钩子试图将完整的Ctrl+Alt+N序列作为一个虚拟键进行处理,但这不是它的工作方式。您必须单独处理这些键
请尝试类似以下内容:
bool ctrlDown = false;
bool altDown = false;
bool nDown = false;
bool locked = false;
void UpdateLock()
{
if (ctrlDown && altDown && nDown) {
locked = !locked;
if (!locked) BlockInput(FALSE);
cout << (locked ? "" : "not ") << "locked" << endl;
}
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
PKBDLLHOOKSTRUCT hookStruct = (PKBDLLHOOKSTRUCT) lParam;
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
switch (hookStruct->vkCode)
{
case VK_CONTROL:
if (!ctrlDown) {
ctrlDown = true;
UpdateLock();
}
break;
case VK_MENU:
if (!altDown) {
altDown = true;
UpdateLock();
}
break;
case 'N':
if (!nDown) {
nDown = true;
UpdateLock();
}
break;
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
switch (hookStruct->vkCode)
{
case VK_CONTROL:
ctrlDown = false;
break;
case VK_MENU:
altDown = false;
break;
case 'N':
nDown = false;
break;
}
break;
}
if ((hookStruct->vkCode == 'A') && locked) {
cout << "The key A is blocked" << endl;
return 1;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
boolctrldown=false;
bool-altDown=false;
bool-nDown=false;
布尔锁定=假;
void UpdateLock()
{
如果(ctrlDown&&altDown&&nDown){
锁定=!锁定;
如果(!锁定)块输入(错误);
cout vkCode=='A')&&locked){
cout您的钩子试图将完整的Ctrl+Alt+N序列作为一个虚拟键进行处理,但这不是它的工作方式。您必须单独处理这些键
请尝试类似以下内容:
bool ctrlDown = false;
bool altDown = false;
bool nDown = false;
bool locked = false;
void UpdateLock()
{
if (ctrlDown && altDown && nDown) {
locked = !locked;
if (!locked) BlockInput(FALSE);
cout << (locked ? "" : "not ") << "locked" << endl;
}
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
PKBDLLHOOKSTRUCT hookStruct = (PKBDLLHOOKSTRUCT) lParam;
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
switch (hookStruct->vkCode)
{
case VK_CONTROL:
if (!ctrlDown) {
ctrlDown = true;
UpdateLock();
}
break;
case VK_MENU:
if (!altDown) {
altDown = true;
UpdateLock();
}
break;
case 'N':
if (!nDown) {
nDown = true;
UpdateLock();
}
break;
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
switch (hookStruct->vkCode)
{
case VK_CONTROL:
ctrlDown = false;
break;
case VK_MENU:
altDown = false;
break;
case 'N':
nDown = false;
break;
}
break;
}
if ((hookStruct->vkCode == 'A') && locked) {
cout << "The key A is blocked" << endl;
return 1;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
boolctrldown=false;
bool-altDown=false;
bool-nDown=false;
布尔锁定=假;
void UpdateLock()
{
如果(ctrlDown&&altDown&&nDown){
锁定=!锁定;
如果(!锁定)块输入(错误);
cout vkCode=='A')&&locked){
cout上选的答案不起作用,因为低级别KeyboardProc永远不会收到VK_控件,至少在WinXP和更高版本中是这样。它总是VK_LCONTROL或VK_RCONTROL。否则这是个好主意,但显然它从未被编译和测试过,所以可能还有其他错误
对于一个可能有点过分,但却有很好评论的示例,请查看“自动热键”的源代码:
投票结果无效,因为低级KeyboardProc永远不会收到VK_控件,至少在WinXP和更高版本中是这样。它总是VK_LCONTROL或VK_RCONTROL。否则这是个好主意,但显然它从未被编译和测试过,所以可能还有其他错误
对于一个可能有点过分,但却有很好评论的示例,请查看“自动热键”的源代码:
我运行了代码,没有bug或错误,但是当我尝试组合时,它没有做它应该做的事情,不是bug的定义吗?hookStruct->vkCode==0x11&&hookStruct->vkCode==0x12&&hookStruct->vkCode==0x4E这永远不会是真的。对不起,我不知道这是定义为什么?@drescherjm。因为h这里,这是虚拟键代码。这是为什么?因为数字不能同时为0x11和0x12。我运行了代码,没有bug或错误,但当我尝试组合时,它没有做它应该做的事情。这不是bug的定义吗?hookStruct->vkCode==0x11&&hookStruct->vkCode==0x12&&hookStruct->vkCode==0x4E This永远不可能是真的。抱歉,我不知道这是定义为什么是tha?@drescherjm。因为这里,这是虚拟密钥代码。为什么是tha?因为数字不能同时是0x11和0x12。我实现了你的方法,但仍然没有阻止a密钥或从低级KeyboardProc显示任何内容。你验证了SetWi吗ndowsHookEx()
没有失败?您正在使用dwThreadId=0
调用它以全局安装钩子,这要求钩子代码位于DLL中,以便可以将其注入其他进程,但您正在设置hMod=0
,因为代码不在DLL中。如果您只想钩子调用线程,请将dwThreadId
设置为returGetCurrentThreadId()
LowLevelKeyboardProc的n值将永远不会接收VK_控件。它始终是VK_LCONTROL或VK_RCONTROL。我实现了您的方法,但仍然没有阻止A键或显示来自LowLevelKeyboardProc的任何内容。是否验证SetWindowsHookEx()
没有失败?您正在使用dwThreadId=0
调用它以全局安装钩子,这要求钩子代码位于DLL中,以便可以将其注入其他进程,但您正在设置hMod=0
,因为代码不在DLL中。如果您只想钩子调用线程,请将dwThreadId
设置为returGetCurrentThreadId()
LowLevelKeyboardProc的n值将永远不会接收VK_控制。它始终是VK_LCONTROL或VK_RCONTROL