友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

深入浅出MFC第2版(PDF格式)-第14部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


       return (FALSE); // FALSE 表示我没有处理这个消息 

     } 



                           图  1…4    对话框的诞生、运作、结束 



                                                                                                                   23 


…………………………………………………………Page 86……………………………………………………………

模块定义文件 (                 ) 

                   。DEF 



    Windows 程序需要一个模块定义文件,将模块名称、程序节区和资料节区的内存特性、 



             heap            stack          callback      。。。 

    模块堆积(        )大小、堆栈(         )大小、所有            函数名称 等等登记下来。下 



    面是个实例: 



        NAME         Generic 



        DESCRIPTION  'Generic Sample' 



        EXETYPE      WINDOWS 



        STUB        'WINSTUB。EXE' 



        CODE        PRELOAD DISCARDABLE 



        DATA        PRELOAD MOVEABLE MULTIPLE 



        HEAPSIZE    4096 



        STACKSIZE   10240 



        EXPORTS 



                    MainWndProc @1 



                    AboutBox @2 



    在Visual C++ 整合环境中开发程序,不再需要特别准备。DEF 文件,因为模块定义文件中的 



    设定都有默认值。模块定义文件中的STUB 指令用来指定所谓的stub 程序(埋在Windows 



    程序中的一个DOS 程序,你所看到的This Program Requires Microsoft Windows 或This 



    Program Can Not Run in DOS mode 就是此程序发出来的),Win16 允许程序员自设一个 



    stub 程序,但Win32 不允许,换句话说在Win32 之中Stub 指令已经失效。 



资源描述档 (              ) 

                。RC 



    RC 文件是一个以文字描述资源的地方。常用的资源有九项之多,分别是ICON 、CURSOR 、 



    BITMAP 、FONT、DIALOG、MENU 、ACCELERATOR 、STRING、VERSIONINFO 。还 



    可能有新的资源不断加入,例如Visual C++ 4。0 就多了一种名为TOOLBAR  的资源。这 



    些文字描述需经过RC 编译器,才产生可使用的二进制代码。本例Generic 示范ICON 、 



    MENU 和DIALOG 三种资源。 



                                                                               24 


…………………………………………………………Page 87……………………………………………………………

Windows 程序的生与死 



     我想你已经了解Windows 程序的架构以及它与Windows 系统之间的关系。对 



     Windows 消息种类以及发生时机的透彻了解,正是程序设计的关键。现在我以窗口的诞 



     生和死亡,说明消息的发生与传递,以及应用程序的兴起与结束,请看图1…5 及图1…6。 



                                                      WinMain(hInst; hPrev; 。。。) 

                                                      { 

                                                      MSG  msg; 

                                                      RegisterClass(。。。); 

                                                                                        WM_CREATE 

                                                      CreateWindow(。。。); 

                                                      ShowWindow(。。。); 

          Message queue 

                                                      UpdateWindow(。。。); 

                                     2                while(GetMessage(&msg。。。)) {        1 

                                                          TranslateMessage(。。。); 

                                                          DispatchMessage(。。。); 

                                                      } 

                                                                                           USER 

                                                      return msg。wParam; 

                                                                                           Module 

                                          WndProc(hwnd; msg; wParam; lParam)        3 

                                          { 

                                          switch (msg) { 

                                              case            : 。。。 

                                                    WM_CREATE   

                      8                       case WM_MAND: 。。。 

       WM_CLOSE 

                                              case WM_LBUTTONDOWN: 。。。 

                      WM_QUIT 

     5                                        case WM_PAINT: 。。。 

                                              case WM_MOUSEMOVE: 。。。 

                                              case WM_DESTROY : 。。。 

                                                   PostQuitMessage(0);  7 

                                                   break; 

                                              default: return DefWindowProc (。。。); 

                             WM_DESTROY  } 



                                          return(0); 

                                                             case WM_CLOSE : 

                                          }             6     case WM_CLOSE : 

                                                                  DestroyWindow(。。。); 

                                                                   DestroyWindow(。。。); 



                                                              (in DefWindowProc) 



                  图  1…5    窗口的生命周期(详细说明请看图  1…6 ) 



                                                                                                 25 


…………………………………………………………Page 88……………………………………………………………

  1。 程序初始化过程中调用Create Window ,为程序建立了一个窗口,做为程序的萤 



           Create Window                 WM  CREA TE  

                                            _ 

    幕舞台。               产生窗口之后会送出                    直接给窗口函数, 



    后者于是可以在此时机做些初始化动作(例如配置内存、开文件、读初始资 



      。。。 

    料  )。 



 2。 程序活着的过程中,不断以GetMessage 从消息贮列中抓取消息。如果这个消 



        WM  QUIT  GetMessage             while  

           _                      0  

    息是          ,           会传回  而结束         循环,进而结束整个程序。 



 3。 Dispat chMessage 透过Windows USER 模块的协助与监督,把消息分派至窗口 



    函数。消息将在该处被判别并处理。 



 4。 程序不断进行2。 和3。  的动作。 



                                               WM  CLOSE 

 5。  当使用者按下系统菜单中的Close 命令项,系统送出                   _      。通常程序 



                              Def WindowProc  

    的窗口函数不栏截此消息,于是                         处理它。 



   Def WindowProc    WM  CLOSE          Destroy Window  

                        _ 

                 收到            后, 调用                 把窗口清除。 

 6。                                  



   Destroy Window           WM DESTROY 

                               _ 

                本身又会送出                  。 



         WM DESTROY                  PostQuitMessage 

            _ 

 7。 程序对               的标准反应是调用                     。 



   PostQuitMessage                       WM  QUIT  

                                            _ 

 8。               没什么其它动作,就只送出                    消息,准备让消息循 



   环中的GetMessage 取得,如步骤 ,结束消息循环。 

                               2 



                   图1…6 窗口的生命周期 ( 请对照图1…5) 



为什么结束一个程序复杂如斯?因为操作系统与应用程序职司不同,二者是互相合作的 



关系,所以必需各做各的份内事,并互以消息通知对方。如果不依据这个游戏规则,可 



能就会有麻烦产生。你可以作一个小实验,在窗口函数中拦截WM_DESTROY,但不调 



'O~APostQuitMessage 。你会发现当选择系统菜单中的Close  时,屏幕上这个窗口消失了, 



                              Def WindowProc    Destroy Window  

 (因为窗口摧毁及数据结构的释放是                           调用               完成的),但 



是应用程序本身并没有结束(因为消息循环结束不了),它还留存在内存中。 



                                                                             26 


…………………………………………………………Page 89……………………………………………………………

空闲时间的处理 : 

                         OnIdle 



    所谓空闲时间(idle time ),是指「系统中没有任何消息等待处理」的时间。举个例子, 



    没有任何程序使用定时器(timer ,它会定时送来WM_TIMER ),使用者也没有碰触键盘 



    和鼠标或任何外围,那么,系统就处于所谓的空闲时间。 



                                                 WM MO USEMO VE 

                                                   _ 

    空闲时间常常发生。不要认为你移动鼠标时产生一大堆的                                  ,事实上夹 



             WM MO USEMO VE  

                _ 

    杂在每一个                   之间就可能存在许多空闲时间。毕竟,计算机速度超乎想 



    像。 



    背景工作最适宜在空闲时间完成。传统的SDK 程序如果要处理空闲时间,可以以下列 



    循环取代WinMain  中传统的消息循环: 



      while  (TRUE) { 



        if  (PeekMessage (&msg; NULL; 0; 0; PM_REMOVE) { 



            if  (msg。message == WM_QUIT) 



                break; 



            TranslateMessage (&msg); 



            DispatchMessage (&msg); 



        } 



        else { 



          OnIdle (); 



        } 



      } 



    原因是PeekMessage 和GetMessage  的性质不同。它们都是到消息队列中抓消息,如果 



    抓不到,程序的主执行线程(primary thread,是一个UI 执行线程)会被操作系统虚悬住。 



    当操作系统再次回来照顾此一执行线程,而发现消息队列中仍然是空的,这时候两个API 



    函数的行为就有不同了: 



   ■GetMessage  

              会过门不入,于是操作系统再去照顾其它人。 



     PeekMessage  

               会取回控制权,使程序得以执行一段时间。于是上述消息循环进 

   ■ 



      入OnIdle  函数中。 



           HelloMFC           MFC               idle time p。403 

    第6章的           将示范如何在         程序中处理所谓的             (    )。 



                                                                             27 


…………………………………………………………Page 90……………………………………………………………

Console 程序 



    说到Windows 程序,一定得有WinMain 、消息循环、窗口函数。即使你只产生一个对 



         Dialog Box        Message Box          Windows API DialogBox  

    话窗(          )或消息窗(             ),也有隐藏在               (        和 



    MessageBox )内里的消息循环和窗口函数。 



                     C/C++             main  pr intf   

    过去那种单单纯纯纯的            程序,有着简单的         和     的好时光到哪里去 



    了?夏天在阴凉的树荫下嬉戏,冬天在温暖的炉火边看书,啊,Where did the good times 



    go ? 



    其实说到Win32 程序,并不是每个都如Windows GUI 程序那么复杂可怖。是的,你可 



       Visual C++     〃DOS…like〃  

    以在          中写一个          程序,而且仍然可以调用部份的、不牵扯到图形 



              GUI   Win32 API           console               console 

    使用者接口(       )的         。这种程序称为          程序。甚至你还可以在 



    程序中使用部份的MFC 类别(同样必须是与GUI 没有关连的),例如处理数组、串 



                collection classes CArray CList CMap       CFile 

    行等数据结构的                 (     、     、 
返回目录 上一页 下一页 回到顶部 0 0
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!