How To Pass String Data Between Applications Using SendMessage
Symptoms
There are many ways to achieve inter-process communication using VisualBasic. Unless you establish an OLE Automation client server relationship,string data is difficult to handle cleanly. The main reason is that 32-bitapplications run in a separate address space, so the address of a string inone application is not meaningful to another application in a differentaddress space. Using the SendMessage() API function to pass a WM_COPYDATAmessage avoids this problem.
This article demonstrates how to pass string data from one application toanother by using the SendMessage API function with the WM_COPYDATA message.
Resolution
WARNING: One or more of the following functions are discussed in this article; VarPtr, VarPtrArray, VarPtrStringArray, StrPtr, ObjPtr. These functions are not supported by Microsoft Technical Support. They are not documented in the Visual Basic documentation and are provided in this Knowledge Base article “as is.” Microsoft does not guarantee that they will be available in future releases of Visual Basic.
Visual Basic does not support pointers and castings in the manner of VisualC++. In order to pass string data from one Visual Basic application toanother, the Unicode string must be converted to ASCII prior to passing itto the other application. The other application must then convert the ASCIIstring back to Unicode.
The following summarizes how to pass string data from one application toanother.
Step-by-Step Example Convert the string to a byte array using the CopyMemory() API.Obtain the address of the byte array using the VarPtr() intrinsicfunction and copy the address and length of the byte array into a COPYDATASTRUCT structure.Pass the COPYDATASTRUCT to another application using the WM_COPYDATAmessage, setting up the other application to receive the message.Unpack the structure on the target system using CopyMemory(), andconvert the byte array back to a string using the StrConv() intrinsicfunction.The next section shows you how to create a sample program that demonstratespassing string data from one application to another.
Steps to Create the SampleTo create this sample, you create two separate projects; a sendingproject and a target project.
Create the target application:Start a new Standard EXE project in Visual Basic. Form1 is created by default. This project will be your target application.Add a Label control to Form1.Copy the following code to the Code window of Form1:
Private Sub Form_Load()gHW = Me.hWndHookMe.Caption = “Target”Me.ShowLabel1.Caption = Hex$(gHW)End SubPrivate Sub Form_Unload(Cancel As Integer)UnhookEnd Sub Add a module to the project and paste the following code in the Module1 code window:
Type COPYDATASTRUCTdwData As LongcbData As LonglpData As LongEnd TypePublic Const GWL_WNDPROC = (-4)Public Const WM_COPYDATA = &H4AGlobal lpPrevWndProc As LongGlobal gHW As Long’Copies a block of memory from one location to another.Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory” _(hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)Declare Function CallWindowProc Lib “user32″ Alias _”CallWindowProcA” (ByVal lpPrevWndFunc As Long, ByVal hwnd As _Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As _Long) As LongDeclare Function SetWindowLong Lib “user32″ Alias “SetWindowLongA” _(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _Long) As LongPublic Sub Hook()lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, _AddressOf WindowProc)Debug.Print lpPrevWndProcEnd SubPublic Sub Unhook()Dim temp As Longtemp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)End SubFunction WindowProc(ByVal hw As Long, ByVal uMsg As Long, _ByVal wParam As Long, ByVal lParam As Long) As LongIf uMsg = WM_COPYDATA ThenCall mySub(lParam)End IfWindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, _lParam)End FunctionSub mySub(lParam As Long)Dim cds As COPYDATASTRUCTDim buf(1 To 255) As ByteCall CopyMemory(cds, ByVal lParam, Len(cds))Select Case cds.dwDataCase 1Debug.Print “got a 1″Case 2Debug.Print “got a 2″Case 3Call CopyMemory(buf(1), ByVal cds.lpData, cds.cbData)a$ = StrConv(buf, vbUnicode)a$ = Left$(a$, InStr(1, a$, Chr$(0)) – 1)Form1.Print a$End SelectEnd Sub Save the project and minimize the Visual Basic IDE.
Create the Sending ApplicationStart a second instance of the Visual Basic IDE and create a new Standard EXE project in Visual Basic. Form1 is created by default.Add a CommandButton to Form1.Copy the following code to the Code window of Form1:
Private Type COPYDATASTRUCTdwData As LongcbData As LonglpData As LongEnd TypePrivate Const WM_COPYDATA = &H4APrivate Declare Function FindWindow Lib “user32″ Alias _”FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName _As String) As LongPrivate Declare Function SendMessage Lib “user32″ Alias _”SendMessageA” (ByVal hwnd As Long, ByVal wMsg As Long, ByVal _wParam As Long, lParam As Any) As Long’Copies a block of memory from one location to another.Private Declare Sub CopyMemory Lib “kernel32″ Alias “RtlMoveMemory” _(hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)Private Sub Command1_Click()Dim cds As COPYDATASTRUCTDim ThWnd As LongDim buf(1 To 255) As Byte’ Get the hWnd of the target applicationThWnd = FindWindow(vbNullString, “Target”)a$ = “It Works!”‘ Copy the string into a byte array, converting it to ASCIICall CopyMemory(buf(1), ByVal a$, Len(a$))cds.dwData = 3cds.cbData = Len(a$) + 1cds.lpData = VarPtr(buf(1))i = SendMessage(ThWnd, WM_COPYDATA, Me.hwnd, cds)End SubPrivate Sub Form_Load()’ This gives you visibility that the target app is running’ and you are pointing to the correct hWndMe.Caption = Hex$(FindWindow(vbNullString, “Target”))End Sub Save the project.
Running the SampleRestore the target application and press the F5 key to run the project. Note that the value of the hWnd displayed in the label.Restore the sending application and press the F5 key to run the project.Verify that the hWnd in the form caption matches the hWnd in the labelon the target application. Click the CommandButton and the text messageshould be displayed on the form of the target application.
