windows进程通信 -- WM_COPYDATA消息

WM_COPYDATA消息,在win32中用来进行进程间的数据传输。

typedef struct tagCOPYDATASTRUCT {  // cds 
    DWORD dwData; 
    DWORD cbData; 
    PVOID lpData; 
} COPYDATASTRUCT;

其中dwData为32位的自定义数据, lpData为指向数据的指针,cbData为lpData指针指向数据的大小(字节数)。

一般推荐用SendMessage函数进行发送,这样就能确保在接收方复制数据前避免发送方能修改或删除数据;

LRESULT SendMessage(
  HWND hWnd,      // handle of destination window
  UINT Msg,       // message to send
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

这里:

hWnd:为接收进程的窗体句柄;

Msg:WM_COPYDATA;
wParam:为发送进程的窗体句柄;

lParam:为指向COPYDATASTRUCT数据结构的指针;

这里需要注意的:传输的COPYDATA数据在发送后要避免被发送进程中的其他线程修改,其次要确保被传输的数据中没有包含接收进程无法访问的对象的指针或引用。比如:发送进程自身的HDC、HBITMAP之类的东西,它们对于接收进程来说是无效的。另外,接收进程窗体句柄可以通过FindWindow函数获取:

const char szDlgTitle[] = "ReceiveProcess";  
HWND hRecvWindow  = ::FindWindow(NULL, szDlgTitle);

这里的“ReceiveProcess”为接收进程的名字;

同时,接收数据的进程中,首先在消息映射表中增加WM_COPYDATA消息映射,然后定义消息映射函数,其函数的格式为:

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

主要代码如下:(这里发送进程发送当前的时间给接收进程)

发送进程:

复制代码
void CProcessCommDlg::OnBTNStart1() 
{
    const char szDlgTitle[] = "ReceiveProcess";  
    HWND hSendWindow =this->GetSafeHwnd();
    HWND hRecvWindow  = ::FindWindow(NULL, szDlgTitle); 

    COPYDATASTRUCT CopyData; 
    char szSendBuf[100];  
    time_t  timenow; 
    time(&timenow);  
    sprintf(szSendBuf, "%s", ctime(&timenow));//注意,ctime()返回的字符串后面带了'\n'  
    CopyData.dwData = 0;  
    CopyData.cbData = strlen(szSendBuf);  
    szSendBuf[CopyData.cbData - 1] = '\0';  
    CopyData.lpData = szSendBuf;  
    
    ::SendMessage(hRecvWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)&CopyData);  
    printf("%s\n", szSendBuf);  

}
复制代码

接收进程:

复制代码
BEGIN_MESSAGE_MAP(CCanCollectorDlg, CDialog)
    //{{AFX_MSG_MAP(CCanCollectorDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_COPYDATA()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

........


BOOL CCanCollectorDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
    char szBuffer[300];  
    
    memset(szBuffer, 0, sizeof(szBuffer));  
    sprintf(szBuffer, "dwData:%d cbData:%d\r\nlpData:0x%08x = %s\r\n\r\n",   
        pCopyDataStruct->dwData, pCopyDataStruct->cbData,   
        (PVOID)pCopyDataStruct->lpData, (char*)pCopyDataStruct->lpData);  

    
    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}
复制代码
posted @   红心李  阅读(11906)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示