`

孙鑫VC++讲座笔记-(3)MFC程序框架的剖析(修订版)

    博客分类:
  • vc++
阅读更多

摘要:讲述MFC AppWizard的原理与MFC程序框架的剖析。AppWizard是一个源代码生成工具,是计算机辅助程序设计工具,WinMain在MFC程序中是 如何从源程序中被隐藏的,theApp全局变量是如何被分配的,MFC框架中的几个类的作用与相互关系,MFC框架窗口是如何产生和销毁的,对窗口类的 PreCreateWindow和OnCreate两个函数的着重分析,Windows窗口与C++中的CWnd类的关系。
1,寻找WinMain入口:
在安装目录下找到MFC文件夹下的SRC文件夹,SRC下是MFC源代码。
WinMain在APPMODUL.CPP中实现:
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
注意:(#define _tWinMain WinMain)

2,对于全局对象或全局变量来说,在程序运行即WinMain函数加载的时候,已经为全局对象或全局变量分配了内存和赋初值。
所以:CTestApp theApp;->CTestApp ::CTestApp(){}->_tWinMain(){}
说 明:每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所实例化的对象,表示应用程序本身。在WIN32程 序当中,表示应用程序是通过WinMain入口函数来表示的(通过一个应用程序的一个实例号这一个标识来表示的)。在基于MFC应用程序中,是通过产生一 个应用程序对象,用它来唯一的表示了应用程序。

3,通过构造应用程序对象过程中调用基类CWinApp的构造函数,在CWinApp的构造函数中对程序包括运行时一些初始化工作完成了。
CWinApp类在APPCORE.CPP中实现:
CWinApp::CWinApp(LPCTSTR lpszAppName){…}//带参数,而CTestApp构造函数没有显式向父类传参,难道CWinApp()有默认参数?见下:
(在CWinApp类定义中, CWinApp(LPCTSTR lpszAppName = NULL); )
注意:CWinApp()函数中:
pThreadState->m_pCurrentWinThread = this;
pModuleState->m_pCurrentWinApp = this
(this指向的是派生类CTestApp对象,即theApp)
调 试:CWinApp::CWinApp();->CTestApp theApp;(->CTestApp ::CTestApp())->CWinApp::CWinApp()->CTestApp ::CTestApp()->_tWinMain(){}

4,_tWinMain函数中通过调用AfxWinMain()函数来完成 它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成, 我们可根据这些类函数来设计自己的应用程序)。
AfxWinMain()函数在WINMAIN.CPP中:
在AfxWinMain()函数中:
CWinApp* pApp = AfxGetApp();
说明:pApp存储的是指向WinApp派生类对象(theApp)的指针。
//_AFXWIN_INLINE CWinApp* AFXAPI AfxGetApp()
// { return afxCurrentWinApp; }

调用pApp->InitApplication():MFC类的一些内部初始化管理。

调用pThread->InitInstance()
说明:pThread也指向theApp,由于基类中virtual BOOL InitInstance()定义为虚函数,所以调用pThread->InitInstance()的时候,调用的是派生类CTestApp的InitInstance()函数。

nReturnCode = pThread->Run();
说明:pThread->Run()完成了消息循环。

5,注册窗口类:AfxEndDeferRegisterClass();
AfxEndDeferRegisterClass()在WINCORE.CPP中实现:
BOOL AFXAPI AfxEndDeferRegisterClass(LONG fToRegister){…}
说明:设计窗口类:在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。
调 试:CWinApp::CWinApp();->CTestApp theApp;(->CTestApp ::CTestApp())->CWinApp::CWinApp()->CTestApp::CTestApp()-> _tWinMain(){}//进入程序
->AfxWinMain();->pApp->InitApplication();->pThread->InitInstance()//父类InitInstance虚函数;
->CTestApp::InitInstance()//子类实现函数;
->AfxEndDeferRegisterClass(LONG fToRegister)//注册所选择的窗口类(出于文档管理,注册提前,正常的应在PreCreateWindow中进行注册)//之后进入创建窗口阶段(以下再不做调试)

6,CMainFrame的PreCreateWindow()://主要是注册窗口类,以及在创建窗口之前让用户有机会对style进行修改
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
return TRUE;
}
说明:
CFrameWnd::PreCreateWindow()函数所在文件:WINFRM.CPP
BOOL CFrameWnd::PreCreateWindow(CREATESTRUCT& cs)
{
if (cs.lpszClass == NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
//判断AFX_WNDFRAMEORVIEW_REG型号窗口类是否注册,如果没有注册则注册
cs.lpszClass = _afxWndFrameOrView; // COLOR_WINDOW background
//把注册后的窗口类名赋给cs.lpszClass
}

if ((cs.style & FWS_ADDTOTITLE) && afxData.bWin4)
cs.style |= FWS_PREFIXTITLE;

if (afxData.bWin4)
cs.dwExStyle |= WS_EX_CLIENTEDGE;

return TRUE;
}

其中:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);//PreCreateWindow()是个虚函数,如果子类有则调用子类的。
#define AfxDeferRegisterClass(fClass) AfxEndDeferRegisterClass(fClass)
const TCHAR _afxWndFrameOrView[] = AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定义为全局数组。
//#define AFX_WNDFRAMEORVIEW AFX_WNDCLASS(”FrameOrView”)

7,创建窗口:
这里只讲解了框架窗口的创建,它的Create()函数在WINFRM.CPP中:
CFrameWnd::Create(…){

CreateEx(…);//从父类继承来的,调用CWnd::CreateEx().

}

CWnd::CreateEx()函数在WINCORE.CPP中:
BOOL CWnd::CreateEx(…){

if (!PreCreateWindow(cs))//虚函数,如果子类有调用子类的。
{
PostNcDestroy();
return FALSE;
}

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);

}
说 明:CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前可以通过 PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。PreCreateWindow(cs))//是虚函数,如果子类有调 用子类的。
HWND CreateWindowEx(
DWORD dwExStyle,
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
typedef struct tagCREATESTRUCT { // cs
LPVOID lpCreateParams;
HINSTANCE hInstance;
HMENU hMenu;
HWND hwndParent;
int cy;
int cx;
int y;
int x;
LONG style;
LPCTSTR lpszName;
LPCTSTR lpszClass;
DWORD dwExStyle;
} CREATESTRUCT;

8,显示和更新窗口:
CTestApp类,TestApp.cpp中
m_pMainWnd->ShowWindow(SW_SHOW);//显示窗口,m_pMainWnd指向框架窗口
m_pMainWnd->UpdateWindow();//更新窗口
说明:
class CTestApp : public CWinApp{…}
class CWinApp : public CWinThread{…}
class CWinThread : public CCmdTarget
{

public:
CWnd* m_pMainWnd;

}

9,消息循环:
int AFXAPI AfxWinMain()
{ …
// Perform specific initializations
if (!pThread->InitInstance()){…}
//完成窗口初始化工作,完成窗口的注册,完成窗口的创建,显示和更新。
nReturnCode = pThread->Run();
//继承基类Run()方法,调用CWinThread::Run()来完成消息循环

}
////////////////////////////////////////////////////////////////
CWinThread::Run()函数在THRDCORE.CPP中
int CWinThread::Run()
{ …
// phase2: pump messages while available
do//消息循环
{
// pump message, but quit on WM_QUIT
if (!PumpMessage())//取消息并处理
return ExitInstance();

} while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE));

}
说明:
BOOL PeekMessage(,,,,)函数说明
The PeekMessage function checks a thread message queue for a message and places the message (if any) in the specified structure.
If a message is available, the return value is nonzero.
If no messages are available, the return value is zero.

/////////////////////////////////////////////////////////////
BOOL CWinThread::PumpMessage()
{

if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))//取消息
{…}

// process this message
if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);//进行消息(如键盘消息)转换
::DispatchMessage(&m_msgCur);//将消息路由给操作系统,由相应的消息响应函数来处理
}
return TRUE;
}

9,文档与视结构:
可以认为CView类窗口是CMainFrame类窗口的子窗口。
CDocument类是文档类。
DOC-VIEW结构将数据本身与它的显示分离开。
文档类:数据的存储,加载
视类:数据的显示,修改

10,文档类,视类,框架类的有机结合:
在CTestApp类CTestApp::InitInstance()函数中通过文档模板将文档类,视类,框架类组织在一起。
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTestDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CTestView));
AddDocTemplate(pDocTemplate);//增加到文档模板

11,窗口类,窗口对象,窗口:
窗口是屏幕上的一块儿矩形区域;窗口类是封装了对窗口的一系列操作的类,比如注册窗口,创建窗口,显示窗口,销毁窗口等等;窗口对象是窗口类的一个实例。

c++, code, mfc, vc, vc++, 孙薪
分享到:
评论

相关推荐

    孙鑫 VC++ 深入详解书中源码

    《孙鑫 VC++ 深入详解》是一本深受程序员喜爱的VC++技术书籍,作者孙鑫以其深入浅出的讲解方式,详细剖析了VC++的底层机制和高级特性。书中的源码是理解理论知识的关键实践部分,通过分析和运行这些代码,读者可以更...

    孙鑫C++教程(全20讲)PPT讲义源码及电子书

    第三课:讲述MFC AppWizard的原理与MFC程序框架的剖析 第四课:MFC消息映射机制的剖析,讲述如何运用ClassWizard 第五课:文本编程 第六课:菜单的工作原理及编写应用 第七课:对话框用户界面程序的编写 第八课:对话框第...

    孙鑫VC++视频讲座配套幻灯+全套示例源代码

    《孙鑫VC++视频讲座配套幻灯+全套示例源代码》是一份全面学习VC++编程的宝贵资源,由知名讲师孙鑫精心制作。这份资料集合了理论讲解、实例演示和源码分析,旨在帮助初学者及有经验的开发者深入理解和掌握VC++这一...

    经典资料:孙鑫vc++视频讲义配套的源代码20集全第1-10。

    《孙鑫VC++视频讲义配套源代码》是一份经典的编程学习资源,涵盖了从基础到进阶的VC++编程知识。这份资料由知名IT讲师孙鑫精心制作,旨在帮助学习者通过实际操作来理解VC++编程的核心概念和技术。源代码分为20个部分...

    java技术从入门到精通(孙鑫)学习笔记-Lesson2.doc

    java技术从入门到精通(孙鑫)学习笔记-Lesson2

    MFC-lesson3-AppWizard的原理与MFC程序框架的剖析.rar

    在本课程“MFC-lesson3-AppWizard的原理与MFC程序框架的剖析”中,我们将深入探讨MFC的核心组件,特别是AppWizard工具的使用,以及MFC程序的基本框架结构。 AppWizard是Visual C++集成开发环境中的一个实用工具,它...

    孙鑫_VC++入门到精通_源代码

    《孙鑫_VC++入门到精通_源代码》是著名编程教育家孙鑫老师针对初学者推出的VC++学习资源,旨在帮助学习者系统地掌握Visual C++编程基础与进阶技术。该资源包含了丰富的源代码实例,覆盖了多个课程章节,如lesson 17...

    孙鑫老师VC++6.0视频教程对应源代码

    它集成了编译器、调试器以及丰富的类库,支持MFC(Microsoft Foundation Classes)框架,使得Windows应用程序开发变得更加便捷。 【孙鑫老师与VC++6.0教程】 孙鑫老师是中国知名的计算机教育专家,他在编程教学领域...

    VC++深入详解-孙鑫,孙老师的C++ 课程的配套demo 源码

    《VC++深入详解》是孙鑫老师的一部经典著作,主要针对C++编程语言在Microsoft Visual C++(简称VC++)环境下的应用进行深入讲解。这本书不仅覆盖了C++的基础语法,还包括了高级特性和实战技巧,是学习C++编程的理想...

    孙鑫_VC++入门到精通_PPT

    4. **MFC框架**:讲解Microsoft Foundation Classes(MFC)库,它是VC++用于构建Windows应用程序的标准库,包括窗口、控件、消息处理机制等内容。 5. **Windows编程**:深入探讨Windows API,学习如何创建窗口、...

    vc视频教程-MFC AppWizard的原理与MFC程序框架的剖析.zip

    《VC视频教程——MFC AppWizard的原理与MFC程序框架的剖析》是孙鑫老师针对C++编程语言中的Microsoft Foundation Class (MFC) 库进行深入讲解的课程。MFC是一个由微软提供的C++类库,它为Windows应用程序开发提供了...

    java技术从入门到精通(孙鑫)学习笔记-Lesson2(面向对象上).doc

    创建对象时,通过`new Point(3,3)`调用此构造方法,所以`output()`方法打印出的坐标值为3,3。 Java中的构造方法是至关重要的,因为它们确保了对象在创建时就处于一个合理的初始状态。如果开发者没有显式定义构造...

    vc++PPT讲义和mfc教程及c++入门基础讲解

    该资源由内附孙鑫讲解的vc++编程1-20课的PPT讲解和详细实现代码,另附c++入门基础的课程,是每位c++编程爱好者必学的课程资源c++编程进阶的必经之路。

    孙鑫MFC全套程序,基于vs2015

    《孙鑫MFC全套程序解析:基于Visual Studio 2015的实践指南》 MFC,即Microsoft Foundation Classes,是微软提供的一套C++类库,用于简化Windows应用程序的开发。孙鑫,作为国内知名的编程教育专家,以其深入浅出的...

    语言程序设计资料:Java-笔记-孙鑫版.doc

    语言程序设计资料:Java-笔记-孙鑫版.doc

    孙鑫MFC完整笔记.pdf

    孙鑫pdf文档,入门C++的好帮手,MFC类库,vc6.0,虽然版本比较老,但是在很多地方使用得仍然比较多。参考性大

    第1章-MFC-面向对象程序设计.ppt

    - 《VC++深入详解》孙鑫:结合实例,全面解析VC++的各个方面。 - 《Visual C++开发实战1200例》刘锐宁:丰富的实例帮助巩固技能。 通过学习MFC,开发者可以构建具有专业品质的Windows应用程序,包括GUI界面、文件...

    VC++深入详解 PDF教程及示例代码.rar

    本书主要从程序内部运行的机制和MFC程序的组织脉络入手,使读者在学习VC++编程知识时,既能够知其然,又能知其所以然,从而帮助读者从根本上理解和掌握Windows的程序设计。另外,全书还贯穿作者多年来学习编程的一些...

    VC++深入详解(课件+源码)

     《VC++深入详解》从实际应用入手,由浅入深、循序渐进地讲述Windows程序内部运行机制、MFC框架、文本、菜单、对话框、文件操作、网络编程、进程间通信、ActiveX控件、动态链接库、HOOK编程等多个主题。  《VC++...

    VC++深入详解.rar

    《VC++深入详解》这本书是面向有一定VC++基础的开发者,旨在揭示Windows程序设计的深层原理,特别是深入探讨Microsoft Foundation Class (MFC)框架的工作机制。MFC是微软提供的一套C++类库,用于简化Windows应用程序...

Global site tag (gtag.js) - Google Analytics