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

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

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



{ 

// Attributes 

                         

    CWnd* m_pMainWnd;      // main window (usually same AfxGetApp()…》m_pMainWnd) 

    CWnd* m_pActiveWnd;   // active main window (may not be m_pMainWnd) 



    // only valid while running 

    HANDLE m_hThread;       // this thread's HANDLE 

    DWORD m_nThreadID;      // this thread's ID 



    int GetThreadPriority(); 

    BOOL SetThreadPriority(int nPriority); 



// Operations 

    DWORD SuspendThread(); 

    DWORD ResumeThread(); 



// Overridables 

    // thread initialization 

    virtual BOOL InitInstance(); 



    // running and idle processing 

    virtual int Run(); 

    virtual BOOL PreTranslateMessage(MSG* pMsg); 

    virtual BOOL PumpMessage();     // low level message pump 

    virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing 



public: 

    // valid after construction 

    AFX_THREADPROC m_pfnThreadProc; 

。。。 

}; 



熟悉Win32  的朋友,看到CWinThread 类别之中的SuspendThread 和ResumeThread 成 



员函数,可能会发出会心微笑。 



                                                                                  361 


…………………………………………………………Page 424……………………………………………………………

                    第篇    湷觥 FC  程式設計 



             CFrameWnd -取代 WndProc 的地位 



                    CFrameWnd 主要用来掌握一个窗口,几乎你可以说它是用来取代SDK 程序中的窗口函 



                    式的地位。传统的SDK 窗口函数写法是: 



                    long FAR PASCAL WndProc(HWND hWnd; UNIT msg; WORD wParam; LONG lParam) 

                    { 

                       switch(msg) { 

                           case WM_MAND : 

                                switch(wParam) { 

                                    case IDM_ABOUT : 

                                         OnAbout(hWnd; wParam; lParam); 

                                         break; 

                                } 

                                break; 

                           case WM_PAINT : 

                                OnPaint(hWnd; wParam; lParam); 

                                break; 

                           default : 

                                DefWindowProc(hWnd; msg; wParam; lParam); 

                       } 

                    } 



                   MFC 程序有新的作法,我们在Hello 程序中也为CMyFrameWnd 准备了两个消息处理 



                   例程,声明如下: 



                    class CMyFrameWnd : public CFrameWnd 

                    { 

                    public: 

                           CMyFrameWnd(); 

                           afx_msg void OnPaint(); 

                           afx_msg void OnAbout(); 

                           DECLARE_MESSAGE_MAP () 

                    }; 



                   OnPaint 处理什么消息?OnAbout 又是处理什么消息?我想你很容易猜到,前者处理 



                   WM_PAINT ,后者处理WM_MAND 的IDM_ABOUT 。这看起来十分俐落,但让人搞 



                   不懂来龙去脉。程序中是不是应该有「把消息和处理函数关联在一起」的设定动作?是 



                   的,这些设定在HELLO。CPP 才看得到。但让我先着一鞭:DECLARE_MESSAGE_MAP 



                   宏与此有关。 



362 


…………………………………………………………Page 425……………………………………………………………

                                            第6章    MFC 程式的生死因果 



这种写法非常奇特,原因是MFC  内建了一个所谓的Message Map 机制,会把消息自动 



送到「与消息对映之特定函数」去;消息与处理函数之间的对映关系由程序员指定。 



DECLARE_MESSAGE_MAP  另搭配其它宏,就可以很便利地将消息与其处理函数关联 



在一起: 



   BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd) 



    ON_WM_PAINT() 



    ON_MAND(IDM_ABOUT; OnAbout) 



   END_MESSAGE_MAP() 



稍后我就来探讨这些神秘的宏。 



                                                                      363 


…………………………………………………………Page 426……………………………………………………………

                    第篇    湷觥 FC  程式設計 



             引爆器-Application object 



                    我们已经看过HELLO。H 声明的两个类别,现在把目光转到HELLO。CPP 身上。这个档 



                    案将两个类别实作出来,并产生一个所谓的application object 。故事就从这里展开。 



                    下面这张图包括右半部的Hello 源代码与左半部的MFC 源代码。从这一节以降,我将 



                    以此图解释MFC 程序的激活、运行、与结束。不同小节的图将标示出当时的程序进行 



                    状况。 



                                                           HELLO。CPP 



                                                        1  CMyWinApp theApp;   // application object 



                                                           BOOL CMyWinApp::InitInstance() 

                    WINMAIN。CPP 

                                                           { 

                     int AFXAPI AfxWinMain (。。。)              m_pMainWnd = new CMyFrameWnd(); 

                     int AFXAPI AfxWinMain (。。。) 

                     {{                                       m_pMainWnd…》ShowWindow(m_nCmdShow); 

                         CWinApp* pApp = AfxGetApp();         m_pMainWnd…》UpdateWindow(); 

                         CWinApp* pApp = AfxGetApp(); 

                                                              return TRUE; 

                         AfxWinInit(。。。);                  } 

                         AfxWinInit(。。。); 



                         pApp…》InitApplication();          CMyFrameWnd::CMyFrameWnd() 

                         pApp…》InitApplication(); 

                         pApp…》InitInstance();             { 

                         pApp…》InitInstance(); 

                         nReturnCode = pApp…》Run();           Create(NULL; 〃Hello MFC〃; 。。。; 

                         nReturnCode = pApp…》Run(); 

                                                                     〃MainMenu〃); 

                         AfxWinTerm();                     } 

                         AfxWinTerm(); 

                     }} 

                                                           void CMyFrameWnd::OnPaint()  { 。。。 } 

                                                           void CMyFrameWnd::OnAbout()  { 。。。 } 



                                                           BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd) 

                                                              ON_MAND(IDM_ABOUT; OnAbout) 

                                                              ON_WM_PAINT() 

                                                           END_MESSAGE_MAP() 



                    上图的theApp 就是Hello 程序的application object ,每一个MFC 应用程序都有一个, 



                    而且也只有这么一个。当你执行Hello,这个全域对象产生,于是构造式执行起来。我们 



                    并没有定义CMyWinApp 构造式;至于其父类别CWinApp 的构造式内容摘要如下(摘 



                    录自APPCORE。CPP ): 



364 


…………………………………………………………Page 427……………………………………………………………

                                                       第6章    MFC 程式的生死因果 



CWinApp::CWinApp(LPCTSTR lpszAppName) 

{ 

    m_pszAppName = lpszAppName; 



    // initialize CWinThread state 

    AFX_MODULE_THREAD_STATE* pThreadState = AfxGetModuleThreadState(); 

    pThreadState…》m_pCurrentWinThread = this; 

    m_hThread = ::GetCurrentThread(); 

    m_nThreadID = ::GetCurrentThreadId(); 



    // initialize CWinApp state 

    AFX_MODULE_STATE* pModuleState = AfxGetModuleState(); 

    pModuleState…》m_pCurrentWinApp = this; 



    // in non…running state until WinMain 

    m_hInstance = NULL; 

    m_pszHelpFilePath = NULL; 

    m_pszProfileName = NULL; 

    m_pszRegistryKey = NULL; 

    m_pszExeName = NULL; 

    m_lpCmdLine = NULL; 

    m_pCmdInfo = NULL; 

    。。。 

} 



CWinApp 之中的成员变量将因为theApp 这个全域对象的诞生而获得配置与初值。如果 



程序中没有theApp 存在,编译联结还是可以顺利通过,但执行时会出现系统错误消息: 



                                                                                      365 


…………………………………………………………Page 428……………………………………………………………

                    第篇    湷觥 FC  程式設計 



              隐晦不明的 WinMain 



                                                             HELLO。CPP 



                                                         1   CMyWinApp theApp;   // application object 



                                                             BOOL CMyWinApp::InitInstance() 

                     WINMAIN。CPP 

                                                             { 

                     int AFXAPI AfxWinMain (。。。)               m_pMainWnd = new CMyFrameWnd(); 

                      int AFXAPI AfxWinMain (。。。) 

                      {{                                       m_pMainWnd…》ShowWindow(m_nCmdShow); 

                         CWinApp* pApp = AfxGetApp();          m_pMainWnd…》UpdateWindow(); 

                          CWinApp* pApp = AfxGetApp(); 

                                                               return TRUE; 

                         AfxWinInit(。。。);                    } 

                          AfxWinInit(。。。); 



                         pApp…》InitApplication();            CMyFrameWnd::CMyFrameWnd() 

                          pApp…》InitApplication(); 

                         pApp…》InitInstance();               { 

                          pApp…》InitInstance(); 

                         nReturnCode = pApp…》Run();            Create(NULL; 〃Hello MFC〃; 。。。; 

                          nReturnCode = pApp…》Run(); 

                                                                      〃MainMenu〃); 

                         AfxWinTerm();                       } 

                          AfxWinTerm(); 

                      } 

                      } 

                                                             void CMyFrameWnd::OnPaint()  { 。。。 } 

                                                             void CMyFrameWnd::OnAbout()  { 。。。 } 



                                                             BEGIN_MESSAGE_MAP(CMyFrameWnd; CFrameWnd) 

                                                               ON_MAND(IDM_ABOUT; OnAbout) 

                                                               ON_WM_PAINT() 

                                                             END_MESSAGE_MAP() 



                    theApp 配置完成后,WinMain 登场。我们并未撰写WinMain 程序代码,这是MFC 早已 



                    准备好并由联结器直接加到应用程序代码中的,其源代码列于图6…4 。_tWinMain  函数的 



                    !   §…t! ¨  是为了支持Unicode 而准备的一个宏。 



                    // in APPMODUL。CPP 

                    extern 〃C〃 int WINAPI 

                    _tWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance; 

                                LPTSTR lpCmdLine; int nCmdShow) 

                     { 

                            // call shared/exported WinMain 

                            return AfxWinMain (hInstance; hPrevInstance; lpCmdLine; nCmdShow); 

                     } 



                     此外,在DLLMODUL。CPP  中有一个DllMain  函数。本书并未涵盖DLL 程序设计。 



