图12-25 设置文档模板字符串
图12-26 图片文件过滤器
? “文件扩展名”编辑框中键入文件扩展名,如:
? 单个扩展名:bmp。
? 多个扩展名:bmp;.gif;.jpg(用分号分割,注意从第2个扩展名起,前面必须
加句点符“.”)。
? 在“文件类型名称”编辑框中键入标识应用程序的文档可归入的文档类型,如“位
图文件”,默认为项目名。
? 在“筛选器名”编辑框中键入(用户可以用来指示查找特定文件类型的文件的名称
的)文件类型的描述,如:“位图文件(*.BMP)”。默认为“项目名 Files (*.扩展名)”,
36
例如,若项目名为“Image”,文件扩展名为“bmp”,则默认的筛选器名就为“Image Files (*.bmp)”。对多个扩展名,需要在第1个扩展名之外的其他扩展名的句点前,手工添加星号符“*”,如“图片文件 (*.bmp;*.gif;*.jpg)”,参见图12-25。 该对话框页中的其他项目的含义如下:
? “文件类型 ID ”——用于在系统注册表中设置文档类型的标签,默认为“项目
名.Document”。
? “语言”——指示为“本地化字符串”下的所有框显示字符串所使用的语言。若要
更改此框中的值,需在 “MFC 应用程序向导”对话框的“应用程序类型”页的“资源语言”下拉式列表中选择合适的语言。
? “主框架标题”——设置出现在主应用程序框架窗口顶部标题条的文本串,默认为
项目名。
? “文件的新简称”——如果有不止一个新文档模板,设置出现在标准 “新建”对
话框中的名称,默认为项目名。
? “文件类型全名”——在系统注册表中设置文件类型名称。默认为“项目
名.Document”。 2) 创建后修改
可通过修改资源视图页的“项目名\\项目名.rc\\String Table\\String Table”串表资源中的ID:IDR_MAINFRAME(SDI)或IDR_MyType(MDI)所对应的串,为应用程序的文件I/O对话框增加文件过滤器。如为Wave程序增加*.wav的过滤器:
将原来的串
SDI:IDR_MAINFRAME“Wave\\n\\nWave\\n\\n\\nWave.Document\\nWave Document” MDI:IDR_WaveTYPE“\\nWave\\nWave\\n\\n\\nWave.Document\\nWave Document” 修改成
SDI:“Wave\\n\\nWave\\n波形文件(*.wav)\\n.wav\\nWave.Document\\nWave Document” MDI:“\\nWave\\nWave\\n波形文件(*.wav)\\n.wav\\nWave.Document\\nWave Document” 其中(每个C++转义字符“\\n”表示一行):
? 第1行“Wave\\n”为应用程序的窗口名。
? 第2行“\\n”为默认文档名的根(若该行为空,则默认文档名的根为“未命名”或
Untitled)。
? 第3行“Wave\\n”为文档类型名。
37
? 第4行“波形文件(*.wav)\\n”为文档类型和过滤器的描述。 ? 第5行“.wav\\n”为过虑器本身(文件扩展名),注意前面有句点。 ? 第6行“Wave.Document”为注册的文件类型的ID ? 第7行“Wave Document”为注册的文件类型的描述
上面讨论的是单个扩展名的情况,也可以设置多个扩展名。例如为Image程序增加多种图像格式的文件过滤器:
SDI:“Image\\n\\nImage\\n图片文件 (*.bmp;*.gif;*.jpg)\\n.bmp;.gif;.jpg\\nImage.Document\\n Image Document”
MDI:“\\nMy\\nImage\\n图片文件 (*.bmp;*.gif;*.jpg)\\n.bmp;.gif;.jpg\\nImage.Document\\n Image.Document”
上面的字符串修改方法,也可以在项目的*.rc源文件中的字符串表部分手工进行。 注意:上面的几个资源串方法都不支持多个文件过虑器(上面只有支持多个扩展名的单个[复合]滤波器),为了同时支持多个滤波器(例如,在图像程序中,可以同时添加多个分别单独处理*.BMP、*.GIF、*.JPG等文件的单扩展名滤波器、以及多个可以处理多个扩展名的多扩展名复合滤波器),可采用下面介绍的两种方法。
2.多文档模板*
在多文档程序的C*App类的InitInstance函数中创建多文档模板类CMultiDocTemplate的对象:
CMultiDocTemplate( UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass );
并使用CWinAPP的成员函数AddDocTemplate:
void AddDocTemplate( CDocTemplate* pTemplate );
将新建的模板加入。如:
pDocTemplate = new CMultiDocTemplate(
IDR_BMPTYPE,
RUNTIME_CLASS(CImageDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CImageView));
38
AddDocTemplate(pDocTemplate);
pDocTemplate = new CMultiDocTemplate(
IDR_GIFTYPE,
RUNTIME_CLASS(CImageDoc),
RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架 RUNTIME_CLASS(CImageView));
AddDocTemplate(pDocTemplate);
其中,IDR_BMPTYPE与IDR_GIFTYPE为资源ID,对应的有与1.类似的串资源,还有菜单资源等。
3.OnFileOpen
如果只是文件过虑器不同,而菜单、文档类、子框架类及视图类都一样的话,则上面方法的编程必须同时维护几个完全相同的菜单,太低效。解决办法是添加自己的OnFileOpen消息响应函数。
具体步骤为:
? 覆盖应用程序类中对ID_FILE_OPEN消息的默认响应CWinApp::OnFileOpen:
//ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
? 为应用程序类添加自己的ID_FILE_OPEN事件处理函数。
? 在自己的OnFileOpen函数中,设置多个文件过虑器,并用其调用文件公用对话框。 ? 用用户选择的完整文件路径名调用CWinApp的成员函数OpenDocumentFile:
virtual CDocument* OpenDocumentFile( LPCTSTR lpszFileName );
? OpenDocumentFile函数,会使MFC系统继续应用程序的文档视图创建过程。 例如(参见图12-27):
void CImageApp::OnFileOpen() {
wchar_t filters[] = L\图像文件(*.bmp;*.gif;*.jpg;*.png;*.tif) \\|*.bmp;*.gif;*.jpg; *.png;*.tif|位图文件(*.bmp)|*.bmp|图形交换\\格式文件(*.gif)|*.gif|联合图象专家组[JPEG]文件(*.jpg)|*.jpg|可移\\植网络图形文件(*.png)|*.png|标记图像文件格式[TIFF]\\ 文件(*.tif)
39
\\|*.tif|所有文件(*.*)|*.*||\
CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY,
}
filters);
if (fileDlg.DoModal() == IDOK)
OpenDocumentFile(fileDlg.GetPathName());
图12-27 具有多个文件过虑器的打开文件对话框
以上的各种方法中,最常用的是:
? 添加单个文件滤波器(包括支持多个文件扩展名的单个复合滤波器)——创建时设置文件扩展名,或在创建后修改资源串。
? 添加多个文件滤波器——添加自己的 OnFileOpen消息响应函数。 而通过创建多个文档模板,来添加多个文件滤波器的方法,则很少被使用。
12.3.4 改变文档窗口的大小和位置*
有时需要根据文档(如图像)的尺寸来调整子窗口的大小,如使用MDI来实现BMP、GIF和JPG等图像的显示。
40