举例:我新建一个名称是lesson4的MFC工程,那么在Clesson4App类的实现文件中,框架自动声明一个全局变量:
Clesson4App theApp;
所有的MFC有且只有一个CWinApp实例,并且这个实例是放在AfxWinMain()之前的,也就是说,在进入传统的WinMain()之前,这个对象已经被构造出来。
进入AfxWinMain()后首先获取Clesson4App对象的指针,调用InitInstance()函数进行窗口类注册与创建,显示,然后调用CWinApp的Run()函数进行消息循环。
/*
winmain.cpp
*/
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
{
int nReturnCode = -1;
CWinThread* pThread = AfxGetThread();//CWinApp由CWinThread派生
CWinApp* pApp = AfxGetApp(); //这两行的指针都指向框架创建的Clesson4App
// 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()) //这里调用Clesson4App的InitInstance()
{
/*.....省略....*/
}
nReturnCode = pThread->Run(); //消息循环
InitFailure:
AfxWinTerm(); //初始化失败
return nReturnCode;
}
这个函数用于把向导生成的CMainFrame类,文档类,视类组建成文档模板类,然后分别创建并显示,更新。
InitInstance()函数是CWinApp类的一个虚函数,MFC框架向导已经在生成的Clesson4App里重写了这个函数:
BOOL Clesson4App::InitInstance()
{
/*此处省略。。。。。。。。*/
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));//操作注册表
LoadStdProfileSettings(4); // 加载标准 INI 文件选项(包括 MRU)
/*此处省略。。。。。。。。*/
// 注册应用程序的文档模板。文档模板
// 将用作文档、框架窗口和视图之间的连接
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(Clesson4Doc),
RUNTIME_CLASS(CMainFrame), // 主 SDI 框架窗口
RUNTIME_CLASS(Clesson4View));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
/*此处省略。。。。。。。。*/
// 唯一的一个窗口已初始化,因此显示它并对其进行更新
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
return TRUE;
}
/*
wincore.cpp
*/
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister)
{
fToRegister &= ~pModuleState->m_fRegisteredClasses;
LONG fRegisteredClasses = 0;
WNDCLASS wndcls;
memset(&wndcls, 0, sizeof(WNDCLASS)); // 清空wndcls
wndcls.lpfnWndProc = DefWindowProc; //赋默认消息处理函数
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hCursor = afxData.hcurArrow;
INITCOMMONCONTROLSEX init;
init.dwSize = sizeof(init);
//判断向导的窗口类,然后赋值
if (fToRegister & AFX_WND_REG)
{
// Child windows - no brush, no icon, safest default class styles
wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wndcls.lpszClassName = _afxWnd;
if (AfxRegisterClass(&wndcls))
fRegisteredClasses |= AFX_WND_REG;
}
/*省略。。。。。。。。*/
pModuleState->m_fRegisteredClasses |= fRegisteredClasses;
// 返回向导指定的窗口类
return (fToRegister & fRegisteredClasses) == fToRegister;
}
typedef struct tagMSG
{
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG, *PMSG;
hwnd指向了具体的窗口,而CWnd类对象有一个成员变量m_hwnd,所以消息触发以后传递给窗口基类,
LRESULT CWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// OnWndMsg does most of the work, except for DefWindowProc call
LRESULT lResult = 0;
if (!OnWndMsg(message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}
BOOL CWnd::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
LRESULT lResult = 0;
union MessageMapFunctions mmf;
mmf.pfn = 0;
CInternalGlobalLock winMsgLock;
// special case for commands
if (message == WM_COMMAND)
{
if (OnCommand(wParam, lParam))
{
lResult = 1;
goto LReturnTrue;
}
return FALSE;
}
// special case for notifies
if (message == WM_NOTIFY)
{
NMHDR* pNMHDR = (NMHDR*)lParam;
if (pNMHDR->hwndFrom != NULL && OnNotify(wParam, lParam, &lResult))
goto LReturnTrue;
return FALSE;
}
// special case for activation
if (message == WM_ACTIVATE)
_AfxHandleActivate(this, wParam, CWnd::FromHandle((HWND)lParam));
// special case for set cursor HTERROR
if (message == WM_SETCURSOR &&
_AfxHandleSetCursor(this, (short)LOWORD(lParam), HIWORD(lParam)))
{
lResult = 1;
goto LReturnTrue;
}
CWnd::OnWndMsg()进行消息判断 ON_COMMAND ON_NOTIFY查看是否有消息处理函数与触发的WM_XXXX对应