MFC编程——Where is WinMain?
阅读原文时间:2023年07月10日阅读:2

源码

#include

class MyApp :public CWinApp
{
public:
virtual BOOL InitInstance();
};

MyApp theApp;

BOOL MyApp::InitInstance()
{
//创建一个代表框架窗口的类
CFrameWnd* pFrame = new CFrameWnd;
//在将框架窗口类和主程序类之间建立联系
this->m_pMainWnd = pFrame;
//创建窗口
pFrame->Create(NULL, TEXT("MFC"));//注册窗口类(::RegisterClassEx),创建窗口(::CreateWindowEx)
//显示窗口
pFrame->ShowWindow(SW_SHOW);//::ShowWindow
//刷新窗口
pFrame->UpdateWindow();//::UpdateWindow
return TRUE;
}

再第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源码

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
ASSERT(hPrevInstance == NULL);

 int nReturnCode = -;  
 CWinThread\* pThread = AfxGetThread();  
 CWinApp\* pApp = AfxGetApp();

 // AFX internal initialization  
 if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow))  
     goto InitFailure;

 // App global initializations (rare)  
 if (pApp != NULL && !pApp->InitApplication())  
     goto InitFailure;

 // Perform specific initializations  
 if (!pThread->InitInstance())  
 {  
     if (pThread->m\_pMainWnd != NULL)  
     {  
         TRACE(traceAppMsg, , "Warning: Destroying non-NULL m\_pMainWnd\\n");  
         pThread->m\_pMainWnd->DestroyWindow();  
     }  
     nReturnCode = pThread->ExitInstance();  
     goto InitFailure;  
 }  
 nReturnCode = pThread->Run();

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

 AfxWinTerm();  
 return nReturnCode;  

}

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

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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章