WM_COPYDATA is a message you can send from your application or dll which allows any kind of data to be sent to the application owning the target of the message. You don't even need to have a window open in the sender if you want. In this case, just set wParam to #Null in the message. If the receiver doesn't have a window, you'll have to open a hidden one to receive the message. It isn't a good idea to send this message to HWND_BROADCAST as several mainstream apps process it (I found that out the hard way.) One important feature is that in the receiver you have to copy the data to local variables when you process the message, because the pointer isn't valid later. Here's a pair of sample programs, you can compile them or run them from the IDE, it doesn't matter:
Receiver (Run this first and let it wait for the sender)
Code: Select all
;==================================================================
; Program: WM_COPYDATA demo - Receiver program
;==================================================================
Enumeration
#Double_Message ; user-defined identifier that a double is being sent
#String_Message ; " " " string " "
#Dog_Message ; " " " dog " "
EndEnumeration
Structure DOG
name.s{10}
age.l
weight.l
breed.s{20}
EndStructure
Procedure.l Callback(hwnd, msg, wparam, lparam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_COPYDATA
*pp.COPYDATASTRUCT = lparam
Select *pp\dwData ; determine the type of data being sent and process accordingly
Case #String_Message
AddGadgetItem(0,-1, "Got a string: "+PeekS(*pp\lpData) )
Case #Double_Message
double.d = PeekD(*pp\lpData)
AddGadgetItem(0,-1, "Got a double: "+StrD(double) )
Case #Dog_Message
*dog.DOG = *pp\lpData
With *dog
name$ = \name
age = \age
weight = \weight
breed$ = \breed
s$ = "Got a dog: "+name$+", "+breed$+", "+Str(age)+" years old, "+Str(weight)+" kg."
AddGadgetItem(0,-1, s$ )
EndWith
EndSelect
result = #True ; You should return #True if processing #WM_COPYDATA
EndSelect
ProcedureReturn result
EndProcedure
OpenWindow(0,0,0,320,240,"WM_COPYDATA Receiver", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ListViewGadget(0,0,0,320,240)
SetWindowCallback(@Callback(),0)
StickyWindow(0,1)
Repeat
ev = WaitWindowEvent()
Until ev = #WM_CLOSE
Code: Select all
;==================================================================
; Program: WM_COPYDATA demo - Sender program
; Author: Lloyd Gallant (netmaestro)
; Date: November 24, 2007
; Target Compiler: PureBasic 4.xx and later
; Target OS: Microsoft Windows All
; License: Free, unrestricted, credit appreciated
; but not required
;==================================================================
Enumeration
#Double_Message
#String_Message
#Dog_Message
EndEnumeration
window = FindWindow_(0, "WM_COPYDATA Receiver")
Structure DOG ; complex structure for data to be sent
name.s{10}
age.l
weight.l
breed.s{20}
EndStructure
; ****************** Prepare a string to be sent ********************
string2send.s = "Testing 123"
*stringdata.COPYDATASTRUCT = AllocateMemory(SizeOf(COPYDATASTRUCT))
With *stringdata
\dwData = #String_Message
\cbData = Len(string2send)+SizeOf(CHARACTER)
\lpData = @string2send
EndWith
; ******************* Prepare a double to be sent *******************
double2send.d = #PI
*doubledata.COPYDATASTRUCT = AllocateMemory(SizeOf(COPYDATASTRUCT))
With *doubledata
\dwData = #Double_Message
\cbData = SizeOf(DOUBLE)
\lpData = @double2send
EndWith
; ************* Prepare a complex structure to be sent **************
dog2send.DOG
With dog2send
\name = "Bowser"
\age = 3
\weight = 20
\breed = "German Shepherd"
EndWith
*dogdata.COPYDATASTRUCT = AllocateMemory(SizeOf(COPYDATASTRUCT))
With *dogdata
\dwData = #Dog_Message
\cbData = SizeOf(DOG)
\lpData = dog2send
EndWith
; *******************************************************************
SendMessage_(window, #WM_COPYDATA, #Null, *stringdata)
SendMessage_(window, #WM_COPYDATA, #Null, *doubledata)
SendMessage_(window, #WM_COPYDATA, #Null, *dogdata)