Go4Expert (http://www.go4expert.com/)
-   Win32 (http://www.go4expert.com/articles/win32-tutorials/)
-   -   Interprocess Communication through WM_COPYDATA & Shared Memory (http://www.go4expert.com/articles/interprocess-communication-wmcopydata-t19730/)

d_arin100 10Oct2009 11:16

Interprocess Communication through WM_COPYDATA & Shared Memory


Here I shall describe the methods of how data is exchanged between windows of different processes. Communication between windows means one window process send/post a message/data to the other window process. The Windows operating system provides the mechanism for communications and data sharing between applications. SendMessage() and PostMessage() are most commonly used method of communication.

Passing Data with WM_COPYDATA

Let us consider a case when you need to send a complex data structure or a string to another window. In such scenario, you can send information to another application using the WM_COPYDATA message. This method requires cooperation between the sending application and the receiving application. The receiving application must know the format of the information and be able to identify the sender. In this method the receiving application receives the data in a COPYDATASTRUCT structure. The application sends WM_COPYDATA message to the other application using SendMessage () function with the following parameters.

Code: Cpp

SendMessage((HWND) hwnd, /// Handle to destination window
    WM_COPYDATA, /// Message to send
    (WPARAM) wparam, /// Handle to window (HWND)
    (LPARAM)lparam /// Data (PCOPYDATASTRUCT)

wParam - Handle to the window passing the data.
lParam - Pointer to a COPYDATASTRUCT structure that contains the data to be passed.

When you're ready to send some data to a window in another process, you must first initialize the COPYDATASTRUCT structure. COPYDATASTRUCT is a structure defined in WinUser.h, and it looks like this:
Code: Cpp

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

dwData specifies data to be passed to the receiving application.

The cbData member specifies the number of bytes that you want to transfer to the other process, and the lpData member points to the first byte of the data.

When SendMessage sees that you are sending a WM_COPYDATA message, it creates memory-mapped file cbData bytes in size and copies the data from your address space to the memory-mapped file. It then sends the message to the destination window. When the receiving window procedure processes this message, the lParam parameter points to a COPYDATASTRUCT that exists in the address space of the receiving process. The lpData member of this structure points to the view of the shared memory-mapped file in the receiving process's address space.

The following example demonstrates how to send information between two applications using the WM_COPYDATA message.

1. Fills the COPYDATA structure.

Code: Cpp

#define ORGINFO 1
typedef struct strData
    char strOrgName[80];
    char strLocation[80];

DATA tData;

lstrcpy(tData.strOrgName, “Go4Expert”);
lstrcpy(tData.strLocation, “Earth”);

cData.dwData = ORGINFO;
cData.cbData = sizeof ( tData );
cData.lpData = &tData;

2. Retrieves a handle to the top-level window.
Code: Cpp

HWND FindWindow(LPCTSTR lpClassName, // class name
    LPCTSTR lpWindowName // window name

3. After getting the handle of the destination window application send the message using SendMessage () function.

SendMessage(dhwnd,WM_COPYDATA,(WPARAM)(HWND)hwnd, (LPARAM)(LPVOID) &cData);

dhwnd – handle of the destination window.
hwnd – handle of the sender window.
cData – COPYDATA structure variable.

The receiving application receives the data in the following way:

1. Declare the data variable.
Code: Cpp

#define iMessage 1
typedef struct strData
    char strOrgName[80];
    char strLocation[80];

2. Implement the WM_COPYDATA message in the WndProc().
Code: Cpp

    pcData = (PCOPYDATASTRUCT) lParam;

    switch ( pcData->dwData )
    case iMessage :
        MessageBox(hwnd, (LPSTR) ( (DATA *) (pcData->lpData) )-> strOrgName, “Organisation Name”, MB_OK);
        MessageBox(hwnd, (LPSTR) ( (DATA *) (pcData->lpData) )-> strLocation, “Location”, MB_OK);

Communication by FileMapping object (Shared Memory)

Processes can communicate between them by a shared memory called File Mapping objects. File mapping is the association of a file's contents with a portion of the virtual address space of a process. The system creates a file-mapping objectto maintain this association.

The creation of File Mapping is shown below:
Code: Cpp

typedef struct structExchangeData
     char cData1;
     DWORD dwData2 ;
const LPCTSTR sMemoryFileName = _T("MappedFile");
LPVOID m_pViewOfFile;
HANDLE hFileMapping;
hFileMapping = CreateFileMapping(
     INVALID_HANDLE_VALUE, // system paging file
     NULL, // security attributes
     PAGE_READWRITE, // protection
     0, // high-order DWORD of size
     sizeof(STRUCT_EXCHANGE_DATA), // low-order DWORD of size
     sMemoryFileName); // name
     ///// Creating a view of the file in the Processes address space
     m_pViewOfFile = MapViewOfFile(
     hFileMapping, // handle to file-mapping object
     FILE_MAP_ALL_ACCESS, // desired access

Now the processes can write data into the shared memory and also read data from the shared memory.
Code: Cpp

///Copying from the structure to the shared memory
 memset((char*)m_pViewOfFile,0, sizeof(STRUCT_EXCHANGE_DATA));
/// “pExchangeData” is a pointer of STRUCT_EXCHANGE_DATA
 memcpy((char*)m_pViewOfFile,pExchangeData, sizeof(STRUCT_EXCHANGE_DATA));
/// Reading data from the shared memory
/// “pExchangeData” is a pointer of STRUCT_EXCHANGE_DATA

Check out Interprocess communication through Named pipes by Shabbir

shabbir 1Nov2009 19:50

Re: Interprocess Communication through WM_COPYDATA & Shared Memory
Nominate this article for Article of the month - Oct 2009

rasd123 4Nov2009 08:23

Re: Interprocess Communication through WM_COPYDATA & Shared Memory
HaHA! I have already seen the great thing!!!

All times are GMT +5.5. The time now is 08:44.