如何使用C#按键并释放?
我正在编写一个C#程序,它从外部设备捕获信号,并将击键发送到另一个应用程序。我使用SendKeys,它工作正常 SendKeys通过按住并立即释放键来“按下”键。我想让它按一下键,然后随意释放 我的问题是:“有没有一种方法可以向钥匙发送“推”信号,然后在一定时间后发送“释放”信号?”如何使用C#按键并释放?,c#,keyboard,C#,Keyboard,我正在编写一个C#程序,它从外部设备捕获信号,并将击键发送到另一个应用程序。我使用SendKeys,它工作正常 SendKeys通过按住并立即释放键来“按下”键。我想让它按一下键,然后随意释放 我的问题是:“有没有一种方法可以向钥匙发送“推”信号,然后在一定时间后发送“释放”信号?” 我不确定SendKeys是否能够做到这一点。有什么线索吗?我认为不可能直接从.NET获得 您可以尝试使用keybd_事件本机调用,方法是p/调用函数,如下所述: keybd_事件的MSDN如下所示: 希望有帮助 您
我不确定SendKeys是否能够做到这一点。有什么线索吗?我认为不可能直接从.NET获得 您可以尝试使用keybd_事件本机调用,方法是p/调用函数,如下所述: keybd_事件的MSDN如下所示:
希望有帮助 您可以使用SendInput或keyb_事件,两者都是本机API函数。SendInput与keybd_事件相比有一些优势,但SendInput仅从XP开始提供 这里是msdn链接
希望这有帮助我曾经想在powerpoint上做同样的事情,隐藏光标,然后停止幻灯片放映。但这很难,也很棘手,因为powerpoint中出现了许多顶级窗口,而且很难确定哪部分仿真失败了。在使用Spy++查看消息队列之后,我注意到accelerator命令是在按键之后发送的,因此,我模拟了accelerator命令,它的工作原理与charm类似。因此,您可能希望研究类似的替代方案。接受的答案使用了
keybd\u事件,这是不推荐的。官方API现已发布。还有一个很好的包装
然而,上述任何一项都不能完全满足“持有钥匙”的情况。这是因为,按住一个键将生成多条WM_KEYDOWN
消息,然后在释放时生成一条WM_keydup
消息(您可以使用Spy++进行检查)
WM_KEYDOWN
消息的频率取决于硬件、BIOS设置和两个Windows设置:和。后者可从Windows窗体(,)访问
使用前面提到的输入模拟器库,我实现了一个模拟实际行为的键保持方法。它是await/async
ready,支持取消
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;
}
static Task SimulateKeyHold(VirtualKeyCode键,int-holdDurationMs,
int repeatDelayMs、int repeatRateMs、CancellationToken令牌)
{
var tcs=new TaskCompletionSource();
var ctr=新的CancellationTokenRegistration();
var startCount=Environment.TickCount;
计时器=空;
定时器=新定时器(s=>
{
锁(定时器)
{
if(Environment.TickCount-startCount
{
timer.Dispose();
tcs.trysetconceled();
});
返回tcs.Task;
}
非常感谢您的宝贵意见。