VB Quicktakes - Pass Data Using Subclassing

This code uses subclassing to capture window messages and allows two visual basic programs to communicate with one another.


***************Send Program*********************************************

----form--------
contains

cmdQuit - command button
cmdSend - command button
txtString - txtbox
------------------

Option Explicit

Private Const WM_COPYDATA = &H4A

Private Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type

Private Declare Function FindWindow Lib "user32" Alias _
   "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName _
   As String) As Long

Private 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 cmdQuit_Click()
Unload Me
End Sub


Private Sub cmdSend_Click()
Dim sString As String
Dim lHwnd   As Long
Dim cds     As COPYDATASTRUCT
Dim buf(1 To 255) As Byte

sString = Trim$(txtString)
If sString = "" Then Exit Sub
'
' Get the handle of the target application.
'
lHwnd = FindWindow(vbNullString, "Receive")
'
' Copy the string into a byte array,
' converting it to ASCII. Assign lpData
' the address of the byte array.
'
Call CopyMemory(buf(1), ByVal sString, Len(sString))
With cds
    .dwData = 3
    .cbData = Len(sString) + 1
    .lpData = VarPtr(buf(1))
End With
'
' Send the string.
'
Call SendMessage(lHwnd, WM_COPYDATA, Me.hwnd, cds)
End Sub

**************Receive program******************************************

Name of Receive program = "Receive"

----module----------------------

Option Explicit

Public lpPrevWndProc As Long
Public lHwnd         As Long

Public Const GWL_WNDPROC = (-4)
Public Const WM_COPYDATA = &H4A

Public Type COPYDATASTRUCT
    dwData As Long
    cbData As Long
    lpData As Long
End Type
'
'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 Long

Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
   (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As _
   Long) As Long
Public Sub pHook()
'
' Sub class the form to trap for Windows messages.
'
lpPrevWndProc = SetWindowLong(lHwnd, GWL_WNDPROC, AddressOf fWindowProc)
Debug.Print lpPrevWndProc
End Sub

Sub pReceiveMsg(lParam As Long)
Dim sString As String
Dim cds     As COPYDATASTRUCT
Dim buf(1 To 255) As Byte
'
' Copy the data sent to this application
' into a local structure.
'
Call CopyMemory(cds, ByVal lParam, Len(cds))
'
' Copy the string that was passed into a byte array.
'
Call CopyMemory(buf(1), ByVal cds.lpData, cds.cbData)
'
' Convert the ASCII byte array back to a Unicode string.
'
sString = StrConv(buf, vbUnicode)
sString = Left$(sString, InStr(1, sString, Chr$(0)) - 1)
'
' Display the received string.
'
frmReceive.lblString = sString
End Sub
Public Sub pUnhook()
'
' Remove the subclassing.
'
Call SetWindowLong(lHwnd, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function fWindowProc(ByVal hw As Long, ByVal uMsg As Long, _
         ByVal wParam As Long, ByVal lParam As Long) As Long
'
' This callback routine is called by Windows whenever
' a message is sent to this form.  If it is the copy
' message call our procedure to receive the message.
'
If uMsg = WM_COPYDATA Then Call pReceiveMsg(lParam)
'
' Call the original window procedure associated with this form.
'
fWindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam)
End Function


-----form-------
name:
frmReceive

contains
cmdQuit - command button
lblString
------------------

Option Explicit

Private Sub cmdQuit_Click()
Unload Me
End Sub

Private Sub Form_Load()
'
' Get this form's handle.
' Subclass this form to trap Windows messages.
'
lHwnd = Me.hwnd
Call pHook
End Sub

Private Sub Form_Unload(Cancel As Integer)
'
' Un-subclass the form.
'
Call pUnhook
End Sub

About this page: