windows从 vista 开始后面操作系统提供新文件选择打开(保存)对话框,文件选择视图与windows资源管理器保持一致,比如上面显示路径可编辑及搜索编辑框,左侧显示树视图,右侧显示预览窗口等。
Vista之前使用 GetOpenFileName,GetSaveFileName函数来启动打开保存文件对话框并支持hook来扩展文件选择对话框的功能,比如修改打开(或保存)按钮文字,获得文件选择事件等等,修改麻烦但自定义比较灵活。
Vista 风格文件选择对话框提供全新封装的com接口来操作文件选择对话框。
IFileOpenDialog 和IFileSaveDialog 继承于 IFileDialog
接口的基本使用参考:http://www.cnblogs.com/dflying/archive/2007/03/23/685540.html
http://www.tuicool.com/articles/r6fmyi
有这样一个需求,要求在文件打开对话框中同时选择文件和文件夹发送,接口提供了 SetOptions 方法可设置多选标记同时选择文件和文件夹,在提供IFileOpenDialog 接口中有 GetResult, GetResults, GetSelectedItems分别能得到单个文件(文件选择对话框没有设置多选标记时)、得到多个文件集合,得到文件夹和文件集合。
我的需求要能同时选择文件和文件夹只能使用GetSelectedItems方法,然而这个方法存在一个问题,当选择多个文件或同时选择文件和文件夹都能拿到正确的集合,但如果只多选文件夹就无法得到文件夹集合,不知道这个算不算bug。
如果是使用 vista之前系统风格对话框即使用GetOpenFileName的对话框因为可以设置hook,而comdlg 又提供一些通用方法在收到用户选择改变事件时能拿到用户选择的文件列表可自义程度高是能满足需求的。使用新风格的IFileDialogEvents接口可以拿到用户选择的事件(注:在这个事件处理中调用GetSelectedItems也有小bug),但没有找到通用的方法拿到用户选择的文件项内容,即使可以也一样相当麻烦。
原本准备放弃,因需求还要求能设置视图类型为大图标,在查找资料时发现可以把文件选择对话框窗口当作shell窗口来看,有IFolderView2,可以通过 IFileDialog query 到IServiceProvider 再 query 到IShellBrowser,就可以query到IFolderView2。
其中有 GetSelection 方法可以在任何情况下获得用户选中的文件和文件夹列表。这样可以使用IFolderView2的GetSelection取代IFileOpenDialog 接口来获得文件和文件夹列表,这样同时选择文件和文件夹发送的需求得以实现。