我正在尝试捕捉击键并在之后重播它们尽可能相等 (时间紧迫)。
到目前为止我尝试了什么:
首先使用SetWindowsHookEx
(使用WH_KEYBOARD_LL
)捕获密钥并记住扫描代码和时间戳(毫秒精度)
然后在捕获后将原始数据转换为预定义函数调用(C#)。
这些是使用SendInput
使用已知扫描代码(KeyUp
结构中的KeyDown
)
KEYBDINPUT
方法>
但是,我对这些电话之间的等待部分表示担忧。目前我正在使用Thread.Sleep
(单线程重播应用程序),但听说这不是非常精确。
我仍然在这里问你,你会想象当前的重播不是那么精确。 虽然每次都不一样!
我可以测量我的程序(或单个函数)的开销,并减去每次等待吗? 我应该尝试不同的方法吗?或者在我的想法中的其他地方是否存在问题?
(该程序不需要是可移植的,只能针对开发计算机进行调整)
答案 0 :(得分:1)
不使用Thread.Sleep而是使用非常紧密的循环并且不断检查时差。你甚至可以让它变得有点聪明,对于任何不到一秒的时间,你只需要在紧密的循环中运行,并且任何超过一秒钟的时间你都会在一段时间内将它停留750毫秒,然后检查差异并继续这样做直到它不到一秒钟。
也许这样的东西,一个容纳你的工作项的课程:
public class workItem
{
public int offset { get; set; }
public string name { get; set; }
}
然后像这样使用它:
Queue<workItem> items = new Queue<workItem>();
items.Enqueue(new workItem() { offset = 200, name = "A" });
items.Enqueue(new workItem() { offset = 220, name = "B" });
items.Enqueue(new workItem() { offset = 240, name = "C" });
items.Enqueue(new workItem() { offset = 230, name = "D" });
items.Enqueue(new workItem() { offset = 250, name = "E" });
items.Enqueue(new workItem() { offset = 260, name = "F" });
DateTime start = DateTime.Now;
Debug.Print(DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"));
while (items.Count > 0)
{
var currItem = items.Dequeue();
while (DateTime.Now < start.AddMilliseconds(currItem.offset))
{
}
Debug.Print("{0}: {1}", DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss.fff tt"), currItem.name);
}
它并不完美,因为在while循环中断和调试触发之间有时间,但它应该让你非常接近。一些评论也有可能有价值的链接(即使用WaitOne或并行任务)