• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            MFC程序框架的剖析

            1,尋找WinMain人口:
            在安裝目錄下找到MFC文件夾下的SRC文件夾,SRC下是MFC源代碼。
            路徑:MFC|SRC|APPMODUL.CPP:
            _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
             LPTSTR lpCmdLine, int nCmdShow)
            {
             // call shared/exported WinMain
             return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
            }
            注意:(#define _tWinMain   WinMain)

            2,對于全局對象或全局變量來說,在程序運(yùn)行即WINMAIN函數(shù)加載的時候,已經(jīng)為全局對象或全局變量分配了內(nèi)存和賦初值。
            所以:CTEApp theApp;->CTEApp ::CTEApp(){}->_tWinMain(){}
            說明:每一個MFC程序,有且只有一個從WinApp類派生的類(應(yīng)用程序類),也只有一個從應(yīng)用程序類所事例化的對象,表示應(yīng)用程序本身。在WIN32程序當(dāng)中,表示應(yīng)用程序是通過WINMAIN入口函數(shù)來表示的(通過一個應(yīng)用程序的一個事例號這一個標(biāo)識來表示的)。在基于MFC應(yīng)用程序中,是通過產(chǎn)生一個應(yīng)用程序?qū)ο螅盟鼇砦ㄒ坏谋硎玖藨?yīng)用程序。

            3,通過構(gòu)造應(yīng)用程序?qū)ο筮^程中調(diào)用基類CWinApp的構(gòu)造函數(shù),在CWinApp的構(gòu)造函數(shù)中對程序包括運(yùn)行時一些初始化工作完成了。
            CWinApp構(gòu)造函數(shù):MFC|SRC|APPCORE.CPP
            CWinApp::CWinApp(LPCTSTR lpszAppName){...}//帶參數(shù),而CTEApp構(gòu)造函數(shù)沒有顯式向父類傳參,難道CWinApp()有默認(rèn)參數(shù)?見下:
            (在CWinApp類定義中, CWinApp(LPCTSTR lpszAppName = NULL); )
            注意:CWinApp()函數(shù)中:
            pThreadState->m_pCurrentWinThread = this;
            pModuleState->m_pCurrentWinApp = this
            (this指向的是派生類CTEApp對象,即theApp)
            調(diào)試:CWinApp::CWinApp();->CTEApp theApp;(->CTEApp ::CTEApp())->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){}

            4,_tWinMain函數(shù)中通過調(diào)用AfxWinMain()函數(shù)來完成它要完成的功能。(Afx*前綴代表這是應(yīng)用程序框架函數(shù),是一些全局函數(shù),應(yīng)用程序框架是一套輔助生成應(yīng)用程序的框架模型,把一些類做一些有機(jī)的集成,我們可根據(jù)這些類函數(shù)來設(shè)計自己的應(yīng)用程序)。
            AfxWinMain()函數(shù)路徑:MFC|SRC|WINMAIN.CPP:
            在AfxWinMain()函數(shù)中:
            CWinApp* pApp = AfxGetApp();
            說明:pApp存儲的是指向WinApp派生類對象(theApp)的指針。
            //_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
            // { return afxCurrentWinApp; }

            調(diào)用pThread->InitInstance()
            說明:pThread也指向theApp,由于基類中virtual BOOL InitApplication()定義為虛函數(shù),所以調(diào)用pThread->InitInstance()時候,調(diào)用的是派生類CTEApp的InitInstance()函數(shù)。

            nReturnCode = pThread->Run();
            說明:pThread->Run()完成了消息循環(huán)。

            5,注冊窗口類:AfxEndDeferRegisterClass();
            AfxEndDeferRegisterClass()函數(shù)所在文件:MFC|SRC|APPCORE.CPP
            BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){...}
            說明:設(shè)計窗口類:在MFC中事先設(shè)計好了幾種缺省的窗口類,根據(jù)不同的應(yīng)用程序的選擇,調(diào)用AfxEndDeferRegisterClass()函數(shù)注冊所選擇的窗口類。
            調(diào)試:CWinApp::CWinApp();->CTEApp theApp;(->CTEApp ::CTEApp())->CWinApp::CWinApp()->CTEApp ::CTEApp()->_tWinMain(){}//進(jìn)入程序
            ->AfxWinMain();->pApp->InitApplication();->pThread->InitInstance()//父類InitInstance虛函數(shù);->CTEApp::InitInstance()//子類實(shí)現(xiàn)函數(shù);->AfxEndDeferRegisterClass(LONG fToRegister)//注冊所選擇的窗口類(出于文檔管理,注冊提前,正常的應(yīng)在PreCreateWindow中進(jìn)行注冊)//之后進(jìn)入創(chuàng)建窗口階段(以下再不做調(diào)試)

            6,PreCreateWindow()://主要是注冊窗口類
            BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
            {
             if( !CFrameWnd::PreCreateWindow(cs) )
              return FALSE;
             return TRUE;
            }
            說明:
            CFrameWnd::PreCreateWindow()函數(shù)所在文件:MFC|SRC|WINFRM.CPP
            BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
            {
             if (cs.lpszClass == NULL)
             {
              VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
               //判斷AFX_WNDFRAMEORVIEW_REG型號窗口類是否注冊,如果沒有注冊則注冊
              cs.lpszClass = _afxWndFrameOrView;  // COLOR_WINDOW background
               //把注冊后的窗口類名賦給cs.lpszClass
             }

             if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
              cs.style |= FWS_PREFIXTITLE;

             if (afxData.bWin4)
              cs.dwExStyle |= WS_EX_CLIENTEDGE;

             return TRUE;
            }

            其中:
            virtual BOOL PreCreateWindow(CREATESTRUCT& cs);//PreCreateWindow()是個虛函數(shù),如果子類有則調(diào)用子類的。
            #define VERIFY(f)          ASSERT(f)
            #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
            define AFX_WNDFRAMEORVIEW_REG          0x00008
            const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定義為全局?jǐn)?shù)組。
            //#define AFX_WNDFRAMEORVIEW  AFX_WNDCLASS("FrameOrView")

            7,創(chuàng)建窗口:
            Create()函數(shù)路徑:MFC|SRC|WINFRM.CPP:
            CFrameWnd::Create(...){
             ...
             CreateEx(...);//從父類繼承來的,調(diào)用CWnd::CreateEx().
             ...
            }

            CWnd::CreateEx()函數(shù)路徑:MFC|SRC|WINCORE.CPP
            BOOL CWnd::CreateEx(...){
             ...
             if (!PreCreateWindow(cs))//虛函數(shù),如果子類有調(diào)用子類的。
             {
              PostNcDestroy();
              return FALSE;
             }
             ...
             HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
              cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
              cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);

             ...
            }
            說明:CreateWindowEx()函數(shù)與CREATESTRUCT結(jié)構(gòu)體參數(shù)的對應(yīng)關(guān)系,使我們在創(chuàng)建窗口之前通過可PreCreateWindow(cs)修改cs結(jié)構(gòu)體成員來修改所要的窗口外觀。PreCreateWindow(cs))//是虛函數(shù),如果子類有調(diào)用子類的。
            HWND CreateWindowEx(
              DWORD dwExStyle,     
              LPCTSTR lpClassName, 
              LPCTSTR lpWindowName,
              DWORD dwStyle,       
              int x,               
              int y,               
              int nWidth,          
              int nHeight,         
              HWND hWndParent,     
              HMENU hMenu,         
              HINSTANCE hInstance, 
              LPVOID lpParam       
            );
            typedef struct tagCREATESTRUCT { // cs
                LPVOID    lpCreateParams;
                HINSTANCE hInstance;
                HMENU     hMenu;
                HWND      hwndParent;
                int       cy;
                int       cx;
                int       y;
                int       x;
                LONG      style;
                LPCTSTR   lpszName;
                LPCTSTR   lpszClass;
                DWORD     dwExStyle;
            } CREATESTRUCT;

            8,顯示和更新窗口:
            CTEApp類,TEApp.cpp中
            m_pMainWnd->ShowWindow(SW_SHOW);//顯示窗口,m_pMainWnd指向框架窗口
            m_pMainWnd->UpdateWindow();//更新窗口
            說明:
            class CTEApp : public CWinApp{...}
            class CWinApp : public CWinThread{...}
            class CWinThread : public CCmdTarget
            {
             ...
            public:
             CWnd* m_pMainWnd;
             ...
            ...
            }

            9,消息循環(huán):
            int AFXAPI AfxWinMain()
            { ...
             // Perform specific initializations
             if (!pThread->InitInstance()){...}
             //完成窗口初始化工作,完成窗口的注冊,完成窗口的創(chuàng)建,顯示和更新。
             nReturnCode = pThread->Run();
             //繼承基類Run()方法,調(diào)用CWinThread::Run()來完成消息循環(huán)
             ...
            }
            ////////////////////////////////////////////////////////////////
            CWinThread::Run()方法路徑:MFC|SRC|THRDCORE.CPP
            int CWinThread::Run()
            { ...
              // phase2: pump messages while available
              do//消息循環(huán)
              {
               // pump message, but quit on WM_QUIT
               if (!PumpMessage())//取消息并處理
                return ExitInstance();
               ...
              } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
             ...
            }
            說明:
            BOOL PeekMessage(,,,,)函數(shù)說明
            The PeekMessage function checks a thread message queue for a message and places the message (if any) in the specified structure.
            If a message is available, the return value is nonzero.
            If no messages are available, the return value is zero.

            /////////////////////////////////////////////////////////////
            BOOL CWinThread::PumpMessage()
            {
             ...
             if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))//取消息
             {...}
             ...
             // process this message
             if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
             {
              ::TranslateMessage(&m_msgCur);//進(jìn)行消息(如鍵盤消息)轉(zhuǎn)換
              ::DispatchMessage(&m_msgCur);//分派消息到窗口的回調(diào)函數(shù)處理(實(shí)際上分派的消息經(jīng)過消息映射,交由消息響應(yīng)函數(shù)進(jìn)行處理。)
             }
             return TRUE;
            }

            9,文檔與視結(jié)構(gòu):
            可以認(rèn)為View類窗口是CMainFram類窗口的子窗口。
            DOCument類是文檔類。
            DOC-VIEW結(jié)構(gòu)將數(shù)據(jù)本身與它的顯示分離開。
            文檔類:數(shù)據(jù)的存儲,加載
            視類:數(shù)據(jù)的顯示,修改

            10,文檔類,視類,框架類的有機(jī)結(jié)合:
            在CTEApp類CTEApp::InitInstance()函數(shù)中通過文檔模板將文檔類,視類,框架類的有機(jī)組織一起。
            ...
            CSingleDocTemplate* pDocTemplate;
            pDocTemplate = new CSingleDocTemplate(
             IDR_MAINFRAME,
             RUNTIME_CLASS(CTEDoc),
             RUNTIME_CLASS(CMainFrame),       // main SDI frame window
             RUNTIME_CLASS(CTEView));
            AddDocTemplate(pDocTemplate);//增加到模板

            posted on 2008-03-11 15:06 弱水一瓢 閱讀(260) 評論(0)  編輯 收藏 引用 所屬分類: MFC

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

            導(dǎo)航

            統(tǒng)計

            文章分類

            最新評論

            成人a毛片久久免费播放| 久久久久99精品成人片三人毛片 | 亚洲午夜久久久| 亚洲精品tv久久久久久久久 | 热久久视久久精品18| 日韩人妻无码精品久久免费一| 狠狠狠色丁香婷婷综合久久俺| 久久精品国产99国产精品| 色综合久久天天综线观看| 99久久精品午夜一区二区| 精品国产乱码久久久久久浪潮| 亚洲伊人久久精品影院| 精品久久综合1区2区3区激情| 亚洲AV无码久久精品狠狠爱浪潮| 777久久精品一区二区三区无码| 久久久www免费人成精品| 国产精品丝袜久久久久久不卡| 狠狠色噜噜色狠狠狠综合久久| 精品综合久久久久久88小说| 男女久久久国产一区二区三区| 欧美久久亚洲精品| 国产叼嘿久久精品久久| 777米奇久久最新地址| 亚洲综合伊人久久综合| 亚洲国产香蕉人人爽成AV片久久| 久久久91精品国产一区二区三区| 久久精品夜夜夜夜夜久久| 东方aⅴ免费观看久久av| 人妻无码久久精品| 久久青青草原精品国产不卡| 99热都是精品久久久久久| 99久久99久久久精品齐齐| 欧洲精品久久久av无码电影 | 久久精品中文字幕有码| 国产精品久久久久9999高清| 少妇久久久久久久久久| 精品熟女少妇AV免费久久| 老男人久久青草av高清| 无码人妻久久一区二区三区蜜桃| 亚洲国产综合久久天堂 | 精品人妻久久久久久888|