MFC编程——Where is WinMain?
源码
1 #include<afxwin.h> 2 3 class MyApp :public CWinApp 4 { 5 public: 6 virtual BOOL InitInstance(); 7 }; 8 9 MyApp theApp; 10 11 BOOL MyApp::InitInstance() 12 { 13 //创建一个代表框架窗口的类 14 CFrameWnd* pFrame = new CFrameWnd; 15 //在将框架窗口类和主程序类之间建立联系 16 this->m_pMainWnd = pFrame; 17 //创建窗口 18 pFrame->Create(NULL, TEXT("MFC"));//注册窗口类(::RegisterClassEx),创建窗口(::CreateWindowEx) 19 //显示窗口 20 pFrame->ShowWindow(SW_SHOW);//::ShowWindow 21 //刷新窗口 22 pFrame->UpdateWindow();//::UpdateWindow 23 return TRUE; 24 }
再第18行打一个断点。F5
调用顺序:
①kernel32.dll!
②wWinMainCRTStartup()
③__tmainCRTStartup()
④wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)
⑤AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow)
⑥MyApp::InitInstance()
对应Windows API编程,MFC把WinMain替换成了AfxWinMain,只是改了个函数名字,函数参数都一样。
AfxWinMain源码
1 int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 2 _In_ LPTSTR lpCmdLine, int nCmdShow) 3 { 4 ASSERT(hPrevInstance == NULL); 5 6 int nReturnCode = -1; 7 CWinThread* pThread = AfxGetThread(); 8 CWinApp* pApp = AfxGetApp(); 9 10 // AFX internal initialization 11 if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) 12 goto InitFailure; 13 14 // App global initializations (rare) 15 if (pApp != NULL && !pApp->InitApplication()) 16 goto InitFailure; 17 18 // Perform specific initializations 19 if (!pThread->InitInstance()) 20 { 21 if (pThread->m_pMainWnd != NULL) 22 { 23 TRACE(traceAppMsg, 0, "Warning: Destroying non-NULL m_pMainWnd\n"); 24 pThread->m_pMainWnd->DestroyWindow(); 25 } 26 nReturnCode = pThread->ExitInstance(); 27 goto InitFailure; 28 } 29 nReturnCode = pThread->Run(); 30 31 InitFailure: 32 #ifdef _DEBUG 33 // Check for missing AfxLockTempMap calls 34 if (AfxGetModuleThreadState()->m_nTempMapLock != 0) 35 { 36 TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n", 37 AfxGetModuleThreadState()->m_nTempMapLock); 38 } 39 AfxLockTempMaps(); 40 AfxUnlockTempMaps(-1); 41 #endif 42 43 AfxWinTerm(); 44 return nReturnCode; 45 }
CWinThread:代表一个线程
AfxGetThread():获得我们定义theApp对象的地址
AfxGetApp():获得我们定义theApp对象的地址
这两个函数都是获取我们定义theApp对象的地址:因为CMyApp继承与CWinApp,CWinApp继承于CWinThread。
消息循环在哪?
CWinApp::Run() ——>CWinThread::Run()——>CWinThread::PumpMessage() ——>AfxInternalPumpMessage() ——>::TranslateMessage();和::DispatchMessage();
创建窗口
MyApp::InitInstance() ——>CFrameWnd::Create(const wchar_t * lpszClassName, const wchar_t * lpszWindowName, unsigned long dwStyle, const tagRECT & rect, CWnd * pParentWnd, const wchar_t * lpszMenuName, unsigned long dwExStyle, CCreateContext * pContext) ——>CWnd::CreateEx(unsigned long dwExStyle, const wchar_t * lpszClassName, const wchar_t * lpszWindowName, unsigned long dwStyle, int x, int y, int nWidth, int nHeight, HWND__ * hWndParent, HMENU__ * nIDorHMenu, void * lpParam)
注册窗口
CWinApp这个类(包括这个类的导出类)代表了我们的程序。一个程序,只允许有一个CWinApp或者继承自CWinApp类的对象实例。
CFrameWnd这个类,代表了程序框架窗口
CWinApp封装了消息循环
CFrameWnd封装了注册窗口类,创建窗口,显示和刷新窗口
通过这两个类,我们可以创建一个应用程序。这两个类将应用程序的窗口类注册,创建窗口,消息循环晚藏起来。