注册 登录
编程论坛 C语言论坛

关于windows平台读键盘按键的问题

Bccn1993 发布于 2023-04-21 10:19, 143 次点击
背景是读键盘按键的程序,功能为按下一个键记录起始时间,放开一个键打印结束时间,从而记录按下的时间。
但是发现现有方案都有一个问题,就是,当我按下一个键不放,此时再按下一个键时,无法读到后面按下的键。
我尝试过其实于_kbhit()+getchar()的方法和ReadConsoleInput()方法都无法处理这个问题,请问是否有可以参考的方法和思路?

新人只有20分,全送了。
3 回复
#2
forever742023-04-21 11:09
学习一下windows程序结构。消息传递机制和处理消息的回调函数。然后考虑一下不写TranslateMessage的后果。
#3
rjsp2023-04-21 15:14
但是发现现有方案都有一个问题,就是,当我按下一个键不放,此时再按下一个键时,无法读到后面按下的键。

https://bbs.bccn.net/viewthread.php?tid=511685&page=1#pid2775217
#4
东海ECS2023-04-21 19:00
你可以使用Windows API函数来实现读取键盘输入的功能,并记录按下时间和放开时间。可以参考以下代码的思路:

1.使用GetAsyncKeyState函数判断某个键是否被按下。

2.如果某个键被按下,记录当前时间为该键的按下时间,并等待该键被释放。

3.当该键被释放时,记录当前时间为该键的放开时间,计算按下和放开时间的差值即为按键持续时间。

4.可以使用一个缓存区来记录多个键的按下和放开时间,如果缓存区已满,则将最早的键的记录覆盖掉。

下面是一个示例代码,可以实现记录多个键的按下时间和放开时间,并计算持续时间:

程序代码:
#include <iostream>
#include <Windows.h>

#define MAX_BUFFER_SIZE 10

struct KeyRecord {
    bool keyDown = false;
    bool keyUp = false;
    DWORD downTime = 0;
    DWORD upTime = 0;
};

void printRecord(const KeyRecord& record) {
    std::cout << "KeyDown: " << record.downTime << ", KeyUp: " << record.upTime
              << ", Duration: " << (record.upTime - record.downTime) << std::endl;
}

int main() {
    KeyRecord buffer[MAX_BUFFER_SIZE];
    int bufferIndex = 0;

    while (true) {
        for (int i = 0; i < 256; ++i) {
            if (GetAsyncKeyState(i) & 0x8000) {
                // Key is down
                if (!buffer[bufferIndex].keyDown) {
                    buffer[bufferIndex].keyDown = true;
                    buffer[bufferIndex].downTime = GetTickCount();
                    std::cout << "Press " << i << "..." << std::endl;
                }
            } else {
                // Key is up
                if (buffer[bufferIndex].keyDown && !buffer[bufferIndex].keyUp) {
                    buffer[bufferIndex].keyUp = true;
                    buffer[bufferIndex].upTime = GetTickCount();
                    printRecord(buffer[bufferIndex]);
                    bufferIndex = (bufferIndex + 1) % MAX_BUFFER_SIZE;
                }
            }
        }
    }

    return 0;
}

通过调用GetAsyncKeyState函数来获取每个键的状态,如果某个键被按下则记录起始时间,等待放开并记录结束时间,最后计算持续时间并输出。结果类似于:

Press 65...
KeyUp: 119392, KeyUp: 119425, Duration: 33




1