Вопрос по c++, winapi, hotkeys – Регистрация Global HotKey без отключения его ключа

1

Я хочу создать программу, которая может перехватывать события клавиатуры, даже если она не активна в любой момент. Хуки были слишком сложны со всеми вещами, которые я должен сделать, чтобы заставить их работать (создание DLL, чтение и так далее), поэтому я решил продолжать использовать горячие клавиши.

Но сейчас у меня проблема. Регистрация горячей клавиши отключает клавишу на клавиатуре, поэтому я могу только отправить эту клавишу в программу, в то время как я не могу набирать текст в любой другой программе (например, в блокноте).

Это мой код:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, NULL, 0x41); //Register A
    MSG msg = {0};

    while (GetMessageA(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            cout << "A"; //Print A if I pressed it
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

// and now I can't type A's

Есть ли простое решение этой проблемы? Спасибо

Выcould отступить к циклуGetAsyncKeyState тоже. chris
Ну, в этом и состоит разница между крючком и горячей клавишей. Ловушка сообщает вам, когда она нажата, горячая клавиша отменяет обработку по умолчанию. Deanna
Благодаря комментариям выше я сделал это. Спасибо ! SmRndGuy
Если недостатки не имеют значения, вы можете использовать не-DLL-хук (сWH_KEYBOARD_LL). Все это пара звонков, чтобы подключить / отцепить и обратный вызов. Сделай что-нибудь с этим, передай это. chris

Ваш Ответ

1   ответ
4

равное тому, которое вы фактически выполняли. Это означает:

You press 'A'. The program catches the 'A'. The program simulates the keypress.

Это довольно просто. Единственная проблема заключается в том, что ваша программа также будет ловить симулированное нажатие клавиши. Чтобы избежать этого, вы можете сделать следующее:

You press 'A'. The program catches the 'A'. The program unregisters the hotkey. The program simulates the keypress. (The program does not (!) catch the 'A'.) The program registers the hotkey again.

Вот и весь цикл.

Теперь, чтобы симулировать нажатие клавиши, вам нужно добавить дополнительный код. Посмотри на это:

#include <iostream>
#include <windows.h>
using namespace std;

int main(int argc, char* argv[]) {
    RegisterHotKey(NULL, 1, 0, 0x41);            //Register A; Third argument should also be "0" instead of "NULL", so it is not seen as pointer argument
    MSG msg = {0};
    INPUT ip;
    ip.type = INPUT_KEYBOARD;
    ip.ki.wScan = 0;
    ip.ki.time = 0;
    ip.ki.dwExtraInfo = 0;
    ip.ki.wVk = 0x41;                            //The key to be pressed is A.

    while (GetMessage(&msg, NULL, 0, 0) != 0) {
        if (msg.message == WM_HOTKEY) {
            UnregisterHotKey(NULL, 1);           //Prevents the loop from caring about the following
            ip.ki.dwFlags = 0;                   //Prepares key down
            SendInput(1, &ip, sizeof(INPUT));    //Key down
            ip.ki.dwFlags = KEYEVENTF_KEYUP;     //Prepares key up
            SendInput(1, &ip, sizeof(INPUT));    //Key up
            cout << "A";                         //Print A if I pressed it
            RegisterHotKey(NULL, 1, 0, 0x41);    //you know...
        }
    }

    UnregisterHotKey(NULL, 1);
    return 0;
}

Я попробовал, и это работает нормально, я думаю. Надеюсь, я мог помочь;)

Последовательные звонкиSendInput сnInputs Аргумент, равный 1, является ошибкой. Единственная разница междуkeybd_event а такжеSendInput является то, что последний способен вводить весь пакет ввода атомарно во входную очередь, так что он не чередуется с вводом из других источников.

Похожие вопросы