Writing a WinForm project in VB.NET on VS 2017, and I am opening an instance of FreeRDP in SplitContainer2.Panel1
. This works just fine, but I would like to scale the form to initially fit the FreeRDP window. In order to do this, I first need to know the size of the FreeRDP instance.
Unfortunately, every attempt I have made returns nothing. I am trying to use GetClientRect()
from the Windows API, but all I ever get back is 0's (or nothing, I suppose). This is the first time I have played with API calls, so I am not sure what I am doing wrong. I have verified I have the correct handle with a break in VS
(I apologize if these scale poorly. Hard to judge on scaled 4k)
compared to Spy++
So, I have confirmed I have the correct hWnd handle, but when I call a GetClientRect()
, I get nothing back.
Here is the relevant code:
Dim rdpWnd As New IntPtr
Dim proc As New Process
Private Declare Auto Function GetClientRect Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByVal lpRect As RECT) As Boolean
<StructLayout(LayoutKind.Sequential)>
Private Structure RECT
Private Left As Short
Private Top As Short
Private Right As Short
Private Bottom As Short
End Structure
Private Sub Form_Load( _
sender As Object, e As EventArgs) Handles MyBase.Load
Dim startInfo As New ProcessStartInfo With {
.FileName = """" & appPath & "\console\wfreerdp.exe""",
.Arguments = "/parent-window:" & SplitContainer2.Panel1.Handle.ToString() & " /t:" & vmId
}
proc = Process.Start(startInfo)
rdpWnd = getWindowHandle(Me.Text, vmId)
End Sub
Private Function getWindowHandle(caption As String, Guid As String) As IntPtr
Dim hWnd As IntPtr = FindWindow(Nothing, caption)
If hWnd.Equals(IntPtr.Zero) Then
Return Nothing
End If
.......
Dim hWndRdp As IntPtr = FindWindowEx(hWndChild4, IntPtr.Zero, Nothing, Guid)
If hWndRdp.Equals(IntPtr.Zero) Then
Return Nothing
End If
Return hWndRdp
End Function
At this point, I am looking at a console window of a Hyper-V VM in my form, but when I click the proverbial Button1...
Private Sub Button1_MouseClick( _
sender As Object, e As MouseEventArgs) Handles Button1.MouseClick
Dim myRect As New RECT
GetClientRect(rdpWnd, myRect)
Dim rdpWndWidth As Short = myRect.Right - myRect.Left
Dim rdpWndHeight As Short = myRect.Bottom - myRect.Top
MsgBox("Width: " & rdpWndWidth & vbCrLf &
"Height: " & rdpWndHeight)
End Sub
The MsgBox()
returns:
and the variables in VS:
What am I doing wrong? Why can I not get the client size when I can clearly see Spy++ can? I have spent many hours trying to figure this out, and I would appreciate the assistance in getting this milestone checked-off. About to move onto something else and come back later if I can't get it soon.
You are passing the RECT
struct by value to GetClientRect
. This creates a copy of the struct. As a result, the original RECT
value is never modified by the method call, and so all its fields will have default values (i.e. zero).
Change your method signature to
Private Declare Auto Function GetClientRect Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
(note the ByRef
keyword).