2016-01-22 24 views
0

我在这里呆了一整天,但几乎没有问过任何问题;你们是如此之好,我不觉得值得(努力在键盘钩内使用秒表

我有这个应用程序,我做了一段时间,最近我再次开始工作。 它记录一个鼠标点击宏并重播它,它工作非常好但我开始觉得还需要增加键盘笔划

所以今天我添加了这个函数来记录键盘笔画,我可以捕捉笔画并显示它们,但是我的问题与事实有关我想运行一个秒表,开始时按键开始,并在键释放结束 除此之外,我应该确保我按的键和我释放的密钥是相同的,我希望这实际上是它

我尝试了很多不同的方式在那里运行秒表,但是关于这段代码的一切让我感到不舒服。该键的监听器应该为keyup和keydown分离,但是如何使用这个计时器呢?

请尽一切努力,全力以赴。


问题是,我试图instanciating秒表全局(Form1的范围),其应:

  1. 运行的方法1时,转到KEYDOWN条件,启动计时器,
  2. 然后再运行一次,进入关键帧并停止计时器。

我认为这应该工作,但我想我有范围问题,考虑到计时器永远不会给出准确的价值。 (按3秒钟1,然后快速按下并释放3)我检查计时器是否开始并在正确的时间停止,我认为它确实如此。

之后我试着在挂钩方法中实例化它,但是因为它必须运行两次才能记录下井号&,计时器被重置。 (写它是这样的我图也许我应该只是检查它是否运行,而不是instanciate它,如果是的话)

我并不急于寻找只是一个快速的方法来解决这个问题,而是寻找实现此功能并尝试使此程序稍微整齐的最佳方式。我有一种感觉,这种方式不对,我应该使用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); 

    } 
+0

问题是...? –

+0

我编辑的问题抱歉,如果它是模糊的。 – mwoa

回答

0

让我们来看看Stopwatchdocumentation

默认情况下,一个秒表实例的经过时间值等于总所有测量时间间隔。每次调用开始时都会从累计经过时间开始计数;每次调用Stop都会结束当前的间隔测量并冻结累计的经过时间值。使用重置方法清除现有秒表实例中的累计已用时间。

正如您所见,您使用它的方式,您的Stopwatch正在累计总时间。如果您想测量两次事件之间的时间,请使用Restart方法而不是Start

+0

谢谢,我会稍后再尝试一下,并回复它是如何发生的。 (离开工作时失败的git提交:l) – mwoa