• <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,對于全局對象或全局變量來說,在程序運行即WINMAIN函數加載的時候,已經為全局對象或全局變量分配了內存和賦初值。
            所以:CTEApp theApp;->CTEApp ::CTEApp(){}->_tWinMain(){}
            說明:每一個MFC程序,有且只有一個從WinApp類派生的類(應用程序類),也只有一個從應用程序類所事例化的對象,表示應用程序本身。在WIN32程序當中,表示應用程序是通過WINMAIN入口函數來表示的(通過一個應用程序的一個事例號這一個標識來表示的)。在基于MFC應用程序中,是通過產生一個應用程序對象,用它來唯一的表示了應用程序。

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

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

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

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

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

            6,PreCreateWindow()://主要是注冊窗口類
            BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
            {
            if( !CFrameWnd::PreCreateWindow(cs) )
               return FALSE;
            return TRUE;
            }
            說明:
            CFrameWnd::PreCreateWindow()函數所在文件: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()是個虛函數,如果子類有則調用子類的。
            #define VERIFY(f)          ASSERT(f)
            #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
            define AFX_WNDFRAMEORVIEW_REG          0x00008
            const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定義為全局數組。
            //#define AFX_WNDFRAMEORVIEW AFX_WNDCLASS("FrameOrView")

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

            CWnd::CreateEx()函數路徑:MFC|SRC|WINCORE.CPP
            BOOL CWnd::CreateEx(...){
            ...
            if (!PreCreateWindow(cs))//虛函數,如果子類有調用子類的。
            {
               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()函數與CREATESTRUCT結構體參數的對應關系,使我們在創建窗口之前通過可PreCreateWindow(cs)修改cs結構體成員來修改所要的窗口外觀。PreCreateWindow(cs))//是虛函數,如果子類有調用子類的。
            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,消息循環:
            int AFXAPI AfxWinMain()
            { ...
            // Perform specific initializations
            if (!pThread->InitInstance()){...}
            //完成窗口初始化工作,完成窗口的注冊,完成窗口的創建,顯示和更新。
            nReturnCode = pThread->Run();
            //繼承基類Run()方法,調用CWinThread::Run()來完成消息循環
            ...
            }
            ////////////////////////////////////////////////////////////////
            CWinThread::Run()方法路徑:MFC|SRC|THRDCORE.CPP
            int CWinThread::Run()
            { ...
               // phase2: pump messages while available
               do//消息循環
               {
                // pump message, but quit on WM_QUIT
                if (!PumpMessage())//取消息并處理
                 return ExitInstance();
                ...
               } while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
            ...
            }
            說明:
            BOOL PeekMessage(,,,,)函數說明
            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);//進行消息(如鍵盤消息)轉換
               ::DispatchMessage(&m_msgCur);//分派消息到窗口的回調函數處理(實際上分派的消息經過消息映射,交由消息響應函數進行處理。)
            }
            return TRUE;
            }

            9,文檔與視結構:
            可以認為View類窗口是CMainFram類窗口的子窗口。
            DOCument類是文檔類。
            DOC-VIEW結構將數據本身與它的顯示分離開。
            文檔類:數據的存儲,加載
            視類:數據的顯示,修改

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


            posted on 2010-06-21 22:43 lhking 閱讀(453) 評論(0)  編輯 收藏 引用

            導航

            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            統計

            常用鏈接

            留言簿

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久国产一级毛片高清版| 国产亚州精品女人久久久久久 | 久久精品极品盛宴观看| 中文字幕亚洲综合久久2| 亚洲国产精品综合久久一线| 久久精品国产亚洲AV蜜臀色欲| 久久综合给合久久狠狠狠97色| 国内精品伊人久久久久网站| 久久国产乱子伦精品免费午夜| 久久精品一本到99热免费| 中文字幕日本人妻久久久免费| 青青草原综合久久大伊人精品| 品成人欧美大片久久国产欧美| 久久久久亚洲av无码专区 | 99久久99久久久精品齐齐| 国产ww久久久久久久久久| 性做久久久久久久久| 99久久www免费人成精品| 伊人色综合久久天天网| 91视频国产91久久久| A级毛片无码久久精品免费| 欧美一区二区精品久久| 日韩乱码人妻无码中文字幕久久 | 人妻丰满AV无码久久不卡| 91久久香蕉国产熟女线看| 亚洲国产成人精品91久久久 | 人人狠狠综合久久亚洲88| 久久综合亚洲色一区二区三区| 久久av免费天堂小草播放| 国内精品人妻无码久久久影院| 无码超乳爆乳中文字幕久久| 一本色道久久88综合日韩精品 | 99久久99久久| 国内精品伊人久久久久777| 亚洲精品高清一二区久久| 久久成人国产精品一区二区| 日本精品久久久中文字幕| 国产精品久久久久久| 国产V亚洲V天堂无码久久久| 无码专区久久综合久中文字幕 | 久久免费香蕉视频|