merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / win32 / filepicker / VistaFilePickerImpl.cxx
blob31784e44bdaeba63a7998f5be01b7746fdfef153
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: VistaFilePickerImpl.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 //-----------------------------------------------------------------------------
32 // includes
33 //-----------------------------------------------------------------------------
35 #include "VistaFilePickerImpl.hxx"
37 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
38 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
39 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
40 #include <comphelper/sequenceasvector.hxx>
41 #include <osl/file.hxx>
42 #include <osl/mutex.hxx>
43 #ifdef __MINGW32__
44 #include <limits.h>
45 #endif
46 #include "..\misc\WinImplHelper.hxx"
48 inline bool is_current_process_window(HWND hwnd)
50 DWORD pid;
51 GetWindowThreadProcessId(hwnd, &pid);
52 return (pid == GetCurrentProcessId());
55 HWND choose_parent_window()
57 HWND hwnd_parent = GetForegroundWindow();
58 if (!is_current_process_window(hwnd_parent))
59 hwnd_parent = GetDesktopWindow();
60 return hwnd_parent;
63 //-----------------------------------------------------------------------------
64 // namespace
65 //-----------------------------------------------------------------------------
67 namespace fpicker{
68 namespace win32{
69 namespace vista{
71 namespace css = ::com::sun::star;
73 //-----------------------------------------------------------------------------
74 // types, const etcpp.
75 //-----------------------------------------------------------------------------
78 static const ::sal_Int16 INVALID_CONTROL_ID = -1;
79 static const ::sal_Int16 INVALID_CONTROL_ACTION = -1;
81 typedef ::comphelper::SequenceAsVector< ::rtl::OUString > TStringList;
83 // Guids used for IFileDialog::SetClientGuid
84 static const GUID CLIENTID_FILEDIALOG_SIMPLE = {0xB8628FD3, 0xA3F5, 0x4845, 0x9B, 0x62, 0xD5, 0x1E, 0xDF, 0x97, 0xC4, 0x83};
85 static const GUID CLIENTID_FILEDIALOG_OPTIONS = {0x93ED486F, 0x0D04, 0x4807, 0x8C, 0x44, 0xAC, 0x26, 0xCB, 0x6C, 0x5D, 0x36};
86 static const GUID CLIENTID_FILESAVE = {0x3B2E2261, 0x402D, 0x4049, 0xB0, 0xC0, 0x91, 0x13, 0xF8, 0x6E, 0x84, 0x7C};
87 static const GUID CLIENTID_FILESAVE_PASSWORD = {0xC12D4F4C, 0x4D41, 0x4D4F, 0x97, 0xEF, 0x87, 0xF9, 0x8D, 0xB6, 0x1E, 0xA6};
88 static const GUID CLIENTID_FILESAVE_SELECTION = {0x5B2482B3, 0x0358, 0x4E09, 0xAA, 0x64, 0x2B, 0x76, 0xB2, 0xA0, 0xDD, 0xFE};
89 static const GUID CLIENTID_FILESAVE_TEMPLATE = {0x9996D877, 0x20D5, 0x424B, 0x9C, 0x2E, 0xD3, 0xB6, 0x31, 0xEC, 0xF7, 0xCE};
90 static const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE = {0x32237796, 0x1509, 0x49D1, 0xBB, 0x7E, 0x63, 0xAD, 0x36, 0xAE, 0x86, 0x8C};
91 static const GUID CLIENTID_FILEOPEN_PLAY = {0x32CFB147, 0xF5AE, 0x4F90, 0xA1, 0xF1, 0x81, 0x20, 0x72, 0xBB, 0x2F, 0xC5};
92 static const GUID CLIENTID_FILEOPEN_LINK = {0x39AC4BAE, 0x7D2D, 0x46BC, 0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A};
94 //-----------------------------------------------------------------------------
95 ::rtl::OUString lcl_getURLFromShellItem (IShellItem* pItem)
97 LPOLESTR pStr = NULL;
98 ::rtl::OUString sURL;
100 SIGDN eConversion = SIGDN_FILESYSPATH;
101 HRESULT hr = pItem->GetDisplayName ( eConversion, &pStr );
103 if ( FAILED(hr) )
105 eConversion = SIGDN_URL;
106 hr = pItem->GetDisplayName ( eConversion, &pStr );
108 if ( FAILED(hr) )
109 return ::rtl::OUString();
111 sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr));
113 else
115 ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL );
118 CoTaskMemFree (pStr);
119 return sURL;
122 //-----------------------------------------------------------------------------------------
123 ::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer& rContainer)
125 const sal_Int32 c = rContainer.numFilter();
126 sal_Int32 i = 0;
127 ::std::vector< COMDLG_FILTERSPEC > lList ;
128 CFilterContainer::FILTER_ENTRY_T aFilter;
130 rContainer.beginEnumFilter( );
131 while( rContainer.getNextFilter(aFilter) )
133 COMDLG_FILTERSPEC aSpec;
135 aSpec.pszName = reinterpret_cast<LPCTSTR>(aFilter.first.getStr()) ;
136 aSpec.pszSpec = reinterpret_cast<LPCTSTR>(aFilter.second.getStr());
138 lList.push_back(aSpec);
141 return lList;
144 //-----------------------------------------------------------------------------------------
145 VistaFilePickerImpl::VistaFilePickerImpl()
146 : m_iDialogOpen ()
147 , m_iDialogSave ()
148 , m_hLastResult ()
149 , m_lFilters ()
150 , m_lLastFiles ()
151 , m_iEventHandler(new VistaFilePickerEventHandler(this))
152 , m_bInExecute (sal_False)
153 , m_sDirectory ()
154 , m_sFilename ()
156 m_hParentWindow = choose_parent_window();
159 //-------------------------------------------------------------------------------
160 VistaFilePickerImpl::~VistaFilePickerImpl()
164 //-------------------------------------------------------------------------------
165 void VistaFilePickerImpl::before()
167 // SYNCHRONIZED->
168 ::osl::ResettableMutexGuard aLock(m_aMutex);
170 // TRICKY .-)
171 // osl::Thread class initializes COm already in MTA mode because it's needed
172 // by VCL and UNO so. There is no way to change that from outside ...
173 // but we need a STA environment ...
174 // So we make it by try-and-error ...
175 // If first CoInitialize will fail .. we unitialize COM initialize it new .-)
177 m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
178 if ( FAILED(m_hLastResult) )
180 CoUninitialize();
181 m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
185 //-------------------------------------------------------------------------------
186 void VistaFilePickerImpl::doRequest(const RequestRef& rRequest)
190 switch(rRequest->getRequest())
192 case E_ADD_PICKER_LISTENER :
193 impl_sta_addFilePickerListener(rRequest);
194 break;
196 case E_REMOVE_PICKER_LISTENER :
197 impl_sta_removeFilePickerListener(rRequest);
198 break;
200 case E_APPEND_FILTER :
201 impl_sta_appendFilter(rRequest);
202 break;
204 case E_SET_CURRENT_FILTER :
205 impl_sta_setCurrentFilter(rRequest);
206 break;
208 case E_GET_CURRENT_FILTER :
209 impl_sta_getCurrentFilter(rRequest);
210 break;
212 case E_CREATE_OPEN_DIALOG :
213 impl_sta_CreateOpenDialog(rRequest);
214 break;
216 case E_CREATE_SAVE_DIALOG :
217 impl_sta_CreateSaveDialog(rRequest);
218 break;
220 case E_SET_MULTISELECTION_MODE :
221 impl_sta_SetMultiSelectionMode(rRequest);
222 break;
224 case E_SET_TITLE :
225 impl_sta_SetTitle(rRequest);
226 break;
228 case E_SET_FILENAME:
229 impl_sta_SetFileName(rRequest);
230 break;
232 case E_SET_DIRECTORY :
233 impl_sta_SetDirectory(rRequest);
234 break;
236 case E_GET_DIRECTORY :
237 impl_sta_GetDirectory(rRequest);
238 break;
240 case E_SET_DEFAULT_NAME :
241 impl_sta_SetDefaultName(rRequest);
242 break;
244 case E_GET_SELECTED_FILES :
245 impl_sta_getSelectedFiles(rRequest);
246 break;
248 case E_SHOW_DIALOG_MODAL :
249 impl_sta_ShowDialogModal(rRequest);
250 break;
252 case E_SET_CONTROL_VALUE :
253 impl_sta_SetControlValue(rRequest);
254 break;
256 case E_GET_CONTROL_VALUE :
257 impl_sta_GetControlValue(rRequest);
258 break;
260 case E_SET_CONTROL_LABEL :
261 impl_sta_SetControlLabel(rRequest);
262 break;
264 case E_GET_CONTROL_LABEL :
265 impl_sta_GetControlLabel(rRequest);
266 break;
268 case E_ENABLE_CONTROL :
269 impl_sta_EnableControl(rRequest);
270 break;
272 // no default: let the compiler detect changes on enum ERequest !
275 catch(...)
279 //-------------------------------------------------------------------------------
280 void VistaFilePickerImpl::after()
282 CoUninitialize();
285 //-------------------------------------------------------------------------------
286 void VistaFilePickerImpl::impl_sta_addFilePickerListener(const RequestRef& rRequest)
288 // SYNCHRONIZED outside !
289 const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
290 if ( ! xListener.is())
291 return;
293 // SYNCHRONIZED->
294 ::osl::ResettableMutexGuard aLock(m_aMutex);
295 TFileDialogEvents iHandler = m_iEventHandler;
296 aLock.clear();
297 // <- SYNCHRONIZED
299 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
300 if (pHandlerImpl)
301 pHandlerImpl->addFilePickerListener(xListener);
304 //-------------------------------------------------------------------------------
305 void VistaFilePickerImpl::impl_sta_removeFilePickerListener(const RequestRef& rRequest)
307 // SYNCHRONIZED outside !
308 const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >());
309 if ( ! xListener.is())
310 return;
312 // SYNCHRONIZED->
313 ::osl::ResettableMutexGuard aLock(m_aMutex);
314 TFileDialogEvents iHandler = m_iEventHandler;
315 aLock.clear();
316 // <- SYNCHRONIZED
318 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
319 if (pHandlerImpl)
320 pHandlerImpl->removeFilePickerListener(xListener);
323 //-------------------------------------------------------------------------------
324 void VistaFilePickerImpl::impl_sta_appendFilter(const RequestRef& rRequest)
326 const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
327 const ::rtl::OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, ::rtl::OUString());
329 // SYNCHRONIZED->
330 ::osl::ResettableMutexGuard aLock(m_aMutex);
332 m_lFilters.addFilter(sTitle, sFilter);
335 //-------------------------------------------------------------------------------
336 void VistaFilePickerImpl::impl_sta_setCurrentFilter(const RequestRef& rRequest)
338 const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString());
340 // SYNCHRONIZED->
341 ::osl::ResettableMutexGuard aLock(m_aMutex);
343 m_lFilters.setCurrentFilter(sTitle);
346 //-------------------------------------------------------------------------------
347 void VistaFilePickerImpl::impl_sta_getCurrentFilter(const RequestRef& rRequest)
349 TFileDialog iDialog = impl_getBaseDialogInterface();
350 UINT nIndex = UINT_MAX;
351 HRESULT hResult = iDialog->GetFileTypeIndex(&nIndex);
352 if (
353 ( FAILED(hResult) ) ||
354 ( nIndex == UINT_MAX ) // COM dialog sometimes return S_OK for empty filter lists .-(
356 return;
358 // SYNCHRONIZED->
359 ::osl::ResettableMutexGuard aLock(m_aMutex);
361 ::rtl::OUString sTitle;
362 ::sal_Int32 nRealIndex = (nIndex-1); // COM dialog base on 1 ... filter container on 0 .-)
363 if (
364 (nRealIndex >= 0 ) &&
365 (m_lFilters.getFilter(nRealIndex, sTitle))
367 rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
368 else if ( nRealIndex == -1 ) // Dialog not visible yet
370 sTitle = m_lFilters.getCurrentFilter();
371 rRequest->setArgument(PROP_FILTER_TITLE, sTitle);
374 aLock.clear();
375 // <- SYNCHRONIZED
378 //-------------------------------------------------------------------------------
379 void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest)
381 // SYNCHRONIZED->
382 ::osl::ResettableMutexGuard aLock(m_aMutex);
384 m_hLastResult = m_iDialogOpen.create();
385 if (FAILED(m_hLastResult))
386 return;
388 TFileDialog iDialog;
389 #ifdef __MINGW32__
390 m_iDialogOpen->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
391 #else
392 m_iDialogOpen.query(&iDialog);
393 #endif
395 TFileDialogEvents iHandler = m_iEventHandler;
397 aLock.clear();
398 // <- SYNCHRONIZED
400 DWORD nFlags = 0;
401 iDialog->GetOptions ( &nFlags );
403 nFlags &= ~FOS_FORCESHOWHIDDEN;
404 nFlags |= FOS_PATHMUSTEXIST;
405 nFlags |= FOS_FILEMUSTEXIST;
406 nFlags |= FOS_OVERWRITEPROMPT;
407 nFlags |= FOS_DONTADDTORECENT;
409 iDialog->SetOptions ( nFlags );
411 ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
412 ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
413 impl_sta_enableFeatures(nFeatures, nTemplate);
415 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
416 if (pHandlerImpl)
417 pHandlerImpl->startListening(iDialog);
420 //-------------------------------------------------------------------------------
421 void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest)
423 // SYNCHRONIZED->
424 ::osl::ResettableMutexGuard aLock(m_aMutex);
426 m_hLastResult = m_iDialogSave.create();
427 if (FAILED(m_hLastResult))
428 return;
430 TFileDialogEvents iHandler = m_iEventHandler;
431 TFileDialog iDialog;
432 #ifdef __MINGW32__
433 m_iDialogSave->QueryInterface(IID_IFileDialog, (void **)(&iDialog));
434 #else
435 m_iDialogSave.query(&iDialog);
436 #endif
438 aLock.clear();
439 // <- SYNCHRONIZED
441 DWORD nFlags = 0;
442 iDialog->GetOptions ( &nFlags );
444 nFlags &= ~FOS_FORCESHOWHIDDEN;
445 nFlags |= FOS_PATHMUSTEXIST;
446 nFlags |= FOS_FILEMUSTEXIST;
447 nFlags |= FOS_OVERWRITEPROMPT;
448 nFlags |= FOS_DONTADDTORECENT;
450 iDialog->SetOptions ( nFlags );
452 ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0);
453 ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0);
454 impl_sta_enableFeatures(nFeatures, nTemplate);
456 VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get();
457 if (pHandlerImpl)
458 pHandlerImpl->startListening(iDialog);
461 //-------------------------------------------------------------------------------
462 static const ::sal_Int32 GROUP_VERSION = 1;
463 static const ::sal_Int32 GROUP_TEMPLATE = 2;
464 static const ::sal_Int32 GROUP_IMAGETEMPLATE = 3;
465 static const ::sal_Int32 GROUP_CHECKBOXES = 4;
467 //-------------------------------------------------------------------------------
468 static void setLabelToControl(CResourceProvider& rResourceProvider, TFileDialogCustomize iCustom, sal_uInt16 nControlId)
470 ::rtl::OUString aLabel = rResourceProvider.getResString(nControlId);
471 aLabel = SOfficeToWindowsLabel(aLabel);
472 iCustom->SetControlLabel(nControlId, reinterpret_cast<LPCWSTR>(aLabel.getStr()) );
475 //-------------------------------------------------------------------------------
476 void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate)
478 GUID aGUID = {};
479 switch (nTemplate)
481 case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE :
482 case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE :
483 aGUID = CLIENTID_FILEDIALOG_SIMPLE;
484 break;
486 case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION :
487 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS :
488 aGUID = CLIENTID_FILEDIALOG_OPTIONS;
489 break;
491 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION :
492 aGUID = CLIENTID_FILESAVE;
493 break;
495 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
496 aGUID = CLIENTID_FILESAVE_PASSWORD;
497 break;
499 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION :
500 aGUID = CLIENTID_FILESAVE_SELECTION;
501 break;
503 case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE :
504 aGUID = CLIENTID_FILESAVE_TEMPLATE;
505 break;
507 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE :
508 aGUID = CLIENTID_FILEOPEN_LINK_TEMPLATE;
509 break;
511 case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY :
512 aGUID = CLIENTID_FILEOPEN_PLAY;
513 break;
515 case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
516 aGUID = CLIENTID_FILEOPEN_LINK;
517 break;
519 TFileDialog iDialog = impl_getBaseDialogInterface();
520 iDialog->SetClientGuid ( aGUID );
522 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
524 if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION)
526 iCustom->StartVisualGroup (GROUP_VERSION, L"Version");
527 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION);
528 iCustom->EndVisualGroup ();
529 iCustom->MakeProminent (GROUP_VERSION);
532 if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE)
534 iCustom->StartVisualGroup (GROUP_TEMPLATE, L"Template");
535 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE);
536 iCustom->EndVisualGroup ();
537 iCustom->MakeProminent (GROUP_TEMPLATE);
540 if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE)
542 iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, L"Style");
543 iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE);
544 iCustom->EndVisualGroup ();
545 iCustom->MakeProminent (GROUP_IMAGETEMPLATE);
548 iCustom->StartVisualGroup (GROUP_CHECKBOXES, L"");
550 sal_uInt16 nControlId(0);
551 if ((nFeatures & FEATURE_AUTOEXTENSION) == FEATURE_AUTOEXTENSION)
553 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION;
554 iCustom->AddCheckButton (nControlId, L"Auto Extension", true);
555 setLabelToControl(m_ResProvider, iCustom, nControlId);
558 if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD)
560 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD;
561 iCustom->AddCheckButton (nControlId, L"Password", false);
562 setLabelToControl(m_ResProvider, iCustom, nControlId);
565 if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
567 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
568 iCustom->AddCheckButton (nControlId, L"Readonly", false);
569 setLabelToControl(m_ResProvider, iCustom, nControlId);
572 if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS)
574 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS;
575 iCustom->AddCheckButton (nControlId, L"Filter Options", false);
576 setLabelToControl(m_ResProvider, iCustom, nControlId);
579 if ((nFeatures & FEATURE_LINK) == FEATURE_LINK)
581 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK;
582 iCustom->AddCheckButton (nControlId, L"Link", false);
583 setLabelToControl(m_ResProvider, iCustom, nControlId);
586 if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION)
588 nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION;
589 iCustom->AddCheckButton (nControlId, L"Selection", false);
590 setLabelToControl(m_ResProvider, iCustom, nControlId);
593 /* can be ignored ... new COM dialog supports preview native now !
594 if ((nFeatures & FEATURE_PREVIEW) == FEATURE_PREVIEW)
595 iCustom->AddCheckButton (css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, L"Preview", false);
598 iCustom->EndVisualGroup();
600 if ((nFeatures & FEATURE_PLAY) == FEATURE_PLAY)
601 iCustom->AddPushButton (css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, L"Play");
605 //-------------------------------------------------------------------------------
606 void VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequest)
608 const ::sal_Bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, (::sal_Bool)sal_True);
610 // SYNCHRONIZED->
611 ::osl::ResettableMutexGuard aLock(m_aMutex);
612 TFileDialog iDialog = impl_getBaseDialogInterface();
613 aLock.clear();
614 // <- SYNCHRONIZED
616 DWORD nFlags = 0;
617 m_hLastResult = iDialog->GetOptions ( &nFlags );
619 if (bMultiSelection)
620 nFlags |= FOS_ALLOWMULTISELECT;
621 else
622 nFlags &= ~FOS_ALLOWMULTISELECT;
624 iDialog->SetOptions ( nFlags );
627 //-------------------------------------------------------------------------------
628 void VistaFilePickerImpl::impl_sta_SetTitle(const RequestRef& rRequest)
630 ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, ::rtl::OUString());
632 // SYNCHRONIZED->
633 ::osl::ResettableMutexGuard aLock(m_aMutex);
634 TFileDialog iDialog = impl_getBaseDialogInterface();
635 aLock.clear();
636 // <- SYNCHRONIZED
638 iDialog->SetTitle(reinterpret_cast<LPCTSTR>(sTitle.getStr()));
641 //-------------------------------------------------------------------------------
642 void VistaFilePickerImpl::impl_sta_SetFileName(const RequestRef& rRequest)
644 ::rtl::OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
646 // SYNCHRONIZED->
647 ::osl::ResettableMutexGuard aLock(m_aMutex);
648 TFileDialog iDialog = impl_getBaseDialogInterface();
649 aLock.clear();
650 // <- SYNCHRONIZED
652 iDialog->SetFileName(reinterpret_cast<LPCTSTR>(sFileName.getStr()));
655 //-------------------------------------------------------------------------------
656 void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest)
658 ::rtl::OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, ::rtl::OUString());
659 bool bForce = rRequest->getArgumentOrDefault(PROP_FORCE, false);
661 if( !m_bInExecute)
663 // Vista stores last used folders for file dialogs
664 // so we don't want the application to change the folder
665 // in most cases.
666 // Store the requested folder in the mean time and decide later
667 // what to do
668 m_sDirectory = sDirectory;
671 // SYNCHRONIZED->
672 ::osl::ResettableMutexGuard aLock(m_aMutex);
673 TFileDialog iDialog = impl_getBaseDialogInterface();
674 aLock.clear();
675 // <- SYNCHRONIZED
677 ComPtr< IShellItem > pFolder;
678 #ifdef __MINGW32__
679 HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(sDirectory.getStr()), NULL, IID_IShellItem, (void**)(&pFolder) );
680 #else
681 HRESULT hResult = SHCreateItemFromParsingName ( sDirectory, NULL, IID_PPV_ARGS(&pFolder) );
682 #endif
683 if ( FAILED(hResult) )
684 return;
686 if ( m_bInExecute || bForce )
687 iDialog->SetFolder(pFolder);
688 else
690 // Use set default folder as Microsoft recommends in the IFileDialog documentation.
691 iDialog->SetDefaultFolder(pFolder);
695 void VistaFilePickerImpl::impl_sta_GetDirectory(const RequestRef& rRequest)
697 TFileDialog iDialog = impl_getBaseDialogInterface();
698 ComPtr< IShellItem > pFolder;
699 HRESULT hResult = iDialog->GetFolder( &pFolder );
700 if ( FAILED(hResult) )
701 return;
702 ::rtl::OUString sFolder = lcl_getURLFromShellItem ( pFolder );
703 if( sFolder.getLength())
704 rRequest->setArgument( PROP_DIRECTORY, sFolder );
707 //-------------------------------------------------------------------------------
708 void VistaFilePickerImpl::impl_sta_SetDefaultName(const RequestRef& rRequest)
710 ::rtl::OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString());
711 TFileDialog iDialog = impl_getBaseDialogInterface();
713 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
714 if ( ! iCustom.is())
715 return;
717 // if we have the autoextension check box set, remove (or change ???) the extension of the filename
718 // so that the autoextension mechanism can do its job
719 BOOL bValue = FALSE;
720 HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
721 if ( bValue )
723 sal_Int32 nSepPos = sFilename.lastIndexOf( '.' );
724 if ( -1 != nSepPos )
725 sFilename = sFilename.copy(0, nSepPos);
728 iDialog->SetFileName ( reinterpret_cast<LPCTSTR>(sFilename.getStr()));
729 m_sFilename = sFilename;
732 //-------------------------------------------------------------------------------
733 void VistaFilePickerImpl::impl_sta_setFiltersOnDialog()
735 // SYNCHRONIZED->
736 ::osl::ResettableMutexGuard aLock(m_aMutex);
738 ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
739 ::rtl::OUString sCurrentFilter = m_lFilters.getCurrentFilter();
740 sal_Int32 nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
741 TFileDialog iDialog = impl_getBaseDialogInterface();
742 TFileDialogCustomize iCustomize = impl_getCustomizeInterface();
744 aLock.clear();
745 // <- SYNCHRONIZED
747 COMDLG_FILTERSPEC *pFilt = &lFilters[0];
748 iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/);
749 iDialog->SetFileTypeIndex(nCurrentFilter + 1);
751 BOOL bValue = FALSE;
752 HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue);
754 if ( bValue )
756 LPCWSTR lpFilterExt = lFilters[0].pszSpec;
758 lpFilterExt = wcsrchr( lpFilterExt, '.' );
759 if ( lpFilterExt )
760 lpFilterExt++;
761 iDialog->SetDefaultExtension( lpFilterExt );
766 //-------------------------------------------------------------------------------
767 void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest)
769 // SYNCHRONIZED->
770 ::osl::ResettableMutexGuard aLock(m_aMutex);
772 TFileOpenDialog iOpen = m_iDialogOpen;
773 TFileSaveDialog iSave = m_iDialogSave;
774 ::sal_Bool bInExecute = m_bInExecute;
776 aLock.clear();
777 // <- SYNCHRONIZED
779 // ask dialog for results
780 // Note : we must differ between single/multi selection !
781 // Note further: we must react different if dialog is in execute or not .-(
782 ComPtr< IShellItem > iItem;
783 ComPtr< IShellItemArray > iItems;
784 HRESULT hResult = E_FAIL;
786 if (iOpen.is())
788 if (bInExecute)
789 hResult = iOpen->GetSelectedItems(&iItems);
790 else
792 hResult = iOpen->GetResults(&iItems);
793 if (FAILED(hResult))
794 hResult = iOpen->GetResult(&iItem);
797 else
798 if (iSave.is())
800 if (bInExecute)
801 hResult = iSave->GetCurrentSelection(&iItem);
802 else
803 hResult = iSave->GetResult(&iItem);
806 if (FAILED(hResult))
807 return;
809 // convert and pack results
810 TStringList lFiles;
811 if (iItem.is())
813 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
814 if (sURL.getLength() > 0)
815 lFiles.push_back(sURL);
818 if (iItems.is())
820 DWORD nCount;
821 hResult = iItems->GetCount(&nCount);
822 if ( SUCCEEDED(hResult) )
824 for (DWORD i=0; i<nCount; ++i)
826 hResult = iItems->GetItemAt(i, &iItem);
827 if ( SUCCEEDED(hResult) )
829 const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem);
830 if (sURL.getLength() > 0)
831 lFiles.push_back(sURL);
837 rRequest->setArgument(PROP_SELECTED_FILES, lFiles.getAsConstList());
840 //-------------------------------------------------------------------------------
841 void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest)
843 impl_sta_setFiltersOnDialog();
845 // SYNCHRONIZED->
846 ::osl::ResettableMutexGuard aLock(m_aMutex);
848 TFileDialog iDialog = impl_getBaseDialogInterface();
849 TFileOpenDialog iOpen = m_iDialogOpen;
850 TFileSaveDialog iSave = m_iDialogSave;
852 // it's important to know if we are showing the dialog.
853 // Some dialog interface methods cant be called then or some
854 // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
855 m_bInExecute = 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 switch (nId)
1100 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
1101 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY :
1102 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
1103 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK :
1104 //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now !
1105 case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
1107 BOOL bValue = sal_False;
1108 HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
1109 if ( SUCCEEDED(hResult) )
1110 aValue = css::uno::makeAny((sal_Bool)bValue);
1112 break;
1115 if (aValue.hasValue())
1116 rRequest->setArgument(PROP_CONTROL_VALUE, aValue);
1119 //-------------------------------------------------------------------------------
1120 void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest)
1122 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1123 ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() );
1125 // dont check for right values here ...
1126 // most parameters are optional !
1128 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1129 if ( ! iCustom.is())
1130 return;
1131 iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr()));
1134 //-------------------------------------------------------------------------------
1135 void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/)
1139 //-------------------------------------------------------------------------------
1140 void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest)
1142 ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID );
1143 ::sal_Bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True);
1145 // dont check for right values here ...
1146 // most parameters are optional !
1148 TFileDialogCustomize iCustom = impl_getCustomizeInterface();
1149 if ( ! iCustom.is())
1150 return;
1152 CDCONTROLSTATEF eState = CDCS_VISIBLE;
1153 if (bEnabled)
1154 eState |= CDCS_ENABLED;
1155 else
1156 eState |= CDCS_INACTIVE;
1158 iCustom->SetControlState(nId, eState);
1160 //-------------------------------------------------------------------------------
1161 void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter )
1163 TFileDialog iDialog = impl_getBaseDialogInterface();
1164 if (currentFilter.getLength())
1166 rtl::OUString FilterExt;
1167 m_lFilters.getFilter(currentFilter, FilterExt);
1169 sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
1170 const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
1172 sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
1173 if (posOfSemiColon < 0)
1174 posOfSemiColon = FilterExt.getLength() - 1;
1176 FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
1177 iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) );
1182 //-------------------------------------------------------------------------------
1183 void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked)
1185 // SYNCHRONIZED->
1186 ::osl::ResettableMutexGuard aLock(m_aMutex);
1188 const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter ();
1189 ::rtl::OUString sExt ;
1190 if ( !m_lFilters.getFilter (sFilter, sExt))
1191 return;
1193 TFileDialog iDialog = impl_getBaseDialogInterface();
1195 aLock.clear();
1196 // <- SYNCHRONIZED
1198 LPCWSTR pExt = 0;
1199 if ( bChecked )
1201 pExt = reinterpret_cast<LPCTSTR>(sExt.getStr());
1202 pExt = wcsrchr( pExt, '.' );
1203 if ( pExt )
1204 pExt++;
1206 iDialog->SetDefaultExtension( pExt );
1209 } // namespace vista
1210 } // namespace win32
1211 } // namespace fpicker