• <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>

            winlinglin

            MFC學習筆記(一)

            Win32應用程序有條明確的主線:
             (1) 進入WinMain函數(shù)
             (2) 設計一個Window
             (3) 注冊這個Window
             (4) 建立這個Window
             (5) 顯示和更新這個Window
             (6) 進入消息循環(huán)
             
            好,我就先找WinMain函數(shù)吧。
            我在C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src\mfc的appmodul.cpp的23行中找到了以下代碼:
            extern "C" int WINAPI
            _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
             _In_ LPTSTR lpCmdLine, int nCmdShow)
            #pragma warning(suppress: 4985)
            {
             // call shared/exported WinMain
             return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
            }

            _tWinMain是一個宏,詳細為: #define _tWinMain WinMain
            所以這個確實是我們要找的WinMain函數(shù)

            從代碼中看出,WinMain將參數(shù)全部交給AfxWinMain,來處理。
            好,我又找AfxWinMain這個函數(shù)。

            我在winmain.cpp的19行找到了AfxWinMain函數(shù)。
            代碼:
            int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
             _In_ LPTSTR lpCmdLine, int nCmdShow)
            {
             ASSERT(hPrevInstance == NULL);   // ASSERT在程序運行時它計算括號內(nèi)的表達式,如果表達式為FALSE (0),
                       // 程序?qū)蟾驽e誤,并終止執(zhí)行。如果表達式不為0,則繼續(xù)執(zhí)行后面的語句。
                       // ASSERT只有在Debug版本中才有效,如果編譯為Release版本則被忽略。
                       // assert()的功能類似,它是ANSI C標準中規(guī)定的函數(shù),它與ASSERT的一個重要區(qū)別是可以用在Release版本中。
             int nReturnCode = -1;
             // AfxGetThread和 AfxGetApp 都是全局函數(shù)
             CWinThread* pThread = AfxGetThread();  // 獲得正在執(zhí)行的線程,Must be called from within the desired thread.
             CWinApp* pApp = AfxGetApp();    // 獲得A pointer to the single CWinApp object for the application

             // AFX internal initialization
                        // This function is called by the MFC-supplied WinMain function, as part of the CWinApp initialization of a GUI-based
                        // application, to initialize MFC.
             if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))  
              goto InitFailure;

             // App global initializations (rare)
             if (pApp != NULL && !pApp->InitApplication())  //InitApplication已經(jīng)過時,用InitInstance代替,完成MFC內(nèi)部管理方面的工作
              goto InitFailure;

             // Perform specific initializations
             if (!pThread->InitInstance())  // 初始化Instance,在每個 a copy of the program runs的時候,虛函數(shù)
             {
              if (pThread->m_pMainWnd != NULL)
              {
               TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n");
               pThread->m_pMainWnd->DestroyWindow();   // m_pMainWnd holds a pointer to the application's main window.返回一個CWnd.
                           // cWnd Destroys the attached Windows window.
              }
              nReturnCode = pThread->ExitInstance();    // to exit this instance of the thread
              goto InitFailure;
             }
             nReturnCode = pThread->Run();  

            InitFailure:
            #ifdef _DEBUG
             // Check for missing AfxLockTempMap calls
             if (AfxGetModuleThreadState()->m_nTempMapLock != 0)
             {
              TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",
               AfxGetModuleThreadState()->m_nTempMapLock);
             }
             AfxLockTempMaps();
             AfxUnlockTempMaps(-1);
            #endif

             AfxWinTerm();
             return nReturnCode;
            }


            找到了WinMain函數(shù)后,看了下MFC為我生成的類:
            1. CTestApp  2. CTestView 3. CMainFrame  4. CTestDoc  5. CAboutDlg
            查看CTestApp.cpp,發(fā)現(xiàn)了一個全局的CTestApp theApp,因為全局對象必須在main函數(shù)之前產(chǎn)生并初始化,所以應用程序調(diào)用的順序應該是
            CTestApp的構造函數(shù) -> WinMain函數(shù)
            又發(fā)現(xiàn)class CTestApp : public CWinApp,子類的構造函數(shù)在父類的構造函數(shù)調(diào)用之后調(diào)用,所以就搜索CWinApp吧。

            在appcore.cpp的368行發(fā)現(xiàn)以下代碼:
            CWinApp::CWinApp(LPCTSTR lpszAppName)  // 此處的lpszAppName有個默認參數(shù)NULL
            {
             if (lpszAppName != NULL)
              m_pszAppName = _tcsdup(lpszAppName); // 為lpszAppName分配內(nèi)存
             else
              m_pszAppName = NULL;

             // initialize CWinThread state
             AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
             ENSURE(pModuleState);
             AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
             ENSURE(pThreadState);
             ASSERT(AfxGetThread() == NULL);
             pThreadState->m_pCurrentWinThread = this;  // 如果有子類繼承了CWinApp, this就是子類
             ASSERT(AfxGetThread() == this);
             m_hThread = ::GetCurrentThread();
             m_nThreadID = ::GetCurrentThreadId();

             // initialize CWinApp state
             ASSERT(afxCurrentWinApp == NULL); // only one CWinApp object please
             pModuleState->m_pCurrentWinApp = this;   // 如果有子類繼承了CWinApp, this就是子類
             ASSERT(AfxGetApp() == this);

             // in non-running state until WinMain
             m_hInstance = NULL;
             m_hLangResourceDLL = NULL;v
             m_pszHelpFilePath = NULL;
             m_pszProfileName = NULL;
             m_pszRegistryKey = NULL;
             m_pszExeName = NULL;
             m_pRecentFileList = NULL;
             m_pDocManager = NULL;
             m_atomApp = m_atomSystemTopic = NULL;
             m_lpCmdLine = NULL;
             m_pCmdInfo = NULL;

             // initialize wait cursor state
             m_nWaitCursorCount = 0;
             m_hcurWaitCursorRestore = NULL;

             // initialize current printer state
             m_hDevMode = NULL;
             m_hDevNames = NULL;
             m_nNumPreviewPages = 0;     // not specified (defaults to 1)

             // initialize DAO state
             m_lpfnDaoTerm = NULL;   // will be set if AfxDaoInit called

             // other initialization
             m_bHelpMode = FALSE;
             m_eHelpType = afxWinHelp;
             m_nSafetyPoolSize = 512;        // default size
            }

            然后是CTestApp的構造函數(shù)的調(diào)用。
            在CTestApp的聲明中,它重寫了InitInstance函數(shù),如下:
            BOOL CTestApp::InitInstance()
            {
             AfxEnableControlContainer();  //Call this function in your application object's InitInstance function
                      //to enable support for containment of ActiveX controls

             // Standard initialization
             // If you are not using these features and wish to reduce the size
             //  of your final executable, you should remove from the following
             //  the specific initialization routines you do not need.

            // In MFC 5.0, Enable3dControls and Enable3dControlsStatic are obsolete because their functionality is incorporated
            // into Microsoft's 32-bit and 64-bit operating systems.  
             
            #ifdef _AFXDLL
             Enable3dControls();   // Call this when using MFC in a shared DLL
            #else
             Enable3dControlsStatic(); // Call this when linking to MFC statically
            #endif

             // Change the registry key under which our settings are stored.
             // TODO: You should modify this string to be something appropriate
             // such as the name of your company or organization.
             SetRegistryKey(_T("Local AppWizard-Generated Applications"));

             LoadStdProfileSettings();  // Load standard INI file options (including MRU)

             // Register the application's document templates.  Document templates
             //  serve as the connection between documents, frame windows and views.

             CSingleDocTemplate* pDocTemplate;  // 單文檔程序的模板生成
             pDocTemplate = new CSingleDocTemplate(
              IDR_MAINFRAME,
              RUNTIME_CLASS(CTestDoc),
              RUNTIME_CLASS(CMainFrame),       // main SDI frame window
              RUNTIME_CLASS(CTestView));
             AddDocTemplate(pDocTemplate);

             // Parse command line for standard shell commands, DDE, file open
             CCommandLineInfo cmdInfo;   // 對命令查詢分析
             ParseCommandLine(cmdInfo);

             // Dispatch commands specified on the command line
             if (!ProcessShellCommand(cmdInfo))
              return FALSE;

             // The one and only window has been initialized, so show and update it.
             m_pMainWnd->ShowWindow(SW_SHOW);  //顯示和更新窗口
             m_pMainWnd->UpdateWindow();

             return TRUE;
            }


            有了WinMain函數(shù),也找到了顯示和更新窗口的語句,但是從哪里開始設計窗口,注冊窗口,建立窗口呢?
            我又搜索了WNDCLASS,在wincore.cpp的4495行發(fā)現(xiàn)了與設計窗口時很像的函數(shù)BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
            發(fā)現(xiàn)MS已經(jīng)在里面為我注冊了一些窗口,我只要選擇自己想要的樣式就可以了。

            那么如何建立一個窗口呢?我又搜索了CreateWindow,在wincore.cpp的675行中有個BOOL CWnd::CreateEx函數(shù)。
            里面有調(diào)用CreateWindowEx。這個函數(shù)還調(diào)用了一個叫PreCreateWindow的函數(shù),這個函數(shù)主要是確定在建立窗口之前,確保要建立的窗口已經(jīng)注冊了。

            好了,一切都準備好了。最后就是進入消息循環(huán)。

            posted on 2009-03-03 01:24 wil 閱讀(1850) 評論(0)  編輯 收藏 引用

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            導航

            統(tǒng)計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            文章分類

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久亚洲日韩精品一区二区三区| 99久久久精品免费观看国产| 久久精品成人免费看| 国产欧美久久久精品| 国产高潮国产高潮久久久91 | 无遮挡粉嫩小泬久久久久久久| 亚洲国产精品无码久久久蜜芽| 狠狠狠色丁香婷婷综合久久五月| 国产高清国内精品福利99久久| 久久综合一区二区无码| 色综合久久中文字幕无码| 久久久久久a亚洲欧洲aⅴ| 久久久精品波多野结衣| 亚洲国产精品无码久久久蜜芽 | 久久性生大片免费观看性| 久久精品国产久精国产果冻传媒 | 九九久久精品无码专区| 亚洲AV日韩精品久久久久久| 精品99久久aaa一级毛片| 伊人久久大香线焦AV综合影院 | 久久国产影院| av无码久久久久不卡免费网站| 青青热久久国产久精品 | 国产美女久久久| 久久99亚洲网美利坚合众国| 久久人妻少妇嫩草AV无码蜜桃| 新狼窝色AV性久久久久久| 亚洲精品国产自在久久| 久久精品中文字幕有码| 91精品婷婷国产综合久久| 久久99精品国产麻豆| 日韩精品久久久肉伦网站| 一级a性色生活片久久无少妇一级婬片免费放 | 亚洲综合久久综合激情久久| 亚洲va中文字幕无码久久不卡| 久久久久亚洲AV无码专区首JN| 一极黄色视频久久网站| 偷窥少妇久久久久久久久| 亚洲中文字幕伊人久久无码| 一本久久免费视频| 亚洲中文字幕久久精品无码喷水|