MFC中自定义消息

本文详细介绍了如何在MFC中创建、处理和应用自定义消息,包括消息映射、消息处理函数的实现、消息的唯一性定义以及如何在不同类间发送消息。通过实例演示了如何在多文档程序中实现自定义消息的发送与接收,提供了具体代码示例,旨在帮助开发者更好地理解和利用MFC中的自定义消息功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MFC中自定义消息

消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。在MFC ClassWizard中不允许添加用户自定义消息,所以我们必须手动在程序中添加相应代码,以便可以象处理其它消息一样处理自定义消息。
自定义消息的步骤如下(举个例子):
(1)建立Single Document的MFC Application,工程名为:MyMessage
(2)自定义消息:
第一步:定义消息
在Resource.h中添加如下代码:
//推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。
#define WM_MY_MESSAGE (WM_USER+100)
第二步:声明消息处理函数
选择CMainFrame类中添加消息处理函数
在MainFrm.h文件中,类CMainFrame内,声明消息处理函数,代码如下:
protect:
    afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); 
第三步:实现消息处理函数
在MainFrm.cpp文件中添加如下代码:
LRESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
      //TODO: Add your message handle code
      return 0;
}
第四步:在CMainFrame类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_WM_CREATE()
    ON_MESSAGE(WM_MY_MESSAGE,OnMyMessage)
    //ON_REGISTERED_MESSAGE (WM_MY_MESSAGE,OnMyMessage)
END_MESSAGE_MAP()
 如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义消息:
在Resource.h中将代码
#define WM_MY_MESSAGE (WM_USER+100)
替换为:
static UINT WM_MY_MESSAGE=RegisterWindowMessage(_T("User"));
并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。
注:如果仍然使用ON_MESSAGE宏指令,compile可以通过,但是无法响应消息。
当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessage发送消息PoseMessage(WM_MY_MESSAGE,O,O)。
RegisterWindowMessage Function
The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system.
The message value can be used when sending or posting messages.
Syntax 
UINT RegisterWindowMessage(          LPCTSTR lpString
    );
Remarks
The RegisterWindowMessage function is typically used to register messages for communicating between two cooperating applications.
If two different applications register the same message string, the applications return the same message value.
The message remains registered until the session ends.
//如果两个Application使用相同的string注册message,他们将等到相同的message值,也就是得到相同的message


 

第一步:定义消息。 

  推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。 

#define WM_MY_MESSAGE (WM_USER+100) 

  第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。 

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam) 
{ 
// TODO: 处理用户自定义消息 
... 
return 0; 
} 

  第三步:在类头文件的AFX_MSG块中说明消息处理函数: 

class CMainFrame:public CMDIFrameWnd 
{ 
... 
// 一般消息映射函数 
protected: 
// {{AFX_MSG(CMainFrame) 
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); 
afx_msg void OnTimer(UINT nIDEvent); 
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); 
//}}AFX_MSG 
DECLARE_MESSAGE_MAP() 
} 

  第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。 


BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) 
//{{AFX_MSG_MAP(CMainFrame) 
ON_WM_CREATE() 
ON_WM_TIMER() 
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage) 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 

如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义 
消息: 

static UINT WM_MY_MESSAGE=RegisterWindowMessage("User"); 

  并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。 

  当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessa 
ge发送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他进程发送消息可通过如下方法 
发送消息: 

DWORD result; 
SendMessageTimeout(wnd->m_hWnd, // 目标窗口 
WM_MY_MESSAGE, // 消息 
0, // WPARAM 
0, // LPARAM 
SMTO_ABORTIFHUNG | 
SMTO_NORMAL, 
TIMEOUT_INTERVAL, 
&result); 

  以避免其它进程如果被阻塞而造成系统死等状态。 

  可是如果需要向其它类(如主框架、子窗口、视类、对话框、状态条、工具条或其他控 
件等)发送消息时,上述方法显得无能为力,而在编程过程中往往需要获取其它类中的某个 
识别信号,MFC框架给我们造成了种种限制,但是可以通过获取某个类的指针而向这个类发送 
消息,而自定义消息的各种动作则在这个类中定义,这样就可以自由自在的向其它类发送 
消息了。 

  下面举的例子叙述了向视类和框架类发送消息的方法: 

  在主框架类中向视类发送消息: 

  视类中定义消息: 

ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定义消息映射 
视类定义消息处理函数: 

// 消息处理函数 
LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam) 
{ 
// TODO: 处理用户自定义消息 
... 
return 0; 
} 

//发送消息的测试函数 
void CMainFrame::OnTest() 
{ 
CView * active = GetActiveView();//获取当前视类指针 
if(active != NULL) 
active->PostMessage(WM_MY_MESSAGE,0,0); 
} 

  在其它类中向视类发送消息: 

//发送消息的测试函数 
void CMainFrame::OnTest() 
{ 
CMDIFrameWnd *pFrame; 
CMDIChildWnd *pChild; 
CView *pView; 
//获取主窗口指针 
pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd; 
// 获取子窗口指针 
pChild = (CMDIChildWnd *) pFrame->GetActiveFrame(); 
//获取视类指针 
pView = pChild->GetActiveView(); 
if(pView != NULL) 
pView->PostMessage(WM_MY_MESSAGE,0,0);//发送消息 
} 

  其余步骤同上。 

在视类中向主框架发送消息: 

  首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下 

//发送消息的测试函数 
void CMessageView::OnTest() 
{ 
CFrameWnd * active = GetActiveFrame();//获取当前主窗口框架指针 
if(active != this) 
active->PostMessage(WM_MY_MESSAGE,0,0); 
return 0; 
} 

  在其它类中向不同的类发送消息可依次方法类推,这样我们的程序就可以的不受限制 
向其它类和进程发送消息,而避免了种种意想不到的风险。 

  下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消 
息的具体过程。 
实现步骤: 

  第一步:在VC++中新建工程Message,所有ClassWizard步骤选项均为缺省,完成。 

  第二步:在主菜单中添加测试菜单为调出对话框,在框架类中建立相应函数OnTest() 

  第三步:在资源中建立对话框,通过ClassWizard添加新类TestDialog,添加测试按钮, 


  在对话框类中建立相应函数OnDialogTest() 

//通过对话框按钮发送消息的函数 
void TestDialog::OnDialogTest() 
{ 
CMDIFrameWnd *pFrame; 
CMDIChildWnd *pChild; 
CView *pView; 
//获取主窗口指针 
pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd; 
// 获取子窗口指针 
pChild = (CMDIChildWnd *) pFrame->GetActiveFrame(); 
//获取视类指针 
pView = pChild->GetActiveView(); 
if(active != NULL) 
active->PostMessage(WM_MY_MESSAGE,0,0);//发送消息 
} 

  在Message.h头文件中添加如下语句: 

static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message"); 

  第四步:在视类中添加自定义消息: 

  在头文件MessageView.h中添加消息映射 

protected: 
//{{AFX_MSG(CMessageView) 
//}}AFX_MSG 
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行为添加代码 
DECLARE_MESSAGE_MAP() 
在视类文件MessageView.cpp中的消息映射中添加自定义消息映射 
BEGIN_MESSAGE_MAP(CMessageView, CView) 
//{{AFX_MSG_MAP(CMessageView) 
//}}AFX_MSG_MAP 
// Standard printing commands 
ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行添加代码定义唯一消息 
END_MESSAGE_MAP() 

  添加相应的0消息处理函数 

LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam) 
{ 
CRect rect; 
GetClientRect(&rect); 
InvalidateRect(&rect); 
test=!test; 
return 0; 
} 

  在MessageView.h中添加布尔变量 public:BOOL test; 

  在视类构造函数中初始化 test变量:test=FALSE; 

  修改CMessageView::OnDraw()函数 

void CMessageView::OnDraw(CDC* pDC) 
{ 
CMessageDoc* pDoc = GetDocument(); 
ASSERT_VALID(pDoc); 
// 以下程序显示消息响应效果 
if(test) 
pDC->TextOut(0,0,"消息响应!"); 
} 

  第五步:显示测试对话框 

  在MainFrame类中包含对话框头文件: 

#include "TestDialog.h"; 
OnTest()函数中添加代码 
void CMainFrame::OnTest() 
{ 
TestDialog dialog; 
dialog.DoModal(); 
} 

  运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果。 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值