实例HelloWord.cpp 首先创建一个CHelloWordApp theApp类型的全局变量;调用完CHelloWordApp 和CWinAppEx以及CWinApp的构造函数以后进入
extern “C” int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
In LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
在TCHAR.h中,有此定义:#define _tWinMain WinMain,所以这里的_tWinMain就是WinMain函数。它调用了AfxWinMain函数(位于WinMain.cpp中)。
在_tWinMain调用了AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow),
在AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
{
// App global initializations (rare)
CWinThread* pThread = AfxGetThread();//得到当前应用程序指针
CWinApp* pApp = AfxGetApp();//AfxGetApp()返回的是应用程序对象theApp的指针.
if (pApp != NULL && !pApp->InitApplication())
goto InitFailure;
if (!pThread->InitInstance())//访问到HelloWord程序中的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();//进入消息循环;
}
MFC里AfxGetThread()与AfxGetAPP()的区别
复制代码
1 CWinThread* AFXAPI AfxGetThread()
2 {
3 // check for current thread in module thread state
4 AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
5 CWinThread* pThread = pState->m_pCurrentWinThread;
6
7 // if no CWinThread for the module, then use the global app
8 if (pThread == NULL)
9 pThread = AfxGetApp();
10
11 return pThread;
12 }
复制代码
复制代码
1 _AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
2 {
3 return afxCurrentWinapp;
4 }
5 //在AFXWIN.H中 #define afxCurrentWinApp AfxGetModuleState()->m_pCurrentWinApp
6 //AfxGetModuleState()就是得到当前模块,AfxGetModuleState()->m_pCurrentWinApp=this;得到当前应用程序的对象指针
复制代码
AfxGetThread()返回的是当前界面线程对象的指针,AfxGetApp()返回的是应用程序对象theApp的指针.
如果该应用程序(或进程)只有一个界面线程在运行,那么这两者返回的都是一个全局的应用程序对象theApp的指针。
如果在多线程时调用AfxGetThread返回的与AfxGetApp并不一定相同。
nReturnCode = pThread->Run();//进入消息循环;
进入函数后发现:
int CWinApp::Run()
{
if (m_pMainWnd == NULL && AfxOleGetUserCtrl())
{
// Not launched /Embedding or /Automation, but has no main window!
TRACE(traceAppMsg, 0, “Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.\n”);
AfxPostQuitMessage(0);
}
return CWinThread::Run();//进入这个Run()
}
CHelloWordApp::InitInstance()里面会创建一个
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
int x, int y, int nWidth, int nHeight,
HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam) 窗口
创建窗口的同时会安装AfxCbtFilterHook
// 安插AfxCbtFilterHook
AfxHookWindowCreate(this);
void AFXAPI AfxHookWindowCreate(CWnd* pWnd)
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
if (pThreadState->m_pWndInit == pWnd)
return;
if (pThreadState->m_hHookOldCbtFilter == NULL)
{
// 安插_AfxCbtFilterHook,因为_AfxCbtFilterHook()是一个基于计算机训练的hook,
// 所以windows在激活、创建、销毁、最大化、最小化、移动窗口或改变窗口大小之前,
// 会调用_AfxCbtFilterHook()
pThreadState->m_hHookOldCbtFilter = ::SetWindowsHookEx(WH_CBT,
_AfxCbtFilterHook, NULL, ::GetCurrentThreadId());
if (pThreadState->m_hHookOldCbtFilter == NULL)
AfxThrowMemoryException();
}
ASSERT(pThreadState->m_hHookOldCbtFilter != NULL);
ASSERT(pWnd != NULL);
ASSERT(pWnd->m_hWnd == NULL); // only do once
ASSERT(pThreadState->m_pWndInit == NULL); // hook not already in progress
pThreadState->m_pWndInit = pWnd;
}
_AfxCbtFilterHook通过SetWindowLongPtr函数将窗口的处理函数替换成AfxWndProc(),同时,在CWnd::m_pfnSuper中保存原来的窗口消息处理函数指针;下面截取一小段:
LRESULT CALLBACK
_AfxCbtFilterHook(int code, WPARAM wParam, LPARAM lParam)
{
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData()
if (code != HCBT_CREATEWND)
{
// wait for HCBT_CREATEWND just pass others on...//在调用create Wind 的时候会触发这个消息;
return CallNextHookEx(pThreadState->m_hHookOldCbtFilter, code,
wParam, lParam);
}
if (pWndInit != NULL)
{
AFX_MANAGE_STATE(pWndInit->m_pModuleState);
// the window should not be in the permanent map at this time
ASSERT(CWnd::FromHandlePermanent(hWnd) == NULL);
// connect the HWND to pWndInit...
pWndInit->Attach(hWnd);
// allow other subclassing to occur first
pWndInit->PreSubclassWindow();
// 消息处理函数指针,用于存储原来的消息处理函数
WNDPROC *pOldWndProc = pWndInit->GetSuperWndProcAddr();
ASSERT(pOldWndProc != NULL);
// 将窗口的消息处理函数设置成AfxWndProc()
// subclass the window with standard AfxWndProc
WNDPROC afxWndProc = AfxGetAfxWndProc();
oldWndProc = (WNDPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC,
(DWORD_PTR)afxWndProc);
ASSERT(oldWndProc != NULL);
if (oldWndProc != afxWndProc)
*pOldWndProc = oldWndProc;
pThreadState->m_pWndInit = NULL;
}
下面是AfxWndProc函数定义
LRESULT CALLBACK
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
// special message which identifies the window as using AfxWndProc
if (nMsg == WM_QUERYAFXWNDPROC)
return 1;
// all other messages route through message map
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
ASSERT(pWnd != NULL);
ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd);
if (pWnd == NULL || pWnd->m_hWnd != hWnd)
return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
}
Run中会调用LRESULT CALLBACK
AfxWndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
// special message which identifies the window as using AfxWndProc
if (nMsg == WM_QUERYAFXWNDPROC)
return 1;
// all other messages route through message map
CWnd* pWnd = CWnd::FromHandlePermanent(hWnd);
ASSERT(pWnd != NULL);
ASSERT(pWnd==NULL || pWnd->m_hWnd == hWnd);
if (pWnd == NULL || pWnd->m_hWnd != hWnd)
return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
return AfxCallWndProc(pWnd, hWnd, nMsg, wParam, lParam);
}