Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Send strings to another application by using Windows messages

0.00/5 (No votes)
30 Jul 2007 1  
A way to send strings to another application by using Windows messages instead of Remoting.

Introduction

Sometimes, we need to communicate with other applications, such as send and receive strings. In VB6, we can easily use the SendMessage function to send a wm_datacopy message, because we can define lparam as Any. But in VB.NET, when we declare the Win32 API function SendMessage, it does not accept "Any" as data type, which means we can only send 32 bit integer parameters by using the SendMessage function in .NET.

Microsoft introduced a way to connect different applications by using Remoting; it's suitable for mass communication, but if we just want to send some simple messages, it will use more resources to develop and run it on the computer.

In this article, I will introduce a simple way to send strings to another application running in the same computer, by using the SendMessage function; the concept is:

Concept

For security reasons, there's no way to directly access another process' memory in VB.NET, so if we want to send a string to another application, what we can do is encode the string to a byte array, and send each member in the byte array sequentially; at the end of the sending session, we need to send a terminator byte.

At the receiving end, we put every received byte into a byte array until the terminator byte is received. Then, we raise en event to indicate that a new string was received successful.

Using the code

Here is the component to send and build the string:

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

To use the component:

The sending end

    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

The receiving end

    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

Points of interest

If you are searching for a simple way to communicate with other applications, this article is for you.

History

  • 02 Aug 2007, fourth version with a new concept; rewrote the whole program.
  • (The versions below can not be used for inter-process communication.)

  • 01 Aug 2007, third version with the free memory method and more comments.
  • 31 July 2007, second version with a better method to copy strings and also a structure.
  • 25 July 2007, the first release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here