SetForegroundWindow被忽略

时间:2014-03-17 16:06:56

标签: .net winapi user32 setforegroundwindow

我正在编写一个小工具,允许我将输入多路复用到多个终端窗口;

enter image description here

表格收到的任何输入(在中心)都会转发到它管理的所有终端窗口。

这很有效但如果我在另一个窗口移动到终端前面会出现问题。输入表单为Topmost,因此始终可见,但终端会话被隐藏。

要解决此问题,双击“输入”窗口会遍历所有终端并依次调用SetForegroundWindow(来自user32.dll)。

For Each Manager In Managers
    SetForegroundWindow(ProcessInfo.MainWindowHandle)
    'Threading.Thread.Sleep(15)
Next

如果我在没有Thread.Sleep(15)的情况下拨打此电话,则只会将列表中的第一个和最后一个窗口置于前台。 Sleep可以解决这个问题但是有点像黑客(当有很多终端打开时会有点难看。)

我假设我正在点击一些内部窗口滴答频率,其中每个窗口最多可以将一个窗口带到前面。

我的假设是否正确?有没有办法解决这个限制?像MoveAllToForeground()或排队消息的方式?

修改

澄清:我正在自动化的终端流程不是我的应用程序的一部分,它是PuTTY

如果我将SetForegroundWindow的呼叫换成BringWindowToTop,我会遇到类似的问题 - 尽管在这种情况下,只有第一个终端被带到前面,其余的终止于任何终端其他窗户。

编辑2:

继David的建议如下。声明:

Private Declare Auto Function SetWindowPos Lib "user32.dll" (
    ByVal hWnd As IntPtr,
    ByVal hWndInsertAfter As IntPtr,
    ByVal X As Integer,
    ByVal Y As Integer,
    ByVal cx As Integer,
    ByVal cy As Integer,
    ByVal uFlags As SetWindowPosFlags
    ) As Boolean

Private Shared ReadOnly HWND_TOPMOST As New IntPtr(-1)
Private Shared ReadOnly HWND_NOTOPMOST As New IntPtr(-2)
Private Shared ReadOnly HWND_TOP As New IntPtr(0)
Private Shared ReadOnly HWND_BOTTOM As New IntPtr(1)

Private Enum SetWindowPosFlags
    NOSIZE = &H1
    NOMOVE = &H2
    NOZORDER = &H4
    NOREDRAW = &H8
    NOACTIVATE = &H10
    DRAWFRAME = &H20
    FRAMECHANGED = &H20
    SHOWWINDOW = &H40
    HIDEWINDOW = &H80
    NOCOPYBITS = &H100
    NOOWNERZORDER = &H200
    NOREPOSITION = &H200
    NOSENDCHANGING = &H400
    DEFERERASE = &H2000
    ASYNCWINDOWPOS = &H4000
End Enum

电话......

SetWindowPos(ProcessInfo.MainWindowHandle,
             HWND_TOP,
             0, 0, 0, 0,
             SetWindowPosFlags.NOMOVE Or
             SetWindowPosFlags.NOSIZE Or
             SetWindowPosFlags.NOACTIVATE)

1 个答案:

答案 0 :(得分:2)

显然你想将这些窗口放在前面而不是让它们成为前景窗口。这样做的方法是致电SetWindowPos通过HWND_TOP。您需要将SWP_NOMOVE | SWP_NOSIZE作为uFlags参数传递,因为您只想更改z顺序,而不是位置和大小。

每次致电SetWindowPos后,请致电SetForegroundWindow通过您应用程序的主窗口句柄。