Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2248 lines
63 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // AtlBaseWiz.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CWizardWindow class.
  10. //
  11. // Author:
  12. // David Potter (davidp) December 2, 1997
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "AtlBaseWiz.h"
  20. #include "AtlBaseWizPage.h"
  21. #include "AtlExtDll.h"
  22. #include "StlUtils.h"
  23. #include "ExcOper.h"
  24. #include "AdmCommonRes.h"
  25. /////////////////////////////////////////////////////////////////////////////
  26. // Local Type Definitions
  27. /////////////////////////////////////////////////////////////////////////////
  28. /////////////////////////////////////////////////////////////////////////////
  29. //
  30. // class CAltExtWizardGuardPage
  31. //
  32. // Purpose:
  33. // Guard page transferring control between the main wizard and the
  34. // alternate extension wizard.
  35. //
  36. /////////////////////////////////////////////////////////////////////////////
  37. template < class T >
  38. class CAltExtWizardGuardPage
  39. : public CExtensionWizardPageImpl< T >
  40. {
  41. typedef CAltExtWizardGuardPage< T > thisClass;
  42. typedef CExtensionWizardPageImpl< T > baseClass;
  43. public:
  44. //
  45. // Construction.
  46. //
  47. // Standard constructor
  48. CAltExtWizardGuardPage(
  49. DLGTEMPLATE * pdt
  50. )
  51. : m_pdt( pdt )
  52. {
  53. ATLASSERT( pdt != NULL );
  54. } //*** CAltExtWizardGuardPage()
  55. // Destructor
  56. ~CAltExtWizardGuardPage( void )
  57. {
  58. delete m_pdt;
  59. } //*** ~CAltExtWizardGuardPage()
  60. WIZARDPAGE_HEADERTITLEID( 0 )
  61. WIZARDPAGE_HEADERSUBTITLEID( 0 )
  62. enum { IDD = 0 };
  63. DECLARE_CLASS_NAME()
  64. // Return the help ID map
  65. static const DWORD * PidHelpMap( void )
  66. {
  67. static const DWORD s_aHelpIDs[] = { 0, 0 };
  68. return s_aHelpIDs;
  69. } //*** PidHelpMap()
  70. // Create the page
  71. DWORD ScCreatePage( void )
  72. {
  73. ATLASSERT( m_hpage == NULL );
  74. m_psp.dwFlags |= PSP_DLGINDIRECT;
  75. m_psp.pResource = m_pdt;
  76. m_hpage = CreatePropertySheetPage( &m_psp );
  77. if ( m_hpage == NULL )
  78. {
  79. return GetLastError();
  80. } // if: error creating the page
  81. return ERROR_SUCCESS;
  82. } //*** ScCreatePage()
  83. public:
  84. //
  85. // Message map.
  86. //
  87. BEGIN_MSG_MAP( thisClass )
  88. MESSAGE_HANDLER( WM_ACTIVATE, OnActivate )
  89. CHAIN_MSG_MAP( baseClass )
  90. END_MSG_MAP()
  91. //
  92. // Message handler functions.
  93. //
  94. // Handler for the WM_ACTIVATE message
  95. LRESULT OnActivate(
  96. UINT uMsg,
  97. WPARAM wParam,
  98. LPARAM lParam,
  99. BOOL & bHandled
  100. )
  101. {
  102. //
  103. // Don't allow us to be activated.
  104. //
  105. WORD fActive = LOWORD( wParam );
  106. HWND hwndPrevious = (HWND) lParam;
  107. if ( wParam != WA_INACTIVE )
  108. {
  109. ::SetActiveWindow( hwndPrevious );
  110. }
  111. return 0;
  112. } //*** OnActivate()
  113. //
  114. // Message handler override functions.
  115. //
  116. protected:
  117. DLGTEMPLATE * m_pdt;
  118. }; //*** class CAltExtWizardGuardPage
  119. /////////////////////////////////////////////////////////////////////////////
  120. //
  121. // class CAltExtWizardPreLauncherPage
  122. //
  123. // Purpose:
  124. // Extension launcher wizard page used to display Wizard97 pages in
  125. // a non-Wizard97 sheet or vice-versa.
  126. //
  127. /////////////////////////////////////////////////////////////////////////////
  128. class CAltExtWizardPreLauncherPage
  129. : public CAltExtWizardGuardPage< CAltExtWizardPreLauncherPage >
  130. {
  131. typedef CAltExtWizardGuardPage< CAltExtWizardPreLauncherPage > baseClass;
  132. public:
  133. //
  134. // Construction.
  135. //
  136. // Standard constructor
  137. CAltExtWizardPreLauncherPage(
  138. DLGTEMPLATE * pdt
  139. )
  140. : baseClass( pdt )
  141. {
  142. } //*** CAltExtWizardPreLauncherPage()
  143. DECLARE_CLASS_NAME()
  144. public:
  145. //
  146. // Message map.
  147. //
  148. //BEGIN_MSG_MAP( CAltExtWizardPreLauncherPage )
  149. // CHAIN_MSG_MAP( baseClass )
  150. //END_MSG_MAP()
  151. //
  152. // Message handler functions.
  153. //
  154. //
  155. // Message handler overrides functions.
  156. //
  157. // Handler for PSN_SETACTIVE
  158. BOOL OnSetActive( void );
  159. }; //*** class CAltExtWizardPreLauncherPage
  160. /////////////////////////////////////////////////////////////////////////////
  161. //
  162. // class CAltExtWizardPostLauncherPage
  163. //
  164. // Purpose:
  165. // Page use to switch between the main wizard and the alternate
  166. // extension wizard when moving backwards.
  167. //
  168. /////////////////////////////////////////////////////////////////////////////
  169. class CAltExtWizardPostLauncherPage
  170. : public CAltExtWizardGuardPage< CAltExtWizardPostLauncherPage >
  171. {
  172. typedef CAltExtWizardGuardPage< CAltExtWizardPostLauncherPage > baseClass;
  173. public:
  174. //
  175. // Construction.
  176. //
  177. // Standard constructor
  178. CAltExtWizardPostLauncherPage(
  179. DLGTEMPLATE * pdt
  180. )
  181. : baseClass( pdt )
  182. {
  183. } //*** CAltExtWizardPostLauncherPage()
  184. DECLARE_CLASS_NAME()
  185. public:
  186. //
  187. // Message map.
  188. //
  189. //BEGIN_MSG_MAP( CAltExtWizardPostLauncherPage )
  190. // CHAIN_MSG_MAP( baseClass )
  191. //END_MSG_MAP()
  192. //
  193. // Message handler functions.
  194. //
  195. //
  196. // Message handler override functions.
  197. //
  198. // Handler for PSN_SETACTIVE
  199. BOOL OnSetActive( void );
  200. }; //*** class CAltExtWizardPostLauncherPage
  201. /////////////////////////////////////////////////////////////////////////////
  202. //
  203. // class CAltExtWizard
  204. //
  205. // Purpose:
  206. // Dummy wizard to host pages that are not of the same type as the main
  207. // wizard, e.g. non-Wizard97 pages in a Wizard97 wizard.
  208. //
  209. /////////////////////////////////////////////////////////////////////////////
  210. class CAltExtWizard : public CWizardImpl< CAltExtWizard >
  211. {
  212. typedef CWizardImpl< CAltExtWizard > baseClass;
  213. friend class CWizardWindow;
  214. friend class CAltExtWizardPreLauncherPage;
  215. friend class CAltExtWizardPostLauncherPage;
  216. friend class CAltExtWizardPrefixPage;
  217. friend class CAltExtWizardPostfixPage;
  218. public:
  219. //
  220. // Construction
  221. //
  222. // Standard constructor
  223. CAltExtWizard( void )
  224. : CWizardImpl< CAltExtWizard >( _T("") )
  225. , m_pwizMain( NULL )
  226. , m_bWindowMoved( FALSE )
  227. , m_bExitMsgLoop( FALSE )
  228. , m_nExitButton( 0 )
  229. {
  230. } //*** CExtensionAltWizard()
  231. // Initialize the sheet
  232. BOOL BInit( IN CWizardWindow * pwiz );
  233. public:
  234. //
  235. // Message map.
  236. //
  237. BEGIN_MSG_MAP( CAltExtWizard )
  238. COMMAND_HANDLER( IDCANCEL, BN_CLICKED, OnCancel )
  239. CHAIN_MSG_MAP( baseClass )
  240. END_MSG_MAP()
  241. //
  242. // Message handler functions.
  243. //
  244. // Handler for BN_CLICKED on the Cancel button
  245. LRESULT OnCancel(
  246. WORD wNotifyCode,
  247. WORD idCtrl,
  248. HWND hwndCtrl,
  249. BOOL & bHandled
  250. )
  251. {
  252. //
  253. // Notify the main wizard that the user pressed the cancel button.
  254. //
  255. ExitMessageLoop( PSBTN_CANCEL );
  256. bHandled = FALSE;
  257. return 0;
  258. } //*** OnCancel()
  259. //
  260. // Message handler override functions.
  261. //
  262. // Handler for the final message after WM_DESTROY
  263. void OnFinalMessage( HWND hWnd )
  264. {
  265. PwizMain()->DeleteAlternateWizard();
  266. } //*** OnFinalMessage()
  267. protected:
  268. CWizardWindow * m_pwizMain; // Pointer to the main wizard.
  269. BOOL m_bWindowMoved; // Indicates whether this window has been
  270. // repositioned over main wizard or not.
  271. BOOL m_bExitMsgLoop; // Indicates whether the message loop
  272. // should be exited or not.
  273. DWORD m_nExitButton; // Button to press after exiting.
  274. protected:
  275. // Return a pointer to the main wizard
  276. CWizardWindow * PwizMain( void ) { return m_pwizMain; }
  277. // Return whether the wizard has been moved yet
  278. BOOL BWindowMoved( void ) const { return m_bWindowMoved; }
  279. // Return whether the message loop should be exited or not
  280. BOOL BExitMessageLoop( void ) const { return m_bExitMsgLoop; }
  281. // Change whether the message loop should be exited or not
  282. void ExitMessageLoop( IN DWORD nButton )
  283. {
  284. ATLASSERT( (nButton == PSBTN_BACK) || (nButton == PSBTN_NEXT) || (nButton == PSBTN_CANCEL) );
  285. m_bExitMsgLoop = TRUE;
  286. m_nExitButton = nButton;
  287. } //*** ExitMessageLoop()
  288. // Return the button to press in the main wizard after exiting
  289. DWORD NExitButton( void ) const { return m_nExitButton; }
  290. protected:
  291. // Add the prefix page
  292. BOOL BAddPrefixPage( IN WORD cx, IN WORD cy );
  293. // Add the postfix page
  294. BOOL BAddPostfixPage( IN WORD cx, IN WORD cy );
  295. // Display the alternate wizard
  296. void DisplayAlternateWizard( void );
  297. // Display the main wizard
  298. void DisplayMainWizard( void );
  299. // Destroy the alternate extension wizard
  300. void DestroyAlternateWizard( void );
  301. // Message loop for the modeless wizard
  302. void MessageLoop( void );
  303. }; //*** class CAltExtWizard
  304. /////////////////////////////////////////////////////////////////////////////
  305. //
  306. // class CAltExtWizardPrefixPage
  307. //
  308. // Purpose:
  309. // Wizard page which precedes the first alternate page. This page
  310. // handles transferring control between the main wizard and the
  311. // alternate wizard.
  312. //
  313. /////////////////////////////////////////////////////////////////////////////
  314. class CAltExtWizardPrefixPage
  315. : public CAltExtWizardGuardPage< CAltExtWizardPrefixPage >
  316. {
  317. typedef CAltExtWizardGuardPage< CAltExtWizardPrefixPage > baseClass;
  318. public:
  319. //
  320. // Construction.
  321. //
  322. // Standard constructor
  323. CAltExtWizardPrefixPage(
  324. DLGTEMPLATE * pdt
  325. )
  326. : baseClass( pdt )
  327. {
  328. } //*** CAltExtWizardPrefixPage()
  329. DECLARE_CLASS_NAME()
  330. public:
  331. //
  332. // Message map.
  333. //
  334. //BEGIN_MSG_MAP( CAltExtWizardPrefixPage )
  335. // CHAIN_MSG_MAP( baseClass )
  336. //END_MSG_MAP()
  337. //
  338. // Message handler functions.
  339. //
  340. //
  341. // Message handler override functions.
  342. //
  343. // Handler for PSN_SETACTIVE
  344. BOOL OnSetActive( void );
  345. protected:
  346. // Return the alternate wizard object
  347. CAltExtWizard * PwizThis( void ) { return (CAltExtWizard *) Pwiz(); }
  348. }; //*** class CAltExtWizardPrefixPage
  349. /////////////////////////////////////////////////////////////////////////////
  350. //
  351. // class CAltExtWizardPostfixPage
  352. //
  353. // Purpose:
  354. // Wizard page which follows the last alternate page. This page
  355. // handles transferring control between the main wizard and the
  356. // alternate wizard.
  357. //
  358. /////////////////////////////////////////////////////////////////////////////
  359. class CAltExtWizardPostfixPage
  360. : public CAltExtWizardGuardPage< CAltExtWizardPostfixPage >
  361. {
  362. typedef CAltExtWizardGuardPage< CAltExtWizardPostfixPage > baseClass;
  363. public:
  364. //
  365. // Construction.
  366. //
  367. // Standard constructor
  368. CAltExtWizardPostfixPage(
  369. DLGTEMPLATE * pdt
  370. )
  371. : baseClass( pdt )
  372. {
  373. } //*** CAltExtWizardPostfixPage()
  374. DECLARE_CLASS_NAME()
  375. public:
  376. //
  377. // Message map.
  378. //
  379. //BEGIN_MSG_MAP( CAltExtWizardPostfixPage )
  380. // CHAIN_MSG_MAP( baseClass )
  381. //END_MSG_MAP()
  382. //
  383. // Message handler functions.
  384. //
  385. //
  386. // Message handler override functions.
  387. //
  388. // Handler for PSN_SETACTIVE
  389. BOOL OnSetActive( void );
  390. protected:
  391. // Return the alternate wizard object
  392. CAltExtWizard * PwizThis( void ) { return (CAltExtWizard *) Pwiz(); }
  393. }; //*** class CAltExtWizardPostfixPage
  394. //*************************************************************************//
  395. /////////////////////////////////////////////////////////////////////////////
  396. // class CWizardWindow
  397. /////////////////////////////////////////////////////////////////////////////
  398. /////////////////////////////////////////////////////////////////////////////
  399. //++
  400. //
  401. // CWizardWindow::~CWizardWindow
  402. //
  403. // Routine Description:
  404. // Destructor.
  405. //
  406. // Arguments:
  407. // None.
  408. //
  409. // Return Value:
  410. // None.
  411. //
  412. // Exceptions Thrown:
  413. // None.
  414. //
  415. //--
  416. /////////////////////////////////////////////////////////////////////////////
  417. CWizardWindow::~CWizardWindow( void )
  418. {
  419. //
  420. // Delete the alternate wizard, if it exists.
  421. //
  422. if ( (PwizAlternate() != NULL) && (PwizAlternate()->m_hWnd != NULL) )
  423. {
  424. reinterpret_cast< CAltExtWizard * >( PwizAlternate() )->DestroyAlternateWizard();
  425. } // if: alternate wizard exists
  426. //
  427. // Delete pages from the page list.
  428. //
  429. if ( m_plwpPages != NULL )
  430. {
  431. DeleteAllPtrListItems( m_plwpPages );
  432. delete m_plwpPages;
  433. } // if: page array has been allocated
  434. if ( m_plewpNormal != NULL )
  435. {
  436. DeleteAllPtrListItems( m_plewpNormal );
  437. delete m_plewpNormal;
  438. } // if: list already exists
  439. if ( m_plewpAlternate != NULL )
  440. {
  441. DeleteAllPtrListItems( m_plewpAlternate );
  442. delete m_plewpAlternate;
  443. } // if: list already exists
  444. } //*** CWizardWindow::~CWizardWindow()
  445. /////////////////////////////////////////////////////////////////////////////
  446. //++
  447. //
  448. // CWizardWindow::BAddPage
  449. //
  450. // Routine Description:
  451. // Add a page to the page list. If it is the first page, it won't have
  452. // a BACK button. If it isn't the first page, the last page will have
  453. // its FINISH button changed to a NEXT button and this page will have
  454. // both a FINISH button and a BACK button.
  455. //
  456. // Arguments:
  457. // pwp [IN] Wizard page to add.
  458. //
  459. // Return Value:
  460. // TRUE Page added successfully.
  461. // FALSE Error adding page.
  462. //
  463. //--
  464. /////////////////////////////////////////////////////////////////////////////
  465. BOOL CWizardWindow::BAddPage( IN CWizardPageWindow * pwp )
  466. {
  467. ATLASSERT( pwp != NULL );
  468. // Make sure specified page hasn't already been added.
  469. ATLASSERT( (m_plwpPages == NULL)
  470. || (std::find( PlwpPages()->begin(), PlwpPages()->end(), pwp ) == PlwpPages()->end()) );
  471. BOOL bSuccess = FALSE;
  472. ULONG fWizardButtons = PSWIZB_FINISH;
  473. ULONG fPrevWizardButtons;
  474. // Loop to avoid goto's.
  475. do
  476. {
  477. //
  478. // Allocate the page list if it doesn't exist yet.
  479. //
  480. if ( m_plwpPages == NULL )
  481. {
  482. m_plwpPages = new CWizardPageList;
  483. if ( m_plwpPages == NULL )
  484. {
  485. CNTException nte(
  486. E_OUTOFMEMORY,
  487. ADMC_IDS_ADD_FIRST_PAGE_TO_PROP_SHEET_ERROR,
  488. NULL, // pszOperArg1
  489. NULL, // pszOperArg2
  490. FALSE // bAutoDelete
  491. );
  492. nte.ReportError();
  493. break;
  494. } // if: error allocating page list
  495. } // if: no page array yet
  496. //
  497. // If this is not the first page in the list, set the previous
  498. // page's wizard buttons to have a NEXT button instead of a
  499. // FINISH button and set this page to have a BACK button.
  500. //
  501. if ( PlwpPages()->size() > 0 )
  502. {
  503. //
  504. // Get the current last page.
  505. //
  506. CWizardPageList::iterator itFirst = PlwpPages()->begin();
  507. CWizardPageList::iterator itLast = PlwpPages()->end();
  508. ATLASSERT( itFirst != itLast );
  509. CWizardPageWindow * pwpPrev = *(--PlwpPages()->end());
  510. ATLASSERT( pwpPrev != NULL );
  511. //
  512. // Set the wizard buttons on that page.
  513. //
  514. fPrevWizardButtons = pwpPrev->FWizardButtons();
  515. fPrevWizardButtons &= ~PSWIZB_FINISH;
  516. fPrevWizardButtons |= PSWIZB_NEXT;
  517. pwpPrev->SetDefaultWizardButtons( fPrevWizardButtons );
  518. fWizardButtons |= PSWIZB_BACK;
  519. } // if: not the first page added
  520. pwp->SetDefaultWizardButtons( fWizardButtons );
  521. //
  522. // Insert the page at the end of the list.
  523. //
  524. PlwpPages()->insert( PlwpPages()->end(), pwp );
  525. //
  526. // Add the page to the sheet. If the sheet hasn't been created yet,
  527. // add it to the sheet header list. If the sheet has been created,
  528. // add it to the sheet dynamically. Note that the page must not be a
  529. // static page.
  530. //
  531. if ( m_hWnd == NULL )
  532. {
  533. //
  534. // If this is a dynamic page, add it using its hpage. Otherwise
  535. // it must be a static page. Add it by its property sheet page header.
  536. //
  537. CDynamicWizardPageWindow * pdwp = dynamic_cast< CDynamicWizardPageWindow * >( pwp );
  538. if ( pdwp != NULL )
  539. {
  540. if ( pdwp->Hpage() != NULL )
  541. {
  542. ATLASSERT( ! pdwp->BPageAddedToSheet() );
  543. bSuccess = BAddPageToSheetHeader( pdwp->Hpage() );
  544. if ( ! bSuccess )
  545. {
  546. CNTException nte(
  547. GetLastError(),
  548. ADMC_IDS_ADD_PAGE_TO_WIZARD_ERROR,
  549. NULL,
  550. NULL,
  551. FALSE
  552. );
  553. nte.ReportError();
  554. break;
  555. } // if: error adding the page to the sheet header
  556. pdwp->SetPageAdded( TRUE );
  557. } // if: page already created
  558. } // if: dynamic page
  559. else
  560. {
  561. // Must be static page
  562. ATLASSERT( dynamic_cast< CStaticWizardPageWindow * >( pwp ) != NULL );
  563. //
  564. // Initialize the page.
  565. //
  566. bSuccess = pwp->BInit( this );
  567. if ( ! bSuccess )
  568. {
  569. break;
  570. } // if: error initializing the page
  571. //
  572. // Add the page.
  573. //
  574. bSuccess = AddPage( pwp->Ppsp() );
  575. if ( ! bSuccess )
  576. {
  577. CNTException nte(
  578. GetLastError(),
  579. ADMC_IDS_ADD_PAGE_TO_WIZARD_ERROR,
  580. NULL,
  581. NULL,
  582. FALSE
  583. );
  584. nte.ReportError();
  585. break;
  586. } // if: error adding the page
  587. } // else: not dynamic page
  588. } // if: sheet has been created
  589. else
  590. {
  591. // Can't be static page. Must be dynamic page.
  592. ATLASSERT( dynamic_cast< CStaticWizardPageWindow * >( pwp ) == NULL );
  593. CDynamicWizardPageWindow * pdwp = dynamic_cast< CDynamicWizardPageWindow * >( pwp );
  594. ATLASSERT( pdwp != NULL );
  595. AddPage( pdwp->Hpage() );
  596. pdwp->SetPageAdded( TRUE );
  597. } // else: sheet already created
  598. //
  599. // If we get to here we are successfully.
  600. //
  601. bSuccess = TRUE;
  602. } while ( 0 );
  603. return bSuccess;
  604. } //*** CWizardWindow::BAddPage()
  605. /////////////////////////////////////////////////////////////////////////////
  606. //++
  607. //
  608. // CWizardWindow::OnSheetInitialized
  609. //
  610. // Routine Description:
  611. // Handler for PSCB_INITIALIZED.
  612. // Add pages that haven't been added yet, which will only be dynamic
  613. // pages.
  614. //
  615. // Arguments:
  616. // None.
  617. //
  618. // Return Value:
  619. // None.
  620. //
  621. // Exceptions Thrown:
  622. // None.
  623. //
  624. //--
  625. /////////////////////////////////////////////////////////////////////////////
  626. void CWizardWindow::OnSheetInitialized( void )
  627. {
  628. //
  629. // Remove the system menu.
  630. //
  631. ModifyStyle( WS_SYSMENU, 0 );
  632. //
  633. // Add dynamic pages, including extension pages, if not added yet.
  634. //
  635. {
  636. //
  637. // Get pointers to beginning and end of list.
  638. //
  639. CWizardPageList::iterator itCurrent = PlwpPages()->begin();
  640. CWizardPageList::iterator itLast = PlwpPages()->end();
  641. //
  642. // Loop through the list and add each dynamic page.
  643. //
  644. for ( ; itCurrent != itLast ; itCurrent++ )
  645. {
  646. CDynamicWizardPageWindow * pdwp = dynamic_cast< CDynamicWizardPageWindow * >( *itCurrent );
  647. if ( pdwp != NULL )
  648. {
  649. if ( ! pdwp->BPageAddedToSheet() && (pdwp->Hpage() != NULL) )
  650. {
  651. AddPage( pdwp->Hpage() );
  652. pdwp->SetPageAdded( TRUE );
  653. } // if: page not added yet and page has already been created
  654. } // if: dynamic page found
  655. } // for: each item in the list
  656. } // Add dynamic pages, including extension pages
  657. //
  658. // Call the base class method.
  659. //
  660. CBaseSheetWindow::OnSheetInitialized();
  661. } //*** CWizardWindow::OnSheetInitialized()
  662. /////////////////////////////////////////////////////////////////////////////
  663. //++
  664. //
  665. // CWizardWindow::SetNextPage
  666. //
  667. // Routine Description:
  668. // Set the next page to be displayed.
  669. //
  670. // Arguments:
  671. // pwCurrentPage [IN] Current page whose next page is to be enabled.
  672. // pszNextPage [IN] Page ID.
  673. //
  674. // Return Value:
  675. // pwizpg
  676. //
  677. //--
  678. /////////////////////////////////////////////////////////////////////////////
  679. void CWizardWindow::SetNextPage(
  680. IN CWizardPageWindow * pwCurrentPage,
  681. IN LPCTSTR pszNextPage
  682. )
  683. {
  684. ATLASSERT( pwCurrentPage != NULL );
  685. ATLASSERT( pszNextPage != NULL );
  686. BOOL bFoundCurrent = FALSE;
  687. CWizardPageWindow * pwPage;
  688. CWizardPageList::iterator itCurrent = PlwpPages()->begin();
  689. CWizardPageList::iterator itLast = PlwpPages()->end();
  690. //
  691. // Skip pages until the current page is found.
  692. //
  693. for ( ; itCurrent != itLast ; itCurrent++ )
  694. {
  695. pwPage = *itCurrent;
  696. if ( pwPage == pwCurrentPage )
  697. {
  698. bFoundCurrent = TRUE;
  699. break;
  700. } // if: found the current page
  701. } // for: each page in the list
  702. ATLASSERT( bFoundCurrent );
  703. //
  704. // Disable all succeeding pages until the desired next page
  705. // is found. Enable that page and then exit.
  706. //
  707. for ( itCurrent++ ; itCurrent != itLast ; itCurrent++ )
  708. {
  709. if ( (*itCurrent)->Ppsp()->pszTemplate == pszNextPage )
  710. {
  711. (*itCurrent)->EnablePage( TRUE );
  712. break;
  713. } // if: found the page
  714. (*itCurrent)->EnablePage( FALSE );
  715. } // for: each page in the list
  716. ATLASSERT( itCurrent != itLast );
  717. } //*** CWizardWindow::SetNextPage( pszNextPage )
  718. /////////////////////////////////////////////////////////////////////////////
  719. //++
  720. //
  721. // CWizardWindow::AddExtensionPages
  722. //
  723. // Routine Description:
  724. // Add extension pages to the sheet.
  725. //
  726. // Arguments:
  727. // hfont [IN] Font to use for the extension pages.
  728. // hicon [IN] Icon to use for the extension pages.
  729. //
  730. // Return Value:
  731. // None.
  732. //
  733. //--
  734. /////////////////////////////////////////////////////////////////////////////
  735. void CWizardWindow::AddExtensionPages( IN HFONT hfont, IN HICON hicon )
  736. {
  737. ATLASSERT( PcoObjectToExtend() != NULL );
  738. //
  739. // Add extension pages if there any extensions.
  740. //
  741. if ( (PcoObjectToExtend()->PlstrAdminExtensions() != NULL)
  742. && (PcoObjectToExtend()->PlstrAdminExtensions()->size() > 0) )
  743. {
  744. //
  745. // Get the currently selected page so we can reset it when we're done.
  746. //
  747. CTabCtrl tabc( GetTabControl() );
  748. int nCurPage = tabc.GetCurSel();
  749. //
  750. // Prepare to add extension pages.
  751. //
  752. CDynamicWizardPageList ldwp;
  753. PrepareToAddExtensionPages( ldwp );
  754. //
  755. // If no extensions object has been created yet, create it now.
  756. //
  757. if ( Pext() == NULL )
  758. {
  759. m_pext = new CCluAdmExtensions;
  760. ATLASSERT( m_pext != NULL );
  761. if ( m_pext == NULL )
  762. {
  763. return;
  764. } // if: error allocating the extension object
  765. } // if: no extensions list yet
  766. //
  767. // Enclose the loading of the extension in a try/catch block so
  768. // that a failure to load the extension won't prevent all pages
  769. // from being displayed.
  770. //
  771. try
  772. {
  773. if ( BWizard97() )
  774. {
  775. Pext()->CreateWizard97Pages(
  776. this,
  777. *PcoObjectToExtend()->PlstrAdminExtensions(),
  778. PcoObjectToExtend(),
  779. hfont,
  780. hicon
  781. );
  782. } // if: Wizard97 wizard
  783. else
  784. {
  785. Pext()->CreateWizardPages(
  786. this,
  787. *PcoObjectToExtend()->PlstrAdminExtensions(),
  788. PcoObjectToExtend(),
  789. hfont,
  790. hicon
  791. );
  792. } // else: non-Wizard97 wizard
  793. } // try
  794. catch (...)
  795. {
  796. } // catch: anything
  797. //
  798. // Complete the process of adding extension pages.
  799. //
  800. CompleteAddingExtensionPages( ldwp );
  801. //
  802. // Restore the current selection.
  803. // This has to be done because sometimes the above process causes
  804. // the current page to be set to the last page added, which prevents
  805. // the next page from being displayed.
  806. //
  807. SetActivePage( nCurPage );
  808. } // if: object has extensions
  809. else
  810. {
  811. //
  812. // Remove extension pages.
  813. //
  814. RemoveAllExtensionPages();
  815. } // else: object doesn't have extensions
  816. } //*** CWizardWindow::AddExtensionPages()
  817. /////////////////////////////////////////////////////////////////////////////
  818. //++
  819. //
  820. // CWizardWindow::PrepareToAddExtensionPages
  821. //
  822. // Routine Description:
  823. // Prepare to add extension pages by deleting existing extension
  824. // pages and removing dynamic pages.
  825. //
  826. // Arguments:
  827. // rldwp [IN OUT] List of dynamic wizard pages.
  828. //
  829. // Return Value:
  830. // None.
  831. //
  832. //--
  833. /////////////////////////////////////////////////////////////////////////////
  834. void CWizardWindow::PrepareToAddExtensionPages(
  835. IN OUT CDynamicWizardPageList & rldwp
  836. )
  837. {
  838. //
  839. // Delete all extension pages from this wizard. This also
  840. // includes destroy the alternate wizard if it exists.
  841. //
  842. RemoveAllExtensionPages();
  843. //
  844. // Delete the lists of extension pages and make sure the lists exist.
  845. //
  846. if ( PlewpNormal() != NULL )
  847. {
  848. DeleteAllPtrListItems( PlewpNormal() );
  849. } // if: list already exists
  850. else
  851. {
  852. m_plewpNormal = new CExtensionWizardPageList;
  853. if ( m_plewpNormal == NULL )
  854. {
  855. return;
  856. } // if: error allocating the page list
  857. } // else: list doesn't exist yet
  858. if ( PlewpAlternate() != NULL )
  859. {
  860. DeleteAllPtrListItems( PlewpAlternate() );
  861. } // if: list already exists
  862. else
  863. {
  864. m_plewpAlternate = new CExtensionWizardPageList;
  865. if ( m_plewpAlternate == NULL )
  866. {
  867. return;
  868. } // if: error allocating the page list
  869. } // else: list doesn't exist yet
  870. //
  871. // Move all dynamic pages to the temporary list.
  872. //
  873. ATLASSERT( rldwp.size() == 0 );
  874. MovePtrListItems< CWizardPageWindow *, CDynamicWizardPageWindow * >( PlwpPages(), &rldwp );
  875. //
  876. // Remove all pages in the temporary list from the wizard.
  877. //
  878. {
  879. CDynamicWizardPageList::iterator itCurrent;
  880. CDynamicWizardPageList::iterator itLast;
  881. itCurrent = rldwp.begin();
  882. itLast = rldwp.end();
  883. for ( ; itCurrent != itLast ; itCurrent++ )
  884. {
  885. CDynamicWizardPageWindow * pdwp = *itCurrent;
  886. ATLASSERT( pdwp != NULL );
  887. if ( pdwp->Hpage() != NULL )
  888. {
  889. RemovePage( pdwp->Hpage() );
  890. pdwp->SetPageAdded( FALSE );
  891. } // if: page already created
  892. } // for: each page in the list
  893. } // Remove dynamic pages
  894. } //*** CWizardWindow::PrepareToAddExtensionPages()
  895. /////////////////////////////////////////////////////////////////////////////
  896. //++
  897. //
  898. // CWizardWindow::HrAddExtensionPage
  899. //
  900. // Routine Description:
  901. // Add an extension page.
  902. //
  903. // Arguments:
  904. // ppage [IN] Page to be added.
  905. //
  906. // Return Value:
  907. // S_OK Page added successfully.
  908. // S_FALSE Page not added.
  909. //
  910. //--
  911. /////////////////////////////////////////////////////////////////////////////
  912. HRESULT CWizardWindow::HrAddExtensionPage( IN CBasePageWindow * ppage )
  913. {
  914. ATLASSERT( ppage != NULL );
  915. HRESULT hr = S_OK;
  916. //
  917. // Make sure this is an extension wizard page object.
  918. //
  919. CExtensionWizardPageWindow * pewp = dynamic_cast< CExtensionWizardPageWindow * >( ppage );
  920. ATLASSERT( pewp != NULL );
  921. if ( (ppage == NULL)
  922. || (pewp == NULL ) )
  923. {
  924. return S_FALSE;
  925. } // if: invalid arguments
  926. //
  927. // If the page is not the same as the type of wizard, add it to the
  928. // alternate list of extension pages and indicate we need a dummy sheet.
  929. // Otherwise, add it to the standard list of extension pages.
  930. //
  931. CExtensionWizard97PageWindow * pew97p = dynamic_cast< CExtensionWizard97PageWindow * >( ppage );
  932. if ( ((pew97p != NULL) && ! BWizard97())
  933. || ((pew97p == NULL) && BWizard97()) )
  934. {
  935. PlewpAlternate()->insert( PlewpAlternate()->end(), pewp );
  936. } // if: trying to add the wrong type of page
  937. else
  938. {
  939. PlewpNormal()->insert( PlewpNormal()->end(), pewp );
  940. } // else: adding page of matching type
  941. return hr;
  942. } //*** CWizardWindow::HrAddExtensionPage()
  943. /////////////////////////////////////////////////////////////////////////////
  944. //++
  945. //
  946. // CWizardWindow::CompleteAddingExtensionPages
  947. //
  948. // Routine Description:
  949. // Complete the process of adding extension pages to the wizard by
  950. // re-adding dynamic pages.
  951. //
  952. // Arguments:
  953. // rldwp [IN OUT] List of dynamic wizard pages.
  954. //
  955. // Return Value:
  956. // None.
  957. //
  958. //--
  959. /////////////////////////////////////////////////////////////////////////////
  960. void CWizardWindow::CompleteAddingExtensionPages(
  961. IN OUT CDynamicWizardPageList & rldwp
  962. )
  963. {
  964. //
  965. // If there are any normal pages, add them here.
  966. // There will be normal pages if pages of the same type as the wizard
  967. // were added.
  968. //
  969. if ( PlewpNormal()->size() > 0 )
  970. {
  971. //
  972. // Add pages to the sheet.
  973. //
  974. if ( m_hWnd != NULL )
  975. {
  976. CExtensionWizardPageList::iterator itCurrent = PlewpNormal()->begin();
  977. CExtensionWizardPageList::iterator itLast = PlewpNormal()->end();
  978. for ( ; itCurrent != itLast ; itCurrent++ )
  979. {
  980. CExtensionWizardPageWindow * pewp = *itCurrent;
  981. ATLASSERT( pewp != NULL );
  982. BAddPage( pewp );
  983. } // for: each page in the list
  984. } // if: sheet is currently being displayed
  985. } // if: there are normal pages
  986. //
  987. // If there are any alternate pages, add a pre-extension launcher page
  988. // and a post-extension launcher page. The pre-extension launcher page
  989. // will display an alternate wizard of the appropriate type and hide the
  990. // main wizard before displaying these pages. After the final page it
  991. // will display the original sheet and hide the other sheet. The
  992. // post-extension launcher page is used to transition between the main
  993. // wizard and the alternate wizard when moving backwards into the
  994. // alternate wizard.
  995. //
  996. if ( PlewpAlternate()->size() > 0 )
  997. {
  998. DLGTEMPLATE * pdt = NULL;
  999. CAltExtWizardPreLauncherPage * pelwpPre = NULL;
  1000. CAltExtWizardPostLauncherPage * pelwpPost = NULL;
  1001. // Loop to avoid goto's
  1002. do
  1003. {
  1004. //
  1005. // Add the pre-extension launcher page.
  1006. //
  1007. {
  1008. //
  1009. // Create the dialog template.
  1010. //
  1011. pdt = PdtCreateDummyPageDialogTemplate( 10, 10 );
  1012. ATLASSERT( pdt != NULL );
  1013. if ( pdt == NULL )
  1014. {
  1015. break;
  1016. } // if: error creating the dialog template
  1017. //
  1018. // Allocate and initialize the launcher page.
  1019. //
  1020. pelwpPre = new CAltExtWizardPreLauncherPage( pdt );
  1021. ATLASSERT( pelwpPre != NULL );
  1022. if ( pelwpPre == NULL )
  1023. {
  1024. break;
  1025. } // if: error allocating the page
  1026. pdt = NULL;
  1027. if ( ! pelwpPre->BInit( this ) )
  1028. {
  1029. break;
  1030. } // if: error initializing the page
  1031. //
  1032. // Create the launcher page.
  1033. //
  1034. DWORD sc = pelwpPre->ScCreatePage();
  1035. if ( sc != ERROR_SUCCESS )
  1036. {
  1037. CNTException nte(
  1038. sc,
  1039. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1040. NULL,
  1041. NULL,
  1042. FALSE
  1043. );
  1044. nte.ReportError();
  1045. break;
  1046. } // if: error creating the page
  1047. //
  1048. // Add the launcher page to the wizard.
  1049. //
  1050. BAddPage( pelwpPre );
  1051. pelwpPre = NULL;
  1052. } // Add the pre-extension launcher page
  1053. //
  1054. // Add the post-extension launcher page
  1055. //
  1056. {
  1057. //
  1058. // Create the dialog template.
  1059. //
  1060. pdt = PdtCreateDummyPageDialogTemplate( 10, 10 );
  1061. ATLASSERT( pdt != NULL );
  1062. if ( pdt == NULL )
  1063. {
  1064. break;
  1065. } // if: error creating the dialog template
  1066. //
  1067. // Allocate and initialize the launcher page.
  1068. //
  1069. pelwpPost = new CAltExtWizardPostLauncherPage( pdt );
  1070. ATLASSERT( pelwpPost != NULL );
  1071. if ( pelwpPost == NULL )
  1072. {
  1073. break;
  1074. } // if: error allocating page
  1075. pdt = NULL;
  1076. if ( ! pelwpPost->BInit( this ) )
  1077. {
  1078. break;
  1079. } // if: error initializing the page
  1080. //
  1081. // Create the launcher page.
  1082. //
  1083. DWORD sc = pelwpPost->ScCreatePage();
  1084. if ( sc != ERROR_SUCCESS )
  1085. {
  1086. CNTException nte(
  1087. sc,
  1088. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1089. NULL,
  1090. NULL,
  1091. FALSE
  1092. );
  1093. nte.ReportError();
  1094. break;
  1095. } // if: error creating the page
  1096. //
  1097. // Add the launcher page to the wizard.
  1098. //
  1099. BAddPage( pelwpPost );
  1100. pelwpPost = NULL;
  1101. } // Add the post-extension launcher page
  1102. } while ( 0 );
  1103. //
  1104. // Cleanup;
  1105. //
  1106. delete pelwpPre;
  1107. delete pelwpPost;
  1108. delete pdt;
  1109. } // if: there are alternate pages
  1110. //
  1111. // Move all pages from the temporary list to the real list and
  1112. // add them to the end of the wizard.
  1113. //
  1114. CDynamicWizardPageList::iterator itCurrent = rldwp.begin();
  1115. CDynamicWizardPageList::iterator itLast = rldwp.end();
  1116. while ( itCurrent != itLast )
  1117. {
  1118. CDynamicWizardPageWindow * pdwp = *itCurrent;
  1119. ATLASSERT( pdwp != NULL );
  1120. //
  1121. // Create the page.
  1122. //
  1123. DWORD sc = pdwp->ScCreatePage();
  1124. if ( sc != ERROR_SUCCESS )
  1125. {
  1126. CNTException nte(
  1127. sc,
  1128. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1129. NULL,
  1130. NULL,
  1131. FALSE
  1132. );
  1133. delete pdwp;
  1134. itCurrent = rldwp.erase( itCurrent );
  1135. continue;
  1136. } // if: error creating the page
  1137. //
  1138. // Add the page to the wizard.
  1139. // This adds it to the real page list as well.
  1140. //
  1141. BAddPage( pdwp );
  1142. //
  1143. // Remove the page from the temporary list.
  1144. //
  1145. itCurrent = rldwp.erase( itCurrent );
  1146. } // while: not at last page
  1147. } //*** CWizardWindow::CompleteAddingExtensionPages()
  1148. /////////////////////////////////////////////////////////////////////////////
  1149. //++
  1150. //
  1151. // CWizardWindow::RemoveAllExtensionPages
  1152. //
  1153. // Routine Description:
  1154. // Remove all extension pages from the wizard.
  1155. //
  1156. // Arguments:
  1157. // None.
  1158. //
  1159. // Return Value:
  1160. // None.
  1161. //
  1162. //--
  1163. /////////////////////////////////////////////////////////////////////////////
  1164. void CWizardWindow::RemoveAllExtensionPages( void )
  1165. {
  1166. //
  1167. // Delete the alternate extension wizard.
  1168. //
  1169. if ( PwizAlternate() != NULL )
  1170. {
  1171. reinterpret_cast< CAltExtWizard * >( PwizAlternate() )->DestroyAlternateWizard();
  1172. } // if: alternate wizard being displayed
  1173. //
  1174. // Remove the extension pages.
  1175. //
  1176. CExtensionWizardPageList lewp;
  1177. MovePtrListItems< CWizardPageWindow *, CExtensionWizardPageWindow * >( PlwpPages(), &lewp );
  1178. CExtensionWizardPageList::iterator itCurrent = lewp.begin();
  1179. CExtensionWizardPageList::iterator itLast = lewp.end();
  1180. for ( ; itCurrent != itLast ; itCurrent++ )
  1181. {
  1182. CExtensionWizardPageWindow * pewp = *itCurrent;
  1183. ATLASSERT( pewp != NULL );
  1184. if ( pewp->Hpage() != NULL )
  1185. {
  1186. RemovePage( pewp->Hpage() );
  1187. pewp->SetPageAdded( FALSE );
  1188. } // if: page already created
  1189. } // for: each page in the list
  1190. DeleteAllPtrListItems( &lewp );
  1191. } //*** CWizardWindow::RemoveAllExtensionPages()
  1192. //*************************************************************************//
  1193. ////////////////////////////////////////////////////////////////////////////
  1194. // class CAltExtWizardPreLauncherPage
  1195. /////////////////////////////////////////////////////////////////////////////
  1196. /////////////////////////////////////////////////////////////////////////////
  1197. //++
  1198. //
  1199. // CAltExtWizardPreLauncherPage::OnSetActive
  1200. //
  1201. // Routine Description:
  1202. // Handler for PSN_SETACTIVE.
  1203. // This page will be displayed if there are pages that are not of the
  1204. // same type as the wizard (e.g. non-Wizard97 pages in a Wizard97
  1205. // wizard).
  1206. //
  1207. // Arguments:
  1208. // None.
  1209. //
  1210. // Return Value:
  1211. // TRUE Page activated successfully.
  1212. // FALSE Error activating page.
  1213. //
  1214. //--
  1215. /////////////////////////////////////////////////////////////////////////////
  1216. BOOL CAltExtWizardPreLauncherPage::OnSetActive( void )
  1217. {
  1218. UINT idsReturn = ID_WIZNEXT;
  1219. CAltExtWizard * pwizAlt;
  1220. //
  1221. // When moving forward, create the alternate extension wizard and return
  1222. // TRUE so that the main wizard will wait here. The alternate wizard
  1223. // will cause the proper button to be pressed so we can do the proper
  1224. // thing when we're done.
  1225. //
  1226. // When moving backward, just return FALSE so we won't be displayed.
  1227. //
  1228. //
  1229. // Create the alternate wizard if moving forward.
  1230. //
  1231. if ( Pwiz()->BNextPressed() )
  1232. {
  1233. // We could have got here by pressing 'Back' on the alternate wizard,
  1234. // and then pressing 'Next' on the normal wizard. So, first check if
  1235. // the alternate wizard has already been created.
  1236. if ( Pwiz()->PwizAlternate() == NULL )
  1237. {
  1238. //
  1239. // Create the alternate extension wizard.
  1240. // It is expected that the wizard doesn't exist yet and that there are
  1241. // alternate extension pages to be displayed.
  1242. //
  1243. ATLASSERT( Pwiz()->PlewpAlternate()->size() > 0 );
  1244. pwizAlt = new CAltExtWizard;
  1245. ATLASSERT( pwizAlt != NULL );
  1246. if ( pwizAlt == NULL )
  1247. {
  1248. return FALSE;
  1249. } // if: error allocating the alternate wizard
  1250. Pwiz()->SetAlternateWizard( pwizAlt );
  1251. //
  1252. // Initialize the alternate extension wizard.
  1253. //
  1254. if ( pwizAlt->BInit( Pwiz() ) )
  1255. {
  1256. //
  1257. // Display the alternate extension wizard.
  1258. // The alternate extension wizard is being displayed as a modeless
  1259. // wizard so that when the user presses the Next button in the
  1260. // wizard and then presses the Back button on the next main wizard
  1261. // page we need the wizard to still exist.
  1262. //
  1263. pwizAlt->Create( GetActiveWindow() );
  1264. //
  1265. // Execute the alternate wizard message loop.
  1266. // This required so that tabs and accelerator keys will work.
  1267. //
  1268. pwizAlt->MessageLoop();
  1269. } // if: wizard initialized successfully
  1270. return TRUE;
  1271. } // if: alternate wizard does not exist
  1272. else
  1273. {
  1274. //
  1275. // Display the existing alternate wizard.
  1276. // Press the alternate wizard's Next button because it is waiting at
  1277. // the prefix page.
  1278. //
  1279. CAltExtWizard * pwizAlt = reinterpret_cast< CAltExtWizard * >( Pwiz()->PwizAlternate() );
  1280. pwizAlt->PressButton( PSBTN_NEXT );
  1281. pwizAlt->DisplayAlternateWizard();
  1282. //
  1283. // Execute the alternate wizard message loop.
  1284. // This required so that tabs and accelerator keys will work.
  1285. //
  1286. pwizAlt->MessageLoop();
  1287. return TRUE;
  1288. } // else: alternate wizard exists already
  1289. } // if: next button pressed
  1290. else
  1291. {
  1292. ATLASSERT( Pwiz()->BBackPressed() );
  1293. return FALSE;
  1294. } // else: back button pressed
  1295. } //*** CAltExtWizardPreLauncherPage::OnSetActive()
  1296. //*************************************************************************//
  1297. ////////////////////////////////////////////////////////////////////////////
  1298. // class CAltExtWizardPostLauncherPage
  1299. /////////////////////////////////////////////////////////////////////////////
  1300. /////////////////////////////////////////////////////////////////////////////
  1301. //++
  1302. //
  1303. // CAltExtWizardPostLauncherPage::OnSetActive
  1304. //
  1305. // Routine Description:
  1306. // Handler for PSN_SETACTIVE.
  1307. // This page will be displayed if there are pages that are not of the
  1308. // same type as the wizard (e.g. non-Wizard97 pages in a Wizard97
  1309. // wizard).
  1310. //
  1311. // Arguments:
  1312. // None.
  1313. //
  1314. // Return Value:
  1315. // TRUE Page activated successfully.
  1316. // FALSE Error activating page.
  1317. //
  1318. //--
  1319. /////////////////////////////////////////////////////////////////////////////
  1320. BOOL CAltExtWizardPostLauncherPage::OnSetActive( void )
  1321. {
  1322. //
  1323. // When moving forward just return FALSE so that we won't be displayed.
  1324. //
  1325. // When moving backward, display the alternate extension wizard and
  1326. // return TRUE so that we will be waiting for the alternate wizard to
  1327. // move us to the right place. Press the alternate wizard's Back button
  1328. // because it is waiting at the postfix page.
  1329. //
  1330. if ( Pwiz()->BNextPressed() )
  1331. {
  1332. return FALSE;
  1333. } // if: moving forward
  1334. else
  1335. {
  1336. ATLASSERT( Pwiz()->BBackPressed() );
  1337. //
  1338. // Display the alternate wizard.
  1339. //
  1340. CAltExtWizard * pwizAlt = reinterpret_cast< CAltExtWizard * >( Pwiz()->PwizAlternate() );
  1341. pwizAlt->PressButton( PSBTN_BACK );
  1342. pwizAlt->DisplayAlternateWizard();
  1343. //
  1344. // Execute the alternate wizard message loop.
  1345. // This required so that tabs and accelerator keys will work.
  1346. //
  1347. pwizAlt->MessageLoop();
  1348. return TRUE;
  1349. } // else: moving backward
  1350. } //*** CAltExtWizardPostLauncherPage::OnSetActive()
  1351. //*************************************************************************//
  1352. ////////////////////////////////////////////////////////////////////////////
  1353. // class CAltExtWizard
  1354. /////////////////////////////////////////////////////////////////////////////
  1355. /////////////////////////////////////////////////////////////////////////////
  1356. //++
  1357. //
  1358. // CAltExtWizard::BInit
  1359. //
  1360. // Routine Description:
  1361. // Initialize the wizard.
  1362. // This wizard is used to display extension pages that are different
  1363. // than the type of the main wizard, e.g. displaying non-Wizard97 pages
  1364. // in a Wizard97 wizard. This wizard will have a dummy prefix page
  1365. // and a dummy postfix page, which are only here to handle entering and
  1366. // exiting the wizard. This routine will add the prefix page, add the
  1367. // alternate extension pages from the main wizard, then add the postfix
  1368. // page.
  1369. //
  1370. // Arguments:
  1371. // pwizMain [IN] Main wizard.
  1372. //
  1373. // Return Value:
  1374. // TRUE Wizard initialized successfully.
  1375. // FALSE Error initializing wizard. Error already displayed.
  1376. //
  1377. //--
  1378. /////////////////////////////////////////////////////////////////////////////
  1379. BOOL CAltExtWizard::BInit( IN CWizardWindow * pwizMain )
  1380. {
  1381. ATLASSERT( pwizMain != NULL );
  1382. ATLASSERT( m_pwizMain == NULL );
  1383. BOOL bSuccess;
  1384. m_pwizMain = pwizMain;
  1385. //
  1386. // Setup the type of wizard to be the opposite of the main wizard.
  1387. //
  1388. m_psh.dwFlags &= ~PSH_PROPSHEETPAGE; // Using HPROPSHEETPAGEs.
  1389. if ( ! PwizMain()->BWizard97() )
  1390. {
  1391. // Don't add a watermark since we don't have a watermark bitmap.
  1392. m_psh.dwFlags &= ~(PSH_WIZARD
  1393. | PSH_WATERMARK
  1394. );
  1395. m_psh.dwFlags |= (PSH_WIZARD97
  1396. | PSH_HEADER
  1397. );
  1398. } // if: Wizard97 wizard
  1399. else
  1400. {
  1401. m_psh.dwFlags |= PSH_WIZARD;
  1402. m_psh.dwFlags &= ~(PSH_WIZARD97
  1403. | PSH_WATERMARK
  1404. | PSH_HEADER
  1405. );
  1406. } // else: non-Wizard97 wizard
  1407. // Loop to avoid goto's
  1408. do
  1409. {
  1410. //
  1411. // Get the first page in the main wizard.
  1412. //
  1413. HWND hwndChild = PwizMain()->GetWindow( GW_CHILD );
  1414. ATLASSERT( hwndChild != NULL );
  1415. //
  1416. // Get the current width and height of the child window.
  1417. //
  1418. CRect rect;
  1419. bSuccess = ::GetClientRect( hwndChild, &rect );
  1420. if ( ! bSuccess )
  1421. {
  1422. CNTException nte(
  1423. GetLastError(),
  1424. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1425. NULL,
  1426. NULL,
  1427. FALSE
  1428. );
  1429. nte.ReportError();
  1430. break;
  1431. } // if: error getting client rectangle
  1432. //
  1433. // Add a prefix page.
  1434. //
  1435. bSuccess = BAddPrefixPage( (WORD)rect.Width(), (WORD)rect.Height() );
  1436. if ( ! bSuccess )
  1437. {
  1438. break;
  1439. } // if: error adding the prefix page
  1440. //
  1441. // Add alternate pages from the main wizard to the wizard page list.
  1442. // They will be added to the wizard at sheet initialization time.
  1443. //
  1444. CExtensionWizardPageList::iterator itCurrent = PwizMain()->PlewpAlternate()->begin();
  1445. CExtensionWizardPageList::iterator itLast = PwizMain()->PlewpAlternate()->end();
  1446. while ( itCurrent != itLast )
  1447. {
  1448. CExtensionWizardPageWindow * pewp = *itCurrent;
  1449. ATLASSERT( pewp != NULL );
  1450. PlwpPages()->insert( PlwpPages()->end(), pewp );
  1451. PwizMain()->PlewpAlternate()->erase( itCurrent );
  1452. itCurrent = PwizMain()->PlewpAlternate()->begin();
  1453. } // for: each page in the list
  1454. //
  1455. // Add a postfix page.
  1456. //
  1457. bSuccess = BAddPostfixPage( (WORD) rect.Width(), (WORD) rect.Height() );
  1458. if ( ! bSuccess )
  1459. {
  1460. break;
  1461. } // if: error adding the postfix page
  1462. } while ( 0 );
  1463. //
  1464. // Call the base class.
  1465. //
  1466. if ( ! baseClass::BInit() )
  1467. {
  1468. return FALSE;
  1469. } // if: error initializing the base class
  1470. return bSuccess;
  1471. } //*** CAltExtWizard::BInit()
  1472. /////////////////////////////////////////////////////////////////////////////
  1473. //++
  1474. //
  1475. // CAltExtWizard::BAddPrefixPage
  1476. //
  1477. // Routine Description:
  1478. // Add a prefix page to the wizard.
  1479. //
  1480. // Arguments:
  1481. // cx [IN] Width of the page.
  1482. // cy [IN] Height of the page.
  1483. //
  1484. // Return Value:
  1485. // TRUE Page added successfully.
  1486. // FALSE Error adding the page. Error already displayed.
  1487. //
  1488. //--
  1489. /////////////////////////////////////////////////////////////////////////////
  1490. BOOL CAltExtWizard::BAddPrefixPage( IN WORD cx, IN WORD cy )
  1491. {
  1492. ATLASSERT( cx > 0 );
  1493. ATLASSERT( cy > 0 );
  1494. BOOL bSuccess;
  1495. DLGTEMPLATE * pdt = NULL;
  1496. CAltExtWizardPrefixPage * pwp = NULL;
  1497. // Loop to avoid goto's
  1498. do
  1499. {
  1500. //
  1501. // Create the dialog template for the page.
  1502. //
  1503. pdt = PdtCreateDummyPageDialogTemplate( cx, cy );
  1504. ATLASSERT( pdt != NULL );
  1505. if ( pdt == NULL )
  1506. {
  1507. bSuccess = FALSE;
  1508. break;
  1509. } // if: error creating the dialog template
  1510. //
  1511. // Adjust the page size so that we will be creating the same size
  1512. // wizard as the main wizard. Non-Wizard97 wizards add padding
  1513. // (7 DLUs on each side) whereas Wizard97 wizards add no padding
  1514. // to the first page, which is where we are expecting these
  1515. // dimensions to come from.
  1516. //
  1517. if ( BWizard97() )
  1518. {
  1519. pdt->cx += 7 * 2;
  1520. pdt->cy += 7 * 2;
  1521. } // if: Wizard97 wizard
  1522. else
  1523. {
  1524. pdt->cx -= 7 * 2;
  1525. pdt->cy -= 7 * 2;
  1526. } // else: non-Wizard97 wizard
  1527. //
  1528. // Allocate and initialize the page.
  1529. //
  1530. pwp = new CAltExtWizardPrefixPage( pdt );
  1531. ATLASSERT( pwp != NULL );
  1532. if ( pwp == NULL )
  1533. {
  1534. bSuccess = FALSE;
  1535. break;
  1536. } // if: error allocating the page
  1537. pdt = NULL;
  1538. bSuccess = pwp->BInit( this );
  1539. if ( ! bSuccess )
  1540. {
  1541. break;
  1542. } // if: error initializing the page
  1543. //
  1544. // Create the page.
  1545. //
  1546. DWORD sc = pwp->ScCreatePage();
  1547. if ( sc != ERROR_SUCCESS )
  1548. {
  1549. CNTException nte(
  1550. sc,
  1551. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1552. NULL,
  1553. NULL,
  1554. FALSE
  1555. );
  1556. nte.ReportError();
  1557. bSuccess = FALSE;
  1558. break;
  1559. } // if: error creating the page
  1560. //
  1561. // Add the page to the wizard.
  1562. //
  1563. bSuccess = BAddPage( pwp );
  1564. pwp = NULL;
  1565. } while ( 0 );
  1566. delete pwp;
  1567. delete pdt;
  1568. return bSuccess;
  1569. } //*** CAltExtWizard::BAddPrefixPage()
  1570. /////////////////////////////////////////////////////////////////////////////
  1571. //++
  1572. //
  1573. // CAltExtWizard::BAddPostfixPage
  1574. //
  1575. // Routine Description:
  1576. // Add a postfix page to the wizard.
  1577. //
  1578. // Arguments:
  1579. // cx [IN] Width of the page.
  1580. // cy [IN] Height of the page.
  1581. //
  1582. // Return Value:
  1583. // TRUE Page added successfully.
  1584. // FALSE Error adding the page. Error already displayed.
  1585. //
  1586. //--
  1587. /////////////////////////////////////////////////////////////////////////////
  1588. BOOL CAltExtWizard::BAddPostfixPage( IN WORD cx, IN WORD cy )
  1589. {
  1590. ATLASSERT( cx > 0 );
  1591. ATLASSERT( cy > 0 );
  1592. BOOL bSuccess;
  1593. DLGTEMPLATE * pdt = NULL;
  1594. CAltExtWizardPostfixPage * pwp = NULL;
  1595. // Loop to avoid goto's
  1596. do
  1597. {
  1598. //
  1599. // Create the dialog template for the page.
  1600. //
  1601. pdt = PdtCreateDummyPageDialogTemplate( cx, cy );
  1602. ATLASSERT( pdt != NULL );
  1603. if ( pdt == NULL )
  1604. {
  1605. bSuccess = FALSE;
  1606. break;
  1607. } // if: error creating the dialog template
  1608. //
  1609. // Adjust the page size so that we will be creating the same size
  1610. // wizard as the main wizard. Non-Wizard97 wizards add padding
  1611. // (7 DLUs on each side) whereas Wizard97 wizards add no padding
  1612. // to the first page, which is where we are expecting these
  1613. // dimensions to come from.
  1614. //
  1615. if ( BWizard97() )
  1616. {
  1617. pdt->cx += 7 * 2;
  1618. pdt->cy += 7 * 2;
  1619. } // if: Wizard97 wizard
  1620. else
  1621. {
  1622. pdt->cx -= 7 * 2;
  1623. pdt->cy -= 7 * 2;
  1624. } // else: non-Wizard97 wizard
  1625. //
  1626. // Allocate and initialize the page.
  1627. //
  1628. pwp = new CAltExtWizardPostfixPage( pdt );
  1629. ATLASSERT( pwp != NULL );
  1630. if ( pwp == NULL )
  1631. {
  1632. bSuccess = FALSE;
  1633. break;
  1634. } // if: error allocating the page
  1635. pdt = NULL;
  1636. bSuccess = pwp->BInit( this );
  1637. if ( ! bSuccess )
  1638. {
  1639. break;
  1640. } // if: error initializing the page
  1641. //
  1642. // Create the page.
  1643. //
  1644. DWORD sc = pwp->ScCreatePage();
  1645. if ( sc != ERROR_SUCCESS )
  1646. {
  1647. CNTException nte(
  1648. sc,
  1649. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  1650. NULL,
  1651. NULL,
  1652. FALSE
  1653. );
  1654. nte.ReportError();
  1655. bSuccess = FALSE;
  1656. break;
  1657. } // if: error creating the page
  1658. //
  1659. // Add the page to the page list. It will be added to the wizard
  1660. // at sheet initialization time.
  1661. //
  1662. PlwpPages()->insert( PlwpPages()->end(), pwp );
  1663. pwp = NULL;
  1664. bSuccess = TRUE;
  1665. } while ( 0 );
  1666. delete pwp;
  1667. delete pdt;
  1668. return bSuccess;
  1669. } //*** CAltExtWizard::BAddPostfixPage()
  1670. /////////////////////////////////////////////////////////////////////////////
  1671. //++
  1672. //
  1673. // CAltExtWizard::DisplayAlternateWizard
  1674. //
  1675. // Routine Description:
  1676. // Display the alternate wizard. This involved the following steps:
  1677. // -- Move the alternate wizard to the position of the main wizard.
  1678. // -- Show the alternate wizard.
  1679. // -- Hide the main wizard.
  1680. //
  1681. // Arguments:
  1682. // None.
  1683. //
  1684. // Return Value:
  1685. // None.
  1686. //
  1687. // Exceptions Thrown:
  1688. // None.
  1689. //
  1690. //--
  1691. /////////////////////////////////////////////////////////////////////////////
  1692. void CAltExtWizard::DisplayAlternateWizard( void )
  1693. {
  1694. //
  1695. // Move the alternate wizard to where the main wizard is positioned.
  1696. //
  1697. CRect rectMain;
  1698. CRect rectAlt;
  1699. CRect rectNew;
  1700. if ( PwizMain()->GetWindowRect( &rectMain ) )
  1701. {
  1702. if ( GetWindowRect( &rectAlt ) )
  1703. {
  1704. //ATLTRACE( _T("CAltExtWizard::DisplayAlternateWizard() - Main = (%d,%d) (%d,%d) Alt = (%d,%d) (%d,%d)\n"),
  1705. // rectMain.left, rectMain.right, rectMain.top, rectMain.bottom,
  1706. // rectAlt.left, rectAlt.right, rectAlt.top, rectAlt.bottom );
  1707. rectNew.left = rectMain.left;
  1708. rectNew.top = rectMain.top;
  1709. rectNew.right = rectNew.left + rectAlt.Width();
  1710. rectNew.bottom = rectNew.top + rectAlt.Height();
  1711. MoveWindow( &rectNew );
  1712. } // if: got the alternate wizard's window rectangle successfully
  1713. } // if: got the main wizard's window rectangle successfully
  1714. //
  1715. // Show the alternate wizard and hide the main wizard.
  1716. //
  1717. ShowWindow( SW_SHOW );
  1718. PwizMain()->ShowWindow( SW_HIDE );
  1719. SetActiveWindow();
  1720. PwizMain()->SetCurrentWizard( this );
  1721. } //*** CAltExtWizard::DisplayAlternateWizard()
  1722. /////////////////////////////////////////////////////////////////////////////
  1723. //++
  1724. //
  1725. // CAltExtWizard::DisplayMainWizard
  1726. //
  1727. // Routine Description:
  1728. // Display the main wizard. This involved the following steps:
  1729. // -- Move the main wizard to the position of the alternate wizard.
  1730. // -- Show the main wizard.
  1731. // -- Hide the alternate wizard.
  1732. //
  1733. // Arguments:
  1734. // None.
  1735. //
  1736. // Return Value:
  1737. // None.
  1738. //
  1739. // Exceptions Thrown:
  1740. // None.
  1741. //
  1742. //--
  1743. /////////////////////////////////////////////////////////////////////////////
  1744. void CAltExtWizard::DisplayMainWizard( void )
  1745. {
  1746. //
  1747. // Move the main wizard to where the alternate wizard is positioned.
  1748. //
  1749. CRect rectMain;
  1750. CRect rectAlt;
  1751. CRect rectNew;
  1752. if ( PwizMain()->GetWindowRect( &rectMain ) )
  1753. {
  1754. if ( GetWindowRect( &rectAlt ) )
  1755. {
  1756. //ATLTRACE( _T("CAltExtWizard::DisplayMainWizard() - Main = (%d,%d) (%d,%d) Alt = (%d,%d) (%d,%d)\n"),
  1757. // rectMain.left, rectMain.right, rectMain.top, rectMain.bottom,
  1758. // rectAlt.left, rectAlt.right, rectAlt.top, rectAlt.bottom );
  1759. rectNew.left = rectAlt.left;
  1760. rectNew.top = rectAlt.top;
  1761. rectNew.right = rectNew.left + rectMain.Width();
  1762. rectNew.bottom = rectNew.top + rectMain.Height();
  1763. PwizMain()->MoveWindow( &rectNew );
  1764. } // if: got the alternate wizard's window rectangle successfully
  1765. } // if: got the main wizard's window rectangle successfully
  1766. //
  1767. // Show the main wizard and hide the alternate wizard.
  1768. //
  1769. PwizMain()->ShowWindow( SW_SHOW );
  1770. PwizMain()->SetActiveWindow();
  1771. ShowWindow( SW_HIDE );
  1772. PwizMain()->SetCurrentWizard( PwizMain() );
  1773. } //*** CAltExtWizard::DisplayMainWizard()
  1774. /////////////////////////////////////////////////////////////////////////////
  1775. //++
  1776. //
  1777. // CAltExtWizard::DestroyAlternateWizard
  1778. //
  1779. // Routine Description:
  1780. // Destroy the alternate extension wizard.
  1781. //
  1782. // Arguments:
  1783. // None.
  1784. //
  1785. // Return Value:
  1786. // None.
  1787. //
  1788. //--
  1789. /////////////////////////////////////////////////////////////////////////////
  1790. void CAltExtWizard::DestroyAlternateWizard( void )
  1791. {
  1792. ATLASSERT( m_hWnd != NULL );
  1793. //
  1794. // Press the Cancel button on the alternate wizard.
  1795. //
  1796. PressButton( PSBTN_CANCEL );
  1797. //
  1798. // Destroy the wizard.
  1799. //
  1800. DestroyWindow();
  1801. } //*** CAltExtWizard::DestroyAlternateWizard()
  1802. /////////////////////////////////////////////////////////////////////////////
  1803. //++
  1804. //
  1805. // CAltExtWizard::MessageLoop
  1806. //
  1807. // Routine Description:
  1808. // Message loop for this wizard as a modeless wizard.
  1809. //
  1810. // Arguments:
  1811. // None.
  1812. //
  1813. // Return Value:
  1814. // None.
  1815. //
  1816. //--
  1817. /////////////////////////////////////////////////////////////////////////////
  1818. void CAltExtWizard::MessageLoop( void )
  1819. {
  1820. MSG msg;
  1821. m_bExitMsgLoop = FALSE;
  1822. while ( (GetActivePage() != NULL)
  1823. && GetMessage( &msg, NULL, 0, 0 ) )
  1824. {
  1825. //
  1826. // Ask the wizard if it wants to process it. If not, go ahead
  1827. // and translate it and dispatch it.
  1828. //
  1829. if ( ! IsDialogMessage( &msg ) )
  1830. {
  1831. TranslateMessage( &msg );
  1832. DispatchMessage( &msg );
  1833. } // if: not a property sheet dialog message
  1834. //
  1835. // If the dialog is done, exit this loop.
  1836. //
  1837. if ( BExitMessageLoop() )
  1838. {
  1839. DisplayMainWizard();
  1840. PwizMain()->PostMessage( PSM_PRESSBUTTON, NExitButton(), 0 );
  1841. break;
  1842. } // if: exiting the wizard
  1843. } // while: active page and not quitting
  1844. } //*** CAltExtWizard::MessageLoop()
  1845. //*************************************************************************//
  1846. ////////////////////////////////////////////////////////////////////////////
  1847. // class CAltExtWizardPrefixPage
  1848. /////////////////////////////////////////////////////////////////////////////
  1849. /////////////////////////////////////////////////////////////////////////////
  1850. //++
  1851. //
  1852. // CAltExtWizardPrefixPage::OnSetActive
  1853. //
  1854. // Routine Description:
  1855. // Handler for PSN_SETACTIVE.
  1856. // This page manages the transfer of control between the main wizard
  1857. // and the first page of the alternate wizard.
  1858. //
  1859. // Arguments:
  1860. // None.
  1861. //
  1862. // Return Value:
  1863. // TRUE Page activated successfully.
  1864. // FALSE Error activating page.
  1865. //
  1866. //--
  1867. /////////////////////////////////////////////////////////////////////////////
  1868. BOOL CAltExtWizardPrefixPage::OnSetActive( void )
  1869. {
  1870. //
  1871. // When moving forward, display the alternate wizard and return FALSE
  1872. // so that this page won't be displayed.
  1873. //
  1874. // When moving backward, display the main wizard and return TRUE so that
  1875. // we'll be waiting for the main wizard to do something with us.
  1876. //
  1877. if ( Pwiz()->BBackPressed() )
  1878. {
  1879. PwizThis()->ExitMessageLoop( PSBTN_BACK );
  1880. return TRUE;
  1881. } // if: moving backward
  1882. else
  1883. {
  1884. PwizThis()->DisplayAlternateWizard();
  1885. return FALSE;
  1886. } // if: moving forward
  1887. } //*** CAltExtWizardPrefixPage::OnSetActive()
  1888. //*************************************************************************//
  1889. ////////////////////////////////////////////////////////////////////////////
  1890. // class CAltExtWizardPostfixPage
  1891. /////////////////////////////////////////////////////////////////////////////
  1892. /////////////////////////////////////////////////////////////////////////////
  1893. //++
  1894. //
  1895. // CAltExtWizardPostfixPage::OnSetActive
  1896. //
  1897. // Routine Description:
  1898. // Handler for PSN_SETACTIVE.
  1899. // This page manages the transfer of control between the main wizard
  1900. // and the last page of the alternate wizard.
  1901. //
  1902. // Arguments:
  1903. // None.
  1904. //
  1905. // Return Value:
  1906. // TRUE Page activated successfully.
  1907. // FALSE Error activating page.
  1908. //
  1909. //--
  1910. /////////////////////////////////////////////////////////////////////////////
  1911. BOOL CAltExtWizardPostfixPage::OnSetActive( void )
  1912. {
  1913. //
  1914. // When moving forward display the main wizard and return TRUE so that
  1915. // we'll be waiting for the main wizard to tell us what to do next.
  1916. //
  1917. // This routine should never be called when moving backward.
  1918. //
  1919. ATLASSERT( Pwiz()->BNextPressed() );
  1920. //
  1921. // Display the main wizard.
  1922. //
  1923. PwizThis()->ExitMessageLoop( PSBTN_NEXT );
  1924. return TRUE;
  1925. } //*** CAltExtWizardPostfixPage::OnSetActive()
  1926. //*************************************************************************//
  1927. /////////////////////////////////////////////////////////////////////////////
  1928. // Global Functions
  1929. /////////////////////////////////////////////////////////////////////////////
  1930. /////////////////////////////////////////////////////////////////////////////
  1931. //++
  1932. //
  1933. // PdtCreateDummyPageDialogTemplate
  1934. //
  1935. // Routine Description:
  1936. // Create a dialog template in memory for use on a dummy page.
  1937. //
  1938. // Arguments:
  1939. // cx [IN] Width of the dialog in pixels.
  1940. // cy [IN] Height of the dialog in pixels.
  1941. //
  1942. // Return Value:
  1943. // ppDlgTemplate Dialog template.
  1944. //
  1945. //--
  1946. /////////////////////////////////////////////////////////////////////////////
  1947. DLGTEMPLATE * PdtCreateDummyPageDialogTemplate( IN WORD cx, IN WORD cy )
  1948. {
  1949. static const WCHAR s_szFontName[] = L"MS Shell Dlg";
  1950. struct FULLDLGTEMPLATE : public DLGTEMPLATE
  1951. {
  1952. WORD nMenuID;
  1953. WORD nClassID;
  1954. WORD nTitle;
  1955. WORD nFontSize;
  1956. WCHAR szFontName[sizeof(s_szFontName) / sizeof(WCHAR)];
  1957. };
  1958. FULLDLGTEMPLATE * pDlgTemplate = new FULLDLGTEMPLATE;
  1959. ATLASSERT( pDlgTemplate != NULL );
  1960. if ( pDlgTemplate != NULL )
  1961. {
  1962. pDlgTemplate->style = WS_CHILD | WS_DISABLED | WS_SYSMENU | DS_SETFONT;
  1963. pDlgTemplate->dwExtendedStyle = 0;
  1964. pDlgTemplate->cdit = 0;
  1965. pDlgTemplate->x = 0;
  1966. pDlgTemplate->y = 0;
  1967. pDlgTemplate->cx = ((cx * 2) + (3 / 2)) / 3; // round off
  1968. pDlgTemplate->cy = ((cy * 8) + (13 / 2)) / 13; // round off
  1969. pDlgTemplate->nMenuID = 0;
  1970. pDlgTemplate->nClassID = 0;
  1971. pDlgTemplate->nTitle = 0;
  1972. pDlgTemplate->nFontSize = 8;
  1973. lstrcpyW( pDlgTemplate->szFontName, s_szFontName );
  1974. } // if: dialog template allocated successfully
  1975. return pDlgTemplate;
  1976. } //*** PdtCreateDummyPageDialogTemplate()