有没有一种可靠的方法来使用C#激活/设置焦点到窗口?

时间:2010-04-19 23:52:07

标签: c# windows focus

我正在尝试使用C#找到一种可靠的方法来激活/设置焦点到外部应用程序的窗口。目前,我正在尝试使用以下Windows API调用实现此目的:

SetActiveWindow(handle);
SwitchToThisWindow(handle, true);

以前我也有ShowWindow(handle, SW_SHOWMAXIMIZED);在另外2个之前执行,但删除了它,因为它导致了奇怪的行为。

我当前实现的问题是偶尔会无法正确设置焦点。窗口将变为可见,但它的顶部仍然显示为灰色,就好像它没有聚焦一样。

有没有办法可靠地做到这一点,100%的时间都在工作,或者是不一致的行为是我无法逃避的副作用?如果您有任何始终有效的建议或实施,请告诉我。

4 个答案:

答案 0 :(得分:8)

您需要使用AttachThreadInput

  

在不同线程中创建的Windows通常彼此独立地处理输入。也就是说,它们有自己的输入状态(焦点,活动,捕获窗口,键状态,队列状态等),并且它们与其他线程的输入处理不同步。通过使用AttachThreadInput函数,线程可以将其输入处理附加到另一个线程。这也允许线程共享它们的输入状态,因此它们可以调用SetFocus函数将键盘焦点设置为不同线程的窗口。这也允许线程获取密钥状态信息。这些功能通常是不可能的。

我不确定从(可能)Windows窗体使用此API的后果。也就是说,我在C ++中使用它来获得这种效果。代码如下所示:

     DWORD currentThreadId = GetCurrentThreadId();
     DWORD otherThreadId = GetWindowThreadProcessId(targetHwnd, NULL);
     if( otherThreadId == 0 ) return 1;
     if( otherThreadId != currentThreadId )
     {
       AttachThreadInput(currentThreadId, otherThreadId, TRUE);
     }

     SetActiveWindow(targetHwnd);

     if( otherThreadId != currentThreadId )
     {
       AttachThreadInput(currentThreadId, otherThreadId, FALSE);
     }

targetHwnd是您要设置焦点的窗口的HWND。我假设您已经可以使用P / Invoke签名,因为您已经在使用本机API。

答案 1 :(得分:3)

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);

这个对我有用

答案 2 :(得分:1)

如果它在您的应用程序中都是内部的,那么您可以获取父窗口或该窗口,并以这种方式激活它(对不起):

Public Class Form1 : Inherits Form

    Protected Overrides Sub OnLoad(e As EventArgs)
        Dim form2 As New Form2
        form2.Show()
    End Sub
End Class

Class Form2 : Inherits Form

    Protected Overrides Sub OnLoad(e As EventArgs)
        MyBase.OnLoad(e)
        Me.Owner.Activate()
    End Sub
End Class

答案 3 :(得分:0)

        hwnd_WhoRecvFocus.ShowWindow( SW_MINIMIZE )
        hwnd_WhoRecvFocus.ShowWindow( SW_RESTORE )