Interprocess Communication through WM_COPYDATA & Shared Memory

Discussion in 'Win32' started by d_arin100, Oct 10, 2009.

  1. d_arin100

    d_arin100 New Member

    Joined:
    Sep 25, 2009
    Messages:
    10
    Likes Received:
    3
    Trophy Points:
    0
    Location:
    Bangalore

    Introduction



    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:
    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:
    typedef struct tagCOPYDATASTRUCT 
    {
    	ULONG_PTR dwData;
    	DWORD cbData; 
    	PVOID lpData; 
    } COPYDATASTRUCT, *PCOPYDATASTRUCT;
    
    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:
    #define ORGINFO 1
    typedef struct strData
    {
    	char strOrgName[80];
    	char strLocation[80];
    }DATA;
    
    COPYDATASTRUCT cData;
    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:
    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.
    Code:
     
    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:
    #define iMessage 1
    typedef struct strData
    {
    	char strOrgName[80];
    	char strLocation[80];
    }DATA;
     
    PCOPYDATASTRUCT pcData;
    
    2. Implement the WM_COPYDATA message in the WndProc().
    Code:
    case WM_COPYDATA:
    	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:
     
    typedef struct structExchangeData
    {
    	 char cData1;
    	 DWORD dwData2 ;
    }STRUCT_EXCHANGE_DATA;
     
    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
    	 0,
    	 0,
     0);
    
    Now the processes can write data into the shared memory and also read data from the shared memory.
    Code:
    ///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
    memcpy(pExchangeData,(char*)m_pViewOfFile,sizeof(STRUCT_EXCHANGE_DATA));
    
    Check out Interprocess communication through Named pipes by Shabbir
     
    shabbir likes this.
  2. shabbir

    shabbir Administrator Staff Member

    Joined:
    Jul 12, 2004
    Messages:
    15,375
    Likes Received:
    388
    Trophy Points:
    83
  3. rasd123

    rasd123 Banned

    Joined:
    Nov 4, 2009
    Messages:
    40
    Likes Received:
    0
    Trophy Points:
    0
    HaHA! I have already seen the great thing!!!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice