0

I use the code below to start a cmd.exe windows and move it into a panel after execution. At this moment, the child window is resized to fit into Panel1 on my Form1. I would like it to be the other way around: my Form1 (and thus Panel1) should resize to fit the size of the child window, so no matter what the size of the default cmd.exe window is on the local computer. Does anybody know how I should do that? Thanks for any help in advance!

Kind regards, Eric

Imports System.Runtime.InteropServices
Public Class Form1
    Private WithEvents Tmr As New Timer With {.Interval = 100}
    Private Const HWND_BOTTOM As Integer = &H1
    Private WithEvents proc As New Process
    <DllImport("user32.dll", EntryPoint:="SetParent")>
    Private Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    End Function
    <DllImport("user32.dll", EntryPoint:="SetWindowPos")>
    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 UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Text = "My title"
        proc.EnableRaisingEvents = True
        proc.StartInfo.FileName = "cmd"
        proc.Start()
        Tmr.Start()
    End Sub
    Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
        If SetParent(proc.MainWindowHandle, Panel1.Handle) <> IntPtr.Zero Then
            Tmr.Stop()
            SetWindowPos(proc.MainWindowHandle, New IntPtr(HWND_BOTTOM), 0, 0, Panel1.ClientSize.Width, Panel1.ClientSize.Height, 0)
        End If
    End Sub
    Private Sub Proc_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles proc.Exited
        Invoke(Sub() Close())
    End Sub
End Class
Eric van Loon
  • 103
  • 1
  • 9
  • Presumably GetWindowPos will give you the size of the other window, so you can then set the ClientSize of your form based that. – John Aug 09 '22 at 15:30
  • 1
    Call `GetWindowRect()` or `GetWindowInfo()` to get the size of the Window, the size the Panel accordingly. Make the Form AutoSize to its content. A piece of code used to parent a Window to a Panel and then restore it to its previous state when needed: [Unhook Window into its original State](https://stackoverflow.com/a/65847818/7444103) -- Note that those functions are not DpiAware, you may get *virtualized* values. If that's the case, use `DwmGetWindowAttribute()` instead. Sample usage here: [Move window when external application's window moves](https://stackoverflow.com/a/48812831/7444103) – Jimi Aug 10 '22 at 08:24
  • Thanks Jimi! I'm will to change my code to DwmGetWindowAttribute, but it's a bit harder then expected... – Eric van Loon Aug 16 '22 at 12:55

1 Answers1

0

As suggested by @Jimi, I used DwmGetWindowAttribute to retrieve the size of the child, before moving it into the panel. Afterwards I use ShowWindow to maximize it, to get rid of the borders. The changed code can be found in a different post of mine.

Eric van Loon
  • 103
  • 1
  • 9