c语言mfc与主函数调用函数,MFC 学习笔记 2 WinMain函数的调用过程

MFC是一个类库, 是别人写好的一套源码,实现了对系统API调用的封装,

与其辛苦学习使用别人设计的类库,不如好好学习一下其实现原理,

一个EXE窗口程序运行后,由系统载入调用的函数过程如下:

一、调用VC运行库文件crtexe.c中的WinMainCRTStartup函数

大致内容整理如下:

主要的功能是设置命令行参数和窗口启动的一些参数。

void WinMainCRTStartup(void )

{

int argc; /* three standard arguments to main */

_TSCHAR **argv;

_TSCHAR **envp;

int mainret;

_TUCHAR *lpszCommandLine;

STARTUPINFO StartupInfo;

_startupinfo startinfo;

__try {

/*

* Set __app_type properly

*/

__set_app_type(_GUI_APP);

__onexitbegin = __onexitend = (_PVFV *)(-1);

_adjust_fdiv = * _imp___adjust_fdiv;

_setargv();

if ( !__defaultmatherr )

__setusermatherr(_matherr);

_setdefaultprecision();

_initterm( __xi_a, __xi_z );

startinfo.newmode = _newmode;

__getmainargs(&argc, &argv, &envp, _dowildcard, &startinfo);

_initterm( __xc_a, __xc_z );

lpszCommandLine = (unsigned char *)_acmdln;

if ( *lpszCommandLine == DQUOTECHAR ) {

while ( *++lpszCommandLine && (*lpszCommandLine

if ( *lpszCommandLine == DQUOTECHAR )

lpszCommandLine++;

}

else {

while (*lpszCommandLine > SPACECHAR)

lpszCommandLine++;

}

while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) {

lpszCommandLine++;

}

StartupInfo.dwFlags = 0;

GetStartupInfo( &StartupInfo );

mainret = WinMain(

GetModuleHandle(NULL),

NULL,

lpszCommandLine,

StartupInfo.dwFlags & STARTF_USESHOWWINDOW

? StartupInfo.wShowWindow

: SW_SHOWDEFAULT

);

__initenv = envp;

mainret = main(argc, argv, envp);

exit(mainret);

}

__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )

{

/*

* Should never reach here

*/

_exit( GetExceptionCode() );

} /* end of try - except */

}

二、调用WinMain函数

winmain是一个函数声明,每个程序中都要自己实现,如果自己没有实现这个函数,就会使用MFC库中实现,

所以每个Win32程序,必须要有一个winmain函数,因为VC运行库中的启动函数WinMainCRTStartup需要调用这个实现函数。

如MFC中也有这个函数声明

extern "C" int WINAPI

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

// call shared/exported WinMain

return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

三、MFC中的AfxWinMain调用

MFC程序也是先调用WinMain,然后转到MFC的AfxWinMain函数。

/

// export WinMain to force linkage to this module

extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow);

extern "C" int WINAPI

_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

// call shared/exported WinMain

return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);

}

四、AfxWinMain函数调用CWinApp中的函数

int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

LPTSTR lpCmdLine, int nCmdShow)

{

ASSERT(hPrevInstance == NULL);

int nReturnCode = -1;

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, 0, "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 != 0)

{

TRACE(traceAppMsg, 0, "Warning: Temp map lock count non-zero (%ld).\n",

AfxGetModuleThreadState()->m_nTempMapLock);

}

AfxLockTempMaps();

AfxUnlockTempMaps(-1);

#endif

AfxWinTerm();

return nReturnCode;

}

在AfxWinMain函数,扯到好几个init**初始化函数,其中pThread->InitInstance()函数,就是MFC向导中生成CMyApp::Initstance之类

在这里就可以开始创建窗口,现在可以开始工作了。

BOOL CTEST1App::InitInstance()

{

CWinApp::InitInstance();

CTEST1Dlg dlg;

m_pMainWnd = &dlg;

INT_PTR nResponse = dlg.DoModal();

return nResponse;

}

这样一个MFC程序的来龙去脉,就是这几个主要的函数实现的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值