问题
最近需要实现文件选择的功能,要求是需要弹出系统标准的文件选择对话框,另外,允许用户选择多个文件。
解决方法
MFC中有一个类CFileDialog就是用来做这件事的,而且功能还挺丰富,今天只是使用它的一小部分特性。
直接上代码
以下代码实现了一个方法,该方法弹出文件选择对话框,允许用户选择多个文件,让点击确定时,以列表的形式,返回用户选择的所有文件。
![b9319a6b9df6d9381746d4a527208e2d.png](https://img-blog.csdnimg.cn/img_convert/b9319a6b9df6d9381746d4a527208e2d.png)
以下是使用上述方法的客户代码
![1adea3f3f1d8125e071ba4aec797e4ea.png](https://img-blog.csdnimg.cn/img_convert/1adea3f3f1d8125e071ba4aec797e4ea.png)
代码解析
1) CFileDiag有如下几个参数:
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);
bOpenFileDialog:TRUE: 创建一个打开文件对话框,FALSE: 创建一个文件另存为对话框。
lpszDefExt: 默认文件后缀。如果用户没有输入后缀,则系统会默认追加此后缀。
lpszFileName:初始文件名。文件打开时,默认加载的文件名。
dwFlags:对话框选项,用来定制对话框的各个属性。
lpszFilter:过滤器,形如:”所有文件 (*.*)|*.*|”。
pParentWnd:指定对话框的父窗口。
dwSize:OPENFILENAME结构体的大小。一般指定为0。
bVistaStyle:启用Vista风格,仅对VS2008及以后的版本可用。
2) 使用到的风格OFN_ALLOWMULTISELECT来启用文件的多选。
3) 当用户选择完毕后,使用GetStartPosition和GetNextPathName来遍历所有用户选择的文件路径,这里的路径是文件的全路径。
4) 使用vector用来返回用户选择的文件列表,返回过程可能会涉及一些对象的拷贝构造,但考虑到不是性能攸关的代码中执行,所以这点开销,还是可以接受的。
5) 客户代码中,使用了一个vector的引用来接方法的返回值,这样避免了对象的额外拷贝构造过程。
另一个问题
在一个项目中发现,调试模式下,CFileDialog打开时速度较慢,如果切换到Release模式,就很快能打开。我想这个可能的原因是调试模式的MFC库因为有许多ASSERT之类的检查,所以才会显得比较慢。
总结
1) 使用系统标准的组件设施,有助于提高应用程序界面和操作上的一致性,这样,用户比较容易上手。
2) 在调试模式下加入一些ASSERT,有助于在开发早期暴露出程序的内部错误,这样在Release模式就比较放心一点,而且,更重要的是,性能较之调试模式,有很大的提升。这就像平时练习跑步上在两只脚上绑上沙袋,练得的确很辛苦,但是当歇下沙袋,就会有身轻如燕的感觉。
![c732713e771162b7dddc1e85e28267e0.png](https://img-blog.csdnimg.cn/img_convert/c732713e771162b7dddc1e85e28267e0.png)