void openBrowseDialogCore(FileDialogType type, const Path& defaultPath, const String& filterList, Vector<Path>& paths, AsyncOp& returnValue) { // Init COM library. CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); IFileDialog* fileDialog = nullptr; UINT32 dialogType = ((UINT32)type & (UINT32)FileDialogType::TypeMask); bool isOpenDialog = dialogType == (UINT32)FileDialogType::OpenFile || dialogType == (UINT32)FileDialogType::OpenFolder; // Create dialog IID classId = isOpenDialog ? CLSID_FileOpenDialog : CLSID_FileSaveDialog; CoCreateInstance(classId, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&fileDialog)); addFiltersToDialog(fileDialog, filterList); setDefaultPath(fileDialog, defaultPath); // Apply multiselect flags bool isMultiselect = false; if (isOpenDialog) { if (dialogType == (UINT32)FileDialogType::OpenFile) { if (((UINT32)type & (UINT32)FileDialogType::Multiselect) != 0) { DWORD dwFlags; fileDialog->GetOptions(&dwFlags); fileDialog->SetOptions(dwFlags | FOS_ALLOWMULTISELECT); isMultiselect = true; } } else { DWORD dwFlags; fileDialog->GetOptions(&dwFlags); fileDialog->SetOptions(dwFlags | FOS_PICKFOLDERS); } } // Show the dialog bool finalResult = false; // Need to enable all windows, otherwise when the browse dialog closes the active window will become some // background window Win32Window::_enableAllWindows(); if (SUCCEEDED(fileDialog->Show(nullptr))) { if (isMultiselect) { // Get file names IFileOpenDialog* fileOpenDialog; fileDialog->QueryInterface(IID_IFileOpenDialog, (void**)&fileOpenDialog); IShellItemArray* shellItems = nullptr; fileOpenDialog->GetResults(&shellItems); getPaths(shellItems, paths); shellItems->Release(); fileOpenDialog->Release(); } else { // Get the file name IShellItem* shellItem = nullptr; fileDialog->GetResult(&shellItem); LPWSTR filePath = nullptr; shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath); paths.push_back((Path)UTF8::fromWide(WString(filePath))); CoTaskMemFree(filePath); shellItem->Release(); } finalResult = true; } // Restore modal window state (before we enabled all windows) Win32Window::_restoreModalWindows(); CoUninitialize(); returnValue._completeOperation(finalResult); }
//----------------------------------------------------------------------------- bool VistaFileSelector::runModalInternal () { fileDialog = 0; HRESULT hr = -1; if (style == kSelectSaveFile) { hr = CoCreateInstance (CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IFileDialog, &fileDialog)); if (defaultSaveName) { fileDialog->SetFileName (UTF8StringHelper (defaultSaveName)); } } else { hr = CoCreateInstance (CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IFileDialog, &fileDialog)); if (SUCCEEDED (hr)) { if (style == kSelectDirectory) { DWORD dwOptions = 0; hr = fileDialog->GetOptions (&dwOptions); if (SUCCEEDED (hr)) hr = fileDialog->SetOptions (dwOptions | FOS_PICKFOLDERS); if (FAILED (hr)) { fileDialog->Release (); fileDialog = 0; return false; } } if (allowMultiFileSelection) { DWORD dwOptions = 0; hr = fileDialog->GetOptions (&dwOptions); if (SUCCEEDED (hr)) hr = fileDialog->SetOptions (dwOptions | FOS_ALLOWMULTISELECT); if (FAILED (hr)) { fileDialog->Release (); fileDialog = 0; return false; } } } } if (FAILED (hr)) { fileDialog = 0; return false; } if (title) hr = fileDialog->SetTitle (UTF8StringHelper (title)); DWORD numExtensions = 0; DWORD defaultFileTypeIndex = 0; COMDLG_FILTERSPEC* filters = buildExtensionFilter (extensions, defaultExtension, numExtensions, defaultFileTypeIndex); if (filters) { fileDialog->SetFileTypes (numExtensions, filters); if (defaultFileTypeIndex) fileDialog->SetFileTypeIndex (defaultFileTypeIndex); } if (initialPath && _SHCreateItemFromParsingName) { IShellItem* shellItem; hr = _SHCreateItemFromParsingName (UTF8StringHelper (initialPath), 0, IID_PPV_ARG (IShellItem, &shellItem)); if (SUCCEEDED (hr)) { fileDialog->SetFolder (shellItem); shellItem->Release (); } } Win32Frame* win32Frame = frame->getPlatformFrame () ? dynamic_cast<Win32Frame*> (frame->getPlatformFrame ()) : 0; hr = fileDialog->Show (win32Frame ? win32Frame->getPlatformWindow () : 0); if (SUCCEEDED (hr)) { if (allowMultiFileSelection) { IFileOpenDialog* openFileDialog = 0; hr = fileDialog->QueryInterface (IID_PPV_ARG(IFileOpenDialog, &openFileDialog)); if (SUCCEEDED (hr)) { IShellItemArray* items; hr = openFileDialog->GetResults (&items); if (SUCCEEDED (hr)) { DWORD count; hr = items->GetCount (&count); for (DWORD i = 0; i < count; i++) { IShellItem* item; hr = items->GetItemAt (i, &item); if (SUCCEEDED (hr)) { LPWSTR filesysPath = 0; hr = item->GetDisplayName (SIGDN_FILESYSPATH, &filesysPath); if (SUCCEEDED (hr)) { UTF8StringHelper str (filesysPath); UTF8StringBuffer resultPath = String::newWithString (str); result.push_back (resultPath); } item->Release (); } } items->Release (); } openFileDialog->Release (); } } else { IShellItem *item; hr = fileDialog->GetResult (&item); if (SUCCEEDED (hr)) { LPWSTR filesysPath = 0; hr = item->GetDisplayName (SIGDN_FILESYSPATH, &filesysPath); if (SUCCEEDED (hr)) { UTF8StringHelper str (filesysPath); UTF8StringBuffer resultPath = String::newWithString (str); result.push_back (resultPath); } item->Release (); } } } fileDialog->Release (); fileDialog = 0; freeExtensionFilter (filters); return SUCCEEDED (hr); }