VB .Net - 将字符串发送到另一个应用程序

Posted

技术标签:

【中文标题】VB .Net - 将字符串发送到另一个应用程序【英文标题】:VB .Net - Send String to Another Application 【发布时间】:2021-02-08 20:32:53 【问题描述】:

从 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)”行返回了我使用 Window Detective 找到的句柄编号,因此我假设到目前为止代码是正确的。另外,我测试了“SetForegroundWindow(TextBoxHwnd1)”,光标位于第一个文本框上,而“SetForegroundWindow(TextBoxHwnd1) 将光标设置在第二个文本框上。

【问题讨论】:

您对SendMessage 的声明看起来很可疑,尤其是我倾向于认为wMsgwParam 可能应该是Integer 而不是Long。这是否源自旧版 VB 代码 (VBA/VB6)? IntegerLong 数据类型的长度从旧版 VB 更改为 VB.NET。 我刚刚检查过,Msg 参数在 Windows API 中是 UINT,在 VB 中最终会是 IntegerwParam 参数是 UINT_PTR,所以实际上对于 64 位构建它应该是 Long,但对于 32 位构建它应该是 Integer;如果可以将其声明为 IntPtr 然后将 0 传递给它,那可能是最好的。 很棒的克雷格,解决了我的问题。太感谢了!!!!如何接受评论作为解决方案? 我会把它写下来作为答案。 【参考方案1】:

您的声明看起来可能是从旧版 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 - 将字符串发送到另一个应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何将图像从一个图片框传输到另一个图片框? VB.NET 和 SQL

SQL Server查询参数用于将数据表复制到另一个表单ListView VB.net

vb.net Datagrid到另一个datagrid的值

如何通过网络在两个 VB.NET 应用程序之间进行通信

将广播从一个进程发送到另一个进程

vb.net 网页提交表单