<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    superwei

    導航

    <2025年7月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    統計

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    《深入淺出MFC》學習筆記之二

    《深入淺出MFC》學習筆記之二 - -

    Tag-《深入淺出MFC》學習筆記之                                          

                                        -《深入淺出MFC》學習筆記之二 
                                        作者:XGM 2001-8-14

                 
                 
                    
                MFC程序也是Windows程序,所以它也有一個WinMain,但是我們在程序中看不到它的蹤影。實際上,在程序進入點之前,有一個(而且只有一個)全局對象(在Hello程序中名為theApp),這是所謂的application
                object,當操作系統將程序加載并激活時,這個全局對象獲得配置,其構造函數會先執行,比WinMain更早。
                書中所舉Hello程序,是一個簡單的MFC程序,其主體在于WinMain和WndProc,而這兩個部分其實都有相當程度的不變性。MFC就是把有著相當固定行為的WinMain內部操作封裝在CWinApp中;把有著相當固定行為的WndProc內部操作封裝在CFrameWnd中。也就是說,CWinApp代表程序本體,CFrameWnd代表一個主框窗口

                雖然WinMain和WndProc內部操作有相當程度的不變性,但面對不同應用程序也需有變化,所以必須以這兩個類為基礎,派生自己的類,并改寫其中一部分成員函數。

                 
                CWinApp----取代WinMain的地位
                傳統上SDK程序的WinMain所完成的工作現由CWinApp的三個函數完成:
                virtual BOOL InitApplication( );
                virtual BOOL InitInstance( );
                virtual BOOL Run( );
                CFrameWnd-----取代WndProc的地位
                CFrameWnd主要用來掌握一個窗口
                引爆器------Application object
                當執行Hello程序時,這個全局對象產生,于是構造函數(見APPCORE.CPP)執行起來,CWinApp之中的成員變量將因為這個全局對象的誕生而獲得配置與初值,配置完成后,WinMain(MFC早已準備好,并由鏈接器直接加到應用程序中去的)登場。

                AfxWinInit:是繼CWinApp構造函數之后的第一個操作;
                此后的操作是pApp->InitApplication(其中的pApp指向CMyWinApp對象,即本例中的theApp),因為CMyWinApp繼承自CWinApp,而InitApplication又是CWinApp的一個虛擬函數,我們沒有改寫它(大部分情況下也不需要改它),所以上述操作相當于調用CWinApp::InitApplication。此程序的代碼出現在APPCORE.CPP中;

                繼InitApplication之后,AfxWinMain調用pApp->InitInstance,InitInstance是CWinApp的一個虛擬函數(應用程序一定要改寫這個函數,因為它在CWinApp中是個空函數,沒有任何默任操作),我們改寫了它,所以上述操作就是調有我們自己的這個InitInstance函數,我們將在該處展開我們的主窗口生命。

                CMyWinApp::InitInstance一開始new了一個CMyFrameWnd對象,new會引發構造函數CmyFrameWnd::CMyFrameWnd,其中調用了CFrameWnd的成員函數Create,它將產生一個窗口。

                  
                Create函數共八個參數,第一個,指定WNDCLASS窗口類,如果放置NULL,表示要以MFC內建的窗口類產生一個標準的外框窗口(Create函數在產生窗口之前會引發窗口類的注冊操作,下一段講述這一內容);第二個,指定窗口標題;第三個,指定窗口風格,默認是WS-OVERLAPPEDWINDOW,如果你不想要窗口右上角的極大極小鈕,可以改成WS-OVERLAPPED|WS-CAPTION|WS-SYSMENU|WS-THICKFRAME|WS-MINIMIZEBOX|WS-MAXIMIZEBOX,如果希望有垂直滾動條,再加上WS-VSCROLL;第四個參數,指定窗口的位置與大小,默認值rectDefault
                ;第五個,指定父窗口,第六個指定菜單;第七個,為擴充風格,唯有以:CreateWindowEx(而非:CreateWindow)函數才能完成,事實上,CFrameWnd:Create最終調用的正是:CreateWindowEx;第八個,是一個指向CCreateContext結構的指針,framework利用它,在具備Document/View結構的程序中初始化外框窗口,默認值NULL

                CFrameWnd:Create在函數中調用CreateEx(CWnd有這個成員函數,但其派生類CFrameWnd并沒有,所以這里調用的實際上是CWnd:CreateEx);后者又調用PreCreateWindow虛擬函數(它在CWnd及其派生類CFrameWnd都有定義,所以實際上調用的是CFrameWnd::PreCreateWindow),這個函數調用了AfxDeferRegisterClass宏,它表示如果變量afxRegisteredClass的值顯示系統已經注冊了fClass
                這種窗口類,MFC啥也不做,否則就調用AfxEndDeferRegisterClass(fClass){它調用兩個函數完成實際的窗口類注冊操作,一個是RegisterWithIcon,一個是AfxRegisterClass},準備注冊之。

                窗口顯示與更新
                CMyFrameWnd::CMyFrameWnd結束后,窗口已經誕生出來;程序又回到CMyWinApp::InitInstance,于是調用ShowWindow函數令窗口顯示出來,并調用UpdateWindow函數令Hello程序送出WM-PAINT

                CWinApp::Run----程序生命的活水源頭
                Run又是CWinApp的一個虛擬函數,我們沒有改寫它(大部分情況下也不需要改它),所以上述操作相當于調用CWinApp::Run
                WinMain已由MFC提供,窗口類已由MFC注冊完成,連窗口函數也都由MFC提供
                把消息與處理函數連接在一起:Message Map機制
                MFC提供給應用程序使用的“很方便的接口”是兩組宏,以Hello為例,第一個操作是在Hello.h的CMyFrameWnd加上DECLARE-MESSAGE-MAP;第二個操作是在Hello.cpp的任何位置(當然不能在函數內)使用宏

                BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
                   ON_COMMAND(IDM_ABOUT, OnAbout)
                   ON_WM_PAINT()
                END_MESSAGE_MAP()
                 
                來龍去脈總整理
                程序的誕生
                Application object 產生, 內存于是獲得配置,初值亦設立了。
                  AfxWinMain執行AfxWinInit,后者又調有AfxInitThread,把消息隊列盡量加
                大到96
                  AfxWinMain執行InitApplication。這是CWinApp的虛擬函數,我們通常不改寫它
                  AfxWinMain執行InitInstance。這是CWinApp的虛擬函數,我們必須改寫它
                  CMyWinApp::InitInstance “new”了一個CMyFrameWnd對象
                 
                CmyFrameWnd構造函數調用Create,產生主窗口。我們在Create參數中指定的窗口類是NULL,于是MFC根據窗口種類,自行為我們注冊一個名為“AfxFrameOrView42d”的窗口類。

                  回到InitInstance中繼續執行ShowWindow,顯示窗口
                執行UpdateWindow,于是發出WM-PAINT
                回到AfxWinMain,執行Run,進入消息循環。
                 
                程序開始運行:
                  程序獲得WM-PAINT消息(由CWinApp::Run中的::GetMessage循環)
                  WM-PAINT經由::DispatchMessage送到窗口函數CWnd::DefWindowProc中。
                  CWnd::DefWindowProc將消息傳遞到消息映射表格
                 
                傳遞過程中發現有相符項目,于是調用項目中對應的函數。此函數是利用BEGIN_MESSAGE_MAP和END_MESSAGE_MAP之間的宏設立起來的。

                  標準消息的處理程序亦有標準命名,例如WM-PAINT必由OnPaint處理
                 
                程序的死亡:
                    使用者單擊File/Close,于是發出WM-CLOSE
                    CMyFrameWnd并沒有設置WM-CLOSE處理程序,于是交給默認的處理程序
                    默認函數對于WM-CLOSE的處理方式是調用::DestroyWindow,并因而發出WM-DESTROY
                    默認的WM-DESTROY處理方式是調用::PostQuitMessage,因此發出WM-QUIT
                   
                CWinApp::Run收到WM-QUIT后會結束內部之消息循環,然后調用ExitInstance,這是CWinApp的一個虛擬函數;如果CMyWinApp改寫了ExitInstance,那么CWinApp::Run所調用的就是CMyWinApp::ExitInstance,否則就是CWinApp::ExitInstance

                    最后回到AfxWinMain,執行AfxWinTerm,結束程序
                 
                附Hello程序部分代碼:
                Hello.cpp
                 
                #include "Stdafx.h"
                #include "Hello.h"
                #include "Resource.h"
                 
                CMyWinApp theApp;   // application object
                 
                //--------------------------------------------------------------------

                // CMyWinApp's member
                //--------------------------------------------------------------------

                BOOL CMyWinApp::InitInstance()
                {
                   m_pMainWnd = new CMyFrameWnd();
                   m_pMainWnd->ShowWindow(m_nCmdShow);
                   m_pMainWnd->UpdateWindow();
                   return TRUE;
                }
                //--------------------------------------------------------------------

                // CMyWinApp's member
                //--------------------------------------------------------------------

                BOOL CMyWinApp::OnIdle(LONG lCount)
                {
                   CMyFrameWnd* pWnd = (CMyFrameWnd*)m_pMainWnd;
                   pWnd->IdleTimeHandler(lCount);
                 
                   return TRUE;
                }
                //--------------------------------------------------------------------

                // CMyFrameWnd's member
                //--------------------------------------------------------------------

                CMyFrameWnd::CMyFrameWnd()
                {
                   Create(NULL, "Hello MFC", WS_OVERLAPPEDWINDOW, rectDefault,
                          NULL, "MainMenu");     }
                //--------------------------------------------------------------------

                BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
                   ON_COMMAND(IDM_ABOUT, OnAbout)
                   ON_WM_PAINT()
                END_MESSAGE_MAP()
                //--------------------------------------------------------------------

                void CMyFrameWnd::OnPaint()
                {
                CPaintDC dc(this);
                CRect rect;
                 
                   GetClientRect(rect);
                 
                   dc.SetTextAlign(TA_BOTTOM | TA_CENTER);
                 
                   ::LineDDA(rect.right/2, 0, rect.right/2, rect.bottom/2,
                       (LINEDDAPROC) LineDDACallback, (LPARAM) (LPVOID) &dc);
                }
                //--------------------------------------------------------------------

                VOID CALLBACK CMyFrameWnd::LineDDACallback(int x, int y, LPARAM
                lpdc)
                {
                static char szText[] = "Hello, MFC";
                 
                   ((CDC*)lpdc)->TextOut(x, y, szText, sizeof(szText)-1);
                   for(int i=1; i<50000; i++); 
                }
                //--------------------------------------------------------------------

                void CMyFrameWnd::OnAbout()
                {
                   CDialog about("AboutBox", this);  // "AboutBox"
                   about.DoModal();
                }
                //--------------------------------------------------------------------

                void CMyFrameWnd::IdleTimeHandler(LONG lCount)
                {
                  CString str;
                  CRect rect(10,10,200,30);
                  CDC* pDC = new CClientDC(this);
                 
                  str.Format("%010d", lCount);
                  pDC->DrawText(str, &rect, DT_LEFT | DT_TOP);
                }
                 
                Hello.h
                 
                class CMyWinApp : public CWinApp
                {
                public:
                   virtual BOOL InitInstance();       //
                   virtual BOOL OnIdle(LONG lCount);  // OnIdle e?^
                };
                 
                //--------------------------------------------------------------------

                class CMyFrameWnd : public CFrameWnd
                {
                public:
                   CMyFrameWnd();            // constructor
                   afx_msg void OnPaint();   // for WM_PAINT
                   afx_msg void OnAbout();   // for WM_COMMAND (IDM_ABOUT)
                   void IdleTimeHandler(LONG lCount);  // we want it call by
                CMyWinApp::OnIdle
                 
                private:
                   DECLARE_MESSAGE_MAP()     // Declare Message Map
                   static VOID CALLBACK LineDDACallback(int,int,LPARAM);
                   //?C
                };

    posted on 2005-11-01 14:39 小辭猬 閱讀(232) 評論(0)  編輯  收藏 所屬分類: C++


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产成人高清亚洲一区久久| 国产国拍精品亚洲AV片| 久久精品国产亚洲av水果派| 中文在线观看永久免费| 亚洲性猛交XXXX| a毛片免费在线观看| 亚洲线精品一区二区三区影音先锋| 色综合久久精品亚洲国产| 日韩免费无码一区二区视频| 色婷婷六月亚洲综合香蕉| 四虎永久免费地址在线网站| 免费看黄福利app导航看一下黄色录像| 又大又硬又爽免费视频| 国产亚洲综合视频| 精品亚洲一区二区三区在线播放| 一区免费在线观看| 亚洲乱码国产一区三区| 久操免费在线观看| 亚洲人成免费电影| 国产男女猛烈无遮档免费视频网站| 久久亚洲中文无码咪咪爱| 国产性爱在线观看亚洲黄色一级片| 中文永久免费观看网站| 日木av无码专区亚洲av毛片| 国产成人精品免费午夜app| 亚洲一区二区观看播放| 亚洲国产午夜中文字幕精品黄网站 | 中文字幕亚洲精品| 无码日韩人妻av一区免费| 国产成人亚洲综合无| 亚洲午夜久久久久久久久久| 久久永久免费人妻精品下载| 亚洲国产精品免费观看 | 亚洲区小说区激情区图片区| 91久久精品国产免费一区| 亚洲欧美日韩中文字幕在线一区| 亚洲日韩国产一区二区三区| 中文字幕天天躁日日躁狠狠躁免费| 国产成人精品日本亚洲专| 久久精品国产精品亚洲下载| 成人福利免费视频|