返回顶部

【windows】 进程间通信 WM_COPYDATA消息

WM_COPYDATA消息可以实现window应用程序之间的数据传输,是同步传输方式。

需要用到结构体 COPYDATASTRUCT

typedef struct tagCOPYDATASTRUCT {
    DWORD dwData;  //32位自定义的数据
    DWORD cbData;   // lpData指针指向的数据的大小,单位字节
    PVOID lpData;     //指向数据的指针,要传输的数据
} COPYDATASTRUCT;

  一般使用 SendMessage()函数发送消息,不使用PostMessage(),可以确保在接收方复制数据前比秒发送方修改或删除数据。

LRESULT SendMessage(
    HWND hWND,  //接收进程的窗体句柄
    UINT Msg,   //发送的消息  WM_COPYDATA
    WPARAM wParam,  //发送进程的窗体句柄
    LPARAM lParam,  //指向COPYDATASTRUCT数据结构的指针
};

 要注意的是  1、 lParam不能为空;2、lParam不包含接收进程无法访问的对象的指针或引用,比如发送进程自身的HDC、HBITMAP之类的东西。

    如果知道接收进程的名字,可以使用FindWindow()函数获取接收进程窗体句柄。

示例:创建两个MFC对话框程序,sendAPP发送时间,receiveAPP接收时间,主要代码如下:

//sendAPP添加一个按钮,添加按钮click处理事件:

//sendAPPDlg.cpp
void CsendAPPDlg::OnBnClickedButtonsendmessage()
{
    // TODO: 在此添加控件通知处理程序代码
    LPCWSTR szReceiveDlgTitle = L"receiveAPP";
    HWND hSendWindow = this->GetSafeHwnd();
    HWND hReceiveWindow = ::FindWindow(NULL, szReceiveDlgTitle);

    COPYDATASTRUCT copyData;
    char szSendBuf[MAX_PATH];
    time_t timeNow;
    time(&timeNow);
    sprintf_s(szSendBuf, "%s", ctime(&timeNow));
    copyData.dwData = 0;//32位自定义数据
    copyData.cbData = strlen(szSendBuf);//lpData指针指向数据的大小,单位字节
    szSendBuf[copyData.cbData ] = '\0';
    copyData.lpData = szSendBuf;//指向数据的指针,就是你要传输的数据
    
    //第一个参数 hWnd:接收进程的窗体句柄
    //第二个参数 Msg:消息类型
    //第三个参数 wParam:发送进程的窗体句柄
    //第四个参数 lParam:指向COPYDATASTRUCT数据结构体的指针
    ::SendMessage(hReceiveWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)&copyData);
    
    printf("%s\n", szSendBuf);
}

//receiveAPP添加 WM_COPYDATA消息处理函数

//receiveAPPDlg.cpp
BOOL CreceiveAPPDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    char szBuffer[300];
    memset(szBuffer, 0, sizeof(szBuffer));
    sprintf(szBuffer, "dwData:%d\ncbData:%d\nlpDdata:0x%08x = %s\n",
        pCopyDataStruct->dwData, pCopyDataStruct->cbData,
        (PVOID)pCopyDataStruct->lpData, (char*)pCopyDataStruct->lpData);

    SetDlgItemText(IDC_STATIC_Show, szBuffer);
    return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}

运行两个exe,点击发送数据,receiveAPP会显示当前时间

 

 

总结:

实现两个进程间同步通信,传输较少数据量

1.sendMessage()发送消息;  发送方

2.onCopyData()消息处理函数处理消息。  接收方

发送方和接收方可以是同一个,可以使用FindWindow()函数获取已知窗口名字的窗体句柄。

 

 

 

参考:https://www.cnblogs.com/xiekeli/p/3994380.html

 

posted @ 2020-10-26 11:17  Zoya23  阅读(318)  评论(0编辑  收藏  举报