深入剖析MFC基础框架——跟踪MFC单文档程序的执行过程:
来源:互联网 发布:智能停车场收费软件 编辑:程序博客网 时间:2024/05/20 14:26
跟踪MFC单文档程序的执行过程:
1、CTestApp theApp; //表示应用程序本身,全局对象
2、CTestApp::CTestApp(){ } //调用构造函数 < class CTestApp::public CWinApp >
以下提到的文件在 D:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC 下。// CWinApp在APPCORE文件中,class CWinApp::public CWinThread
3、//在APPMODUL中定义
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)// 主函数
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
4、// 在WINMAIN.cpp中定义
int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow){
......
if (!pThread->InitInstance()){//虚函数,调用子类的InitInstance()函数。pThread为指向CWinThread对象的指针
......
}
nReturnCode = pThread->Run(); //完成消息循环
}
5、BOOL CTestApp::InitInstance() // 子类的函数
{
......
}
6、// 在WINCORE.cpp中定义
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister) //MFC中提前定义了几个窗口类,在此决定注册哪一个
{
.......
if (AfxRegisterClass(&wndcls))
fRegisteredClasses |= AFX_WND_REG;
// 有n个if语句
} // 单文档牵扯到文档管理,所以注册窗口类位置提前了,多文档没有
7、BOOLCMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return TRUE;
}
8、// CFrameWnd::PreCreateWindow在WINFRM.cpp中定义
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
}
if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
cs.style |= FWS_PREFIXTITLE;
if (afxData.bWin4)
cs.dwExStyle |= WS_EX_CLIENTEDGE;
return TRUE;
}
// AfxDeferRegisterClass 在AFXIMPL中定义,是一个宏:
// #define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
9、因此此处执行的是 步骤6
10、创建窗口:// WINFRM中定义:
BOOL CFrameWnd::Create(LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
LPCTSTR lpszMenuName,
DWORD dwExStyle,
CCreateContext* pContext)
{
.......
if (!CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, // CreateEx是基类(CWnd)中的函数
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), hMenu, (LPVOID)pContext)){
......
}
} //CFrameWnd::LoadFrame()会调用此函数,此处就不演示代码了
11、在WINCORE中定义:
BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,
LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID,
LPVOID lpParam /* = NULL */)
{
return CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID, lpParam);
}
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)
{
// allow modification of several common create parameters
CREATESTRUCT cs;
cs.dwExStyle = dwExStyle;
cs.lpszClass = lpszClassName;
cs.lpszName = lpszWindowName;
cs.style = dwStyle;
cs.x = x;
cs.y = y;
cs.cx = nWidth;
cs.cy = nHeight;
cs.hwndParent = hWndParent;
cs.hMenu = nIDorHMenu;
cs.hInstance = AfxGetInstanceHandle();
cs.lpCreateParams = lpParam;
if (!PreCreateWindow(cs))//又调用一次,这是虚函数,调用的是子类(CMainFrame)中的,若有的话。
{
PostNcDestroy();
return FALSE;
}
AfxHookWindowCreate(this);
HWND hWnd = ::CreateWindowEx(cs.dwExStyle, cs.lpszClass,
cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);
......
return TRUE;
}
12、执行 步骤7
13、执行 步骤8:
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs);
// cs成员变量和CreateWindowEx中参数相同,次序相反。目的:产生窗口之前有机会去修改窗口外观。
// 后面再循环执行后面这几步几次,检查....
14、窗口显示更新:
CWinApp有一个成员变量指针—m_PMainWnd,指向框架类CMainFrame对象。当通过 BOOL CTestApp::InitInstance()内的 ProcessShellCommand(cmdInfo)调用时,框架已经创建完成,尔后调用:
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
完成窗口的显示更新(打断点时会发现窗口显示为透明)。
15、消息循环://在THRDCORD.CPP中
int CWinThread::Run()
{
ASSERT_VALID(this);
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
// acquire and dispatch messages until a WM_QUIT message is received.
for (;;)
{
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))
{
// call OnIdle while in bIdle state
if (!OnIdle(lIdleCount++))
bIdle = FALSE; // assume "no idle" state
}
// phase2: pump messages while available
do
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())
return ExitInstance();
// reset "no idle" state after pumping "normal" message
if (IsIdleMessage(&m_msgCur))
{
bIdle = TRUE;
lIdleCount = 0;
}
} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));
}
ASSERT(FALSE); // not reachable
}
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);
if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
......
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
}
return TRUE;
}
//以上为消息映射(实际上调用了Win32的函数)
- 深入剖析MFC基础框架——跟踪MFC单文档程序的执行过程:
- 深入跟踪MFC程序的执行流程
- 深入跟踪MFC程序的执行流程
- 深入跟踪MFC程序的执行流程
- 深入跟踪MFC程序的执行流程
- 深入剖析 MFC程序的启动过程
- MFC程序执行过程剖析
- MFC程序执行过程剖析
- MFC程序执行过程剖析
- MFC程序执行过程剖析
- MFC 单文档程序的运行过程
- MFC单文档内部执行过程
- MFC程序框架的剖析
- MFC程序框架的剖析
- MFC程序框架的剖析
- MFC程序框架的剖析
- MFC程序框架的剖析 .
- mfc执行过程剖析
- LeetCode: Divide Two Integers
- Python中time模块详解
- 机房收费.NET版重构——总结
- java线程不安全
- 树状数组套主席树(good)uva12345
- 深入剖析MFC基础框架——跟踪MFC单文档程序的执行过程:
- 高速信号和高频信号的区别
- POJ 2456 Aggressive cows(二分搜索最大化最小值)
- 总结StateListDrawable(selector)用法
- 九度_题目1369:字符串的排列
- 约瑟夫问题
- 45个实用的JavaScript技巧、窍门和最佳实践
- Attach Meshes
- HDU 2254 奥运(矩阵)