深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:命令传递) .
命令传递(Command routing)
消息如果是仅仅从派生类流向父类,那就非常简单了。然而MFC用来处理消息的C++类,并不是单线发展的。document/view也具有处理消息的能力。因此,消息应该有横向流动的机会。
MFC对消息循环的规定为:
1:若是一般的windows消息(WM_xx)则一定是由派生类流向基类。
2:如果是WM_COMMAND消息,就非常复杂了。要区分接受者的类型:
1:接受者若为Frame窗口:处理次序为:View-> Frame窗口本身->CWinApp类。
2:接受者若为View :处理次序为:View本身->Document;
3:接受者若为Document:处理次序为:Document本身->Document template
因此,接下来我们的任务就是仿真以上的消息传递路线。
以下为需要添加的函数:
全局函数AfxWndProc,它是整个消息循环的起始点,本来应该在CWinThread::Run中被调用,每调用一次就推送一个消息。模拟windows的disPatch函数。
LRESULT AfxWndPro(HWND hWnd,UINT nMsg,WPARAM
wParam,LPARAM lParam,CWnd *pWnd)
{
cout<<"AfxWndProc()"<<endl;
return AfxCallWndProc (pWnd,hWnd,nMsg,wParam,lParam);
}
LRESULT AfxCallWndProc(CWnd*pWnd,HWND hWnd,UINT nMsg,
WPARAM wParam,LPARAM lParam)
{
cout<<"AfxCallWndProc"<<endl;
LRESULT lResult=pWnd->windowProc(nMsg,wParam,lParam);
return lResult;
}
全局函数AfxCallWndProc用于调用接受消息的类的消息处理函数。pWnd->WindowProc调用哪个函数,取决于pWnd指向的对象类型。
如果pWnd指向CMyFrameWnd对象,则调用CFrameWnd::WindowProc。因为CFrameWnd斌没有改写WindowProc,因此调用的是CWnd::WindowProc。。
如果pWnd指向CMyView对象,那么调用CView::windowProc。而CMyView没有改写WIndowProc所以调用的是CWnd::WindowProc。
在CWnd::windowProc中,首先判断消息是否为WM_COMMAND消息,
如不是,则传递给父类进行处理。
如果是WM_COMMAND消息,CWnd::windowProc调用OnCommand。此函数为虚函数。有以下几种情况:
1:如果this指向CMyFrameWnd对象,则调用的是CFrameWnd::OnComamnd。
2:如果this指向CMyView对象,那么调用的是CView::OnCommand。因为CView并没有改写OnComamnd所以调用的是CWnd::OnCommand。
bool CFrameWnd::OnComamnd(WPARAM wParam,LPARAM lParam)
{
cout<<"CFrameWnd::OnCommand()"<<endl;
return CWnd::OnCommand(wParam,lParam);
}
bool CWnd::OnComamnd(WPARAM wParam,LPARAM lParam)
{
cout<<"CWnd::OnComamnd()"<<endl;
return OnCmdMsg(0,0);
}
OnCmdMsg仍然是虚函数,
1:如果this指向CMyFrameWnd对象,那么调用的是CFrameWnd::OnCmdMsg。
2:如果this指向CMyView对象,则调用CView::OnCmdMsg。
3:如果this指向CMyDoc对象,则调用CDocument::OnCmdMsg。
4:如果this指向CM与WinApp对象,则调用CWinApp:: nCmdMsg。因为CWinApp没有改写OnCmdMsg因此调用的是CCmdTarget::OnCmdMsg。
Bool CFrameWnd::OnCmdMsg(UINT nID,int nCode)
{
cout<<"CFrameWnd::OnCmdMsg()"<<endl;
CView*pView=GetActiveView();
if(pView->OnCmdMsg(nID,nCode))//处理则返回否则继续传递。
return true;
if(CWnd::OnCmdMsg(nID,nCode))
return true;
CWinApp*pApp=AfxGetApp();
if(pApp->OnCmdMsg(nID,nCode)
return true;
return fasle;
}
bool CView::OnCmdMsg(UINT nID,int nCode)
{
cout<<"CView::OnCmdMsg()"<<endl;
if(CWnd::OnCmdMsg(nID,nCode))
return true;
bool bHandled=false;
bHandled=m_pDocument->OnCmdMsg(nID,nCode);
return bHandled;
}
Bool CDocument::OnCmdMsg(UINT nID,int nCode)
{
cout<<"CDocument::OnCmdMsg()"<<endl;
if(CCmdTarget::OnCmdMsg(nID,nCode))
return true;
return false;
}
真正的消息传递路径是从OnCmdMsg开始的。在每个类的OnCmdMsg函数中,会调用其他类的OnCmdMsg函数,从而决定每个消息的传递路径。
如果消息在前一个OnCmdMsg中被处理,就不会继续传递。如果没有被处理,则会继续沿着路径传递下去。无论如何,最终消息的比对是在CCmdTarget类中进行的,只是调用GetMessageMap的this指针不同,会决定调用哪个类的消息映射表。理解这一点很重要!!!
bool CCmdTarget::OnCmdMsg(UINT nID,int nCode)
{
cout<<"CCmdTarget::OnCmdMsg()"<<endl;
for(pMessageMap=GetMessageMap();pMessageMap;
pMessageMap=pMessageMap->pBaseMessageMap()
{
If(找到)
//执行消息处理函数。
}
}
深入浅出MFC学习笔记(第三章:MFC六大关键技术之仿真:命令传递) .相关推荐
- 《Go语言圣经》学习笔记 第三章 基础数据类型
<Go语言圣经>学习笔记 第三章 基础数据类型 目录 整型 浮点数 复数 布尔型 字符串 常量 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记, ...
- 机器人导论(第四版)学习笔记——第三章
机器人导论(第四版)学习笔记--第三章 3 操作臂运动学 3.1 引言 3.2 连杆的描述 3.3 连杆连接的描述 3.4 连杆坐标系的定义 3.5 操作臂运动学 3.6 驱动空间.关节空间和笛卡尔空 ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第三章:简单控件
第 3 章 简单控件 本章介绍了App开发常见的几类简单控件的用法,主要包括:显示文字的文本视图.容纳视图的常用布局.响应点击的按钮控件.显示图片的图像视图等.然后结合本章所学的知识,演示了一个实战项 ...
- Win32学习笔记 第三章 HelloWin 选择自 villager 的 Blog
Win32学习笔记 作者: 姜学哲(netsail0@163.net) 教材: Windows程序设计(第五版)北京大学出版社 [美]Charles Petzold 著 北京博彦科技发展有限公司 ...
- ros2 Navigation 学习笔记 第三章(the construct 网站)
第三章 如何在环境中给机器人定位 序言 本章包括: 机器人定位的意义(即需要知道它对于环境中的位置和方向) 如何在ROS2中用AMCL定位 如何设置机器人的初始位置(手动.自动与使用ROS API) ...
- 信号与系统学习笔记 第三章
第三章 周期信号的傅里叶级数表示 下面将讨论信号与线性时不变系统的另一种表示,讨论的出发点仍是将信号表示成一组基本信号的线性组合.这是因为,将信号表示成基本信号的线性组合是有利的,如果基本信号具有一下 ...
- 仿生学导论学习笔记——第三章
第三章 仿生学基本要素 3.1 仿生需求 3.1.1 需求驱动 3.1.1.1 生存需求 3.1.1.2 健康需求 3.1.1.3 军事需求 3.1.1.4 发展需求 3.1.1.5 精神需求 3.1 ...
- 计算机网络学习笔记——第三章:数据链路层
目录 第三章:数据链路层 3.1 数据链路层功能概述 3.2 封装成帧和透明传输 3.3 差错控制 3.3.1 检错编码 3.3.2 纠错编码 3.4 流量控制与可靠传输机制 3.4.1 流量控制.可 ...
- JavaScript高级程序设计红宝书学习笔记第三章基本概念
第三章 基本概念 本章内容 语法 数据类型 操作符 语句 函数 3.1 语法 3.1.1 区分大小写,ECMAScript中的一切(变量.函数名和操作符)都区分大小写. 3.1.2 标识符 标识符:变 ...
- [吴功宜]计算机网络学习笔记--第三章 数据链路层
教材:计算机网络(第四版) 作者:吴功宜 吴英 出版社:清华大学 第三章 数据链路层 3.1 差错产生的原因与差错控制方法 物理线路:由传输介质与通信设备组成 设计数据链路层的主要目的:在有差错的物理 ...
最新文章
- 南昌计算机专业好的专科,2021年南昌计算机专业学校好不好
- ZVM – 记VMP保护代码还原工程
- 我用着不舒服的东西, 就TM是不合理的东西!!!
- 棍子节快乐~ 顺便转一篇weka源码分析解析~【转自weka中文网】
- linux笔记_20150825_linux下的软件工具唠叨下
- 如何将markdown转换为wxml
- 对今天下午的工作内容的反思
- 今晚直播丨Oracle数据库SQL执行计划的取得和解析
- java做法_Java方法
- 黑莓 QNX 被曝严重的 BadAlloc 漏洞 影响数百万汽车和医疗设备
- edittext禁止换行符但能自动换行简书_利用 subfinder 让群辉 NAS 实现自动下载字幕...
- 你不知道的Bitmap
- 生成指定范围的随机数_JAVA 获取随机数的方式以及应用案例
- SC;FC;LC;光纤接口介绍
- html三角形下拉列表,select自定义小三角样式代码(实用总结)
- 2 errors and 0 warnings potentially fixable with the `--fix` option,vue-cli3中eslint详解(转载)
- C++ OJ习题练习(九)定义哺乳动物类Mammal和Dog类
- systemd服务详解
- Golang 字符串拼接
- 华硕z170-p+英特尔i7-6700k+16GB黑苹果EFI引导文件