使用文件对话框选择包含特定文件类型的文件夹?

Use file dialog to select a folder that contains a specific file type?

本文关键字:文件 类型 文件夹 包含特 对话框 选择      更新时间:2023-10-16

我们的应用程序将其项目保存为一个包含内容的文件夹,包括实际的项目文件 something.abc

加载项目时,我们必须进入项目文件夹并找到项目文件,这是一个小问题。我知道有文件夹选择操作系统对话框,但我只希望它能在它看到文件夹中存在的文件时才起作用。

我确定我看到了这个完成,但我不知道如何...我们正在使用Qt,但欢迎对此或Windows本机提供答案。一件事是我想使用本机操作系统对话框,而不是从头开始构建自己的对话框。

Win32SHBrowseForFolder()IFileOpenDialogAPI 都允许用户选择文件夹。

这两个 API 都允许您对对话框事件做出反应,例如对当前文件夹选择的更改、对当前选择的验证等。SHBrowseForFolder()有一个回调函数,IFileOpenDialog有一个IFileDialogEvents接收器接口。

此类回调/接收器可以检查当前选定的文件夹是否具有给定的文件类型,然后阻止或允许对话框将该结果返回给调用方。

SHBrowseForFolder()

要检查文件类型是否存在,请执行以下操作:

  • 通过将文件夹的绝对 PIDL 传递给SHGetPathFromIDList()来获取文件夹的文件系统路径。
  • 然后使用具有所需文件名模式掩码的FindFirstFile()搜索该路径。

  • 通过将文件夹的绝对 PIDL 传递给SHBindToObject()来检索IShellFolder接口(或者在 Vista 之前的系统上,使用SHGetDesktopFolder()获取顶级桌面 shell 命名空间的IShellFolder,然后将 PIDL 传递给其BindToObject()方法(。
  • 然后使用IShellFolder::EnumObjects()方法获取其IEnumIDList接口。
  • 然后枚举文件的相对 PIDL,使用父文件夹的IShellFolder::GetDisplayNameOf()方法来查找与所需文件名模式匹配的文件。

若要阻止或允许对话框向调用方返回成功,回调函数可以处理BFFM_SELCHANGED通知以根据需要验证文件夹,然后向对话框窗口发送一条BFFM_ENABLEOK消息,lParam相应地设置为零或非零。

IFileOpenDialog

要检查文件类型是否存在,请执行以下操作:

  • 使用文件夹的IShellItem::BindToHandler()方法检索其IEnumShellItems接口。
  • 然后枚举文件的IShellItem接口,使用IShellItem::GetDisplayName()方法查找与所需文件名模式匹配的文件。

若要阻止或允许对话框将成功返回给调用方,接收器可以实现OnFileOk事件来验证所选文件夹并根据需要返回S_OKS_FALSE

或者,接收器可以实现OnFolderChange事件以直接启用/禁用对话框的 OK 按钮(在这种情况下IFileDialogCustomize::SetControlState()不起作用(:

  • 通过查询对话框的IOleWindow接口,然后调用其GetWindow()方法来检索对话框的HWND
  • 然后使用 Win32GetDlgItem()函数通过标准IDOK控件 ID 获取"确定"按钮的HWND
  • 然后使用 Win32EnableWindow()函数启用/禁用按钮。