MFC之CFileDialog文件保存扩展名问题 解决办法

来源:互联网 发布:连接网络投影仪 编辑:程序博客网 时间:2024/05/14 09:34

原帖见 http://blog.csdn.net/shiwei0124/archive/2009/09/10/4538327.aspx

在CSDN论坛上发了帖子后,和人一起解决了该问题

帖子内容如下:

    先看一段代码:
static TCHAR BASED_CODE szFilter[] = _T("Map Files (*.txt)|*.txt|MapCfg Files(*.txty) |*.txty||");
CFileDialog dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, /
szFilter,AfxGetMainWnd());
CString strPath;
CFileException e;
//判断是否按下"保存"按钮
if(dlg.DoModal() == IDOK)       
{
//获得文件保存路径,为下面right(4)方便,而不用GetFileName();可能文件未设置后缀名,则若文件小于4个字符,会出错
strPath = dlg.GetPathName();     
//根据用户选择的扩展名下拉框来确定添加的扩展名
switch (dlg.m_ofn.nFilterIndex)       
        {
//txt
        case 1:
            {
//判断文件扩展名
                if(strPath.Right(4) !=_T(".txt"))     
strPath += _T(".txt");
break;
            }
//txty
        case 2:
            {
//判断文件扩展名
if(strPath.Right(7) !=_T(".txty"))     
strPath += _T(".txty");
                break;
            }
        }
if( access(strPath, 0) == 0 )//需要#include 
        {
            CString strQuery;
            strQuery.Format("%s 已经存在,要替换掉吗?", strPath);
            if ( IDNO == ::MessageBox(m_hWnd, strQuery, "文件覆盖", MB_ICONQUESTION | MB_YESNO) )
            {
                OnBnClickedNew2();
            }
        }
      这段代码中CFileDialog中有自带覆盖文件的提示,但是这个有一个问题,比如我想保存一个文件“temp”,但是我未指定这个文件的后缀名,CFileDialog只能检测我输入框的文件在文件夹内是否有重名文件"temp",我这些代码给附加了一些功能,根据文件扩展名过滤框自动添加未写的扩展名,而且之后进行判断是否有 "temp.txt",这里就等于进行了两次覆盖判断  一次是对话框自动的"temp"检测,还有一次就是我设置的"temp.txt"
      我想要做的就是在对话框内判断"temp.txt",而不是"temp"的判断,即在对话框内自动添加扩展名然后进行判断。
(web浏览器进行图片保存时就是这个做法。)
CFileDialog有什么函数或者参数可以进行设置吗?还是需要重载?
请高手解答下,最好给出段代码研究研究

回复次数:13

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#1楼 得分:0回复于:2009-09-23 15:12:16


没人回答下吗。。。

精华推荐:散分:输入法终结者

  • jiabin_007用户头像
  • jiabin_007
  • (咿呀学语)
  • 等 级:

#2楼 得分:0回复于:2009-09-24 13:17:10

关注中

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#3楼 得分:0回复于:2009-09-27 14:47:01

顶一下,有没有高手来解惑。。。

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#4楼 得分:0回复于:2009-09-27 14:55:24

我觉得还是重写CFileDialog的OnFileNameChange或者OnFileNameOK吧

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#5楼 得分:0回复于:2009-09-27 15:15:54

我刚才在vc2008中看了一下,CFileDialog会自己把后缀名加上然后判断文件是否存在?不直到你用的是那个MFC版本?

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#6楼 得分:0回复于:2009-09-27 15:34:09

我是VS2005, 你说的那种是不是在定义CFileDialog对象的时候给他一个默认扩展名的参数,而不用NULL,我也想过如果只有一个扩展名的话,或许就像你说的那样,设定默认扩展名可以自动添加扩展名后进行覆盖判断,但是我有多个扩展名过滤规则,默认扩展名参数为NULL,MFC怎么自动根据我选择的哪个过滤规则来添加相应的扩展名后进行覆盖判断呢?

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#7楼 得分:0回复于:2009-09-27 15:39:00

我再看看,刚才确实设置了默认扩展名

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#8楼 得分:0回复于:2009-09-27 15:56:51

我也测试了下,发现只要 lpszDefExt 不为NULL就能满足我的需要了,但是我奇怪的是和MSDN上的话语似乎不符..
lpszDefExt 缺省文件扩展名,如果用户在文件名编辑框中不包含扩展名,则lpszDefExt定义的扩展名自动加到文件名后。如果为NULL,则不添加扩展名。 
我的测试结果是lpszDefExt 的值只要不为NULL,就能自动根据过滤规则的扩展名来自动添加该扩展名进行覆盖判断

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#9楼 得分:0回复于:2009-09-27 16:04:28

引用 8 楼 shiwei0124 的回复:
我也测试了下,发现只要 lpszDefExt 不为NULL就能满足我的需要了,但是我奇怪的是和MSDN上的话语似乎不符..
lpszDefExt 缺省文件扩展名,如果用户在文件名编辑框中不包含扩展名,则lpszDefExt定义的扩展名自动加到文件名后。如果为NULL,则不添加扩展名。
我的测试结果是lpszDefExt 的值只要不为NULL,就能自动根据过滤规则的扩展名来自动添加该扩展名进行覆盖判断

嗯,确实是这样的

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#10楼 得分:20回复于:2009-09-27 16:07:58

重写CFileDialog的OnTypeChange函数也是可以的
void CFileDialogEx::OnTypeChange()
{
int n=m_ofn.nFilterIndex;
if (n==1)
{
SetDefExt("txt");
}
else if (n==2)
{
SetDefExt("xls");
}
CFileDialog::OnTypeChange();
}

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#11楼 得分:0回复于:2009-09-27 16:09:45

呵呵,我看了对于lpszDefExt的那段说明,一直以为,添加的扩展名是lpszDefExt中设置的值,而与选取的过滤规则无关,没想到结果会是这样的,看来实践是检验真理的唯一标准。。
感谢oyster2008,和你讨论后,自己也愿意测试代码,否则自己应该还在那里根据看到的进行猜想。。

  • oyster2008用户头像
  • oyster2008
  • (oyster2008)
  • 等 级:

#12楼 得分:0回复于:2009-09-27 16:18:10

引用 11 楼 shiwei0124 的回复:
呵呵,我看了对于lpszDefExt的那段说明,一直以为,添加的扩展名是lpszDefExt中设置的值,而与选取的过滤规则无关,没想到结果会是这样的,看来实践是检验真理的唯一标准。。
感谢oyster2008,和你讨论后,自己也愿意测试代码,否则自己应该还在那里根据看到的进行猜想。。

嗯,我也有同样的感受啊

  • shiwei0124用户头像
  • shiwei0124
  • 等 级:

#13楼 得分:0回复于:2009-09-27 16:19:59

这个问题解决,进行结贴,分都给你了

——————————————————————————无敌分割线——————————————————————————

 

困扰好久的问题已经顺利解决了,另外从这个回复

重写CFileDialog的OnTypeChange函数也是可以的
void CFileDialogEx::OnTypeChange()
{
int n=m_ofn.nFilterIndex;
if (n==1)
{
SetDefExt("txt");
}
else if (n==2)
{
SetDefExt("xls");
}
CFileDialog::OnTypeChange();
}

深入了下,发现源码中有这么一段描述,

// Overridable callbacks
protected:
    friend UINT_PTR CALLBACK _AfxCommDlgProc(HWND, UINT, WPARAM, LPARAM);
    virtual UINT OnShareViolation(LPCTSTR lpszPathName);
    virtual BOOL OnFileNameOK();
    virtual void OnLBSelChangedNotify(UINT nIDBox, UINT iCurSel, UINT nCode);

    // only called back if OFN_EXPLORER is set
    virtual void OnInitDone();
    virtual void OnFileNameChange();
    virtual void OnFolderChange();
    virtual void OnTypeChange();

以前虽然听说过回调函数(callbacks),但是一直不懂什么函数,这次正好学习了下,原来回调函数给我们继承类后,设置一些功能提供了很大方便。虽然如何使用懂了些,但是对回调函数的运行机制还是不是很懂,以后有空深入学习下,自己设计回调函数看看

原创粉丝点击