MFC消息/命令/通知

任何事件的触发与响应均要通过消息的作用才能得以完成。在SDK编程中,对消息的获取与分发主要是通过消息循环来完成的,而在MFC编程中则是通过采取消息映射的方式对其进行处理的。 

1.普通消息.自己定义的消息及映射其流程.

定义一个消息.一般在StdAfx.h 中声明一个消息.自定义消息一般从(VM_USER+100)开始,以免与系统定义的消息冲突:#define WM_MYMESSAGE (WM_USER+100) 
在类的定义(XX.h)中声明消息响应函数:afx_msg LRESULT mymessagefunction(WPARAM wParam, LPARAM lParam); 
添加消息映射,也就是将消息和消息要消息的函数之间的映射关系对应起来 
在XX.cpp中用ON_MESSAGE宏指令将消息映射到消息响应函数中. 
BEGIN_MESSAGE_MAP(rightview, CView) 
    //{{AFX_MSG_MAP(rightview) 
    ON_MESSAGE(WM_MYMESSAGE,mymessagefunction) 
    //}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
在XX.CPP中实现消息响应函数即可 
XX::mymessagefunction(WPARAM wParam, LPARAM lParam) 

      ............... 

一般POST方式用B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam); 
发送方式用LRESULT SendMessage( 
    HWND hWnd, // 目标窗口句柄 
    UINT Msg, // 被发送的消息 
    WPARAM wParam, // 第一个消息参数 
    LPARAM lParam // 第二个消息参数 
    ); 
两种方式参数一样;PostMessage()不等消息处理完毕就返回,SendMessage()必须等消息处理完毕才返回。 
而得到某或是对话框的句柄. 
(1)得到一个窗口(如分窗口)的句柄: 
    CSplitterWnd m_wndSplitter;//这是分窗时用的 
    CMainFrame *pMain = (CMainFrame *)AfxGetMainWnd(); 
    CWnd *pwnd = pMain->m_wndSplitter.GetPane(0, 1);//得到窗口口1行2列的句柄 
    pwnd->PostMessage(WM_MYMESSAGE, 0, 0); 
(2)得到对话框句柄 
CWnd* pWnd = GetDlgItem(对话框ID号);

2.消息映射的工作原理

前面给出了消息映射的一般形式,下面就对消息映射的工作原理做更深入的分析。任何使用了MFC应用程序框架的Windows程序都含有一个从 CWinApp派生的应用程序类对象,成员函数Run()将被隐含调用,其调用的CWinThread类成员函数 Run()将通过对GetMessage()、TranslateMessage()和DispatchMessage()等函数的调用完成同 WinMain()类似的消息循环。在消息处理中,几乎所有的窗口对象都使用AfxWndProc()窗口处理函数,并通过一个包含了窗口句柄和对象指针等信息的列表而获取到一个指向对象的指针,由此可以调用CWnd的虚函数WindowProc()。WindowProc()函数调用了CWnd的另一个成员函数OnWndMsg(),该函数首先检查到达的究竟是消息,命令还是通知(Notify),如果是消息就通过消息映射宏 DECLARE_MESSAGE_MAP,BEGIN_MESSAGE_MAP和END_MESSAGE_MAP 完成对消息的映射。在宏定义中封装了部分代码,这些被封装的预定义代码可以在VC安装目录下的"/MFC/Include/Afxwin.h"中找到,在编译时将为编译器所展开。 
搜寻过程是从CMainWindow的消息入口开始的,DECLARE_MESSAGE_MAP,BEGIN_MESSAGE_MAP和 END_MESSAGE_MAP等消息映射宏通过搜索派生类消息映射的函数允许访问积累消息映射的入口。如果由CFrameWnd类派生的类 CMainWindow没有捕获通常由CFrameWnd捕获的消息,那么消息将由相同的由派生类所继承的CFrameWnd类函数捕获。同样,如果 CFrameWnd类仍没有捕获通常由其父类CWnd捕获的消息,则将继续上溯下去。这种消息映射的继承性与C++的继承是一致的。 
另外,消息映射函数入口可以在在消息到达时为那些被隐含消息循环所调用的函数从中查看,并决定哪一个对象以及对象中的哪一个成员函数应该负责此消息的处理。虽然消息映射的内部工作原理比较复杂,但MFC通过预定义宏等手段将其完整的封装了起来,展现给开发人员的只是简单明了的MFC消息映射。

3.命令和通知

命令和通知实际都是一种特殊的消息类型。在SDK编程中,菜单和控件的动作均会产生一个WM_COMMAND命令消息,通过对消息参数wParam的区分可以识别出具体是哪个控件或菜单发出的命令。在MFC应用程序框架下,菜单和控件产生的消息将有所区分,选取菜单产生的消息被称作命令,而点击控件所产生的消息则被称作通知。由于命令和通知的本质仍是一种消息,因此在基本原理上仍是同消息一致的,即也是通过消息循环进入OnWndMsg()进而为对应的处理函数所响应。但是在使用上,命令和消息还是有区别的,其中一个最主要的区别是消息只有CWnd类的派生类所接收,而命令和通知则可以为所有从 CCmdTarget派生出去的类对象所接收,从MFC类的继承关系可以看出,除CWnd外CWinThread、CDocument和CDocItem 等也都可以接收命令和通知。除此之外,命令和通知在从消息循环进入到 OnWndMsg()后的这段过程也是同消息传递略有出入的 
这里CWnd::OnCommand()在检查完各项细节后、CWnd::OnNotify()在检查完不同条件后都调用了虚函数 OnCmdMsg()。这样,对于不同的菜单项和控件就可以有不同的实现。从下面给出的命令传递过程示例代码可以看出命令/通知的传递与消息的映射是非常类似的: 

// 头文件.h文件
//{{AFX_MSG(CDIP_SystemView)
    afx_msg void OnEmboss();
    afx_msg void OnUpdateEmboss(CCmdUI* pCmdUI);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
……
// 源文件.cpp文件
BEGIN_MESSAGE_MAP(CDIP_SystemView, CScrollView)
/{
    {AFX_MSG_MAP(CDIP_SystemView)
    ON_COMMAND(IDM_EMBOSS, OnEmboss)
    ON_UPDATE_COMMAND_UI(IDM_EMBOSS, OnUpdateEmboss)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
……
void CDIP_SystemView::OnEmboss ()
{
    return;
}
……
void CDIP_SystemView::OnUpdateStartPos(CCmdUI* pCmdUI)
{
    pCmdUI->Enable(m_bCanUse);
}

这里ON_COMMAND宏将特定命令的处理同一个类成员函数建立了关联。而宏ON_UPDATE_COMMAND_UI则负责对命令的更新,即通过 CCmdUI对象控制菜单/控件的是否可用或其他一些状态变化的更新。对命令的更新也可以将其理解为存在一个含有每个菜单入口的大表,各菜单入口含有菜单是否可用的标志。在显示菜单时通过快速检查该表而做出其所对应的每一个菜单项是否可用的决定。如果可用标志发生了变化,该表也将得到及时的更新。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值