You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模拟按键长按未达预期:如何实现物理长按的重复输入效果?

模拟物理长按按键实现重复输入的解决方案

问题中的代码通过keybd_event模拟按键长按,但无法像物理按键那样触发重复输入,原因是系统的按键自动重复机制依赖硬件发送的重复信号,单纯保持按键按下状态并不会触发该机制。以下是两种可行的解决方法:

方法一:模拟重复的按键按下与释放

根据系统的键盘重复延迟和重复率,循环发送按键按下和释放事件,模拟物理长按的重复效果:

#include <windows.h>
#define VK_W 0x57

int main()
{
    // 获取系统键盘重复设置:延迟时间(毫秒)和重复率(次/秒)
    UINT delay, rate;
    SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0);
    SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &rate, 0);
    
    // 转换延迟为毫秒:delay取值0-3,对应250/500/750/1000ms
    DWORD initialDelay = (delay + 1) * 250;
    // 转换重复率为间隔毫秒:rate取值0-31,对应30次/秒到2.5次/秒
    DWORD repeatInterval = 1000 / (rate + 1);
    
    // 先按下一次按键
    keybd_event(VK_W, 0, 0, 0);
    Sleep(initialDelay);
    
    // 循环发送重复的按键事件
    DWORD startTime = GetTickCount();
    while (GetTickCount() - startTime < 3000 - initialDelay)
    {
        keybd_event(VK_W, 0, KEYEVENTF_KEYUP, 0);
        Sleep(10); // 模拟按键弹起的短暂间隔
        keybd_event(VK_W, 0, 0, 0);
        Sleep(repeatInterval);
    }
    
    // 最后释放按键
    keybd_event(VK_W, 0, KEYEVENTF_KEYUP, 0);
    return 0;
}

方法二:使用SendInput模拟更接近硬件的按键信号

SendInput是比keybd_event更可靠的输入模拟API,结合系统参数可以更贴近物理按键的行为:

#include <windows.h>
#define VK_W 0x57

void SimulateKeyPress(WORD vkCode, DWORD duration)
{
    INPUT input[2] = {0};
    
    // 构造按键按下的输入事件
    input[0].type = INPUT_KEYBOARD;
    input[0].ki.wVk = vkCode;
    
    // 构造按键释放的输入事件
    input[1].type = INPUT_KEYBOARD;
    input[1].ki.wVk = vkCode;
    input[1].ki.dwFlags = KEYEVENTF_KEYUP;
    
    // 发送按下事件
    SendInput(1, &input[0], sizeof(INPUT));
    
    // 获取系统重复参数
    UINT delay, rate;
    SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &delay, 0);
    SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &rate, 0);
    DWORD initialDelay = (delay + 1) * 250;
    DWORD repeatInterval = 1000 / (rate + 1);
    
    Sleep(initialDelay);
    DWORD startTime = GetTickCount();
    
    // 循环发送重复的按键敲击
    while (GetTickCount() - startTime < duration - initialDelay)
    {
        SendInput(1, &input[1], sizeof(INPUT));
        Sleep(10);
        SendInput(1, &input[0], sizeof(INPUT));
        Sleep(repeatInterval);
    }
    
    // 发送释放事件
    SendInput(1, &input[1], sizeof(INPUT));
}

int main()
{
    SimulateKeyPress(VK_W, 3000);
    return 0;
}

关键说明

  • 系统的按键重复参数通过SystemParametersInfo获取,确保模拟的重复节奏和系统默认设置完全一致。
  • 两种方法都先等待初始延迟,再开始重复发送按键事件,完全匹配物理按键的重复逻辑。

内容的提问来源于stack exchange,提问作者work work

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 05:45:22