努力在键盘钩中使用秒表
本文关键字:键盘 努力 | 更新日期: 2023-09-27 18:31:32
我整天都在这里度过,但几乎从不问任何问题;你们太好了,我觉得不值得(:
我有一段时间前制作的这个应用程序,我最近又开始工作了。它记录了一个鼠标单击宏并重播它,它非常适合我的使用,但我开始觉得也需要添加键盘笔划。
所以今天我添加了这个记录键盘笔划的功能,我可以捕捉笔画并显示它们,但我的问题是我想运行一个从按键开始并在按键释放时结束的秒表。此外,我应该确保我按下的键和我释放的键是相同的,我希望这实际上可以做到。
我尝试了很多不同的方法来运行秒表,但是关于这段代码的所有内容都让我感到不舒服。键的侦听器应该将键控和键降分开,但我如何使用计时器呢?
无论如何,请全力以赴。
问题是,我尝试全局实例化秒表(Form1 范围),它应该:
- 运行方法1次,进入键下条件,启动定时器,
- 然后运行另一个时间,转到 Keyup 并停止计时器。
我认为这应该有效,但我想我有范围问题,因为计时器从未给出准确的值。(按 3 秒得到 1,之后按下并快速松开得到 3)我检查了计时器是否在正确的时间启动和停止,我认为确实如此。
之后,我尝试在钩子方法中实例化它,但由于它必须运行两次才能很好地记录上下,因此计时器被重置。(这样写,我想也许我应该检查它是否正在运行,如果它正在运行,则不要实例化它)
我并不着急,真的不是在寻找解决此问题的快速方法,而是寻找实现此功能的最佳方法,并尝试使该程序更整洁。我有一种感觉,这很离谱,我应该使用 lParam,这会让它更容易。
我在那里存储按键信息,尽管我认为 lParam 实际上更有效地执行此操作,但无法理解它是如何工作的
public class KeyPressHelper
{
public Keys currentPressedKeyCode;
public Keys currentReleasedKeyCode;
public Keys previousPressedKeyCode;
public KeyPressHelper()
{
currentPressedKeyCode = new Keys();
currentReleasedKeyCode = new Keys();
previousPressedKeyCode = new Keys();
}
}
这是钩子函数,大部分只是MSDN提供的示例代码,我添加了Keyup的条件,但我真的不确定这是真正的正确方法。
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
keyStrokeTimer.Start(); // global Stopwatch
//keypresshelper kph1
kph1.previousPressedKeyCode = 0;
kph1.currentReleasedKeyCode = 0;
int vkCode = Marshal.ReadInt32(lParam);
kph1.currentPressedKeyCode = (Keys)vkCode;
kphList.Add(kph1);
}
if (nCode >= 0 && wParam == (IntPtr)WM_KEYUP)
{
//assign kph2.previousPressedkey to kph1.currentPressedKey
kph2.previousPressedKeyCode
= kphList.Find(k => k.Equals(kph1)).currentPressedKeyCode;
kph2.currentPressedKeyCode = 0;
int vkCode = Marshal.ReadInt32(lParam);
kph2.currentReleasedKeyCode = (Keys)vkCode;
//if they're identical well this is nice.
if (kph2.previousPressedKeyCode == kph2.currentReleasedKeyCode)
{
keyStrokeTimer.Stop();
MessageBox.Show("" + keyStrokeTimer.ElapsedMilliseconds) //goal.
}
else
{
keyStrokeTimer.Stop();
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
让我们看一下Stopwatch
类文档
默认情况下,秒表实例的已用时间值等于所有测量时间间隔的总和。对"开始"屏幕的每个调用都从累计运行时间开始计数;每次调用 Stop 都会结束当前间隔测量并冻结累计已用时间值。使用 Reset 方法清除现有秒表实例中的累计运行时间。
如您所见,您使用它的方式,您的Stopwatch
正在积累总时间。如果要测量两个事件之间的时间,请使用重新启动方法而不是Start
。