366 


…………………………………………………………Page 429……………………………………………………………

                                                       第6章    MFC 程式的生死因果 



// in WINMAIN。CPP 

#0001  ///////////////////////////////////////////////////////////////// 

#0002  // Standard WinMain implementation 

#0003  //  Can be replaced as long as 'AfxWinInit' is called first 

#0004 

#0005  int AFXAPI AfxWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance; 

#0006          LPTSTR lpCmdLine; int nCmdShow) 

#0007  { 

#0008      ASSERT(hPrevInstance == NULL); 

#0009 

#0010      int nReturnCode = …1; 

#0011      CWinApp* pApp = AfxGetApp(); 

#0012 

#0013      // AFX internal initialization 

#0014      if (!AfxWinInit(hInstance; hPrevInstance; lpCmdLine; nCmdShow)) 

#0015              goto InitFailure; 

#0016 

#0017      // App global initializations (rare) 

#0018      ASSERT_VALID(pApp); 

#0019      if (!pApp…》InitApplication()) 

#0020              goto InitFailure; 

#0021      ASSERT_VALID(pApp); 

#0022 

#0023      // Perform specific initializations 

#0024      if (!pApp…》InitInstance()) 

#0025      { 

#0026          if (pApp…》m_pMainWnd != NULL) 

#0027          { 

#0028              TRACE0(〃Warning: Destroying non…NULL m_pMainWndn〃); 

#0029              pApp…》m_pMainWnd…》DestroyWindow(); 

#0030          } 

#0031          nReturnCode = pApp…》ExitInstance(); 

#0032          goto InitFailure; 

#0033      } 

#0034      ASSERT_VALID(pApp); 

#0035 

#0036      nReturnCode = pApp…》Run(); 

#0037      ASSERT_VALID(pApp); 

#0038 

#0039  InitFailure: 

#0040 

#0041      AfxWinTerm(); 

#0042      return nReturnCode; 

#0043  } 



  图6…4 Windows 程序进入点。源代码可从MFC 的WINMAIN。CPP 中获得。 



                                                                                      367 


…………………………………………………………Page 430……………………………………………………………

                  第篇    湷觥 FC  程式設計 



                   稍加整理去芜存菁,就可以看到这个「程序进入点」主要做些什么事: 



                      int AFXAPI AfxWinMain (HINSTANCE hInstance; HINSTANCE hPrevInstance; 

                                        LPTSTR lpCmdLine; int nCmdShow) 

                      { 

                          int nReturnCode = …1; 

                          CWinApp* pApp = AfxGetApp(); 



                          AfxWinInit(hInstance; hPrevInstance; lpCmdLine; nCmdShow); 



                          pApp…》InitApplication(); 

                          pApp…》InitInstance(); 

                          nReturnCode = pApp…》Run(); 



                          AfxWinTerm(); 

                          return nReturnCode; 

                      } 



             其中,AfxGetApp  是一个全域函数,定义于AFXWIN1。INL  中: 



                      _AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp() 

                              { return afxCurrentWinApp; } 



             而afxCurrentWinApp 又定义于AFXWIN。H  中: 



                      #define afxCurrentWinApp  AfxGetModuleState()…》m_pCurrentWinApp 



             再根据稍早所述CWinApp::CWinApp 中的动作,我们于是知道,AfxGetApp  其实就是取 



             得CMyWinApp 对象指针。所以,AfxWinMain  中这样的动作: 



                      CWinApp* pApp = AfxGetApp(); 

                      pApp…》InitApplication(); 

                      pApp…》InitInstance(); 

                      nReturnCode = pApp…》Run(); 



             其实就相当于调用: 



                      CMyWinApp::InitApplication(); 

                      CMyWinApp::InitInstance(); 

                      CMyWinApp::Run(); 



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