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

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

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





      息以及消息处理例程的关联性建立起来: 



      // 消息与处理例程之对照表格 



          struct MSGMAP_ENTRY _messageEntries'' = 



          { 



              WM_CREATE; OnCreate; 



              WM_PAINT; OnPaint; 



              WM_SIZE; OnSize; 



              WM_MAND; Onmand; 



              WM_SETFOCUS; OnSetFocus; 



              WM_CLOSE; OnClose; 



              WM_DESTROY; OnDestroy; 



          } ;      ↑         ↑ 



                这是消息    这是消息处理例程 



                                                                                20 


…………………………………………………………Page 83……………………………………………………………

     // mand…ID  

                    与处理例程之对照表格 

    struct MSGMAP_ENTRY _mandEntries = 

    { 

        IDM_ABOUT;      OnAbout; 

        IDM_FILEOPEN;   OnFileOpen; 

        IDM_SAVEAS;     OnSaveAs; 

    } ;    ↑                ↑ 

     这是WM_MAND 命令项这是命令处理例程 



 于是窗口函数可以这么设计: 



//………………………………………………………………………………………………………………………………………………………………………………………

// 窗口函数 

//………………………………………………………………………………………………………………………………………………………………………………………

LRESULT CALLBACK WndProc(HWND hWnd;     UINT message; 

                             WPARAM wParam; LPARAM lParam) 

{ 

int i; 



  for(i=0; i 《 dim(_messageEntries); i++) {  //  

                                                   消息对照表 

      if (message == _messageEntries'i'。nMessage) 

          return((*_messageEntries'i'。pfn)(hWnd; message; wParam; lParam)); 

  } 

  return(DefWindowProc(hWnd; message; wParam; lParam)); 

} 

//………………………………………………………………………………………………………………………………………………………………………………………

// Onmand … 

                专门处理 WM_MAND 

//………………………………………………………………………………………………………………………………………………………………………………………

LONG Onmand(HWND hWnd; UINT message; 

                  WPARAM wParam; LPARAM lParam) 

{ 

int i; 



  for(i=0; i 《 dim(_mandEntries); i++) {  //  

                                                   命令项目对照表 

      if (LOWORD(wParam) == _mandEntries'i'。nMessage) 

          return((*_mandEntries'i'。pfn)(hWnd; message; wParam; lParam)); 

  } 

  return(DefWindowProc(hWnd; message; wParam; lParam)); 

} 

//………………………………………………………………………………………………………………………………………………………………………………………

LONG OnCreate(HWND hWnd; UINT wMsg; UINT wParam; LONG lParam) 

{ 

   。。。 

} 



                                                                                         21 


…………………………………………………………Page 84……………………………………………………………

    //………………………………………………………………………………………………………………………………………………………………………………………



    LONG OnAbout (HWND hWnd; UINT wMsg; UINT wParam; LONG lParam) 



    { 



    。。。 



    } 



    //………………………………………………………………………………………………………………………………………………………………………………………



    这么一来,WndProc 和Onmand 永远不必改变,每有新要处理的消息,只要在 



    _messageEntries ' ' 和_mandEntries ' ' 两个数组中加上新元素,并针对新消息撰写新 



    的处理例程即可。 



    这种观念以及作法就是MFC  的Message Map  的雏形。MFC 把其中的动作包装得更好 



    更精致(当然因此也就更复杂得多),成为一张庞大的消息地图;程序一旦获得消息, 



    就可以按图上溯,直到被处理为止。我将在第3章简单仿真MFC  的Message Map ,并在 



    第9章「消息映射与绕行」中详细探索其完整内容。 



对话框的运作 



    Windows  的对话框依其与父窗口的关系,分为两类: 



                                               modal  

    1。  「令其父窗口除能,直到对话框结束」,这种称为                      对话框。 



                                       modeless  

    2。  「父窗口与对话框共同运行」,这种称为                     对话框。 



               modal             Generic  ! §About ! ¨  

    比较常用的是          对话框。我就以             的         对话框做为说明范例。 



    为了做出一个对话框,程序员必须准备两样东西: 



                 dialog template      RC  

    1。 对话框模板(                )。这是在       文件中定义的一个对话框外貌,以各 



                                                             。。。 

    种方式决定对话框的大小、字形、内部有哪些控制组件、各在什么位置  等等。 



    2。 对话框函数(dialog procedure )。其类型非常类似窗口函数,但是它通常只处 



      WM_INITDIAL OG   WM  MAND  

                         _ 

    理                和              两个消息。对话框中的各个控制组件也 



    都是小小窗口,各有自己的窗口函数,它们以消息与其管理者(父窗口,也就 



                                               WM  MAND 

                                                 _ 

    是对话框)沟通。而所有的控制组件传来的消息都是                                 ,再由其 



    参数分辨哪一种控制组件以及哪一种通告(notification )。 



                                                                                22 


…………………………………………………………Page 85……………………………………………………………

    Modal 对话框的激活与结束,靠的是DialogBox 和EndDialog 两个API 函数。请看 



    图1…4。 



                                             TR UE                                       FALSE 

    对话框处理过消息之后,应该传回                                 ;如果未处理消息,则应该传回                                。这是 



                                                                                                FALSE 

    因为你的对话框函数之上层还有一个系统提供的预设对话框函数。如果你传回                                                                  , 



    该预设对话框函数就会接手处理。 



                                                              Dialog Templatet    in RC file。 

                                                  对话框模板 (                     ), 



                                                  AboutBox DIALOG DISCARDABLE  22; 17; 144; 75 

                                                  STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU 

                                                  CAPTION 〃About Generic〃 

                                                  BEGIN 

                                                      CTEXT           〃Windows 95〃;         …1;0; 5;144;8 

                                                      CTEXT           〃Generic Application〃;…1;0;14;144;8 

        1 DialogBox 打开一个对话框:                          CTEXT           〃Version 1。0〃;        …1;0;34;144;8 

                                                      DEFPUSHBUTTON   〃OK〃;              IDOK;53;59;32;14;WS_GROUP 

                                                  END 

                DialogBox(_hInst; 

                                  〃AboutBox〃;            // 对话框模板名称 

                                  hWnd;                      // 父窗口 

                                  (DLGPROC)About  // 对话框函数名称 

                                 ); 



                                    2 控制权转到对话框函数 



     LRESULT CALLBACK About(HWND hDlg;     UINT message; 

4                         WPARAM wParam; LPARAM lParam) 

     { 

对      UNREFERENCED_ PARAMETER(lParam);      // 避免編译时的警告 

话 

框      switch (message) { 

结        case WM_INITDIALOG: 

束             return (TRUE);      // TRUE 表示我已处理过这个消息 



 , 

         case WM_MAND: 

回           if (LOWORD(wParam) == IDOK                                             对话框內部自有一个消息 

返                 || LOWORD(wParam) == IDCANCEL) {                             3 回路(由系統维护) 



                  EndDialog(hDlg; TRUE); 

                  return (TRUE);  // TRUE 表示我已处理过这个消息 

              }                                                                   当使用者按下 'OK' 钮,产生 

              break;                                                              WM_MAND 命令消息, 

       }                                                                          识别码为IDOK,于是流往 

       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。               没什么其它动作,就只送出                    消息,准备让消息循 



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