2010-08-26 87 views
0

我有一个应用程序使用下面的代码来获取输入基于从第三方应用程序生成的文件。Tricky C#表单键盘输入焦点问题

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
     const int WM_KEYDOWN = 0x100; 
     const int WM_SYSKEYDOWN = 0x104; 

     if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN)) 
     { 
      switch (keyData) 
      { 
       case Keys.F1: 
        clicked_F1(null, null); 
        break; 

       case Keys.F2: 
        clicked_F2(null, null); 
        break; 

       case Keys.F3: 
        clicked_F3(null, null); 
        break; 
      } 
      return true; 
     } 
     return base.ProcessCmdKey(ref msg, keyData); 
    } 

Form.TopMost设置为true,并且在OnShown回调期间调用this.Activate()。这适用于大多数机器,但有时键盘输入不会传递给我的应用程序,例如,如果按下F1,窗口帮助将弹出。

任何人都可以解释这种行为吗?我需要确保我的表单将会收到这些键盘事件。

干杯, 理查德

回答

3

有您最顶层的形式是不足以保证这种方法运行。你的表单也需要关注。这需要调用其Activate()方法(Win32 API中的SetForegroundWindow)。这是而不是保证运行,你不能从用户正在使用的窗口窃取焦点。只有在自上次输入事件以来已经过了足够的时间后,您才能抓住焦点。

不知道你真的想要做什么,也许你需要一个键盘钩子或使用RegisterHotKey。

+0

感谢汉斯。我在OnShown回调中设置了Activate()方法。我需要在传统Till应用程序上方放置一个窗口,该应用程序始终与TopMost一起运行,为用户提供额外的选项。 – 2010-08-26 18:22:23

+0

那么,Windows并不关心这一点。我认为对AttachThreadInput()进行管理可能会有所帮助,您需要获取该程序的UI线程的TID。 GetWindowThreadProcessId()。 – 2010-08-26 18:24:41

+0

绝对纠正这不是一个传统的情况 - 我希望能够以另一种方式做到这一点。我可能会回到绘图板,看看是否有其他选择。 – 2010-08-26 19:27:01