概述
新建一个MFC工程,集成环境会先帮我们生成一个框架。框架中用到的最重要的基础类层次结构如下所示:
其中在虚矩形框中的类是我们自己继承的类,实矩形框中的类是MFC中自带的类(取自深入浅出MFC)。
下面对MFC中自带的类做一些大致的说明:
CObject类
MFC的CObject类为程序员提供了对象诊断、运行时类型标识、序列化和动态生成等功能。
(1)对象诊断:利用成员函数AssertValid进行对象有效性检查;利用成员函数Dump输出对象的数据成员的值,诊断信息以文本形式放入一个数据流中,用于调试器的输出窗口信息显示。(只能用于Debug版的应用程序)
(2)运行时类型识别:GetRuntimeClass根据对象的类返回一个相关联的指向CRuntimeClass结构的指针,它包含了一个类的运行信息;函数IsKindOf用于测试对象与给定类的关系。
(3)通过与Carchive相结合:CObject类为其派生类提供了序列化功能。要创建一个支持序列化的派生类,必须将DECLARE_SERIAL宏添加到类定义中,将IMPLEMENT_SERIAL添加到类的实现文件中。
(4)动态生成:使得我们可以在执行期产生一个特定的对象。
CCmdTarget类
由CObject类直接派生,所有能实行消息映射MFC类的基类。换言之,派生自它,类才能够处理命令消息WM_COMMAND。这个类是消息映射以及命令消息传递的大部分关键,功能如下:
(1)消息发送:MFC应用程序为每个CCmdTarget派生类创建一个称为消息映射表的静态数据结构,可将消息映射到对象所对应的消息处理函数上。
(2)设置光标:程序正在进行某种操作:BeginWaitCursor()将光标改为沙漏形状;操作完成:EndWaitCursor()将光标改回到之前的形状;处于等待状态时由于某些操作改变了光标形状后,RestoreWaitCursor()用于将光标还原为等待状态。
(3)支持自动化:CCmdTarget类支持程序通过COM接口进行交互操作,自动翻译COM接口的方法。
CWinThread类
由CCmdTarget派生,代表MFC程序中的一个线程。SDK程序中标准的消息循环已经被封装在这一类中,主要工作就是创建和处理消息循环。
CWinApp类
从CWinThread类派生,在MFC应用程序中有且仅有一个CWinApp派生类的对象,代表程序运行的主线程,代表应用程序本身。内含成员变量以及有用的成员函数,如:ProcessShellCommand()、InitApplication()、InitInstance()、Run()。
CWnd类
由CCmdTarget类直接派生,是MFC中最基本的GUI对象。凡派生自CWnd的类才能收到WM_XX窗口消息(WM_COMMAND除外)。CWnd对象有一个成员变量m_hWnd,存放着对应的窗口handle,这样就可以让窗口的handle和C++对象相结合。
CView类
在MFC"文档/视图"架构中,CView类是所有视图类的基类,它提供了用户自定义视图类的公共接口。在"文档/视图"架构中,文档负责管理和维护数据;而视图类则负责如下工作:
(1) 从文档类中将文档中的数据取出后显示给用户;
(2) 接受用户对文档中数据的编辑和修改;
(3) 将修改的结果反馈给文档类,由文档类将修改后的内容保存到磁盘文件中。
文档负责了数据真正在永久介质中的存储和读取工作,视图呈现只是将文档中的数据以某种形式向用户呈现,因此一个文档可对应多个视图。
CFrameWnd类
从CWnd类派生而来,主要用来掌管一个窗口。其对象是一个框架窗口,包括边界、标题栏、菜单、最大化按钮、最小化按钮和一个激活的视图。
其常用成员函数:
GetActiveDocument():得到当前文档的指针。
GetActiveView():得到当前视图的指针。
SetActiveView():激活一个视图。
GetTitle():得到框架窗口的标题。
SetTitle():设置框架窗口的标题。
SetMessageText():设置状态栏文本。
CDocument类
从CCmdTarget派生,作为用户文档的基类,代表了用户存储或打开一个文件。主要功能是把对数据的处理从对用户的界面处理中分离出来,同时提供一个与视图类交互的接口。
常用的成员函数有:
OnNewDocument():建立新文档。
OnOpenDocument():打开一个文档。
好了基础的类就这样了,下面就开始建个工程玩一玩吧。
当我们新建一个MFC程序的时候发现整个程序居然都没有WinMain函数,也没有喜闻乐见的消息处理函数,那这究竟是怎么回事呢?
CWinApp取代WinMain的地位
如果有VC6可以在:安装目录VC6.0Microsoft Visual StudioVC98MFC Include下找到AFXWIN.H其中有CWinApp的类声明。
截取有用的信息如下:
class CWinApp : public CWinThread
{
DECLARE_DYNAMIC(CWinApp)//执行期信息
public:
// Constructor
CWinApp(LPCTSTR lpszAppName = NULL); // app name defaults to EXE name
// Attributes
// Startup args (do not change)
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
LPTSTR m_lpCmdLine;
int m_nCmdShow;
/*上面4个成员变量对应于我们思念的WinMain函数的4个参数:
int CALLBACK WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow);
*/
public:
// Overridables
// hooks for your initialization code
virtual BOOL InitApplication();
// overrides for implementation
virtual BOOL InitInstance();
virtual int ExitInstance(); // return app exit code
virtual int Run();
virtual BOOL OnIdle(LONG lCount); // return TRUE if more idle processing
/*原本该WinMain完成的工作,现在由InitApplication、InitInstance、Run三个函数完成*/
};
其中还有继承自父类(CWinThread)的窗口句柄成员:
CWnd *m_pMainWnd;//主窗口句柄
CWnd*m_pActiveWnd;//当前活动窗口句柄
宏操作取代WndProc的地位
传统的SDK窗体处理函数一般通过switch/case语句来实现,而在MFC中的情况如下:
{
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}
MFC內建了一个“Message Map”机制,会把消息自动送到“与消息对应的特定函数”中去;消息和处理函数之间的对应关系有程序员指定。DECLARE_MESSAGE_MAP搭配其它宏,就可以很便利地将消息与其处理函数关联在一起,如:
BEGIN_MESSAGE_MAP(CMFCApp, CWinApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_WM_PAINT()
END_MESSAGE_MAP()
月光光,心慌慌,今天就先到这里啦。
最后
以上就是顺利帅哥为你收集整理的调皮的MFC(1)的全部内容,希望文章能够帮你解决调皮的MFC(1)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复