如何将外部CLI窗口嵌入Windows表单中的面板中?

发布于 2025-01-27 10:45:22 字数 1004 浏览 2 评论 0 原文

在c#或vb.net中,在Windows表单下,我想知道如何将外部命令行接口(CLI)窗口嵌入面板或其他类型的主机窗口中,我可以在其中渲染外部CLI的内容我的表格内的窗户。

请注意,我不会假装重定向并打印 stdout 自己。我只是想将窗户嵌入我的表格中,然后将其嵌入。

我已经尝试了 setParent 函数效果,但它似乎对非刻板用户-interface Windows不起作用,因为因为设置父窗口时,CLI窗口会从屏幕上消失,并且不会在父(面板)窗口中渲染。

看来这可以在WPF中进行,如所建议的在这里,但是我不知道如何在Windows表单下进行此操作。

我正在寻找可以以这样的方式使用的解决方法:

using (var p = new Process()) {
        p.StartInfo.FileName = @".\cli-process.exe";
        p.StartInfo.Arguments = @"...";
        p.StartInfo.CreateNoWindow = false;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
        p.Start();

        Thread.Sleep(2000);
        EmbedToWindow(p.MainWindowHandle, this.Panel1.Handle);
        p.WaitForExit(TimeOut.Infinite);
    }
}

In C# or VB.NET, under Windows Forms, I would like to know how can I embed a external command-line interface (CLI) window, into a panel or other kind of host window where I can render the contents of the external CLI window inside my form.

Please note that I don't pretend to redirect and print the StdOut stream by myself. I just would like to embed the window into my form and let it be.

I've tried SetParent function as suggested, but it does not seem to work for non-graphical user-interface windows, because when setting the parent window, the CLI window disappear from screen and it is not rendered in the parent (a panel) window.

It seems this can be done in WPF as suggested here, but I'm not aware how to do this under Windows Forms.

I'm looking for some workaround that I could use in a way like this:

using (var p = new Process()) {
        p.StartInfo.FileName = @".\cli-process.exe";
        p.StartInfo.Arguments = @"...";
        p.StartInfo.CreateNoWindow = false;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
        p.Start();

        Thread.Sleep(2000);
        EmbedToWindow(p.MainWindowHandle, this.Panel1.Handle);
        p.WaitForExit(TimeOut.Infinite);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

握住我的手 2025-02-03 10:45:22

我刚刚在vb.net中写了一个简单的助手课,它将使我轻松设置和释放父窗口。

至少在我所需的情况下,它至少可以按预期进行。

感谢@jimi,@rbmm和@Remy Lebeau的帮助以及我需要知道的技巧,以找出如何做到这一点。

但是,由于缺少类型,我在这里分享的内容不起作用,但是您可以理解这个想法。抱歉,但它需要超过此帖子的最大角色限制,也许复制&如果我是唯一有兴趣完成此任务的

人,请粘贴并适应在这里向他们展示的东西...但是,如果您想弄清楚如何使此类功能正常缺少 nativemethods 类定义,然后替换呼叫 window> window> window> win32/api/hinuser/nf-winuser-getWindowInfo“ rel =“ nofollow noreferrer”> getWindowInfo (以及 window> windownfo struct),否则 getClientRect + getwindowlongptr /code>或用于从 safehandlehemandleminusoneisinisinvalid

用法示例:

Dim process As Process = Process.GetProcessesByName("name").Single()
Dim windowParenting As New WindowParenting(process.MainWindowHandle)

windowParenting.SetParent(Me.Panel1, 
                          fitToParentBounds:=True, 
                          removeBorder:=True, 
                          removeCaption:=True, 
                          resizable:=False)

Thread.Sleep(5000)
windowParenting.ReleaseParent(throwOnInvalidSourceWindowHandle:=True)

' Or...
' windowParenting.Dispose() ' It calls ReleaseParent.

窗口parrenting类:

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Implements a mechanism to set and release the parent window for a specific source window.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
Public Class WindowParenting : Implements IDisposable

#Region " Properties"

    ''' <summary>
    ''' A safe handle to the source window.
    ''' </summary>
    Public ReadOnly Property WindowHandle As SafeWindowHandle

    ''' <summary>
    ''' Gets a <see cref="DevCase.Core.IPC.WindowInfo"/> object for the source window.
    ''' </summary>
    Public ReadOnly Property WindowInfo As WindowInfo
        Get
            Return Me.GetWindowInfo()
        End Get
    End Property

    ''' <summary>
    ''' Gets a value that determine whether the source window has a parent window.
    ''' </summary>
    Public ReadOnly Property HasParent As Boolean
        Get
            Try
                Return Me.WindowInfo.ParentWindow IsNot Nothing
            Catch ex As Exception
                Return False
            End Try
        End Get
    End Property

#End Region

#Region " Private Fields"

    ''' <summary>
    ''' Keeps track of the current source window bounds when making a call to <see cref="WindowParenting.SetParent"/> method.
    ''' </summary>
    Private lastBounds As Rectangle = Rectangle.Empty

    ''' <summary>
    ''' Keeps track of the current source <see cref="WindowStyles"/> when making a call to <see cref="WindowParenting.SetParent"/> method.
    ''' </summary>
    Private lastWindowStyle As WindowStyles = WindowStyles.None

#End Region

#Region " Constructors "

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="hwnd">
    ''' A handle to the source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(hwnd As IntPtr)
        Me.New(New SafeWindowHandle(hwnd))
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="hwnd">
    ''' A handle to the source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(hwnd As SafeHandle)
        Me.WindowHandle = hwnd

        If Me.WindowHandle.IsInvalid Then
            Throw New Exception("Invalid window handle.")
        End If
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="window">
    ''' AThe source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(window As NativeWindow)
        Me.New(New SafeWindowHandle(window.Handle))
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="window">
    ''' The source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(window As IWin32Window)
        Me.New(New SafeWindowHandle(window.Handle))
    End Sub

#End Region

#Region " Public Methods "

    ''' <summary>
    ''' Sets a new parent window for the source window.
    ''' </summary>
    ''' <param name="parentWindow">
    ''' The parent window.
    ''' </param>
    ''' 
    ''' <param name="fitToParentBounds">
    ''' If set to <see langword="True"/>, fits to size of the source window to the parent window bounds.
    ''' </param>
    ''' 
    ''' <param name="removeBorder">
    ''' If set to <see langword="True"/>, removes the border from the source window.
    ''' </param>
    ''' 
    ''' <param name="removeCaption">
    ''' If set to <see langword="True"/>, removes the caption from the source window.
    ''' </param>
    ''' 
    ''' <param name="resizable">
    ''' If set to <see langword="False"/>, remove sthe size frame from the source window.
    ''' </param>
    ''' <exception cref="InvalidOperationException">
    ''' Source window already has a parent window.
    ''' </exception>
    <DebuggerStepThrough>
    Public Overridable Sub SetParent(parentWindow As IWin32Window, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Dim curentWindowInfo As WindowInfo = Me.GetWindowInfo()
        If Me.lastBounds = Rectangle.Empty Then
            Me.lastBounds = curentWindowInfo.Bounds
        End If
        If Me.lastWindowStyle = WindowStyles.None Then
            Me.lastWindowStyle = curentWindowInfo.WindowStyle
        End If

        Dim newStyle As WindowStyles = (Me.lastWindowStyle And Not WindowStyles.SysMenu)
        If removeBorder Then
            newStyle = (newStyle And Not WindowStyles.Border)
        End If
        If removeCaption Then
            newStyle = (newStyle And Not WindowStyles.Caption)
        End If
        If Not resizable Then
            newStyle = (newStyle And Not WindowStyles.SizeFrame)
        End If

        Dim parentWindowHandle As New SafeWindowHandle(parentWindow.Handle)

        NativeMethods.SetParent(Me.WindowHandle, parentWindowHandle)
        Me.SetSourceWindowStyle(newStyle)

        Dim parentClientRect As Rectangle
        If fitToParentBounds Then
            NativeMethods.GetClientRect(parentWindowHandle, parentClientRect)
        End If
        NativeMethods.SetWindowPos(Me.WindowHandle, IntPtr.Zero, 0, 0,
                                   If(fitToParentBounds, parentClientRect.Width, 0),
                                   If(fitToParentBounds, parentClientRect.Height, 0),
                                   SetWindowPosFlags.AsyncWindowPos Or
                                   SetWindowPosFlags.ShowWindow Or
                                   If(fitToParentBounds, SetWindowPosFlags.None, SetWindowPosFlags.IgnoreResize))

    End Sub

    Public Overridable Sub SetParent(parentWindow As NativeWindow, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Me.SetParent(DirectCast(parentWindow, IWin32Window), fitToParentBounds, removeBorder, removeCaption, resizable)

    End Sub

    Public Overridable Sub SetParent(parentWindow As Control, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Me.SetParent(DirectCast(parentWindow, IWin32Window), fitToParentBounds, removeBorder, removeCaption, resizable)

    End Sub

    ''' <summary>
    ''' Release the source window from its current parent window.
    ''' </summary>
    ''' <param name="throwOnInvalidSourceWindowHandle">
    ''' If set to <see langword="True"/>, throws an <see cref="NullReferenceException"/> 
    ''' if the source window handle specified in <see cref="WindowParenting.WindowHandle"/> is invalid.
    ''' <para></para>
    ''' This can be useful if you need to detect whether the source window has been destroyed.
    ''' </param>
    <DebuggerStepThrough>
    Public Overridable Sub ReleaseParent(Optional throwOnInvalidSourceWindowHandle As Boolean = False)

        Dim isInvalid As Boolean = Me.WindowHandle.IsInvalid OrElse
                                   Me.WindowHandle.IsClosed OrElse
                                   Not NativeMethods.IsWindow(Me.WindowHandle)

        If isInvalid AndAlso throwOnInvalidSourceWindowHandle Then
            Throw New NullReferenceException("Invalid source window handle.")

        ElseIf Not isInvalid Then
            If Not Me.HasParent Then
                Throw New InvalidOperationException("Source window has not a parent window.")
            End If

            NativeMethods.SetParent(Me.WindowHandle, IntPtr.Zero)

            If Me.lastWindowStyle <> WindowStyles.None Then
                Me.SetSourceWindowStyle(Me.lastWindowStyle)
                Me.lastWindowStyle = WindowStyles.None
            End If

            If Me.lastBounds <> Rectangle.Empty Then
                NativeMethods.SetWindowPos(Me.WindowHandle, IntPtr.Zero,
                                       Me.lastBounds.X, Me.lastBounds.Y,
                                       Me.lastBounds.Width, Me.lastBounds.Height,
                                       SetWindowPosFlags.AsyncWindowPos)
                Me.lastBounds = Rectangle.Empty
            End If

        End If

    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Returns a <see cref="DevCase.Core.IPC.WindowInfo"/> object for the source window.
    ''' </summary>
    <DebuggerStepThrough>
    Private Function GetWindowInfo() As WindowInfo
        Return New WindowInfo(Me.WindowHandle)
    End Function

    ''' <summary>
    ''' Sets the <see cref="WindowStyles"/> for the source window.
    ''' </summary>
    <DebuggerStepThrough>
    Private Sub SetSourceWindowStyle(style As WindowStyles)

        If Environment.Is64BitProcess Then
            NativeMethods.SetWindowLongPtr(Me.WindowHandle, WindowLongValues.WindowStyle, style)
        Else
            NativeMethods.SetWindowLong(Me.WindowHandle, WindowLongValues.WindowStyle, style)
        End If

    End Sub

#End Region

#Region " IDisposable Implementation "

    ''' <summary>
    ''' Flag to detect redundant calls.
    ''' </summary>
    Private disposedValue As Boolean

    ''' <summary>
    ''' Releases all the resources used by this instance.
    ''' </summary>
    ''' <param name="disposing">
    ''' <see langword="True"/> to release both managed and unmanaged resources; 
    ''' <see langword="False"/> to release only unmanaged resources.
    ''' </param>
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue AndAlso disposing Then
            Try
                Me.ReleaseParent()
            Catch ex As Exception
            End Try
            Me.WindowHandle?.Close()
        End If
        Me.disposedValue = True
    End Sub

    ''' <summary>
    ''' Releases all the resources used by this instance.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Me.Dispose(True)
    End Sub

#End Region

End Class

它缺少P/Invokes的Win32错误处理。也许其他事情可以得到改善。

I just wrote a simple helper class in VB.NET that will serve me to set and release a parent window with ease.

It seems to work as expected at least as far as I have tested it in my required scenarios.

Thanks to @Jimi, @RbMm and @Remy Lebeau for their help and their tips that I need to know in order to figure how to do this.

However, what I share here is not functional due to missing types, but you could get the idea. Sorry but it would require to exceed the maximum character limit of this post, and maybe it's too much effort of copy & paste and adapt things to show them here if I'm the only one interested to accomplish this task...

But if you want to figure how to make this class functional then simply add the missing P/Invoke members of which I use in the missing NativeMethods class definition, and replace the missing WindowInfo type for a call to GetWindowInfo (and the WINDOWINFO struct) or else GetClientRect + GetWindowLongPtr functions, and replace missing SafeWindowHandle type for IntPtr or for a custom class derived from SafeHandleZeroOrMinusOneIsInvalid.

Usage Example:

Dim process As Process = Process.GetProcessesByName("name").Single()
Dim windowParenting As New WindowParenting(process.MainWindowHandle)

windowParenting.SetParent(Me.Panel1, 
                          fitToParentBounds:=True, 
                          removeBorder:=True, 
                          removeCaption:=True, 
                          resizable:=False)

Thread.Sleep(5000)
windowParenting.ReleaseParent(throwOnInvalidSourceWindowHandle:=True)

' Or...
' windowParenting.Dispose() ' It calls ReleaseParent.

WindowParenting Class:

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Implements a mechanism to set and release the parent window for a specific source window.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
Public Class WindowParenting : Implements IDisposable

#Region " Properties"

    ''' <summary>
    ''' A safe handle to the source window.
    ''' </summary>
    Public ReadOnly Property WindowHandle As SafeWindowHandle

    ''' <summary>
    ''' Gets a <see cref="DevCase.Core.IPC.WindowInfo"/> object for the source window.
    ''' </summary>
    Public ReadOnly Property WindowInfo As WindowInfo
        Get
            Return Me.GetWindowInfo()
        End Get
    End Property

    ''' <summary>
    ''' Gets a value that determine whether the source window has a parent window.
    ''' </summary>
    Public ReadOnly Property HasParent As Boolean
        Get
            Try
                Return Me.WindowInfo.ParentWindow IsNot Nothing
            Catch ex As Exception
                Return False
            End Try
        End Get
    End Property

#End Region

#Region " Private Fields"

    ''' <summary>
    ''' Keeps track of the current source window bounds when making a call to <see cref="WindowParenting.SetParent"/> method.
    ''' </summary>
    Private lastBounds As Rectangle = Rectangle.Empty

    ''' <summary>
    ''' Keeps track of the current source <see cref="WindowStyles"/> when making a call to <see cref="WindowParenting.SetParent"/> method.
    ''' </summary>
    Private lastWindowStyle As WindowStyles = WindowStyles.None

#End Region

#Region " Constructors "

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="hwnd">
    ''' A handle to the source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(hwnd As IntPtr)
        Me.New(New SafeWindowHandle(hwnd))
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="hwnd">
    ''' A handle to the source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(hwnd As SafeHandle)
        Me.WindowHandle = hwnd

        If Me.WindowHandle.IsInvalid Then
            Throw New Exception("Invalid window handle.")
        End If
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="window">
    ''' AThe source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(window As NativeWindow)
        Me.New(New SafeWindowHandle(window.Handle))
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the <see cref="WindowParenting"/> class.
    ''' </summary>
    ''' <param name="window">
    ''' The source window.
    ''' </param>
    <DebuggerStepThrough>
    Public Sub New(window As IWin32Window)
        Me.New(New SafeWindowHandle(window.Handle))
    End Sub

#End Region

#Region " Public Methods "

    ''' <summary>
    ''' Sets a new parent window for the source window.
    ''' </summary>
    ''' <param name="parentWindow">
    ''' The parent window.
    ''' </param>
    ''' 
    ''' <param name="fitToParentBounds">
    ''' If set to <see langword="True"/>, fits to size of the source window to the parent window bounds.
    ''' </param>
    ''' 
    ''' <param name="removeBorder">
    ''' If set to <see langword="True"/>, removes the border from the source window.
    ''' </param>
    ''' 
    ''' <param name="removeCaption">
    ''' If set to <see langword="True"/>, removes the caption from the source window.
    ''' </param>
    ''' 
    ''' <param name="resizable">
    ''' If set to <see langword="False"/>, remove sthe size frame from the source window.
    ''' </param>
    ''' <exception cref="InvalidOperationException">
    ''' Source window already has a parent window.
    ''' </exception>
    <DebuggerStepThrough>
    Public Overridable Sub SetParent(parentWindow As IWin32Window, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Dim curentWindowInfo As WindowInfo = Me.GetWindowInfo()
        If Me.lastBounds = Rectangle.Empty Then
            Me.lastBounds = curentWindowInfo.Bounds
        End If
        If Me.lastWindowStyle = WindowStyles.None Then
            Me.lastWindowStyle = curentWindowInfo.WindowStyle
        End If

        Dim newStyle As WindowStyles = (Me.lastWindowStyle And Not WindowStyles.SysMenu)
        If removeBorder Then
            newStyle = (newStyle And Not WindowStyles.Border)
        End If
        If removeCaption Then
            newStyle = (newStyle And Not WindowStyles.Caption)
        End If
        If Not resizable Then
            newStyle = (newStyle And Not WindowStyles.SizeFrame)
        End If

        Dim parentWindowHandle As New SafeWindowHandle(parentWindow.Handle)

        NativeMethods.SetParent(Me.WindowHandle, parentWindowHandle)
        Me.SetSourceWindowStyle(newStyle)

        Dim parentClientRect As Rectangle
        If fitToParentBounds Then
            NativeMethods.GetClientRect(parentWindowHandle, parentClientRect)
        End If
        NativeMethods.SetWindowPos(Me.WindowHandle, IntPtr.Zero, 0, 0,
                                   If(fitToParentBounds, parentClientRect.Width, 0),
                                   If(fitToParentBounds, parentClientRect.Height, 0),
                                   SetWindowPosFlags.AsyncWindowPos Or
                                   SetWindowPosFlags.ShowWindow Or
                                   If(fitToParentBounds, SetWindowPosFlags.None, SetWindowPosFlags.IgnoreResize))

    End Sub

    Public Overridable Sub SetParent(parentWindow As NativeWindow, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Me.SetParent(DirectCast(parentWindow, IWin32Window), fitToParentBounds, removeBorder, removeCaption, resizable)

    End Sub

    Public Overridable Sub SetParent(parentWindow As Control, fitToParentBounds As Boolean,
                                     removeBorder As Boolean, removeCaption As Boolean,
                                     resizable As Boolean)

        Me.SetParent(DirectCast(parentWindow, IWin32Window), fitToParentBounds, removeBorder, removeCaption, resizable)

    End Sub

    ''' <summary>
    ''' Release the source window from its current parent window.
    ''' </summary>
    ''' <param name="throwOnInvalidSourceWindowHandle">
    ''' If set to <see langword="True"/>, throws an <see cref="NullReferenceException"/> 
    ''' if the source window handle specified in <see cref="WindowParenting.WindowHandle"/> is invalid.
    ''' <para></para>
    ''' This can be useful if you need to detect whether the source window has been destroyed.
    ''' </param>
    <DebuggerStepThrough>
    Public Overridable Sub ReleaseParent(Optional throwOnInvalidSourceWindowHandle As Boolean = False)

        Dim isInvalid As Boolean = Me.WindowHandle.IsInvalid OrElse
                                   Me.WindowHandle.IsClosed OrElse
                                   Not NativeMethods.IsWindow(Me.WindowHandle)

        If isInvalid AndAlso throwOnInvalidSourceWindowHandle Then
            Throw New NullReferenceException("Invalid source window handle.")

        ElseIf Not isInvalid Then
            If Not Me.HasParent Then
                Throw New InvalidOperationException("Source window has not a parent window.")
            End If

            NativeMethods.SetParent(Me.WindowHandle, IntPtr.Zero)

            If Me.lastWindowStyle <> WindowStyles.None Then
                Me.SetSourceWindowStyle(Me.lastWindowStyle)
                Me.lastWindowStyle = WindowStyles.None
            End If

            If Me.lastBounds <> Rectangle.Empty Then
                NativeMethods.SetWindowPos(Me.WindowHandle, IntPtr.Zero,
                                       Me.lastBounds.X, Me.lastBounds.Y,
                                       Me.lastBounds.Width, Me.lastBounds.Height,
                                       SetWindowPosFlags.AsyncWindowPos)
                Me.lastBounds = Rectangle.Empty
            End If

        End If

    End Sub

#End Region

#Region " Private Methods "

    ''' <summary>
    ''' Returns a <see cref="DevCase.Core.IPC.WindowInfo"/> object for the source window.
    ''' </summary>
    <DebuggerStepThrough>
    Private Function GetWindowInfo() As WindowInfo
        Return New WindowInfo(Me.WindowHandle)
    End Function

    ''' <summary>
    ''' Sets the <see cref="WindowStyles"/> for the source window.
    ''' </summary>
    <DebuggerStepThrough>
    Private Sub SetSourceWindowStyle(style As WindowStyles)

        If Environment.Is64BitProcess Then
            NativeMethods.SetWindowLongPtr(Me.WindowHandle, WindowLongValues.WindowStyle, style)
        Else
            NativeMethods.SetWindowLong(Me.WindowHandle, WindowLongValues.WindowStyle, style)
        End If

    End Sub

#End Region

#Region " IDisposable Implementation "

    ''' <summary>
    ''' Flag to detect redundant calls.
    ''' </summary>
    Private disposedValue As Boolean

    ''' <summary>
    ''' Releases all the resources used by this instance.
    ''' </summary>
    ''' <param name="disposing">
    ''' <see langword="True"/> to release both managed and unmanaged resources; 
    ''' <see langword="False"/> to release only unmanaged resources.
    ''' </param>
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue AndAlso disposing Then
            Try
                Me.ReleaseParent()
            Catch ex As Exception
            End Try
            Me.WindowHandle?.Close()
        End If
        Me.disposedValue = True
    End Sub

    ''' <summary>
    ''' Releases all the resources used by this instance.
    ''' </summary>
    Public Sub Dispose() Implements IDisposable.Dispose
        Me.Dispose(True)
    End Sub

#End Region

End Class

It lacks a bit of win32 error-handling for P/invokes. And maybe other things could be improved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文