- UID
- 1029342
- 性别
- 男
|
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); // 更新数据
} |
|