Try using the Vista+ IFileDialog APIs first with the private interfaces, * falling back to legacy functions if said private APIs aren't available. * * Note neither IFileDialog or the legacy functions are valid for UWP WinRT, * for which Windows::Storage::Pickers::FileOpenPicker will have to be used instead. */
| 250 | * for which Windows::Storage::Pickers::FileOpenPicker will have to be used instead. |
| 251 | */ |
| 252 | QStringList FileDialogInternal::nativeFileDialog( |
| 253 | NativeFileDialogMode mode, |
| 254 | QWidget* parent, |
| 255 | const QString& caption, |
| 256 | const QString& startPath, |
| 257 | const FileDialog::FilterList& filters, |
| 258 | qsizetype& selectedFilterIndex, |
| 259 | FileDialog::Options options |
| 260 | ) |
| 261 | { |
| 262 | ComRuntime com; |
| 263 | const bool isOpen = mode == NativeFileDialogMode::OpenSingle |
| 264 | || mode == NativeFileDialogMode::OpenMultiple; |
| 265 | |
| 266 | ComPointer<IFileDialog> fileDialog; |
| 267 | if (FAILED(CoCreateInstance( |
| 268 | isOpen ? CLSID_FileOpenDialog : CLSID_FileSaveDialog, |
| 269 | nullptr, |
| 270 | CLSCTX_INPROC_SERVER, |
| 271 | isOpen ? IID_IFileOpenDialog : IID_IFileSaveDialog, |
| 272 | fileDialog.ppvObject() |
| 273 | ))) { |
| 274 | Base::Console().warning("Failed to create IFileDialog, falling back on GetOpen/SaveFileNameW"); |
| 275 | return legacyNativeFileDialog(mode, parent, caption, startPath, filters, selectedFilterIndex, options); |
| 276 | } |
| 277 | |
| 278 | // These aren't wrapped interfaces, can't use ComPointer on them |
| 279 | IFileDialogPrivate_W10* w10; |
| 280 | IFileDialogPrivate_W7* w7; |
| 281 | // Set the private flag to hide filter patterns |
| 282 | if (SUCCEEDED( |
| 283 | fileDialog->QueryInterface(IID_IFileDialogPrivate_W10, reinterpret_cast<void**>(&w10)) |
| 284 | )) { |
| 285 | FileDialogPrivateOptions flags; |
| 286 | w10->lpVtbl->GetPrivateOptions(w10, &flags); |
| 287 | w10->lpVtbl->SetPrivateOptions(w10, flags | FDPO_DONT_FORCE_SHOW_EXTS); |
| 288 | w10->lpVtbl->Release(w10); |
| 289 | } |
| 290 | else if ( |
| 291 | SUCCEEDED(fileDialog->QueryInterface(IID_IFileDialogPrivate_W7, reinterpret_cast<void**>(&w7))) |
| 292 | ) { |
| 293 | FileDialogPrivateOptions flags; |
| 294 | w7->lpVtbl->GetPrivateOptions(w7, &flags); |
| 295 | w7->lpVtbl->SetPrivateOptions(w7, flags | FDPO_DONT_FORCE_SHOW_EXTS); |
| 296 | w7->lpVtbl->Release(w7); |
| 297 | } |
| 298 | else { |
| 299 | // No private API, fall back to legacy and emit warning |
| 300 | Base::Console() |
| 301 | .warning("FileDialog fell back on legacy GetOpen/SaveFileNameW, the IFileDialog private API needs to be updated"); |
| 302 | return legacyNativeFileDialog(mode, parent, caption, startPath, filters, selectedFilterIndex, options); |
| 303 | } |
| 304 | |
| 305 | // Populate file filters |
| 306 | const bool showPatterns = getPreferShowFilterPatterns(); |
| 307 | std::vector<std::pair<QString, QString>> qstringFilterSpecs; |
| 308 | qstringFilterSpecs.reserve(filters.size()); |
| 309 | qsizetype totalStringLength = 0; |
nothing calls this directly
no test coverage detected