4.使用CFileDialog打开文件对话框,获得文件路径 -windows编程

引言:没想到2022年还有很多工业软件公司依然使用MFC,微软也一直在更新MFC的库,这次使用MFC封装的CFileDialog类,写一个获得选定文件路径,名称,扩展名的程序。

 

个人技术博客(文章整理+源码): //zobolblog.github.io/LearnWinAPI/

最终效果:

 

 

 

1.CFileDialog的使用

CFileDialog是MFC对windows api的FileDialog的简单封装,增加了一些接口,他的构造函数只有一个:

 

explicit CFileDialog(

BOOL bOpenFileDialog,

LPCTSTR lpszDefExt = NULL,

LPCTSTR lpszFileName = NULL,

DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,

LPCTSTR lpszFilter = NULL,

CWnd* pParentWnd = NULL,

DWORD dwSize = 0,

BOOL bVistaStyle = TRUE);

 

第1个参数bOpenFileDialog为TRUE则表示打开文件对话框,为FALSE则表示保存文件对话框。它也是我们必须填写的,其他的都有默认值。

第2个参数lpszFileName指定默认的文件扩展名。就是txt,exe这类。

第3个参数lpszFileName指定默认的文件名。一般是保存文件框用的。

第4个参数dwFlags 指明一些特定风格,比如多选对话框,可读文件,隐藏文件不显示。

第5个参数lpszFilter是过滤器意思,写法国内的博客很乱,但其实微软官方给了一种很易读的写法。

static TCHAR BASED_CODE szFilter[] = _T(“Chart Files (*.xlc)|*.xlc|”)

_T(“Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|”)

_T(“*.xlc; *.xls|All Files (*.*)|*.*||”);

第6个参数pParentWnd指定父窗口的指针。

第7个参数dwSize是指OPENFILENAME结构的大小,这此值取决于操作系统版本。MFC使用此参数确定要创建的适当类型的对话框。默认大小0表示MFC代码将根据运行程序的操作系统版本确定要使用的正确对话框大小。

第8个参数bVistaStyle,默认都是true。它实际上是因为微软在vs2008后,设计了新的对话框风格。所以就用一个bool类型,表示新旧风格。(微软就不考虑用宏或者枚举,万一以后又出一个第3风格版本呢。。)

 

2.DoModal()函数

  就像QT里面的show函数一样,虽然CFileDialog dlg在内存中创造了一个对话框对象,但是显示出来给人看,还需要专门的函数DoModal()。

  “Call this function to display the Windows common file dialog box and allow the user to browse files and directories and enter a filename.”调用此函数可显示Windows公用文件对话框,允许用户浏览文件和目录并输入文件名。

 

3.DoModal()函数的返回值IDOK和IDCANCEL

  在窗口的生命周期结束后,domodal还会返回一个值,告诉我们一些情况。但是MFC的设计在这里非常的烦人,单纯的IDCANCEL只能告诉我们出现了问题。至于是什么问题还需要调用一个CommDlgExtendedError函数才可以知道。(至于这里为什么不设计成返回一个结构体,直接包含错误信息,估计是90年代开发MFC的时候,计算机性能不够?)

 

源码:

    CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,_T("All FILE|*.*|"),NULL,NULL,1);

    if (dlg.DoModal() != IDOK)
    {
        CommDlgExtendedError();
    }
    else {
        CString filePathName = dlg.GetPathName();
        CString fileName = dlg.GetFileName();  // return only filename
        CString fileExt = dlg.GetFileExt();   // return only ext
        CString fileTitle = dlg.GetFileTitle(); // return file title
    }

 

效果: