VB.NET GetClientRect() ничего не возвращает для дочернего процесса в WinForm
Написание проекта WinForm в VB.NET на VS 2017, и я открываю экземпляр FreeRDP в SplitContainer2.Panel1
, Это прекрасно работает, но я бы хотел масштабировать форму, чтобы она изначально соответствовала окну FreeRDP. Для этого мне сначала нужно узнать размер экземпляра FreeRDP.
К сожалению, все мои попытки ничего не дают. Я пытаюсь использовать GetClientRect()
из Windows API, но все, что я когда-либо получаю, это 0 (или ничего, я полагаю). Я впервые играю с вызовами API, поэтому не уверен, что делаю неправильно. Я подтвердил, что у меня правильная ручка с перерывом в VS
(Прошу прощения, если эти масштабы плохо. Трудно судить по 4k)
по сравнению со Spy++
Итак, я подтвердил, что у меня есть правильный дескриптор hWnd, но когда я вызываю GetClientRect()
Я ничего не получаю обратно.
Вот соответствующий код:
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
На данный момент, я смотрю на консольное окно Hyper-V VM в моей форме, но когда я нажимаю на общеизвестную 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
MsgBox()
возвращает:
и переменные в VS:
Что я делаю неправильно? Почему я не могу получить размер клиента, когда я ясно вижу, что Spy++ может? Я потратил много часов, пытаясь понять это, и я был бы признателен за помощь в проверке этой вехи. Собираюсь перейти на что-то еще и вернуться позже, если я не смогу получить это в ближайшее время.
1 ответ
Вы передаете RECT
структурировать по значению GetClientRect
, Это создает копию структуры. В результате оригинал RECT
значение никогда не изменяется при вызове метода, поэтому все его поля будут иметь значения по умолчанию (т. е. ноль).
Измените подпись вашего метода на
Private Declare Auto Function GetClientRect Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
(Обратите внимание ByRef
ключевое слово).