Fork me on GitHub

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 }
View Code

再第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 }
View Code

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封装了注册窗口类,创建窗口,显示和刷新窗口

通过这两个类,我们可以创建一个应用程序。这两个类将应用程序的窗口类注册,创建窗口,消息循环晚藏起来。

posted @ 2018-07-17 21:14  克拉默与矩阵  阅读(217)  评论(0编辑  收藏  举报