网上第一本以TXT格式的VC++深入详解孙鑫的书.全文全以TXT格式,并每一章节都分了目录,清晰易读
源代码在线查看: 12.5.3 cfiledialog类.txt
12.5.3 CFileDialog类
下面,我们为 File程序增加一个"打开文件"对话框和"另存为"对话框的功能。这可以利用类:
CFileDialog来完成。如图 12.11所示是 CFileDialog类的派生层次结构图。
图 12.11 CFileDialog类的派生层次结构
从图 12.11可以看出. CFileDialog类是从CCommonDialog派生而来,并且间接派生于CDialog类,因
此它也是一个对话框类。该类的构造函数声明形式如下所示:
CFileDialog ( BOOL bOpenFileDialog , LPCTSTR lpszDefExt := NULL , LPCTSTR lpszFileName
= NULL , DWORD dwFlags := OFN_HIDEREADONLY OF~一OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL ,
CWnd* pParentWnd = NULL );
,
该构造函数参数比较多,其意义分别如下所述。
. bOpenFileDialog
BOOL类型。如果将此参数设置为TRUE.那么将构建一个打开对话框:如果将此参数设置为 FALSE.那么
将构建一个保存为对话框。也就是说,通过CFileDialog类,既可以创建"打开"对话框,也可以创建
"保存为"对话框。
. lpszDetExt
指定默认的文件扩展名。如果用户在文件名编辑框中输入的文件名没有包含扩展名,那么此参数指
定的扩展名将自动添加到输入的文件名后面,作为该文件的扩展名。如果此参数为NULL.就不会为文
件添加扩展名。在保存文件时,可以设置这个参数来指定一个默认的文件扩展名。当用户没有输入
文件扩展名时,系统将会自动添加一个。
. lpszFileName
指定显示在文件对话框中的初始文件名。如果为NULL.则没有初始的文件名显示。
. dwFlags
一个或多个标记的组合,允许定制文件对话框。该参数的取值与OPENFILENAME结构体中的Flags字段
相同。
. IpszFilter
一连串的字符串对,用来指定一个或一组文件过滤器。如果指定了文件过滤器,那么只有选择的文
件才出现在文件列表中。我们平时在使用文件打开对话框打开文件时,并不是所有文件都显示在文
件列表中,而是根据我们所选择的文件类型来显示相应文件,选择的文件类型就应用了过滤器,根
据指定的过滤器对文件进行过滤,只有选定的文件才会出现在文件列表当中。
. pParentWnd
一个CWnd指针,用来指定文件对话框的父窗口或者拥有者窗口。在使用时,因为 CFileDialog类构
造函数的后面几个参数都有默认值,所以通常只需要为第一个参数赋值就可以了。
1.另存为对话框
下面首先利用 CFileDialog类来创建一个"另存为"对话框。本例仍在File程序的基础上增加功能,
因此需要先将CFileView类的OnFileWrite函数中已经代码注释起来,然后添加如例 12-20所示代码。
1例 12-20
void CFileView: :OnFileWrite()
CFileDialog fileDlg(FALSE);
fileDlg .DoModal() ;
在如例12-20所示代码中,首先构造了一个 CFileDia10g对象: fileDlg。因为这时想要创建一个"
另存为"对话框,所以为CFileDia10g构造函数的第一个参数传递FALSE值。
另外,我们已经知道 CFileDialog类是从 CDialog类间接派生的,因此也可以通过调用 DoModal函
数显示创建的对话框。运行File程序,单击【文件操作写入文件】菜单项,这时,可以看到程序
弹出了一个"另存为"对话框。程序运行界面如图 12.12所示。
图 12.12"另存为"对话框的显示
如果读者想改变"另存为"对话框的标题,可以利用CFileDialog类的数据成员: m ofn 来实现。该数
据成员是OPENFILENAME结构体类型,这个结构体中有一个LPCTSTR类型的成员: lpstrTitle,用来指
定CFileDialog对话框的标题。如果这个成员的值为NULL,则系统使用默认的标题:"另存为"或"打开
"。因此,如果想修改本例中刚刚创建的fileDlg对话框的标题,可以在上述例 12-20所示代码中在
调用DoModal函数显示对话框之前添加下面这条语句,从而将该对话框的标题修改为:我的文件保存
对话框。
① fileDlg.m_ofn.lpstrTitle="我的文件保存对话框";
如果读者想要设置保存类型,即设置过滤器的话,可以利用 m_ofn这个数据成员中另一个字段: lps
位Filter来完成,该字段是一个指向包含多个过滤字符串对的缓冲区的指针,各过滤字符串对之间,
以及字符串对内部两个字符串之间都以"\。"分隔,最后的过滤器字符串必须以两个"\。"字符结尾。
对一个字符串对来说,第一个字符串描述过滤器,而第二个字符串表明过滤使用的文件扩展名称,
多个扩展名称可以用分号(; )分隔。因此,如果把过滤字符串设置为 "Text Files (飞txt)",那么
该字符串只是出现在"另存为"对话框中保存类型列表框中所看到的文字,并不具有过滤的功能。如
果要想具有过滤功能,必须在其后加上 "\0"字符,井随后加上"*txt"字符串。因此,在上述①符
号所示代码之后再添加下面这条语句设置文件的过滤条件:
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0";
另外,利用 m_ofn数据成员的 lpstrDefExt字段还可以设置默认的扩展名。在上述②符号所示代码之
后再添加下面这条语句,以设置默认扩展名为 "txt"。
fileDlg .m_ofn.lpstrDefExt="txt";
运行 File程序,单击【文件操作\写入文件】菜单项,程序将弹出"另存为"对话框 (如图 12.13所
示),此时可以看到该对话框的标题变成了:我的文件保存对话框。在保存类型下拉列表框中出现了
"Text Files(*.txt)'啪"All Files(*.*)"两种文件过滤类型,它们分别是上述②符号所示代码中所
写的两个过滤器字符串对中"\。"前的字符串,而过滤功能则是通过这两个过滤字符串对中气。"字
符后面的 "*.txt"和"*.*"字符串实现的。初始显示时,我们看到在该对话框的文件列表中只能看到
文本文件。如果想要看到所有文件,在保存类型下拉列表框中选择" All Files(*卢)"类型即可。
图 12.13定制另存为对话框的结果
接下来,我们要实现这样的功能:当用户通过"另存为"对话框选择了某个文件并单击该对话框上的
【保存】按钮后,程序应根据用户所选择的文件名,打开相应文件,然后向其中写入数据。
为了获取用户输入的文件名, CFileDialog类提供了两个函数 : GetPathName和 GetFileName。其
中 GetPathName返回选择文件的完整路径; GetFileName返回选择文件的文件名。例如对于
"C:\FILES\TEXT.DAT"文件来说, GetPathName函数将返回该文件完整的路径:而 GetFileName函数
只返回文件名: tex t. dat。
这时的 OnFileWrite函数的具体实现代码如例 12-21所示,其中加灰显示的为新增代码。
D11 12-21
void CFileView: :OnFileWrite()
CFileDialog fileDlg(FALSE);
fileDlg . m_ofn . lpstrTitle="我的文件保存对话框";
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\O*.txt\OAll Files (*. *)\
0*.*\O \ o " ;
fileDlg .rn_ofn.lpstrDefExt="txt";
if(IDOK==fileDlg.DoModal())
CFile file(fileDlg.GetFileName() , CFile: :modeCreate | CFile::modeWrite) ;
file.Write("http://www.sunxin.org" , strlen("http://www.sunxin.org"));
file.Close() ;
在如例 12-21所示代码中,当用户单击"另存为"对话框上的【保存】按钮(其 E为 IDOK)关闭该对话
框后,程序就将以用户在"另存为"对话框中输入的文件名作为参数来构造一个 CFile对象。本例使
用的是 CFileDialog类的 GetFileName函数得到用户选择的文件名。如果要想得到该文件的完整路
径,可以使用 GetPathName函数。接着,程序调用 CFile类的 Write成员函数向文件中写入数据:
http://www.sunxin.o晤。最后,当对文件的写入操作完成之后,调用 CFile类的 Close成员函数关
闭文件。
运行 File程序,单击【文件操作\写入文件】菜单项,即可弹出如图 12.13所示的"另存为"对话框,
通过这个对话框,我们可以在文件列表中选择一个己有文件作为数据保存的目标文件,也可以在文
件名编辑框中输入一个字符串作为保存数据的文件名称,例如 test。然后单击该对话框上的【保存】
按钮,之后在 File程序所在目录下就可以看到有一个名为 tes t.txt的文件。读者可能会有疑问了,
刚才我们在"另存为"对话框中并没有输入文件的扩展名,但是我们看到这个文件具有扩展名: txt。
这是因为在前面的程序中为这个"另存为"对话框设置了默认的扩展名: txt。所以如果用户没有输入
扩展名的话,系统将
自动为文件加上扩展名 : txt。
2.打开文件对话框
下面,再利用 CFileDialog类创建一个打开文件对话框。在 File程序 CFileView类的 OnFileRead
函数添加如例 12-22所示的代码。
例 12-22
void CFileView: :OnFileRead()
CFileDialog fileDlg(TRUE);
fileDlg.m_ofn.lpstrTitle = "我的文件打开对话框";
fileDlg.m_ofn.lpstrFilter="Text Files(*.txt)\O*.txt\OAll Files(*.*)\ 0*.*\O \0" ;
if(IDOK==fileDlg.DoModal() )
CFile file(fileDlg.GetFileName(), CFile: :modeRead);
char *pBuf;
DWORD dwFileLen;
dwFileLen=file.GetLength() ;
pBuf=new char[dwFileLen+ll ;
pBuf[dwFileLenl=0 ;
file .Read(pBuf,dwFileLen) ;
file .Close() ;
MessageBox (pBuf) ;
在如例 12-22所示代码中,首先构造了一个CFileDialog类型的对象: fileDlg。因为现在需要创建"
文件打开"对话框,所以构造 CFileDialog类对象时第一个参数应设置为 TRUE;接下来,与上面的"
另存为"对话框一样,我们也修改"文件打开"对话框的标题并设置文件过滤字符串。然后如果判断出
用户单击的是"文件打开"对话框上的【打开】按钮,那么就根据用户选择的文件名构造一个 CFile
对象,井且因为是为读取操作而打开文件的,所以构造CFile对象时,指定文件模式为:
CFile: :modeRead。然后就可以读取该文件的内容了,这部分的代码在上面己经讲解过,这里不再
赘述。
运行File程序,单击【文件操作飞读取文件】菜单项,这时程序就会显示如图12.14所示的"文件打
开"对话框。通过这个对话框,用户可以选择一个文件,并单击该对话框上的【打开】按钮,即可打
开该文件,并在弹出的消息框上看到该文件的内容。