65.9K
CodeProject 正在变化。 阅读更多。
Home

通过 Windows 消息将字符串发送到另一个应用程序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.68/5 (13投票s)

2007 年 7 月 24 日

CPOL

2分钟阅读

viewsIcon

190121

downloadIcon

4801

一种使用 Windows 消息而不是 Remoting 向另一个应用程序发送字符串的方法。

引言

有时,我们需要与其他应用程序进行通信,例如发送和接收字符串。在 VB6 中,我们可以轻松使用 SendMessage 函数发送 wm_datacopy 消息,因为我们可以将 lparam 定义为 Any。但在 VB.NET 中,当我们声明 Win32 API 函数 SendMessage 时,它不接受 "Any" 作为数据类型,这意味着我们只能使用 .NET 中的 SendMessage 函数发送 32 位整数参数。

微软引入了一种使用 Remoting 连接不同应用程序的方法;它适用于大规模通信,但如果我们只想发送一些简单的消息,它会使用更多的资源来开发和在计算机上运行。

在本文中,我将介绍一种使用 SendMessage 函数向在同一计算机上运行的另一个应用程序发送字符串的简单方法;其概念是

概念

出于安全原因,在 VB.NET 中无法直接访问另一个进程的内存,因此如果我们要向另一个应用程序发送字符串,我们可以执行的操作是将字符串编码为字节数组,并按顺序发送字节数组中的每个成员;在发送会话结束时,我们需要发送一个终止字节。

在接收端,我们将每个接收到的字节放入一个字节数组中,直到接收到终止字节。然后,我们引发一个事件,以指示已成功接收到新的字符串。

使用代码

这是用于发送和构建字符串的组件

Imports System.Text

Public Class BuildString

    Private Declare Function PostMessage Lib "user32.dll" _
Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As _
Integer, ByVal wParam As Integer, ByVal lParam As Integer) _
As Integer
    Public Event StringOK(ByVal Result As String)
    Private hwnd As Integer = 0
    Private wMsg As Integer = 0
    Private wParam As Integer = 0
    Private lParam As String = ""
    Private tempA(-1) As Byte
    Private enc As Encoding = Encoding.UTF8

    Public Property Encode() As Encoding
        Get
            Return enc
        End Get
        Set(ByVal value As Encoding)
            enc = value
        End Set
    End Property

    Public Sub BuildString(ByVal b As IntPtr)
        If b <> 0 Then
            'build temp array
            Dim tempB(tempA.Length) As Byte
            tempA.CopyTo(tempB, 0)
            tempB(tempA.Length) = b
            ReDim tempA(tempB.Length - 1)
            tempB.CopyTo(tempA, 0)
        Else
            'decode byte array to string
            Dim s As String
            If enc Is Encoding.UTF8 Then
                s = Encoding.UTF8.GetString(tempA)
            ElseIf enc Is Encoding.Unicode Then
                s = Encoding.Unicode.GetString(tempA)
            ElseIf enc Is Encoding.ASCII Then
                s = Encoding.ASCII.GetString(tempA)
            Else
                s = Encoding.Default.GetString(tempA)
            End If
            'send out result string via event
            RaiseEvent StringOK(s)
            ReDim tempA(-1)
        End If
    End Sub

    Public Sub PostString(ByVal hwnd As Integer, ByVal wMsg _
As Integer, ByVal wParam As Integer, ByVal lParam As String)
        Me.hwnd = hwnd
        Me.wMsg = wMsg
        Me.wParam = wParam
        Me.lParam = lParam
        'create a new thread to post window message
        Dim t As Threading.Thread
        t = New Threading.Thread(AddressOf SendString)
        t.Start()
    End Sub

    Private Sub SendString()
        'create byte array
        Dim ba() As Byte
        'encode string to byte array
        If enc Is Encoding.UTF8 Then
            ba = Encoding.UTF8.GetBytes(lParam)
        ElseIf enc Is Encoding.Unicode Then
            ba = Encoding.Unicode.GetBytes(lParam)
        ElseIf enc Is Encoding.ASCII Then
            ba = Encoding.ASCII.GetBytes(lParam)
        Else
            ba = Encoding.Default.GetBytes(lParam)
        End If
        Dim i As Integer
        For i = 0 To ba.Length - 1
            'start post message
            PostMessage(hwnd, wMsg, wParam, ba(i))
        Next
        'post a terminator message to destination window
        PostMessage(hwnd, wMsg, wParam, 0)
    End Sub
End Class

要使用该组件

发送端

    Private WithEvents BS As New BuildString

    Private Sub Button1_Click(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles Button1.Click
        ' "Receive" parameter is the caption of destination window
        Dim hwnd As Integer = FindWindow(vbNullString, "Receive")
        If hwnd <> 0 And TextBox1.Text <> "" Then
            BS.PostString(hwnd, &H400, 0, TextBox1.Text)
        End If
    End Sub

接收端

    Private WithEvents BS As New BuildString

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Select Case m.Msg
            Case &H400
                BS.BuildString(m.LParam)
            Case Else
                MyBase.WndProc(m)
        End Select
    End Sub

    Private Sub SB_StringOK(ByVal Result As String) Handles BS.StringOK
        TextBox1.AppendText(Result & vbNewLine)
    End Sub

关注点

如果您正在寻找一种与其它应用程序通信的简单方法,那么本文就是为您准备的。

历史

  • 2007 年 8 月 2 日,第四版,采用新概念;重写了整个程序。
  • (以下版本不能用于进程间通信。)

  • 2007 年 8 月 1 日,第三版,采用免费内存方法并添加了更多注释。
  • 2007 年 7 月 31 日,第二版,采用更好的字符串复制方法,并添加了一个结构。
  • 2007 年 7 月 25 日,首次发布。
© . All rights reserved.