114 COM_APARTMENT apartment;
116 if( FAILED( apartment.Result() ) )
118 wxLogTrace(
traceModelPreview, wxS(
"Unable to enter a COM apartment for the model picker: 0x%08lx" ),
119 static_cast<unsigned long>( apartment.Result() ) );
123 COM_PTR<IFileOpenDialog> dialog;
124 HRESULT hr = CoCreateInstance( CLSID_FileOpenDialog,
nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( dialog.Put() ) );
128 wxLogTrace(
traceModelPreview, wxS(
"Unable to create the Windows model picker: 0x%08lx" ),
129 static_cast<unsigned long>( hr ) );
133 FILEOPENDIALOGOPTIONS options =
134 FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST | FOS_FORCEPREVIEWPANEON;
136 if( !( aOptions.
style & wxFD_CHANGE_DIR ) )
137 options |= FOS_NOCHANGEDIR;
139 if( aOptions.
style & wxFD_SHOW_HIDDEN )
140 options |= FOS_FORCESHOWHIDDEN;
142 if( aOptions.
style & wxFD_NO_FOLLOW )
143 options |= FOS_NODEREFERENCELINKS;
145 hr = dialog->SetOptions( options );
147 if( SUCCEEDED( hr ) && !aOptions.
title.empty() )
148 hr = dialog->SetTitle( aOptions.
title.wc_str() );
150 if( SUCCEEDED( hr ) && !aOptions.
filename.empty() )
151 hr = dialog->SetFileName( aOptions.
filename.wc_str() );
153 COM_PTR<IShellItem> initialFolder;
155 if( SUCCEEDED( hr ) && !aOptions.
directory.empty() )
157 HRESULT folderResult = SHCreateItemFromParsingName( aOptions.
directory.wc_str(),
nullptr,
158 IID_PPV_ARGS( initialFolder.Put() ) );
160 if( SUCCEEDED( folderResult ) )
161 dialog->SetFolder( initialFolder.Get() );
166 wxArrayString descriptions;
167 wxArrayString patterns;
168 wxParseCommonDialogsFilter( aOptions.
wildcard, descriptions, patterns );
170 std::vector<COMDLG_FILTERSPEC> filterSpecs;
171 filterSpecs.reserve( descriptions.GetCount() );
173 for(
size_t i = 0; i < descriptions.GetCount(); ++i )
174 filterSpecs.push_back( { descriptions[i].wc_str(), patterns[i].wc_str() } );
176 if( SUCCEEDED( hr ) )
177 hr = dialog->SetFileTypes(
static_cast<UINT
>( filterSpecs.size() ), filterSpecs.data() );
179 if( SUCCEEDED( hr ) )
181 UINT filterIndex = aOptions.
filterIndex >= 0 &&
static_cast<size_t>( aOptions.
filterIndex ) < filterSpecs.size()
184 hr = dialog->SetFileTypeIndex( filterIndex );
187 COM_PTR<IFileDialogCustomize> customize;
188 bool hasEmbedControl =
false;
190 if( SUCCEEDED( hr ) )
192 HRESULT customizeResult = dialog->QueryInterface( IID_PPV_ARGS( customize.Put() ) );
194 if( SUCCEEDED( customizeResult ) )
196 customizeResult = customize->AddCheckButton( EMBED_FILE_CONTROL_ID,
_(
"Embed file" ).wc_str(),
198 hasEmbedControl = SUCCEEDED( customizeResult );
201 if( FAILED( customizeResult ) )
203 wxLogTrace(
traceModelPreview, wxS(
"Unable to add the Embed file control: 0x%08lx" ),
204 static_cast<unsigned long>( customizeResult ) );
208 wxWindow* ownerWindow = aOptions.
parent ? wxGetTopLevelParent( aOptions.
parent ) :
nullptr;
209 HWND owner = ownerWindow ?
static_cast<HWND
>( ownerWindow->GetHandle() ) :
nullptr;
211 if( SUCCEEDED( hr ) )
213 wxWindowDisabler disableOtherWindows(
nullptr, ownerWindow );
214 hr = dialog->Show( owner );
217 if( owner && IsWindow( owner ) )
218 SetForegroundWindow( owner );
220 if( hr == HRESULT_FROM_WIN32( ERROR_CANCELLED ) )
226 static_cast<unsigned long>( hr ) );
230 COM_PTR<IShellItem> selectedItem;
231 hr = dialog->GetResult( selectedItem.Put() );
233 COTASKMEM_STRING selectedPath;
235 if( SUCCEEDED( hr ) )
236 hr = selectedItem->GetDisplayName( SIGDN_FILESYSPATH, selectedPath.Put() );
238 BOOL embedFile = aOptions.
embedFile ? TRUE : FALSE;
240 if( SUCCEEDED( hr ) && hasEmbedControl )
242 HRESULT checkboxResult = customize->GetCheckButtonState( EMBED_FILE_CONTROL_ID, &embedFile );
244 if( FAILED( checkboxResult ) )
246 wxLogTrace(
traceModelPreview, wxS(
"Unable to read the Embed file control: 0x%08lx" ),
247 static_cast<unsigned long>( checkboxResult ) );
252 if( SUCCEEDED( hr ) )
254 UINT filterIndex = 1;
256 if( SUCCEEDED( dialog->GetFileTypeIndex( &filterIndex ) ) && filterIndex > 0 )
257 result.filterIndex =
static_cast<int>( filterIndex - 1 );
260 result.path = selectedPath.Get();
261 result.embedFile = embedFile != FALSE;
wxString result
Test unit parsing edge cases and error handling.