Inter Process Communication using WM_COPYDATA by thatsalok

Preface:

Inter Process Communication is major Concept in Windows Programming, there are many ways using which on process is communicate with other process like Memory Mapped Files, Using
Windows Messages (SendMessage and PostMessage api’s), RegisterWindowMessage ,
WM_COPYDATA etc.

Here I am going to use WM_COPYDATA
message to demonstrate Inter Process communication!.

Coding and Explanation:

Now Here I am going to explain WM_COPYDATA using two Applications One will send data using WM_COPYDATA message and other application will receive that!

Some important fact before proceeding to actual coding!

  1. You cannot send a Pointer reference to other process as pointers are not accessible between processes.
  2. You can only use SendMessage to send Data using WM_COPYATA
  3. The Receiving application should consider the received data as read only and copy that data in there local Buffer before Using/Modifying it.

Now, How WM_COPYDATA works? The real power behind is
COPYDATASTRUCT using which the two or more application send and receive data! Let take a look a the COPYDATASTRUCT

typedef struct tagCOPYDATASTRUCT {  ULONG_PTR dwData;
DWORD cbData;
PVOID lpData; 

} COPYDATASTRUCT, *PCOPYDATASTRUCT;

cbData member contains the size of data to be send and
lpData contain the actual data! And dwData is for uniquely distinguish between messages.

Ok, till now you get preview of WM_COPYDATA message! Now let proceed to actual coding! Most important thing is to get the destination Windows i.e. the Window handle where you want to send data!.

Now how to find window where you want to send data? And Windows Handles are generated every time the window created! So how will we proceed now?

Answer is very simple Use FindWindow Api! To find the Window and retrieve the HANDLE of that Window!

 //==================
// From Actual Files
//==================m_RemoteWindow=::FindWindow(NULL,"WMCOPYDATARECV");

Here I have passed the Window Caption of my receiving Window to find the window HANDLE. If this API is successful it will return with the Window Handle otherwise NULL;

Now I will show how to initialize the COPYDATASTRUCT to send a Integer and String data from one Process to other!

struct MyStruct
{ int nNum;
TCHAR szData[256];

};

I have a Created a small structure which has one string member and one integer member.

//Now Copy the data into COPYDATASTRUCTURElstrcpy(l_var.szData,strData);
l_var.nNum=this->GetDlgItemInt(IDC_EDIT_INTEGER);

//Initalize the data member of MyCDS

MyCDS.cbData=sizeof(l_var);
MyCDS.dwData=1;
MyCDS.lpData=(LPVOID)&l_var;;

::SendMessage(this->m_RemoteWindow,WM_COPYDATA,
(WPARAM)this->GetSafeHwnd(),(LPARAM)&MyCDS);

Now, Using the Send Message Send the data to other process! First Parameter: Handle to Remote window, which going to receive data.
Third Parameter: Handle of Windows whom sending the data! Fourth Parameter: Actual Data!

That?s all on Sending side and now on receiving side, using Class Wizard generate the.
MESSENGER HANDLLER for WM_COPYDATA. Which look?s something like this

BOOL CWMCOPYDATARECVDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{}

Now how to retrieve data from pCoydataStruct , here is little piece of code to do that!

MyStruct *tcsBuff=(MyStruct*)(pCopyDataStruct->lpData);

First cast the receiving data to actual structure! i.e. MyStruct
And tcsBuff contains the data send by other application!

Using Demo:

  1. Run Both Application simultaneously after extracting those file from Demo.zip
  2. Press Find Window Button in First application (RegisterCopyData.exe) and if it successful in finding window it will notify you by Message Box.
  3. now fill text boxes with data of your choices and press Send Data button to see WM_COPYDATA in action

Attachments:

Project Files: RegisterCopyData.zip

Special Thanks

My Mother and Father
CoderSource team

About Author

Alok Gupta is working as Software Developer In Noida,UP. You can mail him at thatsalok#gmail.com( replace # with @)