Visual Basic 8 (2005).NET 1.0.NET 1.1Visual Studio 2005.NET 2.0中级开发Visual StudioWindows.NETVisual Basic
通过 Windows 消息将字符串发送到另一个应用程序
一种使用 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 日,首次发布。
(以下版本不能用于进程间通信。)