8

我正在编写一个 C# 程序,它从外部设备捕获信号,并将击键发送到另一个应用程序。我正在使用 SendKeys,它工作正常。

SendKeys 通过立即按住并释放它来“按下”一个键。我想让它按一下键并随意释放它。

我的问题是:“有没有办法向键发送“推”信号,然后在一定时间后发出“释放”信号?

我不确定 SendKeys 是否能够做到这一点。有什么线索吗?

4

4 回答 4

5

我认为不可能直接从.NET 中您可以尝试通过 p/invoking 此处描述的函数来使用 keybd_event 本机调用:http: //pinvoke.net/default.aspx/user32.keybd_event

keybd_event 的 MSDN 在这里:http: //msdn.microsoft.com/en-us/library/ms646304 (VS.85).aspx

希望有帮助!

于 2008-10-05T18:11:45.003 回答
4

接受的答案使用keybd_event已弃用。官方 API 现在是SendInput. 在http://inputsimulator.codeplex.com也有一个很好的包装器。

然而,以上都没有完全迎合“钥匙持有”的情况。这是因为持有一个密钥会生成多WM_KEYDOWN条消息,然后WM_KEYUP在释放时生成一条消息(您可以使用 Spy++ 进行检查)。

消息的频率WM_KEYDOWN取决于硬件、BIOS 设置和一些 Windows 设置:KeyboardDelayKeyboardSpeed. 后者可从 Windows 窗体 ( SystemInformation.KeyboardDelay, SystemInformation.KeyboardSpeed) 访问。

使用前面提到的输入模拟器库,我实现了一个模拟实际行为的键持有方法。它已await/async准备就绪,并支持取消。

static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs, 
                            int repeatDelayMs, int repeatRateMs, CancellationToken token)
{
    var tcs = new TaskCompletionSource<object>();
    var ctr = new CancellationTokenRegistration();
    var startCount = Environment.TickCount;
    Timer timer = null;
    timer = new Timer(s =>         
    {
        lock (timer)
        {
            if (Environment.TickCount - startCount <= holdDurationMs)
                InputSimulator.SimulateKeyDown(key);
            else if (startCount != -1)
            { 
                startCount = -1; 
                timer.Dispose();
                ctr.Dispose();                    
                InputSimulator.SimulateKeyUp(key);
                tcs.TrySetResult(null);
            }
        }
    });
    timer.Change(repeatDelayMs, repeatRateMs);

    if (token.CanBeCanceled)
        ctr = token.Register(() =>
                       {
                           timer.Dispose();
                           tcs.TrySetCanceled();
                       });
    return tcs.Task;
}
于 2012-03-01T02:01:10.567 回答
3

您可以使用 SendInput 或 keyb_event,它们都是原生 API 函数。SendInput 比 keybd_event 有一些优势,但 SendInput 仅从 XP 开始可用。

这是 msdn 链接 http://msdn.microsoft.com/en-us/library/ms646310.aspx

希望这可以帮助

于 2008-10-05T18:22:55.590 回答
1

我曾经想在 powerpoint 上做同样的事情,隐藏光标,然后停止幻灯片。但这既困难又棘手,因为 powerpoint 中出现了许多顶级窗口,而且如果它不起作用,也很难确定仿真的哪个部分失败。使用 Spy++ 查看消息队列后,我注意到加速器命令是在按键之后发送的,所以我模拟了加速器命令,它的工作原理就像魅力一样。所以你可能想研究这样的替代方案。

于 2008-10-06T02:36:58.073 回答