MFC 问题汇总(03)(进程间通信之WM_COPYDATA)

问题描述

需求:
1.客户端基于 MFC 实现,需要浏览器通过 URL Protocol 吊起本地客户端,并且传递参数
2.客户端只能单实例运行
3.如果本地客户端已经启动,再通过浏览器启动新的本地实例需要通过进程间通信,把参数传递给已经启动的进程,保证单实例运行

解决方案

单实例运行参考链接地址:
http://blog.csdn.net/zoomcloudmeetings/article/details/70141427

进程间通信通过 WM_COPYDATA 实现方式,参考地址:
http://www.cnblogs.com/zhuyf87/archive/2013/03/03/2941620.html

完成进程间通信最简单的方式就是发送 WM_COPYDATA 消息,在程序检测到已经有进程启动的时候,发送消息
(1)发送WM_COPYDATA消息
SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)&copyData);

BOOL CVeoApp::InitInstance()
{

    //单例进程模式  
    HANDLE hMutex=::CreateMutex(NULL,TRUE,_T("AtlasSegment"));     
    if(hMutex!=NULL)     
    {     
        if(GetLastError()==ERROR_ALREADY_EXISTS)     
        {     
            // 向已经启动的进程传递参数、指令
            LRESULT copyDataResult;  //copyDataResult has value returned by other app   
            CWnd *pOtherWnd = CWnd::FindWindowW(NULL, _T("埃塔远程诊疗"));

            if (pOtherWnd)  
            {  
                // TODO 实例已经存在时处理逻辑
                CString strDataToSend = AfxGetApp()->m_lpCmdLine;
                COPYDATASTRUCT cpd;  
                cpd.dwData = 0;  
                cpd.cbData = (strDataToSend.GetLength() + 1)*sizeof(TCHAR);          //data length  
                cpd.lpData = (void*)strDataToSend.GetBuffer(cpd.cbData); //data buffer  
                copyDataResult = pOtherWnd->SendMessage(WM_COPYDATA,(WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),(LPARAM)&cpd);  
                strDataToSend.ReleaseBuffer();  
            }  
            CloseHandle(hMutex); 
            return   FALSE;     
        }     
    }
    …… ……
}

(2)接收WM_COPYDATA消息:

WM_COPYDATA

wParam = (WPARAM)(HWND) hwnd;

lParam = (LPARAM)(PCOPYDATASTRUCT) pcds;

hwnd: Handle to the window passing the data. (数据发送方的句柄,接收方可以通过此句柄向发送方反馈数据)

pcds: Pointer to a COPYDATASTRUCT structure that contains the data to be passed.

Return Values

If the receiving application processes this message, it should return TRUE; otherwise, it should return FALSE.

lParam包含了接收到的数据,在处理之前需要将类型转换为COPYDATASTRUCT结构体。接收方应认为这些数据是只读的,并且只在处理该消息的过程中有效。如果想修改这些数据,应该把它们复制到本地buffer。(The receiving application should consider the data read-only. The pcds parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by pcds. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer. )

由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待(SendMessage阻塞)中,所以接收方应当尽快处理WM_COPYDATA消息。

示例代码片段(MFC):

BOOL CVeoDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    CString strRecievedText = (LPCTSTR) (pCopyDataStruct->lpData); 
    // 业务逻辑
    initVeoHandle(strRecievedText);
    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

Zoom云视频会议1
Zoom云视频会议2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值