青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

winlinglin

MFC學習筆記(一)

Win32應用程序有條明確的主線:
 (1) 進入WinMain函數
 (2) 設計一個Window
 (3) 注冊這個Window
 (4) 建立這個Window
 (5) 顯示和更新這個Window
 (6) 進入消息循環
 
好,我就先找WinMain函數吧。
我在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函數

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

我在winmain.cpp的19行找到了AfxWinMain函數。
代碼:
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 _In_ LPTSTR lpCmdLine, int nCmdShow)
{
 ASSERT(hPrevInstance == NULL);   // ASSERT在程序運行時它計算括號內的表達式,如果表達式為FALSE (0),
           // 程序將報告錯誤,并終止執行。如果表達式不為0,則繼續執行后面的語句。
           // ASSERT只有在Debug版本中才有效,如果編譯為Release版本則被忽略。
           // assert()的功能類似,它是ANSI C標準中規定的函數,它與ASSERT的一個重要區別是可以用在Release版本中。
 int nReturnCode = -1;
 // AfxGetThread和 AfxGetApp 都是全局函數
 CWinThread* pThread = AfxGetThread();  // 獲得正在執行的線程,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已經過時,用InitInstance代替,完成MFC內部管理方面的工作
  goto InitFailure;

 // Perform specific initializations
 if (!pThread->InitInstance())  // 初始化Instance,在每個 a copy of the program runs的時候,虛函數
 {
  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函數后,看了下MFC為我生成的類:
1. CTestApp  2. CTestView 3. CMainFrame  4. CTestDoc  5. CAboutDlg
查看CTestApp.cpp,發現了一個全局的CTestApp theApp,因為全局對象必須在main函數之前產生并初始化,所以應用程序調用的順序應該是
CTestApp的構造函數 -> WinMain函數
又發現class CTestApp : public CWinApp,子類的構造函數在父類的構造函數調用之后調用,所以就搜索CWinApp吧。

在appcore.cpp的368行發現以下代碼:
CWinApp::CWinApp(LPCTSTR lpszAppName)  // 此處的lpszAppName有個默認參數NULL
{
 if (lpszAppName != NULL)
  m_pszAppName = _tcsdup(lpszAppName); // 為lpszAppName分配內存
 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的構造函數的調用。
在CTestApp的聲明中,它重寫了InitInstance函數,如下:
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函數,也找到了顯示和更新窗口的語句,但是從哪里開始設計窗口,注冊窗口,建立窗口呢?
我又搜索了WNDCLASS,在wincore.cpp的4495行發現了與設計窗口時很像的函數BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
發現MS已經在里面為我注冊了一些窗口,我只要選擇自己想要的樣式就可以了。

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

好了,一切都準備好了。最后就是進入消息循環。

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


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

導航

統計

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

文章分類

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美日本亚洲| 欧美电影在线观看完整版| 国产精品一区二区男女羞羞无遮挡| 久久偷窥视频| 久久欧美中文字幕| 麻豆国产精品va在线观看不卡| 欧美二区在线观看| 欧美视频在线观看一区二区| 国产精品一区亚洲| 在线免费观看视频一区| 亚洲美女av网站| 香蕉免费一区二区三区在线观看 | 国产精品久久久久一区二区| 国产精品免费看| 国产在线成人| 亚洲最新合集| 久久久精品国产99久久精品芒果| 欧美不卡一卡二卡免费版| 亚洲精品在线二区| 午夜国产精品视频| 欧美成人免费大片| 欧美二区在线| 亚洲国产欧美另类丝袜| 亚洲欧洲精品一区二区三区| 日韩一二在线观看| 噜噜爱69成人精品| 国产日本欧美视频| 在线综合视频| 免费一级欧美在线大片| 日韩午夜精品视频| 久久综合久久久久88| 国产精品永久免费| 一本色道88久久加勒比精品| 久久综合影视| 亚洲资源在线观看| 欧美日韩国产系列| 亚洲国产片色| 久久夜色精品亚洲噜噜国产mv | 狠狠色狠色综合曰曰| 夜夜嗨av一区二区三区四区| 久久一日本道色综合久久| 亚洲美女黄色片| 久久亚洲欧美| 国产自产精品| 久久不射2019中文字幕| 一本一本a久久| 欧美另类变人与禽xxxxx| 在线播放豆国产99亚洲| 久久久www成人免费毛片麻豆| 夜夜躁日日躁狠狠久久88av| 欧美精品在线观看91| 亚洲日韩欧美视频一区| 欧美1区3d| 久久一综合视频| 在线日本高清免费不卡| 蜜桃av噜噜一区| 久久久久久伊人| 国产尤物精品| 免费观看一区| 麻豆国产精品va在线观看不卡| 影音先锋久久久| 免费看成人av| 美日韩精品免费| 亚洲欧洲偷拍精品| 亚洲高清123| 欧美精品日韩三级| 99一区二区| 亚洲精品久久久久中文字幕欢迎你| 欧美成人免费在线| 一区二区免费看| 亚洲一卡二卡三卡四卡五卡| 国产麻豆日韩| 久久视频在线视频| 久久综合色88| 日韩亚洲欧美在线观看| 一区二区三区波多野结衣在线观看| 欧美日韩在线另类| 欧美亚洲网站| 欧美不卡高清| 亚洲一区在线视频| 亚洲欧美日本在线| 欧美伊久线香蕉线新在线| 影音先锋亚洲电影| 亚洲精品网站在线播放gif| 国产精品久久久久久久久免费樱桃 | 亚洲黄色成人| 欧美性大战xxxxx久久久| 午夜精品久久久久久久久| 欧美一区二区视频在线观看2020 | 国产毛片一区二区| 欧美成人网在线| 欧美手机在线视频| 久久久久久一区二区三区| 麻豆av福利av久久av| 亚洲影视九九影院在线观看| 欧美在线播放高清精品| 亚洲精品一区久久久久久| 亚洲永久免费精品| 亚洲国产日韩一区二区| 亚洲天堂激情| 亚洲国产精品一区在线观看不卡 | 欧美一级二级三级蜜桃| 在线日韩电影| 夜夜爽av福利精品导航| 黄色免费成人| 宅男66日本亚洲欧美视频| 亚洲春色另类小说| 亚洲尤物视频网| 亚洲免费观看高清在线观看| 午夜精品成人在线| 亚洲最快最全在线视频| 久久一区二区三区av| 欧美一级专区| 欧美日韩亚洲国产精品| 欧美xx69| 在线成人激情| 欧美制服丝袜| 亚洲欧美精品在线| 欧美日本国产视频| 欧美高潮视频| 亚洲国产欧美一区二区三区同亚洲 | 一区二区三区www| 亚洲精品乱码久久久久久蜜桃91| 久久久久久久精| 欧美日韩精品一区二区在线播放| 免费观看成人网| 国产一区二区电影在线观看| 一区二区高清在线| 99www免费人成精品| 欧美aⅴ一区二区三区视频| 久久亚洲私人国产精品va| 国产主播一区二区| 久久九九久精品国产免费直播| 欧美一级大片在线观看| 国产精品乱码妇女bbbb| 亚洲视频成人| 午夜精品一区二区三区在线| 欧美亚一区二区| 亚洲免费激情| 亚洲一区一卡| 国产精品午夜av在线| 亚洲欧美成人| 久久久精品日韩欧美| 宅男噜噜噜66一区二区 | 亚洲欧美中文日韩v在线观看| 欧美劲爆第一页| 亚洲美女福利视频网站| 亚洲最黄网站| 国产精品欧美日韩一区| 欧美一级淫片播放口| 久久亚洲春色中文字幕久久久| 国一区二区在线观看| 久久嫩草精品久久久精品一| 亚洲国产精品毛片| 亚洲一区二区不卡免费| 国产美女精品一区二区三区| 欧美一区激情视频在线观看| 蜜月aⅴ免费一区二区三区| 亚洲黄色在线| 欧美性淫爽ww久久久久无| 欧美在线视频不卡| 欧美国产三级| 午夜亚洲伦理| 亚洲第一福利社区| 欧美日韩亚洲国产一区| 午夜精品久久99蜜桃的功能介绍| 久久中文欧美| 中国成人黄色视屏| 国产欧美日韩亚洲| 美女爽到呻吟久久久久| 最新国产精品拍自在线播放| 午夜精彩视频在线观看不卡| 在线精品视频一区二区| 欧美在线精品一区| 牛牛精品成人免费视频| 亚洲欧美在线一区二区| 今天的高清视频免费播放成人 | 日韩午夜中文字幕| 欧美色图一区二区三区| 性刺激综合网| 亚洲欧洲精品成人久久奇米网| 亚洲先锋成人| 亚洲国产成人91精品| 国产精品入口夜色视频大尺度| 久久久久久尹人网香蕉| 亚洲午夜精品久久久久久浪潮 | 亚洲欧美久久久| 亚洲一区视频| 亚洲第一成人在线| 羞羞视频在线观看欧美| 亚洲人成人77777线观看| 久久免费视频这里只有精品| 一区二区国产日产| 欧美精品国产一区二区| 欧美尤物巨大精品爽| 亚洲精品欧美日韩专区| 免费观看30秒视频久久| 久久精品免费| 欧美在线视频二区| 香蕉免费一区二区三区在线观看|