1.牢骚发在最前面
三件事情杂糅到了一起弄得我彻夜未眠。
香港大学的Offer不小心丢在了垃圾邮箱里,却阴差阳错的来了清华。平台是一方面,当时谈好的港府奖学金也就此泡汤,这笔钱是我急需的。
惊闻噩耗,苏畅老师逝世,年仅33岁,不知道是生命奉献了科研还是科研磨灭掉了生命。
张礼,读懂你,很难!
2.文档视图体系结构中的命令传送
文档/视图体系结构中最引人注目的特性是应用程序几乎可以在任何地方处理命令的消息。“命令消息”其实是MFC中的术语,质的就是WM_COMMAND消息,当选择了菜单项、键盘加速键被按下或工具栏被单击时产生此消息。框架窗口实际上是大多数命令消息的接收者,但命令消息可以在视图类、文档类、甚至应用程序中被处理,只要在该类的消息的接受中对想要处理的消息添加输入即可。命令传送使得我们可以将命令处理程序放在最合适的地方,避免把他们堆砌在框架窗口类中。对于菜单项、工具栏按钮以及其他用户界面对象的更新命令也遵循命令传送机制,因此也可以把ON_UPDATE_COMMAN_Ui处理程序放在非框架窗口中。
命令传送机制根植在MFC深层内部。当框架窗口接收到WM_COMMAND消息时,会调用所有CCmdTarget派生类特有的虚拟OnComMsg函数来开始传送过程。
CFrameWnd中OnCmdMsg的实现如下:
BOOL <span style="font-size:18px;">CFrameWnd</span>::OnCmdMsg(...) { CView* pView = GetActiveView(); if (pView != NULL && pView->OnCmdMsg(...)) return TRUE; if (CWnd::OnCmdMsg(...)) return TRUE; CWinApp* pApp = AfxGetApp(); if (pApp != NULL && pApp->OnCmdMsg()) return TRUE; return FALSE; }CFrameWnd::OnCmdMsg(...)首先调用视图的pView->OnCmdMsg(...)函数,将消息传送给活动视图。如果pView->OnCmdMsg(...)返回值为0,说明视图没有处理消息(也就是说视图消息映射表中没有包含这个特殊消息的输入项),框架窗口就会亲自调用CWnd:: OnCmdMsg(...)来处理消息。如果这样也不行,框架窗口就会让应用程序对象去处理。最终如果没有对象可以处理这个消息,CFrameWnd::OnCmdMsg(...)就会返回FALSE,主结构将消息传送给::DefWindowProc进行默认处理。这就是我们多次强调的框架窗口获得的命令消息被传送给活动视图和应用程序对象。
但是,我们不仅会去问,这和文档对象有什么关系呢?这就涉及到了所有提交给SDI框架窗口的命令消息所经历的路径,具体如下图所示:
活动视图首先处理消息,接着是与视图关联的文档、文档模板、框架窗口,最后是应用程序对象。
3.预定义的命令ID和命令处理程序
在编写文档/视图应用程序时,通常不用为所有的菜单命令亲自编写处理程序。MFC提供了很多的默认处理程序,此外主结构还提供了多种菜单项命令ID,其中许多已经预先添加到使用它们的来的消息映射表中了。
下表列出了最常用的预定义命令ID和他们相关的命令处理程序:
4.开始实战吧!
通过回顾性的复习视图/文档结构,已经完全具备开发相关的应用程序了,加油!