merged tag ooo/DEV300_m102
[LibreOffice.git] / fpicker / source / win32 / filepicker / VistaFilePickerImpl.cxx
blob677c2bdbfa7defdf691fb6d0f3da7e9e91517bea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 //-----------------------------------------------------------------------------
29 // includes
30 //-----------------------------------------------------------------------------
32 #include "VistaFilePickerImpl.hxx"
34 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
35 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
36 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
37 #include <comphelper/sequenceasvector.hxx>
38 #include <osl/file.hxx>
39 #include <osl/mutex.hxx>
40 #ifdef __MINGW32__
41 #include <limits.h>
42 #endif
43 #include "..\misc\WinImplHelper.hxx"
45 inline bool is_current_process_window(HWND hwnd)
47 DWORD pid;
48 GetWindowThreadProcessId(hwnd, &pid);
49 return (pid == GetCurrentProcessId());
52 HWND choose_parent_window()
54 HWND hwnd_parent = GetForegroundWindow();
55 if (!is_current_process_window(hwnd_parent))
56 hwnd_parent = GetDesktopWindow();
57 return hwnd_parent;
60 //-----------------------------------------------------------------------------
61 // namespace
62 //-----------------------------------------------------------------------------
64 namespace fpicker{
65 namespace win32{
66 namespace vista{
68 namespace css = ::com::sun::star;
70 //-----------------------------------------------------------------------------
71 // types, const etcpp.
72 //-----------------------------------------------------------------------------
75 static const ::sal_Int16 INVALID_CONTROL_ID = -1;
76 static const ::sal_Int16 INVALID_CONTROL_ACTION = -1;
78 typedef ::comphelper::SequenceAsVector< ::rtl::OUString > TStringList;
80 // Guids used for IFileDialog::SetClientGuid
81 static const GUID CLIENTID_FILEDIALOG_SIMPLE = {0xB8628FD3, 0xA3F5, 0x4845, 0x9B, 0x62, 0xD5, 0x1E, 0xDF, 0x97, 0xC4, 0x83};
82 static const GUID CLIENTID_FILEDIALOG_OPTIONS = {0x93ED486F, 0x0D04, 0x4807, 0x8C, 0x44, 0xAC, 0x26, 0xCB, 0x6C, 0x5D, 0x36};
83 static const GUID CLIENTID_FILESAVE = {0x3B2E2261, 0x402D, 0x4049, 0xB0, 0xC0, 0x91, 0x13, 0xF8, 0x6E, 0x84, 0x7C};
84 static const GUID CLIENTID_FILESAVE_PASSWORD = {0xC12D4F4C, 0x4D41, 0x4D4F, 0x97, 0xEF, 0x87, 0xF9, 0x8D, 0xB6, 0x1E, 0xA6};
85 static const GUID CLIENTID_FILESAVE_SELECTION = {0x5B2482B3, 0x0358, 0x4E09, 0xAA, 0x64, 0x2B, 0x76, 0xB2, 0xA0, 0xDD, 0xFE};
86 static const GUID CLIENTID_FILESAVE_TEMPLATE = {0x9996D877, 0x20D5, 0x424B, 0x9C, 0x2E, 0xD3, 0xB6, 0x31, 0xEC, 0xF7, 0xCE};
87 static const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE = {0x32237796, 0x1509, 0x49D1, 0xBB, 0x7E, 0x63, 0xAD, 0x36, 0xAE, 0x86, 0x8C};
88 static const GUID CLIENTID_FILEOPEN_PLAY = {0x32CFB147, 0xF5AE, 0x4F90, 0xA1, 0xF1, 0x81, 0x20, 0x72, 0xBB, 0x2F, 0xC5};
89 static const GUID CLIENTID_FILEOPEN_LINK = {0x39AC4BAE, 0x7D2D, 0x46BC, 0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A};
91 //-----------------------------------------------------------------------------
92 ::rtl::OUString lcl_getURLFromShellItem (IShellItem* pItem)
94 LPOLESTR pStr = NULL;
95 ::rtl::OUString sURL;
97 SIGDN eConversion = SIGDN_FILESYSPATH;
98 HRESULT hr = pItem->GetDisplayName ( eConversion, &pStr );
100 if ( FAILED(hr) )
102 eConversion = SIGDN_URL;
103 hr = pItem->GetDisplayName ( eConversion, &pStr );
105 if ( FAILED(hr) )
106 return ::rtl::OUString();
108 sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr));
110 else
112 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL );
115 CoTaskMemFree (pStr);
116 return sURL;
119 //-----------------------------------------------------------------------------------------
120 ::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer& rContainer)
122 const sal_Int32 c = rContainer.numFilter();
123 sal_Int32 i = 0;
124 ::std::vector< COMDLG_FILTERSPEC > lList ;
125 CFilterContainer::FILTER_ENTRY_T aFilter;
127 rContainer.beginEnumFilter( );
128 while( rContainer.getNextFilter(aFilter) )
130 COMDLG_FILTERSPEC aSpec;
132 aSpec.pszName = reinterpret_cast<LPCTSTR>(aFilter.first.getStr()) ;
133 aSpec.pszSpec = reinterpret_cast<LPCTSTR>(aFilter.second.getStr());
135 lList.push_back(aSpec);
138 return lList;
141 //-----------------------------------------------------------------------------------------
142 VistaFilePickerImpl::VistaFilePickerImpl()
143 : m_iDialogOpen ()
144 , m_iDialogSave ()
145 , m_hLastResult ()
146 , m_lFilters ()
147 , m_lLastFiles ()
148 , m_iEventHandler(new VistaFilePickerEventHandler(this))
149 , m_bInExecute (sal_False)
150 , m_bWasExecuted (sal_False)
151 , m_sDirectory ()
152 , m_sFilename ()
154 m_hParentWindow = choose_parent_window();
157 //-------------------------------------------------------------------------------
158 VistaFilePickerImpl::~VistaFilePickerImpl()
162 //-------------------------------------------------------------------------------
163 void VistaFilePickerImpl::before()
165 // SYNCHRONIZED->
166 ::osl::ResettableMutexGuard aLock(m_aMutex);
168 // TRICKY .-)
169 // osl::Thread class initializes COm already in MTA mode because it's needed
170 // by VCL and UNO so. There is no way to change that from outside ...
171 // but we need a STA environment ...
172 // So we make it by try-and-error ...
173 // If first CoInitialize will fail .. we unitialize COM initialize it new .-)
175 m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
176 if ( FAILED(m_hLastResult) )
178 CoUninitialize();
179 m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
183 //-------------------------------------------------------------------------------
184 void VistaFilePickerImpl::doRequest(const RequestRef& rRequest)
188 switch(rRequest->getRequest())
190 case E_ADD_PICKER_LISTENER :
191 impl_sta_addFilePickerListener(rRequest);
192 break;
194 case E_REMOVE_PICKER_LISTENER :
195 impl_sta_removeFilePickerListener(rRequest);
196 break;
198 case E_APPEND_FILTER :
199 impl_sta_appendFilter(rRequest);
200 break;
202 case E_SET_CURRENT_FILTER :
203 impl_sta_setCurrentFilter(rRequest);
204 break;
206 case E_GET_CURRENT_FILTER :
207 impl_sta_getCurrentFilter(rRequest);
208 break;
210 case E_CREATE_OPEN_DIALOG :
211 impl_sta_CreateOpenDialog(rRequest);
212 break;
214 case E_CREATE_SAVE_DIALOG :
215 impl_sta_CreateSaveDialog(rRequest);
216 break;
218 case E_SET_MULTISELECTION_MODE :
219 impl_sta_SetMultiSelectionMode(rRequest);
220 break;
222 case E_SET_TITLE :
223 impl_sta_SetTitle(rRequest);
224 break;
226 case E_SET_FILENAME:
227 impl_sta_SetFileName(rRequest);
228 break;
230 case E_SET_DIRECTORY :
231 impl_sta_SetDirectory(rRequest);
232 break;
234 case E_GET_DIRECTORY :
235 impl_sta_GetDirectory(rRequest);
236 break;
238 case E_SET_DEFAULT_NAME :
239 impl_sta_SetDefaultName(rRequest);
240 break;
242 case E_GET_SELECTED_FILES :
243 impl_sta_getSelectedFiles(rRequest);
244 break;
246 case E_SHOW_DIALOG_MODAL :
247 impl_sta_ShowDialogModal(rRequest);
248 break;
250 case E_SET_CONTROL_VALUE :
251 impl_sta_SetControlValue(rRequest);
252 break;
254 case E_GET_CONTROL_VALUE :
255 impl_sta_GetControlValue(rRequest);
256 break;
258 case E_SET_CONTROL_LABEL :
259 impl_sta_SetControlLabel(rRequest);
260 break;
262 case E_GET_CONTROL_LABEL :
263 impl_sta_GetControlLabel(rRequest);
264 break;
266 case E_ENABLE_CONTROL :
267 impl_sta_EnableControl(rRequest);
268 break;
270 // no default: let the compiler detect changes on enum ERequest !
273 catch(...)
277 //-------------------------------------------------------------------------------
278 void VistaFilePickerImpl::after()
280 CoUninitialize();
283 //-------------------------------------------------------------------------------
284 void VistaFilePickerImpl::impl_sta_addFilePickerListener(const RequestRef& rRequest)
286 // SYNCHRONIZED outside !
287 const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
288 if ( ! xListener.is())
289 return;
291 // SYNCHRONIZED->
292 ::osl::ResettableMutexGuard aLock(m_aMutex);
293 TFileDialogEvents iHandler = m_iEventHandler;
294 aLock.clear();
295 // <- SYNCHRONIZED
297 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
298 if (pHandlerImpl)
299 pHandlerImpl->addFilePickerListener(xListener);
302 //-------------------------------------------------------------------------------
303 void VistaFilePickerImpl::impl_sta_removeFilePickerListener(const RequestRef& rRequest)
305 // SYNCHRONIZED outside !
306 const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
307 if ( ! xListener.is())
308 return;
310 // SYNCHRONIZED->
311 ::osl::ResettableMutexGuard aLock(m_aMutex);
312 TFileDialogEvents iHandler = m_iEventHandler;
313 aLock.clear();
314 // <- SYNCHRONIZED
316 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
317 if (pHandlerImpl)
318 pHandlerImpl->removeFilePickerListener(xListener);
321 //-------------------------------------------------------------------------------
322 void VistaFilePickerImpl::impl_sta_appendFilter(const RequestRef& rRequest)
324 const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
325 const ::rtl::OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, ::rtl::OUString());
327 // SYNCHRONIZED->
328 ::osl::ResettableMutexGuard aLock(m_aMutex);
330 m_lFilters.addFilter(sTitle, sFilter);
333 //-------------------------------------------------------------------------------
334 void VistaFilePickerImpl::impl_sta_setCurrentFilter(const RequestRef& rRequest)
336 const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
338 // SYNCHRONIZED->
339 ::osl::ResettableMutexGuard aLock(m_aMutex);
341 m_lFilters.setCurrentFilter(sTitle);
344 //-------------------------------------------------------------------------------
345 void VistaFilePickerImpl::impl_sta_getCurrentFilter(const RequestRef& rRequest)
347 TFileDialog iDialog = impl_getBaseDialogInterface();
348 UINT nIndex = UINT_MAX;
349 HRESULT hResult = iDialog->GetFileTypeIndex(&nIndex);
350 if (
351 ( FAILED(hResult) ) ||
352 ( nIndex == UINT_MAX ) // COM dialog sometimes return S_OK for empty filter lists .-(
354 return;
356 // SYNCHRONIZED->
357 ::osl::ResettableMutexGuard aLock(m_aMutex);
359 ::rtl::OUString sTitle;
360 ::sal_Int32 nRealIndex = (nIndex-1); // COM dialog base on 1 ... filter container on 0 .-)
361 if (
362 (nRealIndex >= 0 ) &&
363 (m_lFilters.getFilter(nRealIndex, sTitle))
365 rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
366 else if ( nRealIndex == -1 ) // Dialog not visible yet
368 sTitle = m_lFilters.getCurrentFilter();
369 rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
372 aLock.clear();
373 // <- SYNCHRONIZED
376 //-------------------------------------------------------------------------------
377 void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest)
379 // SYNCHRONIZED->
380 ::osl::ResettableMutexGuard aLock(m_aMutex);
382 m_hLastResult = m_iDialogOpen.create();
383 if (FAILED(m_hLastResult))
384 return;
386 TFileDialog iDialog;
387 #ifdef __MINGW32__
388 m_iDialogOpen->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
389 #else
390 m_iDialogOpen.query(&iDialog);
391 #endif
393 TFileDialogEvents iHandler = m_iEventHandler;
395 aLock.clear();
396 // <- SYNCHRONIZED
398 DWORD nFlags = 0;
399 iDialog->GetOptions ( &nFlags );
401 nFlags &= ~FOS_FORCESHOWHIDDEN;
402 nFlags |= FOS_PATHMUSTEXIST;
403 nFlags |= FOS_FILEMUSTEXIST;
404 nFlags |= FOS_OVERWRITEPROMPT;
405 nFlags |= FOS_DONTADDTORECENT;
407 iDialog->SetOptions ( nFlags );
409 ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
410 ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
411 impl_sta_enableFeatures(nFeatures, nTemplate);
413 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
414 if (pHandlerImpl)
415 pHandlerImpl->startListening(iDialog);
418 //-------------------------------------------------------------------------------
419 void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest)
421 // SYNCHRONIZED->
422 ::osl::ResettableMutexGuard aLock(m_aMutex);
424 m_hLastResult = m_iDialogSave.create();
425 if (FAILED(m_hLastResult))
426 return;
428 TFileDialogEvents iHandler = m_iEventHandler;
429 TFileDialog iDialog;
430 #ifdef __MINGW32__
431 m_iDialogSave->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
432 #else
433 m_iDialogSave.query(&iDialog);
434 #endif
436 aLock.clear();
437 // <- SYNCHRONIZED
439 DWORD nFlags = 0;
440 iDialog->GetOptions ( &nFlags );
442 nFlags &= ~FOS_FORCESHOWHIDDEN;
443 nFlags |= FOS_PATHMUSTEXIST;
444 nFlags |= FOS_FILEMUSTEXIST;
445 nFlags |= FOS_OVERWRITEPROMPT;
446 nFlags |= FOS_DONTADDTORECENT;
448 iDialog->SetOptions ( nFlags );
450 ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
451 ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
452 impl_sta_enableFeatures(nFeatures, nTemplate);
454 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
455 if (pHandlerImpl)
456 pHandlerImpl->startListening(iDialog);
459 //-------------------------------------------------------------------------------
460 static const ::sal_Int32 GROUP_VERSION = 1;
461 static const ::sal_Int32 GROUP_TEMPLATE = 2;
462 static const ::sal_Int32 GROUP_IMAGETEMPLATE = 3;
463 static const ::sal_Int32 GROUP_CHECKBOXES = 4;
465 //-------------------------------------------------------------------------------
466 static void setLabelToControl(CResourceProvider& rResourceProvider, TFileDialogCustomize iCustom, sal_uInt16 nControlId)
468 ::rtl::OUString aLabel = rResourceProvider.getResString(nControlId);
469 aLabel = SOfficeToWindowsLabel(aLabel);
470 iCustom->SetControlLabel(nControlId, reinterpret_cast<LPCWSTR>(aLabel.getStr()) );
473 //-------------------------------------------------------------------------------
474 void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate)
476 GUID aGUID = {};
477 switch (nTemplate)
479 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE :
480 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE :
481 aGUID = CLIENTID_FILEDIALOG_SIMPLE;
482 break;
484 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION :
485 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS :
486 aGUID = CLIENTID_FILEDIALOG_OPTIONS;
487 break;
489 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION :
490 aGUID = CLIENTID_FILESAVE;
491 break;
493 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
494 aGUID = CLIENTID_FILESAVE_PASSWORD;
495 break;
497 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION :
498 aGUID = CLIENTID_FILESAVE_SELECTION;
499 break;
501 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE :
502 aGUID = CLIENTID_FILESAVE_TEMPLATE;
503 break;
505 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE :
506 aGUID = CLIENTID_FILEOPEN_LINK_TEMPLATE;
507 break;
509 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY :
510 aGUID = CLIENTID_FILEOPEN_PLAY;
511 break;
513 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
514 aGUID = CLIENTID_FILEOPEN_LINK;
515 break;
517 TFileDialog iDialog = impl_getBaseDialogInterface();
518 iDialog->SetClientGuid ( aGUID );
520 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
522 if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION)
524 iCustom->StartVisualGroup (GROUP_VERSION, L"Version");
525 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION);
526 iCustom->EndVisualGroup ();
527 iCustom->MakeProminent (GROUP_VERSION);
530 if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE)
532 iCustom->StartVisualGroup (GROUP_TEMPLATE, L"Template");
533 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE);
534 iCustom->EndVisualGroup ();
535 iCustom->MakeProminent (GROUP_TEMPLATE);
538 if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE)
540 iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, L"Style");
541 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE);
542 iCustom->EndVisualGroup ();
543 iCustom->MakeProminent (GROUP_IMAGETEMPLATE);
546 iCustom->StartVisualGroup (GROUP_CHECKBOXES, L"");
548 sal_uInt16 nControlId(0);
549 if ((nFeatures & FEATURE_AUTOEXTENSION) == FEATURE_AUTOEXTENSION)
551 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION;
552 iCustom->AddCheckButton (nControlId, L"Auto Extension", true);
553 setLabelToControl(m_ResProvider, iCustom, nControlId);
556 if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD)
558 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD;
559 iCustom->AddCheckButton (nControlId, L"Password", false);
560 setLabelToControl(m_ResProvider, iCustom, nControlId);
563 if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
565 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
566 iCustom->AddCheckButton (nControlId, L"Readonly", false);
567 setLabelToControl(m_ResProvider, iCustom, nControlId);
570 if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS)
572 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS;
573 iCustom->AddCheckButton (nControlId, L"Filter Options", false);
574 setLabelToControl(m_ResProvider, iCustom, nControlId);
577 if ((nFeatures & FEATURE_LINK) == FEATURE_LINK)
579 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK;
580 iCustom->AddCheckButton (nControlId, L"Link", false);
581 setLabelToControl(m_ResProvider, iCustom, nControlId);
584 if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION)
586 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION;
587 iCustom->AddCheckButton (nControlId, L"Selection", false);
588 setLabelToControl(m_ResProvider, iCustom, nControlId);
591 /* can be ignored ... new COM dialog supports preview native now !
592 if ((nFeatures & FEATURE_PREVIEW) == FEATURE_PREVIEW)
593 iCustom->AddCheckButton (css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, L"Preview", false);
596 iCustom->EndVisualGroup();
598 if ((nFeatures & FEATURE_PLAY) == FEATURE_PLAY)
599 iCustom->AddPushButton (css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, L"Play");
603 //-------------------------------------------------------------------------------
604 void VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequest)
606 const ::sal_Bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, (::sal_Bool)sal_True);
608 // SYNCHRONIZED->
609 ::osl::ResettableMutexGuard aLock(m_aMutex);
610 TFileDialog iDialog = impl_getBaseDialogInterface();
611 aLock.clear();
612 // <- SYNCHRONIZED
614 DWORD nFlags = 0;
615 m_hLastResult = iDialog->GetOptions ( &nFlags );
617 if (bMultiSelection)
618 nFlags |= FOS_ALLOWMULTISELECT;
619 else
620 nFlags &= ~FOS_ALLOWMULTISELECT;
622 iDialog->SetOptions ( nFlags );
625 //-------------------------------------------------------------------------------
626 void VistaFilePickerImpl::impl_sta_SetTitle(const RequestRef& rRequest)
628 ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, ::rtl::OUString());
630 // SYNCHRONIZED->
631 ::osl::ResettableMutexGuard aLock(m_aMutex);
632 TFileDialog iDialog = impl_getBaseDialogInterface();
633 aLock.clear();
634 // <- SYNCHRONIZED
636 iDialog->SetTitle(reinterpret_cast<LPCTSTR>(sTitle.getStr()));
639 //-------------------------------------------------------------------------------
640 void VistaFilePickerImpl::impl_sta_SetFileName(const RequestRef& rRequest)
642 ::rtl::OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
644 // SYNCHRONIZED->
645 ::osl::ResettableMutexGuard aLock(m_aMutex);
646 TFileDialog iDialog = impl_getBaseDialogInterface();
647 aLock.clear();
648 // <- SYNCHRONIZED
650 iDialog->SetFileName(reinterpret_cast<LPCTSTR>(sFileName.getStr()));
653 //-------------------------------------------------------------------------------
654 void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest)
656 ::rtl::OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, ::rtl::OUString());
657 bool bForce = rRequest->getArgumentOrDefault(PROP_FORCE, false);
659 if( !m_bInExecute)
661 // Vista stores last used folders for file dialogs
662 // so we don't want the application to change the folder
663 // in most cases.
664 // Store the requested folder in the mean time and decide later
665 // what to do
666 m_sDirectory = sDirectory;
669 // SYNCHRONIZED->
670 ::osl::ResettableMutexGuard aLock(m_aMutex);
671 TFileDialog iDialog = impl_getBaseDialogInterface();
672 aLock.clear();
673 // <- SYNCHRONIZED
675 ComPtr< IShellItem > pFolder;
676 #ifdef __MINGW32__
677 HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(sDirectory.getStr()), NULL, IID_IShellItem, (void**)(&pFolder) );
678 #else
679 HRESULT hResult = SHCreateItemFromParsingName ( sDirectory, NULL, IID_PPV_ARGS(&pFolder) );
680 #endif
681 if ( FAILED(hResult) )
682 return;
684 if ( m_bInExecute || bForce )
685 iDialog->SetFolder(pFolder);
686 else
688 // Use set default folder as Microsoft recommends in the IFileDialog documentation.
689 iDialog->SetDefaultFolder(pFolder);
693 void VistaFilePickerImpl::impl_sta_GetDirectory(const RequestRef& rRequest)
695 TFileDialog iDialog = impl_getBaseDialogInterface();
696 ComPtr< IShellItem > pFolder;
697 HRESULT hResult = iDialog->GetFolder( &pFolder );
698 if ( FAILED(hResult) )
699 return;
700 ::rtl::OUString sFolder = lcl_getURLFromShellItem ( pFolder );
701 if( sFolder.getLength())
702 rRequest->setArgument( PROP_DIRECTORY, sFolder );
705 //-------------------------------------------------------------------------------
706 void VistaFilePickerImpl::impl_sta_SetDefaultName(const RequestRef& rRequest)
708 ::rtl::OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
709 TFileDialog iDialog = impl_getBaseDialogInterface();
711 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
712 if ( ! iCustom.is())
713 return;
715 // if we have the autoextension check box set, remove (or change ???) the extension of the filename
716 // so that the autoextension mechanism can do its job
717 BOOL bValue = FALSE;
718 HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
719 if ( bValue )
721 sal_Int32 nSepPos = sFilename.lastIndexOf( '.' );
722 if ( -1 != nSepPos )
723 sFilename = sFilename.copy(0, nSepPos);
726 iDialog->SetFileName ( reinterpret_cast<LPCTSTR>(sFilename.getStr()));
727 m_sFilename = sFilename;
730 //-------------------------------------------------------------------------------
731 void VistaFilePickerImpl::impl_sta_setFiltersOnDialog()
733 // SYNCHRONIZED->
734 ::osl::ResettableMutexGuard aLock(m_aMutex);
736 ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
737 ::rtl::OUString sCurrentFilter = m_lFilters.getCurrentFilter();
738 sal_Int32 nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
739 TFileDialog iDialog = impl_getBaseDialogInterface();
740 TFileDialogCustomize iCustomize = impl_getCustomizeInterface();
742 aLock.clear();
743 // <- SYNCHRONIZED
745 COMDLG_FILTERSPEC *pFilt = &lFilters[0];
746 iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/);
747 iDialog->SetFileTypeIndex(nCurrentFilter + 1);
749 BOOL bValue = FALSE;
750 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
752 if ( bValue )
754 LPCWSTR lpFilterExt = lFilters[0].pszSpec;
756 lpFilterExt = wcsrchr( lpFilterExt, '.' );
757 if ( lpFilterExt )
758 lpFilterExt++;
759 iDialog->SetDefaultExtension( lpFilterExt );
764 //-------------------------------------------------------------------------------
765 void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest)
767 // SYNCHRONIZED->
768 ::osl::ResettableMutexGuard aLock(m_aMutex);
770 TFileOpenDialog iOpen = m_iDialogOpen;
771 TFileSaveDialog iSave = m_iDialogSave;
772 ::sal_Bool bInExecute = m_bInExecute;
774 aLock.clear();
775 // <- SYNCHRONIZED
777 // ask dialog for results
778 // Note : we must differ between single/multi selection !
779 // Note further: we must react different if dialog is in execute or not .-(
780 ComPtr< IShellItem > iItem;
781 ComPtr< IShellItemArray > iItems;
782 HRESULT hResult = E_FAIL;
784 if (iOpen.is())
786 if (bInExecute)
787 hResult = iOpen->GetSelectedItems(&iItems);
788 else
790 hResult = iOpen->GetResults(&iItems);
791 if (FAILED(hResult))
792 hResult = iOpen->GetResult(&iItem);
795 else
796 if (iSave.is())
798 if (bInExecute)
799 hResult = iSave->GetCurrentSelection(&iItem);
800 else
801 hResult = iSave->GetResult(&iItem);
804 if (FAILED(hResult))
805 return;
807 // convert and pack results
808 TStringList lFiles;
809 if (iItem.is())
811 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
812 if (sURL.getLength() > 0)
813 lFiles.push_back(sURL);
816 if (iItems.is())
818 DWORD nCount;
819 hResult = iItems->GetCount(&nCount);
820 if ( SUCCEEDED(hResult) )
822 for (DWORD i=0; i<nCount; ++i)
824 hResult = iItems->GetItemAt(i, &iItem);
825 if ( SUCCEEDED(hResult) )
827 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
828 if (sURL.getLength() > 0)
829 lFiles.push_back(sURL);
835 rRequest->setArgument(PROP_SELECTED_FILES, lFiles.getAsConstList());
838 //-------------------------------------------------------------------------------
839 void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest)
841 impl_sta_setFiltersOnDialog();
843 // SYNCHRONIZED->
844 ::osl::ResettableMutexGuard aLock(m_aMutex);
846 TFileDialog iDialog = impl_getBaseDialogInterface();
847 TFileOpenDialog iOpen = m_iDialogOpen;
848 TFileSaveDialog iSave = m_iDialogSave;
850 // it's important to know if we are showing the dialog.
851 // Some dialog interface methods cant be called then or some
852 // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
853 m_bInExecute = sal_True;
855 m_bWasExecuted = sal_True;
857 aLock.clear();
858 // <- SYNCHRONIZED
860 // we set the directory only if we have a save dialog and a filename
861 // for the other cases, the file dialog remembers its last location
862 // according to its client guid.
863 if( m_sDirectory.getLength())
865 ComPtr< IShellItem > pFolder;
866 #ifdef __MINGW32__
867 HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(m_sDirectory.getStr()), NULL, IID_IShellItem, (void**)(&pFolder) );
868 #else
869 HRESULT hResult = SHCreateItemFromParsingName ( m_sDirectory, NULL, IID_PPV_ARGS(&pFolder) );
870 #endif
871 if ( SUCCEEDED(hResult) )
873 if (m_sFilename.getLength())
875 ::rtl::OUString aFileURL(m_sDirectory);
876 sal_Int32 nIndex = aFileURL.lastIndexOf('/');
877 if (nIndex != aFileURL.getLength()-1)
878 aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/"));
879 aFileURL += m_sFilename;
881 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
883 BOOL bValue = FALSE;
884 HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
885 if ( bValue )
887 ::rtl::OUString aExt;
888 UINT nFileType;
889 hResult = iDialog->GetFileTypeIndex(&nFileType);
890 if ( SUCCEEDED(hResult) )
892 ::sal_Int32 nRealIndex = (nFileType-1); // COM dialog base on 1 ... filter container on 0 .-)
893 ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
894 LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec;
896 lpFilterExt = wcsrchr( lpFilterExt, '.' );
897 if ( lpFilterExt )
898 aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt);
902 // Check existence of file. Set folder only for this special case
903 ::rtl::OUString aSystemPath;
904 osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );
906 WIN32_FIND_DATA aFindFileData;
907 HANDLE hFind = FindFirstFile( reinterpret_cast<LPCWSTR>(aSystemPath.getStr()), &aFindFileData );
908 if (hFind != INVALID_HANDLE_VALUE)
909 iDialog->SetFolder(pFolder);
910 else
911 hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
913 FindClose( hFind );
915 else
916 hResult = iDialog->AddPlace(pFolder, FDAP_TOP);
921 HRESULT hResult = E_FAIL;
924 // show dialog and wait for user decision
925 if (iOpen.is())
926 hResult = iOpen->Show( m_hParentWindow ); // parent window needed
927 else
928 if (iSave.is())
929 hResult = iSave->Show( m_hParentWindow ); // parent window needed
931 catch(...)
934 // SYNCHRONIZED->
935 aLock.reset();
936 m_bInExecute = sal_False;
937 aLock.clear();
938 // <- SYNCHRONIZED
940 if ( FAILED(hResult) )
941 return;
943 impl_sta_getSelectedFiles(rRequest);
944 rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, (::sal_Bool)sal_True);
947 //-------------------------------------------------------------------------------
948 TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface()
950 TFileDialog iDialog;
952 // SYNCHRONIZED->
953 ::osl::ResettableMutexGuard aLock(m_aMutex);
955 if (m_iDialogOpen.is())
956 #ifdef __MINGW32__
957 m_iDialogOpen->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
958 #else
959 m_iDialogOpen.query(&iDialog);
960 #endif
961 if (m_iDialogSave.is())
962 #ifdef __MINGW32__
963 m_iDialogSave->QueryInterface(IID_IFileDialog, (void**)(&iDialog));
964 #else
965 m_iDialogSave.query(&iDialog);
966 #endif
968 return iDialog;
971 //-------------------------------------------------------------------------------
972 TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface()
974 TFileDialogCustomize iCustom;
976 // SYNCHRONIZED->
977 ::osl::ResettableMutexGuard aLock(m_aMutex);
979 if (m_iDialogOpen.is())
980 #ifdef __MINGW32__
981 m_iDialogOpen->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
982 #else
983 m_iDialogOpen.query(&iCustom);
984 #endif
985 else
986 if (m_iDialogSave.is())
987 #ifdef __MINGW32__
988 m_iDialogSave->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom));
989 #else
990 m_iDialogSave.query(&iCustom);
991 #endif
993 return iCustom;
996 //-------------------------------------------------------------------------------
997 void lcl_removeControlItemsWorkaround(const TFileDialogCustomize& iCustom ,
998 ::sal_Int16 nControlId)
1000 ::sal_Int32 i = 0;
1001 HRESULT hResult;
1003 hResult = iCustom->SetSelectedControlItem(nControlId, 1000);
1004 hResult = S_OK;
1005 while ( SUCCEEDED(hResult) )
1006 hResult = iCustom->RemoveControlItem(nControlId, i++);
1009 //-------------------------------------------------------------------------------
1010 void VistaFilePickerImpl::impl_sta_SetControlValue(const RequestRef& rRequest)
1012 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1013 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1014 css::uno::Any aValue = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE , css::uno::Any() );
1016 // dont check for right values here ...
1017 // most parameters are optional !
1019 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1020 if ( ! iCustom.is())
1021 return;
1023 switch (nId)
1025 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
1026 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1027 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1028 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1029 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1030 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1031 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1033 ::sal_Bool bValue = sal_False;
1034 aValue >>= bValue;
1035 iCustom->SetCheckButtonState(nId, bValue);
1037 break;
1039 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION :
1040 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
1041 case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
1043 HRESULT hResult;
1044 switch (nAction)
1046 case css::ui::dialogs::ControlActions::DELETE_ITEMS :
1048 hResult = iCustom->RemoveAllControlItems(nId);
1049 if ( FAILED(hResult) )
1050 lcl_removeControlItemsWorkaround(iCustom, nId);
1052 break;
1054 case css::ui::dialogs::ControlActions::ADD_ITEMS :
1056 css::uno::Sequence< ::rtl::OUString > lItems;
1057 aValue >>= lItems;
1058 for (::sal_Int32 i=0; i<lItems.getLength(); ++i)
1060 const ::rtl::OUString& sItem = lItems[i];
1061 hResult = iCustom->AddControlItem(nId, i, reinterpret_cast<LPCTSTR>(sItem.getStr()));
1064 break;
1066 case css::ui::dialogs::ControlActions::SET_SELECT_ITEM :
1068 ::sal_Int32 nItem = 0;
1069 aValue >>= nItem;
1070 hResult = iCustom->SetSelectedControlItem(nId, nItem);
1072 break;
1075 break;
1077 case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
1080 break;
1084 //-------------------------------------------------------------------------------
1085 void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest)
1087 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1088 ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION);
1090 // dont check for right values here ...
1091 // most parameters are optional !
1093 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1094 if ( ! iCustom.is())
1095 return;
1097 css::uno::Any aValue;
1098 if( m_bWasExecuted )
1099 switch (nId)
1101 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1102 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1103 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1104 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1105 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1106 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1108 BOOL bValue = FALSE;
1109 HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
1110 if ( SUCCEEDED(hResult) )
1111 aValue = css::uno::makeAny((sal_Bool)bValue);
1113 break;
1116 if (aValue.hasValue())
1117 rRequest->setArgument(PROP_CONTROL_VALUE, aValue);
1120 //-------------------------------------------------------------------------------
1121 void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest)
1123 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1124 ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() );
1126 // dont check for right values here ...
1127 // most parameters are optional !
1129 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1130 if ( ! iCustom.is())
1131 return;
1132 iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr()));
1135 //-------------------------------------------------------------------------------
1136 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/)
1140 //-------------------------------------------------------------------------------
1141 void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest)
1143 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1144 ::sal_Bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True);
1146 // dont check for right values here ...
1147 // most parameters are optional !
1149 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1150 if ( ! iCustom.is())
1151 return;
1153 CDCONTROLSTATEF eState = CDCS_VISIBLE;
1154 if (bEnabled)
1155 eState |= CDCS_ENABLED;
1156 else
1157 eState |= CDCS_INACTIVE;
1159 iCustom->SetControlState(nId, eState);
1161 //-------------------------------------------------------------------------------
1162 void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter )
1164 TFileDialog iDialog = impl_getBaseDialogInterface();
1165 if (currentFilter.getLength())
1167 rtl::OUString FilterExt;
1168 m_lFilters.getFilter(currentFilter, FilterExt);
1170 sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
1171 const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
1173 sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
1174 if (posOfSemiColon < 0)
1175 posOfSemiColon = FilterExt.getLength() - 1;
1177 FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
1178 iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) );
1183 //-------------------------------------------------------------------------------
1184 void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked)
1186 // SYNCHRONIZED->
1187 ::osl::ResettableMutexGuard aLock(m_aMutex);
1189 const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter ();
1190 ::rtl::OUString sExt ;
1191 if ( !m_lFilters.getFilter (sFilter, sExt))
1192 return;
1194 TFileDialog iDialog = impl_getBaseDialogInterface();
1196 aLock.clear();
1197 // <- SYNCHRONIZED
1199 LPCWSTR pExt = 0;
1200 if ( bChecked )
1202 pExt = reinterpret_cast<LPCTSTR>(sExt.getStr());
1203 pExt = wcsrchr( pExt, '.' );
1204 if ( pExt )
1205 pExt++;
1207 iDialog->SetDefaultExtension( pExt );
1210 } // namespace vista
1211 } // namespace win32
1212 } // namespace fpicker