Board logo

标题: MFC中通过自定义消息实现进程间通信的方法 [打印本页]

作者: yuyang911220    时间: 2014-7-28 15:27     标题: MFC中通过自定义消息实现进程间通信的方法

MFC中消息分为两种,即系统消息和用户(程序设计者)自定义消息。系统消息定义从0到0x3FF,可以使用0x400到0x7FFF定义自己的消息。Windows把0x400定义为WM_USER。如果想定义自己的一个消息,可以在WM_USER上加上一个值。
还有一种自定义窗口消息的方法是用RegisterWindowsMessage()函数来注册这个消息。与在WM_USER上加上某个数相比,它的好处是不必考虑所表示的消息标识符是否超出工程的允许范围。
要想用消息实现进程间通信,则需要在这两个程序中定义或注册相同的消息,才能保证数据通信顺利进行。用户自定义消息的方法如下:
l         
#define WM_COMM      WM_USER+100
const UINT wm_nRegMsg=RegisterWindowMessage("reg_data");
有了这两种定义的消息后,可以用如下的方法来发送消息。
pWnd->SendMessage(WM_COMM,NULL,(LPARAM)uMsg);
pWnd->SendMessage(wm_nRegMsg,NULL,(LPARAM)uMsg);
其中pWnd为接收这个消息的窗口句柄,uMsg为要通过消息发送的数据,是长整型。这两个消息的发送可以分别在一个发送函数里实现,其具体的做法见以后的实例。通过实验可知,这两种自定义消息的发送效果是一样的。
在接收消息的程序中,除与发送消息的程序需要定义相同的消息外,还需要定义相应的消息映射和消息映射函数,消息的映射方法如下:
ON_MESSAGE(WM_COMM,OnUserReceiveMsg)
ON_REGISTERED_MESSAGE(wm_nRegMsg,OnRegReceiveMsg)
与以上消息映射对应的函数定义如下:
void CDataRecvDlg::OnUserReceiveMsg(WPARAM wParam,LPARAM lParam)
{
    // 增加用户自定义程序代码

}
//--------------------------------------------------------------------
void CDataRecvDlg::OnRegReceiveMsg(WPARAM wParam,LPARAM lParam)
{
// 增加用户自定义程序代码

}
其中OnUserReceiveMsg()函数为WM_COMM消息的映射函数,OnRegReceiveMsg()函数为wm_nRegMsg消息的映射函数。可以看出,这两种消息的映射函数形式是一样的。
3.3.2  通过自定义消息实现进程间通信的实例
为说明以自定义消息实现进程之间的通信,作者用VC++
编写了这样的程序。有两个对话框程序,其中一个为发送程序,另一个为接收程序。在这两个程序中分别定义了两个消息WM_COMM和wm_nRegMsg,在CDataSendDlg类中增加了用于发送数据的两个函数,即void
CDataSendDlg::OnSendUsermsg()和void CDataSendDlg::OnSendRegmsg()。它们的源代码如下:
void CDataSendDlg::OnSendUsermsg()
{
    UpdateData();                                   // 更新数据
    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv"));   // 查找DataRecv进程
    if(pWnd==NULL){
        AfxMessageBox(TEXT("Unable to find DataRecv."));
        return;
    }
    UINT uMsg;
    uMsg=atoi(m_strUserMsg);
    pWnd->SendMessage(WM_COMM,NULL,(LPARAM)uMsg);   // 发送.
}
//--------------------------------------------------------------------
void CDataSendDlg::OnSendRegmsg()
{
    UpdateData();                                   // 更新数据
    CWnd *pWnd=CWnd::FindWindow(NULL,_T("DataRecv"));   // 查找DataRecv进程
    if(pWnd==NULL){
        AfxMessageBox("Unable to find DataRecv.");
        return;
    }
    UINT uMsg;
    uMsg=atoi(m_strRegMsg);
    pWnd->SendMessage(wm_nRegMsg,NULL,(LPARAM)uMsg); // 发送
}
在接收数据的程序中要做三件事:①定义自定义消息;②定义消息映射表;③定义消息映射函数。自定义消息的方法如前面所述。在CDataRecvDlg类中增加了两个用于接收数据的函数,即void
CDataRecvDlg::OnUserReceiveMsg()和void CDataRecvDlg:: OnRegReceiveMsg()。消息映射表如下:
BEGIN_MESSAGE_MAP(CDataRecvDlg, CDialog)
    //{{AFX_MSG_MAP(CDataRecvDlg)
    ON_MESSAGE(WM_COMM,OnUserReceiveMsg)
    ON_REGISTERED_MESSAGE(wm_nRegMsg,OnRegReceiveMsg)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
消息映射表中的映射函数名的格式是一样的。其实它们可以用同一个函数,为了说明方便,这里把它们的名字取为不一样。接收数据程序中的消息映射函数的源代码如下:
void CDataRecvDlg::OnUserReceiveMsg(WPARAM wParam,LPARAM lParam)
{
    m_strUserMsg.Format("%d\n",int(lParam));
    UpdateData(FALSE);   // 更新数据
}
//--------------------------------------------------------------------
void CDataRecvDlg::OnRegReceiveMsg(WPARAM wParam,LPARAM lParam)
{
    m_strRegMsg.Format("%d\n",int(lParam));
    UpdateData(FALSE);   // 更新数据
}




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0