The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: jj2007 on January 25, 2010, 10:21:11 AM

Title: Interprocess communication (IPC): Using WM_COPYDATA or WM_GETTEXT
Post by: jj2007 on January 25, 2010, 10:21:11 AM
As an add-on to the WinHelp32 thread (http://www.masm32.com/board/index.php?topic=12690.msg101791#msg101791), here an example on how to use WM_COPYDATA for sending data between processes. I post this because there seems no good example in the forum so far.

I attach a complete working example. Here are the essential snippets:
Server side (assuming the data to send is the text of an edit control):
Quote            push eax               ; handle to the slave window obtained with FindWindowEx
            lea edi, buffer         ; pointer to a local buffer
            invoke SendMessage, hEdit, WM_GETTEXT, LocBufSize, edi
            lea edx, cds            ; a local copydatastruct
            mov [edx.COPYDATASTRUCT.dwData], Magic   ; a user-defined password ;-)
            mov [edx.COPYDATASTRUCT.cbData], eax   ; the length returned by WM_GETTEXT
            mov [edx.COPYDATASTRUCT.lpData], edi   ; pointer to the text
            pop eax
            invoke SendMessage, eax, WM_COPYDATA, Magic, edx
(You may or may not use a "Magic" value for identification.)

Now the client side:
Quote  SWITCH uMsg
  CASE WM_COPYDATA
  mov edx, lParam
  lea edi, buffer   ; a local buffer
  mov esi, [edx.COPYDATASTRUCT.lpData]
  mov ecx, [edx.COPYDATASTRUCT.cbData]
  rep movsb
  mov [edi], cl   ; we add a delimiter (ecx is zero after movsb)
  invoke SendMessage, hEdit, WM_SETTEXT, 0, addr buffer   ; we display the data

The second option, sending a handle to an editbox containing the source text, is also available in the attached source.
Title: Re: Interprocess communication (IPC): Using WM_COPYDATA or WM_GETTEXT
Post by: jj2007 on January 25, 2010, 01:17:39 PM
The example above can be shortened on the client side by inserting an "inc eax" in the server side code:
Quote            push eax               ; handle to the slave window obtained with FindWindowEx
            lea edi, buffer         ; pointer to a local buffer
            invoke SendMessage, hEdit, WM_GETTEXT, LocBufSize, edi
            lea edx, cds            ; a local copydatastruct
            mov [edx.COPYDATASTRUCT.dwData], Magic   ; a user-defined password ;-)
            inc eax               ; if omitted, Windows will forget to copy the zero delimiter
            mov [edx.COPYDATASTRUCT.cbData], eax   ; the length returned by WM_GETTEXT, plus one for delimiter
            mov [edx.COPYDATASTRUCT.lpData], edi   ; pointer to the text
            pop eax
            invoke SendMessage, eax, WM_COPYDATA, hWnd, edx   ; optional: hWnd for feedback
Now the client side handler is just two lines:
Quote;  SWITCH uMsg
;  CASE WM_COPYDATA
   mov edx, lParam
   invoke SendMessage, hEdit, WM_SETTEXT, 0, [edx.COPYDATASTRUCT.lpData]   ; we display the data
Full code attached.
Title: Re: Interprocess communication (IPC): Using WM_COPYDATA or WM_GETTEXT
Post by: jj2007 on June 12, 2010, 12:35:34 PM
Inspired by Joseph M. Newcomer's warning about HWND_BROADCAST (http://www.flounder.com/wm_copydata.htm), here a macro that allows checking for validity:

CopyData$ MACRO magic
mov edx, lParam
ifnb <magic>
cmp [edx.COPYDATASTRUCT.dwData], magic ; sets zero flag: .if not Zero? then error
endif
EXITM <[edx.COPYDATASTRUCT.lpData]>
ENDM


Usage:
SWITCH uMsg
CASE WM_COPYDATA
mov edx, CopyData$(54321)
.if Zero?
MsgBox 0, edx, "Data, hooray:", MB_OK
.else
MsgBox 0, "Data is not valid", "Hi", MB_OK
.endif


Corresponding server code:
push eax ; handle to the client window obtained e.g. with FindWindowEx
lea edi, buffer ; pointer to a local buffer
invoke SendMessage, hEdit, WM_GETTEXT, LocBufSize, edi
lea edx, cds ; a local copydatastruct
magic = 54321
mov [edx.COPYDATASTRUCT.dwData], Magic ; a user-defined password ;-)
inc eax ; if omitted, Windows will forget to copy the zero delimiter
mov [edx.COPYDATASTRUCT.cbData], eax ; the length returned by WM_GETTEXT, plus one for delimiter
mov [edx.COPYDATASTRUCT.lpData], edi ; pointer to the text
pop eax ; handle to the client window
mov eax, HWND_BROADCAST  ; ######### playing foul here #########
invoke SendMessage, eax, WM_COPYDATA, hWnd, edx ; optional: hWnd for feedback


By the way, on my machine (XP SP2), sending data with HWND_BROADCAST makes Firefox open a new instance. Weird...