现在的位置: 首页 > 综合 > 正文

23、深入浅出MFC学习笔记,MFC解剖(骨干程序)相关

2013年06月04日 ⁄ 综合 ⁄ 共 3427字 ⁄ 字号 评论关闭

1Document/ViewMFC进化为Application Framework的灵魂。在MFC中,可以把Document简单想像成数据,MFCCDocument已经负责处理数据的类。同时,CDocument搭配了另一个重要的类CView

CView为了数据的表现(显示)而设计的。就是如何将你处理的结果显示出来(输出到屏幕或者打印机)。除了负责显示外,View还负责程序与使用者之间的交谈接口。使用者对数据的编辑、修改都需要仰赖窗口上的鼠标与键盘操作才得以完成,这些消息都将由View接受后通知Document

Document/View的价值在于,这些MFC类已经把一个应用程序所需的“数据处理与显示”的函数空壳都设计好了,这些函数都是虚函数,所以你可以也应该在派生类中改写他们。有关文件读写的操作在CDocumentSerialize函数中进行,有关画面显示的操作在CViewOnDrawOnPaint函数中进行。当我们为自己派生两个类CMyDocCMyView时,只要把心思花在CMyDoc::SerializeCMyView::OnDraw上,其他琐事不用管,整个程序会运行的好好的。示例:

1)如果按下【File/Open】,Application Framework会激活对话框,让你指定文件名,然后调用CMyDoc::Serialize读文件。Application Framework还会调用CMyView::OnDraw,把数据显示出来。

2)如果屏幕状态改变,产生了WM_PAINTFrameWork会自动调用你的CMyView::OnDraw,传一个Display DC,让你重新绘制窗口内容。

3)如果按下【File/Print..】,FrameWork会自动调用你CMyView::OnDraw,这次传进去的是一个Printer DC,因此绘图操作的输出对象就变成了打印机。

2、多文档的一个图示

wps_clip_image-16406

3Document Template的意义

程序每打开一份文件(数据),就产生三份对象:

1)一份Document对象

2)一份View对象

3)一份CMDIChildWnd对象(作为外框窗口)

这三份对象由一个所谓的Document Template对象来管理;让这三份对象产生关系的关键在于CMultiDocTemplate:

	// 注册应用程序的文档模板。文档模板
	// 将用作文档、框架窗口和视图之间的连接
	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(IDR_TestMFC_1TYPE,
		RUNTIME_CLASS(CTestMFC_1Doc),
		RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
		RUNTIME_CLASS(CTestMFC_1View));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

如果程序支持不同的数据格式,则需要不同的Document Template:

	// 注册应用程序的文档模板。文档模板
	// 将用作文档、框架窗口和视图之间的连接
	CMultiDocTemplate* pDocTemplate;
	pDocTemplate = new CMultiDocTemplate(IDR_TestMFC_1TYPE1,
		RUNTIME_CLASS(CTestMFC_1Doc),
		RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
		RUNTIME_CLASS(CTestMFC_1View));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

	pDocTemplate = new CMultiDocTemplate(IDR_TestMFC_1TYPE2,
		RUNTIME_CLASS(CTestMFC_2Doc),
		RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架
		RUNTIME_CLASS(CTestMFC_2View));
	if (!pDocTemplate)
		return FALSE;
	AddDocTemplate(pDocTemplate);

CMultiDocTemplate的构造函数如下所示:

	CMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
		CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);

说明:CRuntimeClass

它就是“类别型录网”链表中的元素类型,任何一个类只要在声明时使用DECLRAE_DYNCREATEDECLARE_SERIAL宏,就会拥有一个静态的CRuntimeClass内嵌对象。

7、字符串资源的7个字段值[1,P322]

    每一个字符串都可以再程序中取得,通过调用CDocTemplate::GetDocString,并在第二个参数中指定索引(1~7),但最好还是以CDocTempalte所定义的七个常量来代替索引值:

所以你可以这么做:

    // in AFXWIN.h
    Class CDocTempalte :: public CCmdTarget
    {
        ...
        emum DocStringIndex
        {
            windowTitle,
            docName,
            filterName,
            filterExt,
            regFileTypeID,
            regFileTypeName
        }
	}
	
    CString strDefExt,strDocName;
    pDocTemplate->GetDocString(strDefExt, CDocTemplate::filterExt);
    pDocTemplate->GetDocString(strDocName, CDocTemplate::docName);

8、再述Document/View

Document是数据的体,View是数据的面,我们藉CDocument管理数据,藉Collections Classes(MFC中的一组专门用来处理数据的类)处理实际的数据,藉CView显示数据,藉CDCCGdiObject实际绘图。

使用者对Document的任何编辑操作都必须通过Document Frame窗口,消息随后传到CView

9、鼠标拖放(Drag and Drop)

当使用者从Shell中拖放一个文件到程序AShell就配置一块全局内存,填入被拖拽的文件名称(包含路径),然后发出WM_DROPFILES传到程序A的消息队列,程序A取得此消息后,应该把内存的内容取出,再想办法打开、读文件。

只有具备WS_EX_ACCEPTFILES风格的窗口才有收到这一消息。所以在使用CreateWindowEx第一个参数应当指定WS_EX_ACCEPTFILES

10、操作注册表

在传统的Windows程序中操作注册表两种方法:

1)写一个.reg文件,通过regedit.exe来注册。

2::RegCreateKey,::RegSetValue来直接编辑Registry

MFC中则更简单:

只要调用RegisterShellFileTypes即可。

11、消息映射

每一个派生于CCmdTarget的类都可以有自己的Message Map 用于处理消息。首先在类声明中加上DECLARE_MESSAGE_MAP();在.cpp使用BEGIN_MESSAGE_MAPEND_MESSAGE_MAP两个宏,中间就是消息与函数对应关系表。

12、默认的菜单命令项及其处理程序[1,P332]

13CEditView是一个已具备文字编辑能力的类,它所使用的窗口是Windows的标准控件之一Edit,SerializeRaw成员函数可以把Edit控件中的raw text(而不是“对象”所持有的数据)写到文件中。

参考

[1] 深入浅出MFC

[2] MFC Technical Notes

http://msdn.microsoft.com/en-us/library/h6h0eact%28VS.80%29.aspx

[3] http://hi.baidu.com/even_xf/blog/item/2da097f46b7841e57609d787.html

抱歉!评论已关闭.