使表格无法在C#中聚焦

我想写一个虚拟键盘,就像触摸屏电脑的Windows屏幕键盘一样。 但我的虚拟键盘问题正在从使用的应用程序中窃取焦点。 即使用户点击它,Windows屏幕键盘也会将焦点集中在当前应用程序上。 有没有办法在C#中使用Windows窗体做同样的事情?

我现在唯一能做的就是将键盘事件发送到特定的应用程序,例如以下代码中的记事本。 如果我可以使表单不可聚焦,我可以使用GetForegroundWindow获取当前聚焦窗口。

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName,string lpWindowName); [DllImport("USER32.DLL")] public static extern bool SetForegroundWindow(IntPtr hWnd); private void button1_Click(object sender, EventArgs e) { IntPtr calculatorHandle = FindWindow("notepad", null); SetForegroundWindow(calculatorHandle); SendKeys.SendWait("111"); } 

有没有办法可以做到这一点? 有没有更好的方法让表格将键盘事件发送到正在使用的应用程序?

谢谢!!

在点击一个活动窗口后,我宁愿尝试阻止您的窗口接收焦点/被激活,而不是尝试重置活动窗口。

看看这篇文章 。 最后,作者简要介绍了如何做到这一点:

如何在显示时阻止窗口激活和聚焦?

在Windows Forms 2.0中有一个名为ShowWithoutActivation的新属性 – 您需要在Form上覆盖它。 在本机应用程序中,您可以将SetWindowPos与SWP_NOACTIVATE标志一起使用,或者将ShowWindow与SW_SHOWNA标志一起使用。

此外,在本文中,他提供了Windows窗体的代码示例:

如果你想要一个完整的表单,你现在可以覆盖一个名为ShowWithoutActivation的属性:

 公共类NoActivateForm:Form {  
     protected override bool ShowWithoutActivation {  
        得到{  
            返回true;  
         }  
     }  
 } 

请记住,这并不是一直“阻止”激活 – 您仍然可以通过调用Activate()Focus() …等方法来Activate() 。 如果要阻止客户区上的单击激活窗口,可以处理WM_MOUSEACTIVATE消息。

  private const int WM_MOUSEACTIVATE = 0x0021,MA_NOACTIVATE = 0x0003;

 protected override void WndProc(ref message m){
     if(m.Msg == WM_MOUSEACTIVATE){
          m.Result =(IntPtr)MA_NOACTIVATE;
         返回;
     }
     base.WndProc(ref m);
 } 

它解决了!

我尝试过gehho的解决方案,但我还需要覆盖CreateParams方法:

 private const int WS_EX_NOACTIVATE = 0x08000000; protected override CreateParams CreateParams { get { CreateParams createParams = base.CreateParams; createParams.ExStyle |= WS_EX_NOACTIVATE; return createParams; } }