如何正确使用键盘钩按键组合以阻止键并再次按C 将其解开
How to correctly use keyboard hooks to press a key combination to block a key and to press it again to unblock it in C++
在以下代码中,我没有构建错误,但是"键a被阻止"。未在运行时打印:
#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;
}
您的钩子正在尝试处理完整的 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);
}
uptevoted答案无法正常工作,因为LowlevelkeyboardProc永远不会收到vk_control,至少在WinxP和以后。它始终是vk_lcontrol或vk_rcontrol。否则,这是一个好主意,但是显然它从未经过编译和测试,因此可能还有其他错误。
对于可能过于杀伤但充满爱意的示例,请查看Autohotkey的来源:
https://github.com/autohotkey/autohotkey/blob/master/source/hook.cpp#l201
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- CMake-按正确顺序将项目与C运行时对象文件链接
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 用于访问容器<T>数据成员的正确 API
- 物理键盘上的触发器按键
- 如何使用Luacneneneba API正确读取字符串和表参数
- 如何使用用户输入在C++中正确填充2D数组
- node-gyp 在 macOS 上未正确链接库
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- 为什么我的for循环不能正确获取argv
- 如何取消对nullptr的屏蔽,返回正确的对象
- AES加密到解密未正确输出
- 如何使用C/C++在MacOSX中获得键盘布局
- 使用C++程序合并排序没有得到正确的输出
- 在 c++ 中拥有一组结构的正确方法是什么?
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 如何正确使用键盘钩按键组合以阻止键并再次按C 将其解开
- 按下按钮时,键盘矩阵代码未返回正确的列号
- SFML 2.0:键盘::是按键并不总是正确返回