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