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