VC++ MFC的消息映射、循环机制

消息映射、循环机制是Windows程序运行的基本方式。VC++ MFC 中有许多现成的消息句柄
,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。在MFC
<wbr><wbr><br> ClassWizard中不允许添加用户自定义消息,所以我们必须在程序中添加相应代码,以便可<br> 以象处理其它消息一样处理自定义消息。通常的做法是采取以下步骤:<br><wbr><wbr><br>   第一步:定义消息。<br><wbr><wbr><br>   推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。<br><wbr><wbr><br> #define WM_MY_MESSAGE (WM_USER+100) <wbr><wbr><br><wbr><wbr><br>   第二步:实现消息处理函数。该函数使用WPRAM和LPARAM参数并返回LPESULT。<wbr><wbr><br><wbr><wbr><br> LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)<wbr><wbr><br> { <wbr><wbr><br> // TODO: 处理用户自定义消息 <wbr><wbr><br> ... <wbr><wbr><br> return 0; <wbr><wbr><br> } <wbr><wbr><br><wbr><wbr><br>   第三步:在类头文件的AFX_MSG块中说明消息处理函数:<br><wbr><wbr><br> class CMainFrame:public CMDIFrameWnd<wbr><wbr><br> { <wbr><wbr><br> ... <wbr><wbr><br> // 一般消息映射函数 <wbr><wbr><br> protected: <wbr><wbr><br> // {{AFX_MSG(CMainFrame) <wbr><wbr><br> afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);<wbr><wbr><br> afx_msg void OnTimer(UINT nIDEvent);<wbr><wbr><br> afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);<wbr><wbr><br> //}}AFX_MSG <wbr><wbr><br> DECLARE_MESSAGE_MAP() <wbr><wbr><br> } <wbr><wbr><br><wbr><wbr><br>   第四步:在用户类的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函数中。<br><wbr><wbr><br><wbr><wbr><br> BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)<wbr><wbr><br> //{{AFX_MSG_MAP(CMainFrame) <wbr><wbr><br> ON_WM_CREATE() <wbr><wbr><br> ON_WM_TIMER() <wbr><wbr><br> ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)<wbr><wbr><br> //}}AFX_MSG_MAP <wbr><wbr><br> END_MESSAGE_MAP() <wbr><wbr><br><wbr><wbr><br> 如果用户需要一个定义整个系统唯一的消息,可以调用SDK函数RegisterWindowMessage定义<br> 消息:<br><wbr><wbr><br> static UINT WM_MY_MESSAGE=RegisterWindowMessage("User");<wbr><wbr><br><wbr><wbr><br>   并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步骤同上。<br><wbr><wbr><br>   当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessa<br> ge发送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他进程发送消息可通过如下方法<br> 发送消息:<br><wbr><wbr><br> DWORD result;<br> SendMessageTimeout(wnd-&gt;m_hWnd, // 目标窗口<br> WM_MY_MESSAGE, // 消息<br> 0, // WPARAM<br> 0, // LPARAM<br> SMTO_ABORTIFHUNG |<br> SMTO_NORMAL,<br> TIMEOUT_INTERVAL,<br> &amp;result); <wbr><wbr><br><wbr><wbr><br>   以避免其它进程如果被阻塞而造成系统死等状态。<br><wbr><wbr><br>   可是如果需要向其它类(如主框架、子窗口、视类、对话框、状态条、工具条或其他控<br> 件等)发送消息时,上述方法显得无能为力,而在编程过程中往往需要获取其它类中的某个<br> 识别信号,MFC框架给我们造成了种种限制,但是可以通过获取某个类的指针而向这个类发送<br> 消息,而自定义消息的各种动作则在这个类中定义,这样就可以自由自在的向其它类发送<br> 消息了。<br><wbr><wbr><br>   下面举的例子叙述了向视类和框架类发送消息的方法:<br><wbr><wbr><br>   在主框架类中向视类发送消息:<br><wbr><wbr><br>   视类中定义消息:<br><wbr><wbr><br> ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定义消息映射<br> 视类定义消息处理函数:<br><wbr><wbr><br> // 消息处理函数<br> LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAMlParam)<br> {<br> // TODO: 处理用户自定义消息 <wbr><wbr><br> ... <wbr><wbr><br> return 0;<br> } <wbr><wbr><br><wbr><wbr><br> //发送消息的测试函数<br> void CMainFrame::OnTest()<br> {<br> CView * active = GetActiveView();//获取当前视类指针<br> if(active != NULL)<br> active-&gt;PostMessage(WM_MY_MESSAGE,0,0);<br> } <wbr><wbr><br><wbr><wbr><br>   在其它类中向视类发送消息:<br><wbr><wbr><br> //发送消息的测试函数<br> void CMainFrame::OnTest()<br> {<br> CMDIFrameWnd *pFrame;<br> CMDIChildWnd *pChild;<br> CView *pView;<br> //获取主窗口指针<br> pFrame=(CMDIFrameWnd*)AfxGetApp()-&gt;m_pMainWnd;<br> // 获取子窗口指针<br> pChild = (CMDIChildWnd *)pFrame-&gt;GetActiveFrame();<br> //获取视类指针<br> pView = pChild-&gt;GetActiveView();<br> if(pView != NULL)<br> pView-&gt;PostMessage(WM_MY_MESSAGE,0,0);//发送消息<br> } <wbr><wbr><br><wbr><wbr><br>   其余步骤同上。<br><wbr><wbr><br> 在视类中向主框架发送消息:<br><wbr><wbr><br>   首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下<br><wbr><wbr><br> //发送消息的测试函数<br> void CMessageView::OnTest()<br> {<br> CFrameWnd * active = GetActiveFrame();//获取当前主窗口框架指针<br> if(active != this)<br> active-&gt;PostMessage(WM_MY_MESSAGE,0,0);<br> return 0;<br> } <wbr><wbr><br><wbr><wbr><br>   在其它类中向不同的类发送消息可依次方法类推,这样我们的程序就可以的不受限制<br> 向其它类和进程发送消息,而避免了种种意想不到的风险。<br><wbr><wbr><br>   下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消<br> 息的具体过程。<br> 实现步骤:<br><wbr><wbr><br>   第一步:在VC++中新建工程Message,所有ClassWizard步骤选项均为缺省,完成。<br><wbr><wbr><br>   第二步:在主菜单中添加测试菜单为调出对话框,在框架类中建立相应函数OnTest()<br><wbr><wbr><br>   第三步:在资源中建立对话框,通过ClassWizard添加新类TestDialog,添加测试按钮,<br><wbr><wbr><br><wbr><wbr><br>   在对话框类中建立相应函数OnDialogTest()<br><wbr><wbr><br> //通过对话框按钮发送消息的函数<br> void TestDialog::OnDialogTest()<br> {<br> CMDIFrameWnd *pFrame;<br> CMDIChildWnd *pChild;<br> CView *pView;<br> //获取主窗口指针<br> pFrame=(CMDIFrameWnd*)AfxGetApp()-&gt;m_pMainWnd;<br> // 获取子窗口指针<br> pChild = (CMDIChildWnd *)pFrame-&gt;GetActiveFrame();<br> //获取视类指针<br> pView = pChild-&gt;GetActiveView();<br> if(active != NULL)<br> active-&gt;PostMessage(WM_MY_MESSAGE,0,0);//发送消息<br> } <wbr><wbr><br><wbr><wbr><br>   在Message.h头文件中添加如下语句:<br><wbr><wbr><br> static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");<wbr><wbr><br><wbr><wbr><br>   第四步:在视类中添加自定义消息:<br><wbr><wbr><br>   在头文件MessageView.h中添加消息映射<br><wbr><wbr><br> protected:<br> //{{AFX_MSG(CMessageView)<br> //}}AFX_MSG<br> afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);//此行为添加代码<br> DECLARE_MESSAGE_MAP()<br> 在视类文件MessageView.cpp中的消息映射中添加自定义消息映射<br> BEGIN_MESSAGE_MAP(CMessageView, CView)<br> //{{AFX_MSG_MAP(CMessageView)<br> //}}AFX_MSG_MAP<br> // Standard printing commands<br> ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage)//此行添加代码定义唯一消息<br> END_MESSAGE_MAP() <wbr><wbr><br><wbr><wbr><br>   添加相应的0消息处理函数<br><wbr><wbr><br> LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAMlParam)<br> {<br> CRect rect;<br> GetClientRect(&amp;rect);<br> InvalidateRect(&amp;rect);<br> test=!test;<br> return 0;<br> } <wbr><wbr><br><wbr><wbr><br>   在MessageView.h中添加布尔变量 public:BOOL test;<br><wbr><wbr><br>   在视类构造函数中初始化 test变量:test=FALSE;<br><wbr><wbr><br>   修改CMessageView::OnDraw()函数<br><wbr><wbr><br> void CMessageView::OnDraw(CDC* pDC)<br> {<br> CMessageDoc* pDoc = GetDocument();<br> ASSERT_VALID(pDoc);<br> // 以下程序显示消息响应效果<br> if(test)<br> pDC-&gt;TextOut(0,0,"消息响应!");<br> } <wbr><wbr><br><wbr><wbr><br>   第五步:显示测试对话框<br><wbr><wbr><br>   在MainFrame类中包含对话框头文件:<br><wbr><wbr><br> #include "TestDialog.h";<br> OnTest()函数中添加代码<br> void CMainFrame::OnTest()<br> {<br> TestDialog dialog;<br> dialog.DoModal();<br> } <wbr><wbr><br><wbr><wbr><br>   运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值