可以利用MFC提供的文件对话框CFileDialog和文件CFile类来完成文件操作。这种方式不需要使用MFC的文档视图框架,更加灵活。
MFC的通用对话框
1、文件对话框
CFileDialog(BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL
);
参数:
- bOpenFileDialg:如果为TRUE,则创建文件打开对话框;如果为FALSE,则构造一个File Save As(另存为)对话框。
- lpszDefExt:缺省文件扩展名,如果用户在文件名编辑框中不包含扩展名,则lpszDefExt定义的扩展名自动加到文件名后。如果为NULL,则不添加扩展名。
- lpszFileName:初始显示于文件名编辑框中的文件名,如果为NULL,则不显示初始文件名。
- dwFlags:一个或多个标志的组合,使你可定制对话框。即OPENFILENAME结构中的Flag成员。
- lpszFilter:一列字符串对,指定可以应用到文件的过滤器。如果指定过滤器,则只有符合规则的文件显示于文件列表框中。
- pParentWnd 指向文件对话框对象的父窗口或拥有者窗口。
使用范例:
CString SelectFile()
{
CFileDialog dlg(TRUE,NULL,NULL,OFN_READONLY|OFN_FILEMUSTEXIST,"Student File(*.stu)|*.stu||All File(*.*)|*.*||");
if(dlg.DoModal()==IDOK)
return dlg.GetPathName();
return "";
}
过滤器稍微注意一下:
双字符串的第一个字符串描述过滤器,第二个串表明使用的文件扩展名,多重扩展可用“;”来指定。字符串由两个“|”字符结尾。
例如:有两个过滤规则,一个是图片文件:.bmp或者.jpg;另一个是所有文件:*.*
。则过滤规则为:" 图片文件 |*.jpg;*.bmp | 所有文件 | *.* ||"
一次选择多个文件可以使用OFN_ALLOWMULTISELECT,然后用枚举方式来获取选择的多个文件名称。
CFileDialog dlg(TRUE,NULL,NULL,OFN_ALLOWMULTISELECT|OFN_READONLY|OFN_FILEMUSTEXIST,"Student File(*.stu)|*.stu||All File(*.*)|*.*||");
if(dlg.DoModal()==IDOK)
{
POSITION ps=dlg.GetStartPosition();
while(ps!=NULL)
{
CString fileName=dlg.GetNextPathName(ps);
/* 多个文件名操作 */
}
}
保存文件,第一个参数设置成FALSE,语法基本一致。
2、颜色选取对话框
CColorDialog colorDialog;
COLORREF color ;
if (colorDialog.DoModal() == IDOK)
color = colorDialog.GetColor();
COLORREF 是一个 32-bit 整型数值,它代表了一种颜色。
可以使用 RGB 函数来初始化 COLORREF。例如:
COLORREF color=RGB(0,255,0);
提取COLORREF的三种颜色分别用:宏GetRValue、GetGValue、GetBValue,如:
COLORREF color=RGB(120,250,110);
BYTE r = GetRValue(color);
3、字体选择对话框
CString strFontName; // 字体名称
CFont f; // LOGFONT变量
CFontDialog fontDlg;
if (IDOK == fontDlg.DoModal()) // 显示字体对话框
{
f.CreateFontIndirect(fontDlg.m_cf.lpLogFont);
LOGFONT lf;
f.GetLogFont(&lf);
CString fontName=lf.lfFaceName;
}
使用方式与以上对话框基本相似。
4、浏览对话框
BROWSEINFO bi;
ZeroMemory(&bi,sizeof(BROWSEINFO));
char buff[255];
LPITEMIDLIST itemIdList=::SHBrowseForFolder(&bi);
if(itemIdList != NULL)
{
::SHGetPathFromIDList(itemIdList,buff);
::AfxMessageBox(buff);
}
MFC文件相关类
CFile的几个构造函数:
CFile();
//不带参数的构造函数。
CFile(
int
hFile);
//带文件句柄参数的构造函数。
CFile(LPCTSTR
lpszFileName,
//要打开的文件路径
UINT
nOpenFlage
//打开文件时的共享和访问模式
);
//带文件路径和打开方式的构造函数
文件打开方式nOpenFlage
的取值:
常用函数:
virtual BOOL Open(LPCTSTR lpszFileName,UINT nOpenFlags,CFileException* pError = NULL);
打开文件。它通常与默认构造函数CFile::CFile()一起使用。参数lpszFileName和nOpenFlags同构造函数。参数pError为指向文件异常对象的指针,默认为NULL。
virtual void Close( );
关闭文件。如果你没有在执行析构函数前调用此成员函数关闭文件,则析构函数会为你关闭。
virtual UINT Read(void* lpBuf,UINT nCount);
读取文件数据到缓存。参数lpBuf是由用户提供的指向接收文件数据的缓存的指针;参数nCount为读取的最大字节数。返回值是实际读取到缓存的字节数,如果到达文件尾则返回值可能会小于nCount,此时继续读取的话,会返回0,所以通常我们都会判断返回值是否小于nCount或者等于0来确定是否到达文件尾。
virtual void Write(const void* lpBuf,UINT nCount);
将缓存中的数据写入文件。参数lpBuf也是由用户提供,指向包含写入数据的缓存的指针;参数nCount为缓存中要被写入文件的数据的字节数。
virtual ULONGLONG Seek(LONGLONG lOff,UINT nFrom);
在一个打开的文件中重定位文件指针。参数lOff为文件指针移动的字节个数,为正数时表示向文件尾移动,为负数时表示向文件开头移动;参数nFrom为lOff的基准位置,即由nFrom位置开始移动lOff个字节,它可以取下面几个值中的一个:
CFile::begin 从文件开头开始移动
CFile::current 从文件指针的当前位置开始移动
CFile::end 从文件尾开始移动
文件打开时,文件指针被置于0,即文件开头处。
如果此函数成功则返回文件指针的位置。
void SeekToBegin( );
将文件指针移动到文件开头。它等价于Seek( 0L, CFile::begin )。
ULONGLONG SeekToEnd( );
将文件指针移动到文件末尾。返回值是文件的字节长度。它等价于CFile::Seek( 0L, CFile::end )。
virtual ULONGLONG GetLength( ) const;
获取文件的字节长度。
virtual CString GetFileName( ) const;
获取文件名称。
virtual CString GetFilePath( ) const;
获取文件的绝对路径。
很显然:结合MFC提供的文件对话框和文件类可以比较灵活地完成文档操作。