1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_fpicker.hxx"
26 
27 //------------------------------------------------------------------------
28 // includes
29 //------------------------------------------------------------------------
30 #include "filepickerstate.hxx"
31 #include <osl/diagnose.h>
32 #include "controlaccess.hxx"
33 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
34 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
35 #include <com/sun/star/ui/dialogs/ListBoxControlActions.hpp>
36 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
37 #include "controlcommandrequest.hxx"
38 #include "controlcommandresult.hxx"
39 #include <com/sun/star/uno/Reference.hxx>
40 #include <com/sun/star/uno/XInterface.hpp>
41 #include <osl/file.hxx>
42 #include "FileOpenDlg.hxx"
43 
44 #include <memory>
45 #include "..\misc\WinImplHelper.hxx"
46 //---------------------------------------------
47 //
48 //---------------------------------------------
49 
50 using rtl::OUString;
51 using com::sun::star::uno::Any;
52 using com::sun::star::uno::Sequence;
53 using com::sun::star::uno::Reference;
54 using com::sun::star::uno::XInterface;
55 
56 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
57 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
58 using namespace ::com::sun::star::ui::dialogs::ListboxControlActions;
59 
60 //---------------------------------------------
61 //
62 //---------------------------------------------
63 
64 const sal_Int32 MAX_LABEL = 256;
65 const sal_Int16 LISTBOX_LABEL_OFFSET = 100;
66 
67 //---------------------------------------------
68 // declaration
69 //---------------------------------------------
70 
71 CFilePickerState::~CFilePickerState( )
72 {
73 }
74 
75 //---------------------------------------------
76 //
77 //---------------------------------------------
78 
79 CNonExecuteFilePickerState::CNonExecuteFilePickerState( ) :
80     m_FirstControlCommand( NULL )
81 {
82 }
83 
84 //---------------------------------------------
85 //
86 //---------------------------------------------
87 
88 CNonExecuteFilePickerState::~CNonExecuteFilePickerState( )
89 {
90     reset( );
91 }
92 
93 //---------------------------------------------
94 //
95 //---------------------------------------------
96 
97 void SAL_CALL CNonExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue )
98 {
99     CValueControlCommand* value_command = new CValueControlCommand(
100         aControlId, aControlAction, aValue );
101 
102     addControlCommand( value_command );
103 }
104 
105 //---------------------------------------------
106 //
107 //---------------------------------------------
108 
109 Any SAL_CALL CNonExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
110 {
111     CValueControlCommandRequest value_request( aControlId, aControlAction );
112     Any aAny;
113 
114 	if (m_FirstControlCommand)
115 	{
116 		// pass the request along the command-chain
117 		std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &value_request ) );
118 
119 		OSL_ENSURE( result.get(), "invalid getValue request" );
120 
121 		if ( result.get() )
122 		{
123 			// #101753 must remove assertion else running into deadlock
124 			// because getValue may be called asynchronously from main thread
125 			// with locked SOLAR_MUTEX but we also need SOLAR_MUTEX in
126 			// WinFileOpenDialog::onInitDone ... but we cannot dismiss the
127 			// assertion dialog because at this point the FileOpen Dialog
128 			// has aleady the focus but is not yet visible :-(
129 			// The real cure is to remove the VCL/SOLAR_MUTEX dependency
130 			// cause by the use of our resource manager and not being able to
131 			// generate native windows resources
132 			//OSL_ENSURE( result->hasResult( ), "invalid getValue request" );
133 
134 			if ( result->hasResult( ) )
135 			{
136 				CValueCommandResult* value_result = dynamic_cast< CValueCommandResult* >( result.get( ) );
137 				OSL_ENSURE( value_result, "should have be a CValueCommandResult" );
138 
139 				aAny = value_result->getValue( );
140 				OSL_ENSURE( aAny.hasValue( ), "empty any" );
141 			}
142 		}
143 	}
144 
145     return aAny;
146 }
147 
148 //---------------------------------------------
149 //
150 //---------------------------------------------
151 
152 void SAL_CALL CNonExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable )
153 {
154     CEnableControlCommand* enable_command = new CEnableControlCommand(
155         aControlId, bEnable );
156 
157     addControlCommand( enable_command );
158 }
159 
160 //---------------------------------------------
161 //
162 //---------------------------------------------
163 
164 void SAL_CALL CNonExecuteFilePickerState::setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel )
165 {
166     CLabelControlCommand* label_command = new CLabelControlCommand(
167         aControlId, aLabel );
168 
169     addControlCommand( label_command );
170 }
171 
172 //---------------------------------------------
173 //
174 //---------------------------------------------
175 
176 OUString SAL_CALL CNonExecuteFilePickerState::getLabel( sal_Int16 aControlId )
177 {
178     CControlCommandRequest label_request( aControlId );
179 
180     // pass the request along the command-chain
181     std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &label_request ) );
182 
183     OSL_ENSURE( result->hasResult( ), "invalid getValue request" );
184 
185     OUString aLabel;
186 
187     if ( result->hasResult( ) )
188     {
189         CLabelCommandResult* label_result = dynamic_cast< CLabelCommandResult* >( result.get( ) );
190         OSL_ENSURE( label_result, "should have be a CLabelCommandResult" );
191 
192         aLabel = label_result->getLabel( );
193     }
194 
195     return aLabel;
196 }
197 
198 /*  #i26224#
199     When typing file names with drive letter but without '\'
200     in the "File name" box of the FileOpen dialog the FileOpen
201     dialog makes strange paths out of them e.g. "d:.\test.sxw".
202     Such file names will not be accepted by sal so we fix these
203     somehow broken paths here. */
204 OUString MatchFixBrokenPath(const OUString& path)
205 {
206     OSL_ASSERT(path.getLength() >= 4);
207 
208     if (path[1] == ':' && path[2] == '.' && path[3] == '\\')
209     {
210         // skip the '.'
211         return OUString(path, 2) + path.copy(3, path.getLength() - 3);
212     }
213     return path;
214 }
215 
216 //-----------------------------------------------------------------------------------------
217 //
218 //-----------------------------------------------------------------------------------------
219 static ::rtl::OUString trimTrailingSpaces(const ::rtl::OUString& rString)
220 {
221     rtl::OUString aResult(rString);
222 
223     sal_Int32 nIndex = rString.lastIndexOf(' ');
224     if (nIndex == rString.getLength()-1)
225     {
226         while (nIndex >= 0 && rString[nIndex] == ' ')
227             nIndex--;
228         if (nIndex >= 0)
229             aResult = rString.copy(0,nIndex+1);
230         else
231             aResult = ::rtl::OUString();
232     }
233     return aResult;
234 }
235 
236 Sequence< OUString > SAL_CALL CNonExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog )
237 {
238     OSL_PRECOND( aFileOpenDialog, "invalid parameter" );
239 
240     Sequence< OUString > aFilePathList;
241     OUString aFilePathURL;
242     OUString aFilePath;
243     ::osl::FileBase::RC rc;
244 
245     aFilePath = aFileOpenDialog->getFullFileName( );
246 
247     if ( aFilePath.getLength( ) )
248     {
249         // tokenize the returned string and copy the
250         // sub-strings separately into a sequence
251         const sal_Unicode* pTemp = aFilePath.getStr();
252         const sal_Unicode* pStrEnd = pTemp + aFilePath.getLength();
253         sal_uInt32 lSubStr;
254 
255         while (pTemp < pStrEnd)
256         {
257             // detect the length of the next sub string
258             lSubStr = rtl_ustr_getLength(pTemp);
259 
260             aFilePathList.realloc(aFilePathList.getLength() + 1);
261 
262             aFilePathList[aFilePathList.getLength() - 1] =
263                 MatchFixBrokenPath(OUString(pTemp, lSubStr));
264 
265             pTemp += (lSubStr + 1);
266         }
267 
268         // change all entries to file URLs
269         sal_Int32 lenFileList = aFilePathList.getLength( );
270 		OSL_ASSERT( lenFileList >= 1 );
271 
272         for ( sal_Int32 i = 0; i < lenFileList; i++ )
273         {
274 			aFilePath = trimTrailingSpaces(aFilePathList[i]);
275 			rc = ::osl::FileBase::getFileURLFromSystemPath(
276                 aFilePath, aFilePathURL );
277 
278             // we do return all or nothing, that means
279             // in case of failures we destroy the sequence
280             // and return an empty sequence
281             if ( rc != ::osl::FileBase::E_None )
282             {
283                 aFilePathList.realloc( 0 );
284                 break;
285             }
286 
287             aFilePathList[i] = aFilePathURL;
288         }
289     }
290 
291     return aFilePathList;
292 }
293 
294 //---------------------------------------------
295 //
296 //---------------------------------------------
297 
298 OUString SAL_CALL CNonExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog )
299 {
300     OSL_PRECOND( aFileOpenDialog, "invalid parameter" );
301 
302     OUString pathURL;
303     OUString displayDir;
304 
305     displayDir = aFileOpenDialog->getLastDisplayDirectory( );
306 
307 	if ( displayDir.getLength( ) )
308         ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL );
309 
310 	return pathURL;
311 }
312 
313 //---------------------------------------------
314 //
315 //---------------------------------------------
316 
317 void SAL_CALL CNonExecuteFilePickerState::reset( )
318 {
319     CControlCommand* nextCommand;
320     CControlCommand* currentCommand = m_FirstControlCommand;
321 
322     while( currentCommand )
323     {
324         nextCommand = currentCommand->getNextCommand( );
325         delete currentCommand;
326         currentCommand = nextCommand;
327     }
328 
329     m_FirstControlCommand = NULL;
330 }
331 
332 //---------------------------------------------
333 //
334 //---------------------------------------------
335 
336 CControlCommand* SAL_CALL CNonExecuteFilePickerState::getControlCommand( ) const
337 {
338     return m_FirstControlCommand;
339 }
340 
341 //---------------------------------------------
342 // we append new control commands to the end
343 // of the list so that we are sure the commands
344 // will be executed as the client issued it
345 //---------------------------------------------
346 
347 void SAL_CALL CNonExecuteFilePickerState::addControlCommand( CControlCommand* aControlCommand )
348 {
349     OSL_ASSERT( aControlCommand );
350 
351     if ( NULL == m_FirstControlCommand )
352     {
353         m_FirstControlCommand = aControlCommand;
354     }
355     else
356     {
357         CControlCommand* pNextControlCommand = m_FirstControlCommand;
358 
359         while ( pNextControlCommand->getNextCommand( ) != NULL )
360             pNextControlCommand = pNextControlCommand->getNextCommand( );
361 
362         pNextControlCommand->setNextCommand( aControlCommand );
363     }
364 }
365 
366 //#######################################################################
367 
368 //---------------------------------------------
369 //
370 //---------------------------------------------
371 
372 CExecuteFilePickerState::CExecuteFilePickerState( HWND hwndDlg ) :
373     m_hwndDlg( hwndDlg )
374 {
375 }
376 
377 //---------------------------------------------
378 //
379 //---------------------------------------------
380 
381 void SAL_CALL CExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue )
382 {
383     // we do not support SET_HELP_URL/GET_HELP_URL
384     if ( com::sun::star::ui::dialogs::ControlActions::SET_HELP_URL == aControlAction )
385         return;
386 
387     HWND hwndCtrl = GetHwndDlgItem( aControlId );
388 
389 	// the filter listbox can be manipulated via this
390 	// method the caller should use XFilterManager
391     if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) )
392     {
393         OSL_ENSURE( sal_False, "invalid control id" );
394         return;
395     }
396 
397     CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl );
398     if ( UNKNOWN == aCtrlClass )
399     {
400         OSL_ENSURE( sal_False, "unsupported control class" );
401         return;
402     }
403 
404     CTRL_SETVALUE_FUNCTION_T lpfnSetValue =
405         GetCtrlSetValueFunction( aCtrlClass, aControlAction );
406 
407     if ( !lpfnSetValue )
408     {
409         OSL_ENSURE( sal_False, "unsupported control action" );
410         return;
411     }
412 
413     // the function that we call should throw an IllegalArgumentException if
414     // the given value is invalid or empty, that's why we provide a Reference
415     // to an XInterface and a argument position
416     lpfnSetValue( hwndCtrl, aValue, Reference< XInterface >( ), 3 );
417 }
418 
419 //---------------------------------------------
420 //
421 //---------------------------------------------
422 
423 Any SAL_CALL CExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
424 {
425     // we do not support SET_HELP_URL/GET_HELP_URL
426     if ( com::sun::star::ui::dialogs::ControlActions::GET_HELP_URL == aControlAction )
427         return Any( );
428 
429     HWND hwndCtrl = GetHwndDlgItem( aControlId );
430 
431 	// the filter listbox can be manipulated via this
432 	// method the caller should use XFilterManager
433     if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) )
434     {
435         OSL_ENSURE( sal_False, "invalid control id" );
436         return Any( );
437     }
438 
439     CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl );
440     if ( UNKNOWN == aCtrlClass )
441     {
442         OSL_ENSURE( sal_False, "unsupported control class" );
443         return Any( );
444     }
445 
446     CTRL_GETVALUE_FUNCTION_T lpfnGetValue =
447         GetCtrlGetValueFunction( aCtrlClass, aControlAction );
448 
449     if ( !lpfnGetValue )
450     {
451         OSL_ENSURE( sal_False, "unsupported control action" );
452         return Any( );
453     }
454 
455     return lpfnGetValue( hwndCtrl );
456 }
457 
458 //---------------------------------------------
459 //
460 //---------------------------------------------
461 
462 void SAL_CALL CExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable )
463 {
464     HWND hwndCtrl = GetHwndDlgItem( aControlId );
465 
466     OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");
467 
468     EnableWindow( hwndCtrl, bEnable );
469 }
470 
471 //---------------------------------------------
472 //
473 //---------------------------------------------
474 
475 void SAL_CALL CExecuteFilePickerState::setLabel( sal_Int16 aControlId, const OUString& aLabel )
476 {
477     HWND hwndCtrl = GetHwndDlgItem( aControlId );
478 
479     OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");
480 
481     if ( IsListboxControl( hwndCtrl ) )
482         hwndCtrl = GetListboxLabelItem( aControlId );
483 
484     OUString aWinLabel = SOfficeToWindowsLabel( aLabel );
485 
486 	// somewhat risky because we don't know if OUString
487 	// has a terminating '\0'
488     SetWindowText( hwndCtrl, reinterpret_cast<LPCTSTR>(aWinLabel.getStr( )) );
489 }
490 
491 //---------------------------------------------
492 //
493 //---------------------------------------------
494 
495 OUString SAL_CALL CExecuteFilePickerState::getLabel( sal_Int16 aControlId )
496 {
497     HWND hwndCtrl = GetHwndDlgItem( aControlId );
498 
499     OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id");
500 
501     if ( IsListboxControl( hwndCtrl ) )
502         hwndCtrl = GetListboxLabelItem( aControlId );
503 
504     sal_Unicode aLabel[MAX_LABEL];
505     int nRet = GetWindowText( hwndCtrl, reinterpret_cast<LPTSTR>(aLabel), MAX_LABEL );
506 
507     OUString ctrlLabel;
508     if ( nRet )
509     {
510         ctrlLabel = OUString( aLabel, rtl_ustr_getLength( aLabel ) );
511         ctrlLabel = WindowsToSOfficeLabel( aLabel );
512     }
513 
514     return ctrlLabel;
515 }
516 
517 //---------------------------------------------
518 //
519 //---------------------------------------------
520 
521 Sequence< OUString > SAL_CALL CExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog )
522 {
523     OSL_POSTCOND( aFileOpenDialog, "invalid parameter" );
524 
525     Sequence< OUString > aFilePathList;
526     OUString aFilePathURL;
527     OUString aFilePath;
528     ::osl::FileBase::RC rc;
529 
530 	// in execution mode getFullFileName doesn't
531 	// return anything, so we must use another way
532 
533     // returns the currently selected file(s)
534     // including path information
535     aFilePath = aFileOpenDialog->getCurrentFilePath( );
536 
537 	// if multiple files are selected or the user
538 	// typed anything that doesn't seem to be a valid
539 	// file name getFileURLFromSystemPath fails
540 	// and we return an empty file list
541     rc = ::osl::FileBase::getFileURLFromSystemPath(
542         aFilePath, aFilePathURL );
543 
544     if ( ::osl::FileBase::E_None == rc )
545     {
546         aFilePathList.realloc( 1 );
547         aFilePathList[0] = aFilePathURL;
548     }
549 
550     return aFilePathList;
551 }
552 
553 //---------------------------------------------
554 //
555 //---------------------------------------------
556 
557 OUString SAL_CALL CExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog )
558 {
559     OSL_POSTCOND( aFileOpenDialog, "invalid parameter" );
560 
561     OUString pathURL;
562     OUString displayDir;
563 
564     displayDir = aFileOpenDialog->getCurrentFolderPath( );
565 
566     if ( displayDir.getLength( ) )
567         ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL );
568 
569 	return pathURL;
570 }
571 
572 //---------------------------------------------
573 //
574 //---------------------------------------------
575 
576 void SAL_CALL CExecuteFilePickerState::initFilePickerControls( CControlCommand* firstControlCommand )
577 {
578     CControlCommand* aControlCommand = firstControlCommand;
579 
580     while ( aControlCommand )
581     {
582         aControlCommand->exec( this );
583         aControlCommand = aControlCommand->getNextCommand( );
584     }
585 }
586 
587 //---------------------------------------------
588 //
589 //---------------------------------------------
590 
591 void SAL_CALL CExecuteFilePickerState::cacheControlState( HWND hwndControl, CFilePickerState* aNonExecFilePickerState )
592 {
593     OSL_ENSURE( hwndControl && aNonExecFilePickerState, "invalid parameters" );
594 
595     CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl );
596 
597     sal_Int16 aControlAction;
598     CTRL_GETVALUE_FUNCTION_T lpfnGetValue;
599 
600     if ( CHECKBOX == aCtrlClass )
601     {
602         aControlAction = 0;
603 
604         lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );
605 
606         OSL_ASSERT( lpfnGetValue );
607 
608         aNonExecFilePickerState->setValue(
609             sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
610             aControlAction,
611             lpfnGetValue( hwndControl ) );
612 
613         aNonExecFilePickerState->setLabel(
614             sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
615             getLabel(
616                 sal::static_int_cast< sal_Int16 >(
617                     GetDlgCtrlID( hwndControl ) ) ) );
618     }
619     else if ( LISTBOX == aCtrlClass )
620     {
621         // for listboxes we save only the
622         // last selected item and the last
623         // selected item index
624 
625         aControlAction = GET_SELECTED_ITEM;
626 
627         lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );
628 
629         aNonExecFilePickerState->setValue(
630             sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
631             aControlAction,
632             lpfnGetValue( hwndControl ) );
633 
634         aControlAction = ::com::sun::star::ui::dialogs::ControlActions::GET_SELECTED_ITEM_INDEX;
635 
636         lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction );
637 
638         aNonExecFilePickerState->setValue(
639             sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ),
640             aControlAction,
641             lpfnGetValue( hwndControl ) );
642     }
643 }
644 
645 //---------------------------------------------
646 //
647 //---------------------------------------------
648 
649 void SAL_CALL CExecuteFilePickerState::setHwnd( HWND hwndDlg )
650 {
651     m_hwndDlg = hwndDlg;
652 }
653 
654 //---------------------------------------------
655 //
656 //---------------------------------------------
657 
658 inline sal_Bool SAL_CALL CExecuteFilePickerState::IsListboxControl( HWND hwndControl ) const
659 {
660     OSL_PRECOND( IsWindow( hwndControl ), "invalid parameter" );
661 
662     CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl );
663     return ( LISTBOX == aCtrlClass );
664 }
665 
666 //---------------------------------------------
667 // because listboxes (comboboxes) and their labels
668 // are seperated we have to translate the listbox
669 // id to their corresponding label id
670 // the convention is that the label id of a listbox
671 // is the id of the listbox + 100
672 //---------------------------------------------
673 
674 inline sal_Int16 SAL_CALL CExecuteFilePickerState::ListboxIdToListboxLabelId( sal_Int16 aListboxId ) const
675 {
676     return ( aListboxId + LISTBOX_LABEL_OFFSET );
677 }
678 
679 //---------------------------------------------
680 //
681 //---------------------------------------------
682 
683 inline HWND SAL_CALL CExecuteFilePickerState::GetListboxLabelItem( sal_Int16 aControlId ) const
684 {
685     sal_Int16 aLabelId = ListboxIdToListboxLabelId( aControlId );
686     HWND hwndCtrl = GetHwndDlgItem( aLabelId );
687 
688     OSL_ASSERT( IsWindow( hwndCtrl ) );
689 
690     return hwndCtrl;
691 }
692 
693 //---------------------------------------------
694 //
695 //---------------------------------------------
696 
697 HWND SAL_CALL CExecuteFilePickerState::GetHwndDlgItem( sal_Int16 aControlId, sal_Bool bIncludeStdCtrls ) const
698 {
699     OSL_ENSURE( IsWindow( m_hwndDlg ), "no valid parent window set before" );
700 
701     HWND hwndCtrl = GetDlgItem( m_hwndDlg, aControlId );
702 
703     // maybe it's a control of the dialog itself for instance
704     // the ok and cancel button
705     if ( !hwndCtrl && bIncludeStdCtrls )
706     {
707 		hwndCtrl = GetDlgItem(
708             GetParent( m_hwndDlg ),
709             CommonFilePickerCtrlIdToWinFileOpenCtrlId( aControlId ) );
710     }
711 
712 	return hwndCtrl;
713 }
714