【问题标题】:Topmost window over everything, except child processes除子进程外,所有内容的最顶层窗口
【发布时间】:2015-08-24 00:45:20
【问题描述】:

我的程序是全屏和最顶层的,我希望该窗口的所有子进程都位于我程序的主窗口之上。这些过程是未知的,并且是外部的。

我可以使用System.Diagnostics.Process.Start(exeName,procArgs).WaitForExit() 启动该进程,但从那里我被卡住了。

【问题讨论】:

    标签: vb.net windows process window


    【解决方案1】:

    基本上,您使用 SetParent() API 使外部应用程序成为您的子应用程序。在这里,我还使用 GetWindowRect() 和 SetWindowPos() API 在其父窗口更改后将窗口保持在相同的启动位置。最后,您需要跟踪进程并手动关闭它们,这样它们就不会在表单关闭时变成孤立的:

    Imports System.ComponentModel
    Imports System.IO
    Imports System.Runtime.InteropServices
    Imports System.Text.RegularExpressions
    
    Public Class Form1
    
        Private Const SWP_NOSIZE As Integer = &H0001
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure RECT
            Public Left As Integer, Top As Integer, Right As Integer, Bottom As Integer
        End Structure
    
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
        Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
        End Function
    
        <DllImport("user32.dll")>
        Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
        End Function
    
        <DllImport("user32.dll", SetLastError:=True)>
        Private Shared Function SetWindowPos(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 Integer) As Boolean
        End Function
    
        Private Ps As New List(Of Process)
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim exeName As String = "Notepad"
            Dim procArgs As String = ""
            LaunchExe(exeName, procArgs)
        End Sub
    
        Private Sub LaunchExe(ByVal exeName As String, ByVal procArgs As String)
            Try
                Dim p As Process = System.Diagnostics.Process.Start(exeName, procArgs)
                If Not IsNothing(p) Then
                    p.WaitForInputIdle()
                    Dim rc As RECT
                    GetWindowRect(p.MainWindowHandle, rc)
                    Dim pt As New Point(rc.Left, rc.Top)
                    pt = Me.PointToClient(pt)
                    SetParent(p.MainWindowHandle, Me.Handle)
                    SetWindowPos(p.MainWindowHandle, 0, pt.X, pt.Y, 0, 0, SWP_NOSIZE)
                    Ps.Add(p)
                End If
            Catch ex As Exception
                MessageBox.Show(exeName & vbCrLf & procArgs, "Error Starting Application")
            End Try
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Me.Close()
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            For Each P As Process In Ps
                If Not P.HasExited Then
                    P.CloseMainWindow()
                End If
            Next
        End Sub
    
    End Class
    

    【讨论】:

    • 非常感谢!我已经坚持了一周!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    相关资源
    最近更新 更多