【问题标题】:C: Fastest way to determine, if any key on the keyboard has been pressedC:最快的判断方法,是否按下了键盘上的任何键
【发布时间】:2020-09-08 06:32:55
【问题描述】:

我正在寻找 C 语言中最快的方法来确定是否按下了键盘上的任何键。

我不是在寻找如何确定是否按下了特定键(在这种情况下,GetAsyncKeyState() 会起作用)。

另外,它需要在后台工作,所以程序窗口没有焦点(程序将在后台运行)。

编辑:该程序将对每次按键做出反应并输出声音。我希望它在我每次输入内容时输出声音(比如在 Word 等中)。这也是它需要在后台运行的原因。我希望它快一点,这样我可以最大限度地减少按键和声音输出之间的延迟。

EDIT2:我正在寻找 Windows Hooks 以外的东西。虽然它确实可以在后台获取按键,但我正在寻找更快(尽可能少的延迟)的东西。

例如:GetAsyncKeyState() 用于对特定按键做出反应,而程序窗口没有焦点。我正在寻找类似的东西,但能够对任何按键做出反应,而不是特定的按键。

【问题讨论】:

  • 听起来像键盘记录器...您需要解决什么问题?为什么需要键盘按键?为什么需要从后台进程执行此操作?为什么需要它“快”?
  • @Someprogrammerdude 我担心有人会这么想。我想用声音(如点击)对每一次键盘按键做出反应。这是我在学校时错过机械键盘的点击后得到的一个想法。该过程必须在后台运行,因为我想要点击,同时使用 word 等,而不仅仅是在该程序中。它必须很快,这样我才能最大限度地减少按键和声音输出之间的延迟。
  • edit您的问题包含该信息。对于未来的问题,请告诉我们您需要解决的实际问题,直接询问(而不是间接询问)总是更好,甚至可以为您提供一些您可能没有想到的惊喜解决方案。
  • 您在寻找什么样的“快速”?学得快吗?快速实施?您需要什么级别的“快速”?比你所拥有的快 1%?快 200%?快一周?您使用什么度量来确定答案是否提供了足够快的实现。?你目前的实现是什么?
  • 我认为您正在寻找“低延迟”,这对许多人来说不一定与“快速”相同。

标签: c winapi


【解决方案1】:

作为注释,您可以将RegisterRawInputDevices 用作this sample

  1. 创建仅消息窗口。
  2. 将 RAWINPUTDEVICE.hwndTarget 设置为步骤 1 中创建的窗口,这样您就不需要关注窗口。
  3. 调用GetRawInputData获取输入数据。

示例(删除了错误检查):

#include <windows.h>
#include <iostream>
using namespace std;
LRESULT CALLBACK WindProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    if (Msg == WM_INPUT)
    {
        HRAWINPUT hRawInput = (HRAWINPUT)lParam;
        RAWINPUT input = { 0 };
        UINT size = sizeof(input);
        GetRawInputData(hRawInput, RID_INPUT,&input,&size,sizeof(RAWINPUTHEADER));
        
        printf("vkey: %x, flag: %d\n",input.data.keyboard.VKey, input.data.keyboard.Flags);
    }
    return DefWindowProc(hWnd, Msg, wParam, lParam);
}

int main()
{
    WNDCLASSEX wcx = { 0 };
    wcx.cbSize = sizeof(WNDCLASSEX);
    wcx.lpfnWndProc = WindProc;
    wcx.hInstance = GetModuleHandle(NULL);
    wcx.lpszClassName = TEXT("RawInputClass");
    RegisterClassEx(&wcx);
    HWND hWnd = CreateWindowEx(0, TEXT("RawInputClass"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);

    RAWINPUTDEVICE rid = { 0 };
    rid.usUsagePage = 0x01;
    rid.usUsage = 0x06; //keyboard
    rid.dwFlags = RIDEV_INPUTSINK;
    rid.hwndTarget = hWnd;

    RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE));

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

【讨论】:

  • 我尝试了你的代码,但是在错误之后我得到一个编译器错误,说明许多宏未声明(如 WM_INPUT、HRAWINPUT 等)但它正在寻找其他宏相同的标题。我错过了什么吗?我什至试图复制你的整个代码(我必须做一些改变,因为我使用的是 C 而不是 C++)。
  • @Ascendise 发现了这个问题。我没有设置 WINVER,这就是为什么它没有在标题中创建宏。
猜你喜欢
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
  • 2015-03-29
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多