调皮的MFC(1)

17 篇文章 1 订阅
9 篇文章 6 订阅

新建一个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.0\Microsoft Visual Studio\VC98\MFC\ 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()

月光光,心慌慌,今天就先到这里啦。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值