0

我正在编写一个小实用程序来允许我将输入多路复用到多个终端窗口;

在此处输入图像描述

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

这很好用,但是如果我在终端前面移动另一个窗口,就会出现问题。输入表单Topmost总是可见的,但终端会话是隐藏的。

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

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

如果我在没有 的情况下进行此调用Thread.Sleep(15),则仅将列表中的第一个和最后一个窗口置于前台。解决了这个Sleep问题,但有点破解(当有很多终端打开时有点难看)。

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

我的假设是否正确?有没有办法绕过这个限制?诸如排队消息之类的东西MoveAllToForeground()

编辑:

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

如果我将调用换成SetForegroundWindowfor BringWindowToTop,我会遇到类似的问题 - 尽管在这种情况下,只有第一个终端被带到前面,其余的留在任何其他窗口后面。

编辑2:

以下是大卫的建议。声明:

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)
4

1 回答 1

2

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

每次调用 后SetWindowPos,调用SetForegroundWindow传递应用程序的主窗口句柄。

于 2014-03-17T16:18:07.703 回答