友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

深入浅出MFC第2版(PDF格式)-第140章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!






          00000066                   第二个圆形的中心点Y 坐标 



          00000077                   第二个圆形的半径 



          图8…10b TEST。SCB 文件内容剖析。别忘了Intel 采用〃little…endian〃 位 

                  组排列方式,每一字组的前后字节系颠倒放置。本图已将之摆正。 



Document 与View 交流为Step4 做准备 



        虽然Scribble Step1  已经可以正常工作,有些地方仍值得改进。 



        在一个子窗口上作画,然后选按【Window/New Window 】,会蹦出一个新的子窗口,内 



        有第一个子窗口的图形,同时,第一个子窗口的标题加上:1 字样,第二个子窗口的标 



        题则有:2 字样。这是Document/View 架构带给我们的礼物,换句话说,想以多个窗口 



        观察同一份资料,程序员不必负担什么任务。但是,如果此后使用者在其中一个子窗口 



        上作画而不缩放窗口尺寸的话(也就是没有产生WM_PAINT),另一个子窗口内看不到 



        新的绘图内容: 



                                                                                     543 


…………………………………………………………Page 606……………………………………………………………

               第篇    深入  MFC  程式設計 



                 这不是好现象!一体的两面怎么可以不一致呢?! 



                 那么,让「作用中的View 窗口」以消息通知隶属同一份Document  的其它「兄弟窗口」, 



                 是不是就可以解决这个问题?是的,而且Framework  已经把这样的机制埋伏下去了。 



                 CView 之中的三个虚拟函数: 



                CView::OnInitialUpdate 负责View  的初始化。 



                CView::OnUpdate 当Framework 调用此函数,表示Document  的内容已有变化。 



                CView::OnDraw Framework 将在WM_PAINT 发生后,调用此函数。此函数应 



                 负责更新View 窗口的内容。 



                 这些函数往往成为程序员改写的目标。Scribble 第一版就是因为只改写了其中的OnDraw 



                 函数,所以才有「多个View 窗口不能同步更新」的缺失。想要改善这项缺失,我们必 



                 须改写OnUpdate。 



                 让所有的View 窗口「同步」更新资料的关键在于两个函数: 



                CDocument::UpdateAllViews 如果这个函数执行起来,它会巡访所有隶属同一 



                 Document  的各个Views ,找到一个就通知一个,而所谓「通知」就是调用View 



                 的OnUpdate 函数。 



544 


…………………………………………………………Page 607……………………………………………………………

                                          第8章    Document…View  深入探討 



  CView::OnUpdate 这是一个虚拟函数,我们可以改写它,在其中设计绘图动作, 



  也许全部重绘(这比较笨一点),也许想办法只绘必要的一小部份(这样速度 



  比较快,但设计上比较复杂些)。 



 因此,当一个Document  的资料改变时,我们应该设法调用其UpdateAllViews,通知所 



 有的Views 。什么时候Scribble 的资料会改变?答案是鼠标左键按下时! 所以你可能猜 



 测到,我打算在CView::OnLButtonDown  内调用CDocument::UpdateAllViews。这个猜测 



 的立论点是对的而结果是错的,Scribble Step4 的作法是在CView::OnButtonUp  内部调用 



 它。 



 CView::OnUpdate 被调用,代表着View 被告知:「嘿,Document  的内容已经改变了, 



 请你准备修改你的显示画面」。如果你想节省力气,利用Invalidate(TRUE) 把窗口整个 



 设为重绘区(无效区)并产生WM_PAINT,再让CView::OnDraw 去伤脑筋算了。但是 



 全部重绘的效率低落,程序看起来很笨拙,Step4 将有比较精致的作法。 



                          Document 



                           。       



              View:1       View:2      View:3 



      o1 使用者在View:1 做动作(View 扮演使用者接口的第一线)。 



      o2 View:1 调用GetDocument ,取得Document  指针,更改资料内容。 



      o3 View:1 调用Document  的UpdateAllViews 



      o4 View:2 和View:3  的OnUpdate 一一被调用起来,这是更新画面的时机。 



           图8…11 假设一份Document 联结了三个Views 



注意:在MFC 手册或其它书籍中,你可能会看到像「View1  以消息通知Document 」 



或「Document  以消息通知View2、View3 」的说法。这里所谓的「消息」是对象导向学 



术界的术语,不要和Windows  的消息混淆了。事实上整个过程中并没有任何一个Windows 



消息参与其中。 



                                                                      545 


