VB.NET GetClientRect() returns WinForm 中的子进程没有任何内容
VB.NET GetClientRect() returns nothing for child process in WinForm
在 VS 2017 VB.NET 中编写一个 WinForm 项目,我正在 SplitContainer2.Panel1
中打开一个 FreeRDP 的实例。这工作得很好,但我想缩放表格以最初适合 FreeRDP window。为此,我首先需要知道 FreeRDP 实例的大小。
不幸的是,我的每一次尝试都returns一无所获。我正在尝试使用 Windows API 中的 GetClientRect()
,但我得到的只是 0(我想什么也没有)。这是我第一次玩 API 电话,所以我不确定我做错了什么。我已经验证我有正确的句柄,在 VS
中有中断
(如果这些缩放比例不佳,我深表歉意。很难在缩放的 4k 上判断)
与间谍++相比
所以,我已经确认我有正确的 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 的控制台 window,但是当我单击众所周知的 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()
returns:
VS中的变量:
我做错了什么?为什么我可以清楚地看到 Spy++ 可以获取客户端大小?我花了很多时间试图弄清楚这一点,我将不胜感激在检查这个里程碑方面的帮助。即将转移到其他事情上,如果我不能很快得到它,稍后再回来。
您正在将 RECT
结构按值 传递给 GetClientRect
。这将创建该结构的副本。结果,方法调用永远不会修改原始 RECT
值,因此它的所有字段都将具有默认值(即零)。
将您的方法签名更改为
Private Declare Auto Function GetClientRect Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
(注意 ByRef
关键字)。
在 VS 2017 VB.NET 中编写一个 WinForm 项目,我正在 SplitContainer2.Panel1
中打开一个 FreeRDP 的实例。这工作得很好,但我想缩放表格以最初适合 FreeRDP window。为此,我首先需要知道 FreeRDP 实例的大小。
不幸的是,我的每一次尝试都returns一无所获。我正在尝试使用 Windows API 中的 GetClientRect()
,但我得到的只是 0(我想什么也没有)。这是我第一次玩 API 电话,所以我不确定我做错了什么。我已经验证我有正确的句柄,在 VS
(如果这些缩放比例不佳,我深表歉意。很难在缩放的 4k 上判断)
与间谍++相比
所以,我已经确认我有正确的 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 的控制台 window,但是当我单击众所周知的 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()
returns:
VS中的变量:
我做错了什么?为什么我可以清楚地看到 Spy++ 可以获取客户端大小?我花了很多时间试图弄清楚这一点,我将不胜感激在检查这个里程碑方面的帮助。即将转移到其他事情上,如果我不能很快得到它,稍后再回来。
您正在将 RECT
结构按值 传递给 GetClientRect
。这将创建该结构的副本。结果,方法调用永远不会修改原始 RECT
值,因此它的所有字段都将具有默认值(即零)。
将您的方法签名更改为
Private Declare Auto Function GetClientRect Lib "user32.dll" ( _
ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
(注意 ByRef
关键字)。