Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C+中,如何正确使用键盘挂钩来按组合键以阻止某个键,并再次按组合键以取消阻止该键+;_C++_Winapi_Keyboard_Hook - Fatal编程技术网

C++ 在C+中,如何正确使用键盘挂钩来按组合键以阻止某个键,并再次按组合键以取消阻止该键+;

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

在以下代码中,我没有得到生成错误,但在运行时未打印消息“密钥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;
}
#包括“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
设置为retur
GetCurrentThreadId()
LowLevelKeyboardProc的n值将永远不会接收VK_控件。它始终是VK_LCONTROL或VK_RCONTROL。我实现了您的方法,但仍然没有阻止A键或显示来自LowLevelKeyboardProc的任何内容。是否验证
SetWindowsHookEx()
没有失败?您正在使用
dwThreadId=0
调用它以全局安装钩子,这要求钩子代码位于DLL中,以便可以将其注入其他进程,但您正在设置
hMod=0
,因为代码不在DLL中。如果您只想钩子调用线程,请将
dwThreadId
设置为retur
GetCurrentThreadId()
LowLevelKeyboardProc的n值将永远不会接收VK_控制。它始终是VK_LCONTROL或VK_RCONTROL