…………………………………………………………Page 608……………………………………………………………

                第篇    深入  MFC  程式設計 



546 


…………………………………………………………Page 609……………………………………………………………

   第9章   



              消息映射与命令绕行 



     Message Mapping and mand Routing 



             消息映射机制与命令绕行,活像是米诺托斯的迷宫, 



                   是MFC 最曲折幽深的神秘地带。 



   你已经从前一章中彻底了解了MFC 程序极端重要的Document/View 架构。本章的重点 



   有两个,第一个是修改程序的人机接口,增添菜单项目和工具栏按钮。这一部份藉Visual 



   C++ 工具之助,非常简单,但是我们往往不知道该在程序的什么地方(哪一个类别之中) 



   处理来自菜单和工具栏的消息(也就是WM_MAND 消息)。本章第二个重点就是 



   要解决这个迷惑,我将对所谓的消息映射(Message Map )和命令绕行(mand Routing) 



   机制做深入的讨论。这两个机制宛如MFC 最曲折幽深的神秘地带,是把杂乱无章的 



   Windows API  函数和Windows 消息对象导向化的大功臣。 



到底要解决什么 



   Windows 程序的本质系借着消息来维持脉动。每一个消息都有一个代码,并以WM_ 开 



   头的常数表示之。消息在传统SDK 程序方法中的流动以及处置方式,在第1章已经交 



   待得很清楚。 



   各种消息之中,来自菜单或工具栏者,都以WM_MAND 表示,所以这一类消息我 



   们又称之为命令消息(mand Message ),其wParam 记录着此一消息来自哪一个菜单 



   项目。 



                                                        547 


…………………………………………………………Page 610……………………………………………………………

                   第篇    深入  MFC  程式設計 



                   除了命令消息,还有一种消息也比较特殊,出现在对话框函数中,是控制组件(controls ) 



                   传送给父窗口(即对话框)的消息。虽然它们也是以WM_MAND 为外衣,但特别 



                   归类为「notification 消息」。 



                   注意:Windows 95 新的控制组件(所谓的mon controls )不再传送WM_MAND 



                   消息给对话框,而是送WM_NOTIFY 。这样就不会纠缠不清了。但为了回溯兼容,旧有 



                   的控制组件(如edit 、list box、bo box。。。 )都还是传送WM_MAND。 



                   消息会循着Application Framework 规定的路线,游走于各个对象之间,直到找到它的依 



                   归(消息处理函数)。找不到的话,Framework 最终就把它交给::DefWindowProc 函数 



                   去处理。 



                   但愿你记忆犹新,第6章曾经挖掘MFC 源代码,得知MFC 在为我们产生窗口之前, 



                   如果我所指定的窗口类别是NULL ,MFC 会自动先注册一个适当的窗口类别。这个类别 



                   在动态联结、除错版、非Unicode 环境的情况下,可能是下列五种窗口类别之一: 



                      〃AfxWnd42d〃 



                      〃AfxControlBar42d〃 



                      〃AfxMDIFrame42d〃 



                      〃AfxFrameOrView42d〃 



                      ! AfxOleControl42d!§ ¨ 



                   每一个窗口类别有它自己的窗口函数。根据SDK 的基础,我们推想,不同窗口所获得 



                   的消息,应该由不同的窗口函数来处理。如果都没有能够处理,最后再交由Windows API 



                   函数::DefWindowProc 处理。 



                   这是很直觉的想法,而且对于一般消息(如WM_MOVE 、WM_SIZE、WM_CREATE 等) 



                   也是天经地义的。但是今天Application Framework  比传统的SDK 程序多出了一个 



                   Document/View 架构,试想,如果菜单上有个命令项关乎文件的处理,那么让这个命令 



548 


…………………………………………………………Page 611……………………………………………………………

                                        第9章   訊息映射與命令繞行   



  消息流到Document 类别去不是最理想吗?一旦流入Document 大本营,我们(程序员) 



  就可以很方便地取得Document 成员变量、调用Document 成员函数,做爱做的事。 



  但是Document 不是窗口,也没有对应的窗口类别,怎么让消息能够七拐八弯地流往 



  Document 类别去?甚至更往上流向Application 类别去?这就是所谓的命令绕行机制! 



  而为了让消息的流动有线路可循,MFC 必须做出一个巨大的网,实现所有可能的路线, 



  这个网就是所谓的消息映射地图(Message map 
返回目录 上一页 下一页 回到顶部 0 1
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!