VB .Net - 将字符串发送到另一个应用程序
VB .Net - Send String to Another Application
来自 VB .Net,我试图将字符串发送到另一个应用程序的文本框,但我无法使其工作。我能够获取句柄,甚至将焦点设置到文本框,但我的 SendMessage 函数似乎不正确,因为我收到错误消息“SendMessage”使堆栈不平衡。这可能是因为托管 PInvoke 签名确实如此与非托管目标签名不匹配。请检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。"
这是我的代码:
Module Module1
Private Const WM_SETTEXT As Int32 = &HC
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function FindWindowEx Lib "user32" (ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As IntPtr
Sub Main()
Dim AppHwnd As IntPtr = FindWindow(vbNullString, "Test Application"
Dim WinHwnd1 As IntPtr = FindWindowEx(AppHwnd, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd2 As IntPtr = FindWindowEx(WinHwnd1, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd3 As IntPtr = FindWindowEx(WinHwnd2, 0&, "SWT_Window0", vbNullString)
Dim TextBoxHwnd1 As IntPtr = FindWindowEx(WinHwnd3, 0&, "Edit", vbNullString)
Dim TextBoxHwnd2 As IntPtr = FindWindowEx(WinHwnd3, TextBoxHwnd1, "Edit", vbNullString)
MsgBox(TextBoxHwnd2)
SetForegroundWindow(TextBoxHwnd2)
SendMessage(TextBoxHwnd2, WM_SETTEXT, 0&, "text")
End Sub
End Module
行“MsgBox(TextBoxHwnd2)”returns 是我使用 Window Detective 找到的句柄号,所以我假设到目前为止代码是正确的。另外,我测试了“SetForegroundWindow(TextBoxHwnd1)”,光标位于第一个文本框上,而“SetForegroundWindow(TextBoxHwnd1) 将光标设置在第二个文本框上。
您的声明看起来可能是从遗留 VB 代码迁移过来的,其中 Long
是一个 32 位整数,而 Integer
只是 16 位(追溯到遗留) VB 起源于 16 位 Windows)。在转向通用 32 位 Windows 后创建的 .NET 中数据类型的长度发生了变化,因此 Integer
是 32 位,Long
是 64 位。
此外,Windows API 本身需要针对 64 位 Windows 进行更新。 SendMessage
是具有一些在 64 位中更长的参数的函数之一,因为它们应该保存指针。
我检查了 SendMessage
的本机头文件声明,发现:
- 参数
Msg
声明为UINT
,对应VB中的Integer
。无论您使用的是 32 位还是 64 位版本,都需要对此进行更改。
- 参数
wParam
被声明为 UINT_PTR
因此对于 64 位版本它实际上应该是 Long
,但是对于 32 位版本它应该是 Integer
;如果可以将其声明为 IntPtr
然后将 0 传递给它,那可能是最好的,因为它应该根据您是为 32 位还是 64 位构建而自动调整长度。
来自 VB .Net,我试图将字符串发送到另一个应用程序的文本框,但我无法使其工作。我能够获取句柄,甚至将焦点设置到文本框,但我的 SendMessage 函数似乎不正确,因为我收到错误消息“SendMessage”使堆栈不平衡。这可能是因为托管 PInvoke 签名确实如此与非托管目标签名不匹配。请检查 PInvoke 签名的调用约定和参数是否与目标非托管签名匹配。"
这是我的代码:
Module Module1
Private Const WM_SETTEXT As Int32 = &HC
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As IntPtr) As Long
Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function FindWindowEx Lib "user32" (ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As IntPtr
Sub Main()
Dim AppHwnd As IntPtr = FindWindow(vbNullString, "Test Application"
Dim WinHwnd1 As IntPtr = FindWindowEx(AppHwnd, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd2 As IntPtr = FindWindowEx(WinHwnd1, 0&, "SWT_Window0", vbNullString)
Dim WinHwnd3 As IntPtr = FindWindowEx(WinHwnd2, 0&, "SWT_Window0", vbNullString)
Dim TextBoxHwnd1 As IntPtr = FindWindowEx(WinHwnd3, 0&, "Edit", vbNullString)
Dim TextBoxHwnd2 As IntPtr = FindWindowEx(WinHwnd3, TextBoxHwnd1, "Edit", vbNullString)
MsgBox(TextBoxHwnd2)
SetForegroundWindow(TextBoxHwnd2)
SendMessage(TextBoxHwnd2, WM_SETTEXT, 0&, "text")
End Sub
End Module
行“MsgBox(TextBoxHwnd2)”returns 是我使用 Window Detective 找到的句柄号,所以我假设到目前为止代码是正确的。另外,我测试了“SetForegroundWindow(TextBoxHwnd1)”,光标位于第一个文本框上,而“SetForegroundWindow(TextBoxHwnd1) 将光标设置在第二个文本框上。
您的声明看起来可能是从遗留 VB 代码迁移过来的,其中 Long
是一个 32 位整数,而 Integer
只是 16 位(追溯到遗留) VB 起源于 16 位 Windows)。在转向通用 32 位 Windows 后创建的 .NET 中数据类型的长度发生了变化,因此 Integer
是 32 位,Long
是 64 位。
此外,Windows API 本身需要针对 64 位 Windows 进行更新。 SendMessage
是具有一些在 64 位中更长的参数的函数之一,因为它们应该保存指针。
我检查了 SendMessage
的本机头文件声明,发现:
- 参数
Msg
声明为UINT
,对应VB中的Integer
。无论您使用的是 32 位还是 64 位版本,都需要对此进行更改。 - 参数
wParam
被声明为UINT_PTR
因此对于 64 位版本它实际上应该是Long
,但是对于 32 位版本它应该是Integer
;如果可以将其声明为IntPtr
然后将 0 传递给它,那可能是最好的,因为它应该根据您是为 32 位还是 64 位构建而自动调整长度。