Reputation: 63846
Our application saves its projects as a folder full of stuff, including the actual project file something.abc
It is a niggle that when loading a project, we have to go into the project folder and find the project file. I know there are folder-selection OS dialogs but I only want it to work if it can see the file exists inside the folder.
I'm sure I saw this done but I've no idea how... we're using Qt but answers for that or natively for Windows are welcome. The one thing is I want to use the native OS dialogs not build my own from scratch.
Upvotes: 1
Views: 354
Reputation: 598449
The Win32 SHBrowseForFolder()
and IFileOpenDialog
APIs both allow the user to select a folder.
Both APIs allow you to react to dialog events, like changes to the current folder selection, validation of the current selection, etc. SHBrowseForFolder()
has a callback function, and IFileOpenDialog
has an IFileDialogEvents
sink interface.
Such a callback/sink can check whether the currently selected folder has a given file type, and then block or allow the dialog from returning that result to the caller.
SHBrowseForFolder()
To check for a file type's existence:
SHGetPathFromIDList()
.FindFirstFile()
with the desired filename pattern mask. or
IShellFolder
interface by passing the folder's absolute PIDL to SHBindToObject()
(or, on pre-Vista systems, use SHGetDesktopFolder()
to get the IShellFolder
of the top-level Desktop shell namespace, then pass the PIDL to its BindToObject()
method).IShellFolder::EnumObjects()
method to get its IEnumIDList
interface.IShellFolder::GetDisplayNameOf()
method to look for a file matching the desired filename pattern.To block or allow the dialog from returning success to the caller, the callback function can handle the BFFM_SELCHANGED
notification to validate the folder as needed and then send the dialog window a BFFM_ENABLEOK
message with the lParam
set to zero or non-zero accordingly.
IFileOpenDialog
To check for a file type's existence:
IShellItem::BindToHandler()
method to retrieve its IEnumShellItems
interface.IShellItem
interfaces for the files, using the IShellItem::GetDisplayName()
method to look for a file matching the desired filename pattern.To block or allow the dialog from returning success to the caller, the sink can implement the OnFileOk
event to validate the selected folder and return S_OK
or S_FALSE
as needed.
Alternatively, the sink can implement the OnFolderChange
event to enable/disable the dialog's OK button directly (IFileDialogCustomize::SetControlState()
doesn't work in this case):
HWND
by querying the dialog for its IOleWindow
interface, and then calling its GetWindow()
method.GetDlgItem()
function to get the HWND
of the OK button using the standard IDOK
control ID.EnableWindow()
function to enable/disable the button.Upvotes: 6