使表单无法在C#中聚焦

时间:2010-03-11 07:22:10

标签: c# forms keyboard focus sendkeys

我想写一个虚拟键盘,就像触摸屏电脑的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");
}

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

谢谢!

2 个答案:

答案 0 :(得分:13)

它解决了!

我尝试过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;
        }
    }

答案 1 :(得分:9)

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

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

  

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

     

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

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

  

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

public class NoActivateForm : Form {  
    protected override bool ShowWithoutActivation {  
        get {  
            return true;  
        }  
    }  
}
     

请记住,这并不是一直“阻止”激活 - 你可以   仍然通过调用Activate()Focus() ...等方法激活。如果   您希望阻止客户区域的点击激活   窗口,您可以处理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;
         return;
    }
    base.WndProc(ref m);
}