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.

1743 lines
49 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // AtlExtDll.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the Cluster Administrator extension classes.
  10. //
  11. // Author:
  12. // David Potter (davidp) May 31, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. // This file is intended to be included in a stub file which includes
  18. // the ATL header files and defines _Module. This allos _Module to be
  19. // defined as an instance of some application-specific class.
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. #include <algorithm>
  23. #include <CluAdmEx.h>
  24. #include "CluAdmExHostSvr.h"
  25. #include "AtlExtDll.h"
  26. #include "AdmCommonRes.h"
  27. #include "AtlExtMenu.h"
  28. //#include "TraceTag.h"
  29. #include "ExcOper.h"
  30. #include "ClusObj.h"
  31. #include "AtlBaseSheet.h"
  32. #include "AtlBasePropSheet.h"
  33. #include "AtlBaseWiz.h"
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. /////////////////////////////////////////////////////////////////////////////
  40. // Global Variables
  41. /////////////////////////////////////////////////////////////////////////////
  42. #if DBG
  43. //CTraceTag g_tagExtDll(_T("UI"), _T("EXTENSION DLL"), 0);
  44. //CTraceTag g_tagExtDllRef(_T("UI"), _T("EXTENSION DLL References"), 0);
  45. #endif // DBG
  46. /////////////////////////////////////////////////////////////////////////////
  47. // class CCluAdmExtensions
  48. /////////////////////////////////////////////////////////////////////////////
  49. /////////////////////////////////////////////////////////////////////////////
  50. //++
  51. //
  52. // CCluAdmExtensions::Init
  53. //
  54. // Routine Description:
  55. // Common initializer for all interfaces.
  56. //
  57. // Arguments:
  58. // rlstrExtensions [IN] List of extension CLSID strings.
  59. // pco [IN OUT] Cluster object to be administered.
  60. // hfont [IN] Font for dialog text.
  61. // hicon [IN] Icon for upper left corner.
  62. //
  63. // Return Value:
  64. // None.
  65. //
  66. // Exceptions Thrown:
  67. // Any exceptions thrown by new.
  68. //
  69. //--
  70. /////////////////////////////////////////////////////////////////////////////
  71. void CCluAdmExtensions::Init(
  72. IN const CStringList & rlstrExtensions,
  73. IN OUT CClusterObject * pco,
  74. IN HFONT hfont,
  75. IN HICON hicon
  76. )
  77. {
  78. ATLASSERT( rlstrExtensions.size() > 0 );
  79. ATLASSERT( pco != NULL );
  80. CWaitCursor wc;
  81. UnloadExtensions();
  82. //
  83. // Save parameters.
  84. //
  85. m_plstrExtensions = &rlstrExtensions;
  86. m_pco = pco;
  87. m_hfont = hfont;
  88. m_hicon = hicon;
  89. //
  90. // Allocate a new Data Object.
  91. //
  92. m_pdoData = new CComObject< CCluAdmExDataObject >;
  93. if ( m_pdoData == NULL )
  94. {
  95. goto MemoryError;
  96. } // if: error allocating memory
  97. m_pdoData->AddRef();
  98. // Construct the Data Object.
  99. Pdo()->Init( pco, GetUserDefaultLCID(), hfont, hicon );
  100. // Allocate the extension list.
  101. m_plextdll = new CCluAdmExDllList;
  102. if ( m_plextdll == NULL )
  103. {
  104. goto MemoryError;
  105. } // if: error allocating memory
  106. ATLASSERT( Plextdll() != NULL );
  107. //
  108. // Loop through the extensions and load each one.
  109. //
  110. {
  111. CComCluAdmExDll * pextdll = NULL;
  112. CStringList::iterator itCurrent = rlstrExtensions.begin();
  113. CStringList::iterator itLast = rlstrExtensions.end();
  114. CCluAdmExDllList::iterator itDll;
  115. for ( ; itCurrent != itLast ; itCurrent++ )
  116. {
  117. //
  118. // Allocate an extension DLL object and add it to the list.
  119. //
  120. pextdll = new CComCluAdmExDll;
  121. if ( pextdll == NULL )
  122. {
  123. goto MemoryError;
  124. } // if: error allocating memory
  125. pextdll->AddRef();
  126. itDll = Plextdll()->insert( Plextdll()->end(), pextdll );
  127. try
  128. {
  129. pextdll->Init( *itCurrent, this );
  130. } // try
  131. catch ( CException * pe )
  132. {
  133. pe->ReportError();
  134. pe->Delete();
  135. ATLASSERT( itDll != Plextdll()->end() );
  136. Plextdll()->erase( itDll );
  137. delete pextdll;
  138. } // catch: CException
  139. } // while: more items in the list
  140. } // Loop through the extensions and load each one
  141. Cleanup:
  142. return;
  143. MemoryError:
  144. CNTException nte(
  145. E_OUTOFMEMORY,
  146. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  147. NULL, // pszOperArg1
  148. NULL, // pszOperArg2
  149. FALSE // bAutoDelete
  150. );
  151. nte.ReportError();
  152. goto Cleanup;
  153. } //*** CCluAdmExtensions::Init()
  154. /////////////////////////////////////////////////////////////////////////////
  155. //++
  156. //
  157. // CCluAdmExtensions::UnloadExtensions
  158. //
  159. // Routine Description:
  160. // Unload the extension DLL.
  161. //
  162. // Arguments:
  163. // None.
  164. //
  165. // Return Value:
  166. // None.
  167. //
  168. //--
  169. /////////////////////////////////////////////////////////////////////////////
  170. void CCluAdmExtensions::UnloadExtensions( void )
  171. {
  172. //
  173. // Delete all the extension DLL objects.
  174. //
  175. if ( Plextdll() != NULL )
  176. {
  177. CCluAdmExDllList::iterator itCurrent = Plextdll()->begin();
  178. CCluAdmExDllList::iterator itLast = Plextdll()->end();
  179. CComCluAdmExDll * pextdll;
  180. for ( ; itCurrent != itLast ; itCurrent++ )
  181. {
  182. pextdll = *itCurrent;
  183. pextdll->AddRef(); // See comment below.
  184. pextdll->UnloadExtension();
  185. if ( pextdll->m_dwRef != 2 )
  186. {
  187. Trace( g_tagError, _T("CCluAdmExtensions::UnloadExtensions() - Extension DLL has ref count = %d"), pextdll->m_dwRef );
  188. } // if: not last reference
  189. // We added a reference above. Combined with the reference that
  190. // was added when the object was created, we typically will need
  191. // to release two references. However, due to bogus code
  192. // generated by earlier versions of the custom AppWizard where the
  193. // extension was releasing the interface but not zeroing out its
  194. // pointer in the error case, we may not need to release the
  195. // second reference.
  196. if ( pextdll->Release() != 0 )
  197. {
  198. pextdll->Release();
  199. } // if: more references to release
  200. } // while: more items in the list
  201. delete m_plextdll;
  202. m_plextdll = NULL;
  203. } // if: there is a list of extensions
  204. if ( m_pdoData != NULL )
  205. {
  206. if ( m_pdoData->m_dwRef != 1 )
  207. {
  208. Trace( g_tagError, _T("CCluAdmExtensions::UnloadExtensions() - Data Object has ref count = %d"), m_pdoData->m_dwRef );
  209. } // if: not last reference
  210. m_pdoData->Release();
  211. m_pdoData = NULL;
  212. } // if: data object allocated
  213. m_pco = NULL;
  214. m_hfont = NULL;
  215. m_hicon = NULL;
  216. //
  217. // Delete all menu items.
  218. //
  219. if ( PlMenuItems() != NULL )
  220. {
  221. CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin();
  222. CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end();
  223. CCluAdmExMenuItem * pemi;
  224. for ( ; itCurrent != itLast ; itCurrent++ )
  225. {
  226. pemi = *itCurrent;
  227. delete pemi;
  228. } // while: more items in the list
  229. delete m_plMenuItems;
  230. m_plMenuItems = NULL;
  231. } // if: there is a list of menu items
  232. } //*** CCluAdmExtensions::UnloadExtensions()
  233. /////////////////////////////////////////////////////////////////////////////
  234. //++
  235. //
  236. // CCluAdmExtensions::PwpPageFromHpage
  237. //
  238. // Routine Description:
  239. // Get the wizard page pointer from an HPROPSHEETPAGE.
  240. //
  241. // Arguments:
  242. // hpage [IN] Page handle.
  243. //
  244. // Return Value:
  245. // pwp Pointer to wizard page object.
  246. // NULL Page not found.
  247. //
  248. // Exceptions Thrown:
  249. // None.
  250. //
  251. //--
  252. /////////////////////////////////////////////////////////////////////////////
  253. CWizardPageWindow * CCluAdmExtensions::PwpPageFromHpage( IN HPROPSHEETPAGE hpage )
  254. {
  255. ATLASSERT( hpage != NULL );
  256. //
  257. // Get a pointer to the wizard object so we can traverse the page list.
  258. //
  259. CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() );
  260. ATLASSERT( pwiz != NULL );
  261. //
  262. // Loop through each page looking for an extension page whose
  263. // page handle matches the one specified.
  264. //
  265. CWizardPageList::iterator itCurrent = pwiz->PlwpPages()->begin();
  266. CWizardPageList::iterator itLast = pwiz->PlwpPages()->end();
  267. for ( ; itCurrent != itLast ; itCurrent++ )
  268. {
  269. CCluAdmExWizPage * pewp = dynamic_cast< CCluAdmExWizPage * >( *itCurrent );
  270. if ( pewp != NULL )
  271. {
  272. if ( pewp->Hpage() == hpage )
  273. {
  274. return pewp;
  275. } // if: found the matching page
  276. } // if: found an extension page
  277. } // for: each page in the list
  278. //
  279. // Look at the alternate wizard if there is one.
  280. //
  281. pwiz = pwiz->PwizAlternate();
  282. if ( pwiz != NULL )
  283. {
  284. itCurrent = pwiz->PlwpPages()->begin();
  285. itLast = pwiz->PlwpPages()->end();
  286. for ( ; itCurrent != itLast ; itCurrent++ )
  287. {
  288. CCluAdmExWizPage * pewp = dynamic_cast< CCluAdmExWizPage * >( *itCurrent );
  289. if ( pewp != NULL )
  290. {
  291. if ( pewp->Hpage() == hpage )
  292. {
  293. return pewp;
  294. } // if: found the matching page
  295. } // if: found an extension page
  296. } // for: each page in the list
  297. } // if: alternate wizard exists
  298. return NULL;
  299. } //*** CCluAdmExtensions::PwpPageFromHpage()
  300. /////////////////////////////////////////////////////////////////////////////
  301. //++
  302. //
  303. // CCluAdmExtensions::CreatePropertySheetPages
  304. //
  305. // Routine Description:
  306. // Add pages to a property sheet.
  307. //
  308. // Arguments:
  309. // psht [IN OUT] Property sheet to which pages are to be added.
  310. // rlstrExtensions [IN] List of extension CLSID strings.
  311. // pco [IN OUT] Cluster object to be administered.
  312. // hfont [IN] Font for dialog text.
  313. // hicon [IN] Icon for upper left corner.
  314. //
  315. // Return Value:
  316. // None.
  317. //
  318. // Exceptions Thrown:
  319. // Any exceptions thrown by CCluAdmExDll::AddPages().
  320. //
  321. //--
  322. /////////////////////////////////////////////////////////////////////////////
  323. void CCluAdmExtensions::CreatePropertySheetPages(
  324. IN OUT CBasePropertySheetWindow * psht,
  325. IN const CStringList & rlstrExtensions,
  326. IN OUT CClusterObject * pco,
  327. IN HFONT hfont,
  328. IN HICON hicon
  329. )
  330. {
  331. ATLASSERT( psht != NULL );
  332. ATLASSERT( pco != NULL );
  333. m_psht = psht;
  334. //
  335. // Initialize for all extensions.
  336. //
  337. Init( rlstrExtensions, pco, hfont, hicon );
  338. ATLASSERT( Plextdll() != NULL );
  339. //
  340. // Let each extension create property pages.
  341. //
  342. CCluAdmExDllList::iterator itCurrent = Plextdll()->begin();
  343. CCluAdmExDllList::iterator itLast = Plextdll()->end();
  344. CComCluAdmExDll * pextdll;
  345. for ( ; itCurrent != itLast ; itCurrent++ )
  346. {
  347. pextdll = *itCurrent;
  348. try
  349. {
  350. pextdll->CreatePropertySheetPages();
  351. } // try
  352. catch ( CException * pe )
  353. {
  354. pe->ReportError();
  355. pe->Delete();
  356. } // catch: CException
  357. } // while: more items in the list
  358. } //*** CCluAdmExtensions::CreatePropertySheetPages()
  359. /////////////////////////////////////////////////////////////////////////////
  360. //++
  361. //
  362. // CCluAdmExtensions::CreateWizardPages
  363. //
  364. // Routine Description:
  365. // Add pages to a wizard.
  366. //
  367. // Arguments:
  368. // psht [IN OUT] Property sheet to which pages are to be added.
  369. // rlstrExtensions [IN] List of extension CLSID strings.
  370. // pco [IN OUT] Cluster object to be administered.
  371. // hfont [IN] Font for dialog text.
  372. // hicon [IN] Icon for upper left corner.
  373. //
  374. // Return Value:
  375. // None.
  376. //
  377. // Exceptions Thrown:
  378. // Any exceptions thrown by CCluAdmExDll::AddPages().
  379. //
  380. //--
  381. /////////////////////////////////////////////////////////////////////////////
  382. void CCluAdmExtensions::CreateWizardPages(
  383. IN OUT CWizardWindow * psht,
  384. IN const CStringList & rlstrExtensions,
  385. IN OUT CClusterObject * pco,
  386. IN HFONT hfont,
  387. IN HICON hicon
  388. )
  389. {
  390. ATLASSERT( psht != NULL );
  391. ATLASSERT( pco != NULL );
  392. m_psht = psht;
  393. //
  394. // Initialize for all extensions.
  395. //
  396. Init( rlstrExtensions, pco, hfont, hicon );
  397. ATLASSERT( Plextdll() != NULL );
  398. //
  399. // Let each extension create wizard pages.
  400. //
  401. CCluAdmExDllList::iterator itCurrent = Plextdll()->begin();
  402. CCluAdmExDllList::iterator itLast = Plextdll()->end();
  403. CComCluAdmExDll * pextdll;
  404. for ( ; itCurrent != itLast ; itCurrent++ )
  405. {
  406. pextdll = *itCurrent;
  407. try
  408. {
  409. pextdll->CreateWizardPages();
  410. } // try
  411. catch ( CException * pe )
  412. {
  413. pe->ReportError();
  414. pe->Delete();
  415. } // catch: CException
  416. } // while: more items in the list
  417. } //*** CCluAdmExtensions::CreateWizardPages()
  418. /////////////////////////////////////////////////////////////////////////////
  419. //++
  420. //
  421. // CCluAdmExtensions::CreateWizard97Pages
  422. //
  423. // Routine Description:
  424. // Add pages to a Wizard 97 wizard.
  425. //
  426. // Arguments:
  427. // psht [IN OUT] Property sheet to which pages are to be added.
  428. // rlstrExtensions [IN] List of extension CLSID strings.
  429. // pco [IN OUT] Cluster object to be administered.
  430. // hfont [IN] Font for dialog text.
  431. // hicon [IN] Icon for upper left corner.
  432. //
  433. // Return Value:
  434. // None.
  435. //
  436. // Exceptions Thrown:
  437. // Any exceptions thrown by CCluAdmExDll::AddPages().
  438. //
  439. //--
  440. /////////////////////////////////////////////////////////////////////////////
  441. void CCluAdmExtensions::CreateWizard97Pages(
  442. IN OUT CWizardWindow * psht,
  443. IN const CStringList & rlstrExtensions,
  444. IN OUT CClusterObject * pco,
  445. IN HFONT hfont,
  446. IN HICON hicon
  447. )
  448. {
  449. ATLASSERT( psht != NULL );
  450. ATLASSERT( pco != NULL );
  451. m_psht = psht;
  452. //
  453. // Initialize for all extensions.
  454. //
  455. Init( rlstrExtensions, pco, hfont, hicon );
  456. ATLASSERT( Plextdll() != NULL );
  457. //
  458. // Let each extension create wizard pages.
  459. //
  460. CCluAdmExDllList::iterator itCurrent = Plextdll()->begin();
  461. CCluAdmExDllList::iterator itLast = Plextdll()->end();
  462. CComCluAdmExDll * pextdll;
  463. for ( ; itCurrent != itLast ; itCurrent++ )
  464. {
  465. pextdll = *itCurrent;
  466. try
  467. {
  468. pextdll->CreateWizard97Pages();
  469. } // try
  470. catch ( CException * pe )
  471. {
  472. pe->ReportError();
  473. pe->Delete();
  474. } // catch: CException
  475. } // while: more items in the list
  476. } //*** CCluAdmExtensions::CreateWizard97Pages()
  477. /////////////////////////////////////////////////////////////////////////////
  478. //++
  479. //
  480. // CCluAdmExtensions::AddContextMenuItems
  481. //
  482. // Routine Description:
  483. // Query the extension DLL for new menu items to be added to the context
  484. // menu.
  485. //
  486. // Arguments:
  487. // pmenu [IN OUT] Menu to which items are to be added.
  488. // rlstrExtensions [IN] List of extension CLSID strings.
  489. // pco [IN OUT] Cluster object to be administered.
  490. //
  491. // Return Value:
  492. // None.
  493. //
  494. // Exceptions Thrown:
  495. // Any exceptions thrown by CCluAdmExDll::AddContextMenuItems() or
  496. // CExtMenuItemList::new().
  497. //
  498. //--
  499. /////////////////////////////////////////////////////////////////////////////
  500. void CCluAdmExtensions::AddContextMenuItems(
  501. IN OUT CMenu * pmenu,
  502. IN const CStringList & rlstrExtensions,
  503. IN OUT CClusterObject * pco
  504. )
  505. {
  506. ATLASSERT( m_pmenu == NULL );
  507. ATLASSERT( pmenu != NULL );
  508. //
  509. // Initialize for all extensions.
  510. //
  511. Init( rlstrExtensions, pco, NULL, NULL );
  512. ATLASSERT( Plextdll() != NULL );
  513. m_pmenu = pmenu;
  514. m_nFirstCommandID = CAEXT_MENU_FIRST_ID;
  515. m_nNextCommandID = m_nFirstCommandID;
  516. m_nFirstMenuID = 0;
  517. m_nNextMenuID = m_nFirstMenuID;
  518. //
  519. // Create the list of menu items.
  520. //
  521. ATLASSERT( m_plMenuItems == NULL );
  522. m_plMenuItems = new CCluAdmExMenuItemList;
  523. if ( m_plMenuItems == NULL )
  524. {
  525. CNTException nte(
  526. E_OUTOFMEMORY,
  527. ADMC_IDS_INIT_EXT_PAGES_ERROR,
  528. NULL, // pszOperArg1
  529. NULL, // pszOperArg2
  530. FALSE // bAutoDelete
  531. );
  532. nte.ReportError();
  533. } // if: error allocating memory
  534. else
  535. {
  536. CCluAdmExDllList::iterator itCurrent = Plextdll()->begin();
  537. CCluAdmExDllList::iterator itLast = Plextdll()->end();
  538. CComCluAdmExDll * pextdll;
  539. for ( ; itCurrent != itLast ; itCurrent++ )
  540. {
  541. pextdll = *itCurrent;
  542. try
  543. {
  544. pextdll->AddContextMenuItems();
  545. } // try
  546. catch ( CException * pe )
  547. {
  548. pe->ReportError();
  549. pe->Delete();
  550. } // catch: CException
  551. } // while: more items in the list
  552. } // else: memory allocated successfully
  553. } //*** CCluAdmExtensions::AddContextMenuItems()
  554. /////////////////////////////////////////////////////////////////////////////
  555. //++
  556. //
  557. // CCluAdmExtensions::BExecuteContextMenuItem
  558. //
  559. // Routine Description:
  560. // Execute a command associated with a menu item added to a context menu
  561. // by the extension DLL.
  562. //
  563. // Arguments:
  564. // nCommandID [IN] Command ID for the menu item chosen by the user.
  565. //
  566. // Return Value:
  567. // TRUE Context menu item was executed.
  568. // FALSE Context menu item was not executed.
  569. //
  570. // Exceptions Thrown:
  571. // Any exceptions thrown by CExceptionDll::BExecuteContextMenuItem().
  572. //
  573. //--
  574. /////////////////////////////////////////////////////////////////////////////
  575. BOOL CCluAdmExtensions::BExecuteContextMenuItem( IN ULONG nCommandID )
  576. {
  577. BOOL bHandled = FALSE;
  578. HRESULT hr;
  579. CCluAdmExMenuItem * pemi;
  580. //
  581. // Find the item in our list.
  582. //
  583. pemi = PemiFromCommandID( nCommandID );
  584. if ( pemi != NULL )
  585. {
  586. ATLASSERT( pemi->PiCommand() != NULL );
  587. Pdo()->AddRef();
  588. hr = pemi->PiCommand()->InvokeCommand( pemi->NExtCommandID(), Pdo()->GetUnknown() );
  589. if ( hr == NOERROR )
  590. {
  591. bHandled = TRUE;
  592. } // if: no error occurred
  593. } // if: found an item for the command ID
  594. return bHandled;
  595. } //*** CCluAdmExtensions::BExecuteContextMenuItem()
  596. /////////////////////////////////////////////////////////////////////////////
  597. //++
  598. //
  599. // CCluAdmExtensions::BGetCommandString
  600. //
  601. // Routine Description:
  602. // Get a command string from a menu ID.
  603. //
  604. // Arguments:
  605. // nCommandID [IN] Command ID for the menu item.
  606. // rstrMessage [OUT] String in which to return the message.
  607. //
  608. // Return Value:
  609. // TRUE String is being returned.
  610. // FALSE No string is being returned.
  611. //
  612. // Exceptions Thrown:
  613. // Any exceptions thrown by CCluAdmExDll::BGetCommandString().
  614. //
  615. //--
  616. /////////////////////////////////////////////////////////////////////////////
  617. BOOL CCluAdmExtensions::BGetCommandString(
  618. IN ULONG nCommandID,
  619. OUT CString & rstrMessage
  620. )
  621. {
  622. BOOL bHandled = FALSE;
  623. CCluAdmExMenuItem * pemi;
  624. //
  625. // Find the item in our list.
  626. //
  627. pemi = PemiFromCommandID( nCommandID );
  628. if ( pemi != NULL )
  629. {
  630. rstrMessage = pemi->StrStatusBarText();
  631. bHandled = TRUE;
  632. } // if: found an item for the command ID
  633. return bHandled;
  634. } //*** CCluAdmExtensions::BGetCommandString()
  635. /////////////////////////////////////////////////////////////////////////////
  636. //++
  637. //
  638. // CCluAdmExtensions::OnUpdateCommand
  639. //
  640. // Routine Description:
  641. // Determines whether extension DLL menu items should be enabled or not.
  642. //
  643. // Arguments:
  644. // pCmdUI [IN OUT] Command routing object.
  645. //
  646. // Return Value:
  647. // None.
  648. //
  649. // Exceptions Thrown:
  650. // Any exceptions thrown by CCluAdmExDll::BOnUpdateCommand().
  651. //
  652. //--
  653. /////////////////////////////////////////////////////////////////////////////
  654. #if 0
  655. void CCluAdmExtensions::OnUpdateCommand( CCmdUI * pCmdUI )
  656. {
  657. CCluAdmExMenuItem * pemi;
  658. ATLASSERT( Plextdll() != NULL );
  659. //
  660. // Find the item in our list.
  661. //
  662. // Trace( g_tagExtDll, _T("OnUpdateCommand() - ID = %d"), pCmdUI->m_nID );
  663. pemi = PemiFromCommandID( pCmdUI->m_nID );
  664. if ( pemi != NULL )
  665. {
  666. // Trace( g_tagExtDll, _T("OnUpdateCommand() - Found a match with '%s' ExtID = %d"), pemi->StrName(), pemi->NExtCommandID() );
  667. pCmdUI->Enable();
  668. } // if: found an item for the command ID
  669. } //*** CCluAdmExtensions::OnUpdateCommand()
  670. #endif
  671. /////////////////////////////////////////////////////////////////////////////
  672. //++
  673. //
  674. // CCluAdmExtensions::OnCmdMsg
  675. //
  676. // Routine Description:
  677. // Processes command messages. Attempts to pass them on to a selected
  678. // item first.
  679. //
  680. // Arguments:
  681. // nID [IN] Command ID.
  682. // nCode [IN] Notification code.
  683. // pExtra [IN OUT] Used according to the value of nCode.
  684. // pHandlerInfo [OUT] ???
  685. //
  686. // Return Value:
  687. // TRUE Message has been handled.
  688. // FALSE Message has NOT been handled.
  689. //
  690. //--
  691. /////////////////////////////////////////////////////////////////////////////
  692. #if 0
  693. BOOL CCluAdmExtensions::OnCmdMsg(
  694. UINT nID,
  695. int nCode,
  696. void * pExtra,
  697. AFX_CMDHANDLERINFO * pHandlerInfo
  698. )
  699. {
  700. return BExecuteContextMenuItem( nID );
  701. } //*** CCluAdmExtensions::OnCmdMsg()
  702. #endif
  703. /////////////////////////////////////////////////////////////////////////////
  704. //++
  705. //
  706. // CCluAdmExtensions::PemiFromCommandID
  707. //
  708. // Routine Description:
  709. // Find the menu item for the specified command ID.
  710. //
  711. // Arguments:
  712. // nCommandID [IN] Command ID for the menu item.
  713. //
  714. // Return Value:
  715. // pemi Menu item or NULL if not found.
  716. //
  717. // Exceptions Thrown:
  718. // None.
  719. //
  720. //--
  721. /////////////////////////////////////////////////////////////////////////////
  722. CCluAdmExMenuItem * CCluAdmExtensions::PemiFromCommandID( IN ULONG nCommandID ) const
  723. {
  724. CCluAdmExMenuItem * pemiReturn = NULL;
  725. if ( PlMenuItems() != NULL )
  726. {
  727. CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin();
  728. CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end();
  729. CCluAdmExMenuItem * pemi;
  730. for ( ; itCurrent != itLast ; itCurrent++ )
  731. {
  732. pemi = *itCurrent;
  733. if ( pemi->NCommandID() == nCommandID )
  734. {
  735. pemiReturn = pemi;
  736. break;
  737. } // if: match was found
  738. } // while: more items in the list
  739. } // if: item list exists
  740. return pemiReturn;
  741. } //*** CCluAdmExtensions::PemiFromCommandID()
  742. #if DBG
  743. /////////////////////////////////////////////////////////////////////////////
  744. //++
  745. //
  746. // CCluAdmExtensions::PemiFromExtCommandID
  747. //
  748. // Routine Description:
  749. // Find the menu item for the specified extension command ID.
  750. //
  751. // Arguments:
  752. // nExtCommandID [IN] Extension command ID for the menu item.
  753. //
  754. // Return Value:
  755. // pemi Menu item or NULL if not found.
  756. //
  757. // Exceptions Thrown:
  758. // None.
  759. //
  760. //--
  761. /////////////////////////////////////////////////////////////////////////////
  762. CCluAdmExMenuItem * CCluAdmExtensions::PemiFromExtCommandID( IN ULONG nExtCommandID ) const
  763. {
  764. CCluAdmExMenuItem * pemiReturn = NULL;
  765. if ( PlMenuItems() != NULL )
  766. {
  767. CCluAdmExMenuItemList::iterator itCurrent = PlMenuItems()->begin();
  768. CCluAdmExMenuItemList::iterator itLast = PlMenuItems()->end();
  769. CCluAdmExMenuItem * pemi;
  770. for ( ; itCurrent != itLast ; itCurrent++ )
  771. {
  772. pemi = *itCurrent;
  773. if ( pemi->NExtCommandID() == nExtCommandID )
  774. {
  775. pemiReturn = pemi;
  776. break;
  777. } // if: match was found
  778. } // while: more items in the list
  779. } // if: item list exists
  780. return pemiReturn;
  781. } //*** CCluAdmExtensions::PemiFromExtCommandID()
  782. #endif // DBG
  783. //*************************************************************************//
  784. /////////////////////////////////////////////////////////////////////////////
  785. // CComObject< CCluAdmExDll >
  786. /////////////////////////////////////////////////////////////////////////////
  787. BEGIN_OBJECT_MAP( AtlExtDll_ObjectMap )
  788. OBJECT_ENTRY( CLSID_CoCluAdmExHostSvr, CComCluAdmExDll )
  789. END_OBJECT_MAP()
  790. /////////////////////////////////////////////////////////////////////////////
  791. //++
  792. //
  793. // CCluAdmExDll::Init
  794. //
  795. // Routine Description:
  796. // Initialize this class in preparation for accessing the extension.
  797. //
  798. // Arguments:
  799. // rstrCLSID [IN] CLSID of the extension in string form.
  800. //
  801. // Return Value:
  802. // None.
  803. //
  804. // Exceptions Thrown:
  805. // CNTException 0 (error converting CLSID from string)
  806. // Any exceptions thrown by CString::operater=().
  807. //
  808. //--
  809. /////////////////////////////////////////////////////////////////////////////
  810. void CCluAdmExDll::Init(
  811. IN const CString & rstrCLSID,
  812. IN OUT CCluAdmExtensions * pext
  813. )
  814. {
  815. ATLASSERT( pext != NULL );
  816. HRESULT hr;
  817. CWaitCursor wc;
  818. //
  819. // Save parameters.
  820. //
  821. ATLASSERT( StrCLSID().IsEmpty() || (StrCLSID() == rstrCLSID) );
  822. m_strCLSID = rstrCLSID;
  823. m_pext = pext;
  824. //
  825. // Convert the CLSID string to a CLSID.
  826. //
  827. hr = ::CLSIDFromString( (LPWSTR) (LPCTSTR) rstrCLSID, &m_clsid );
  828. if ( hr != S_OK )
  829. {
  830. ThrowStaticException( hr, ADMC_IDS_CLSIDFROMSTRING_ERROR, rstrCLSID );
  831. } // if: error converting CLSID
  832. } //*** CCluAdmExDll::Init()
  833. /////////////////////////////////////////////////////////////////////////////
  834. //++
  835. //
  836. // CCluAdmExDll::LoadInterface
  837. //
  838. // Routine Description:
  839. // Load an extension DLL.
  840. //
  841. // Arguments:
  842. // riid [IN] Interface ID.
  843. //
  844. // Return Value:
  845. // piUnk IUnknown interface pointer for interface.
  846. //
  847. // Exceptions Thrown:
  848. // CNTException ADMC_IDS_EXT_CREATE_INSTANCE_ERROR
  849. //
  850. //--
  851. /////////////////////////////////////////////////////////////////////////////
  852. IUnknown * CCluAdmExDll::LoadInterface( IN const REFIID riid )
  853. {
  854. HRESULT hr;
  855. IUnknown * piUnk;
  856. CWaitCursor wc;
  857. //
  858. // Load the inproc server and get the specified interface pointer.
  859. //
  860. // Trace( g_tagExtDllRef, _T("LoadInterface() - Getting interface pointer") );
  861. hr = ::CoCreateInstance(
  862. Rclsid(),
  863. NULL,
  864. CLSCTX_INPROC_SERVER,
  865. riid,
  866. (LPVOID *) &piUnk
  867. );
  868. if ( (hr != S_OK)
  869. && (hr != REGDB_E_CLASSNOTREG)
  870. && (hr != E_NOINTERFACE)
  871. )
  872. {
  873. ThrowStaticException( hr, ADMC_IDS_EXT_CREATE_INSTANCE_ERROR, StrCLSID() );
  874. } // if: error creating the object instance
  875. return piUnk;
  876. } //*** CCluAdmExDll::LoadInterface()
  877. /////////////////////////////////////////////////////////////////////////////
  878. //++
  879. //
  880. // CCluAdmExDll::UnloadExtension
  881. //
  882. // Routine Description:
  883. // Unload the extension DLL.
  884. //
  885. // Arguments:
  886. // None.
  887. //
  888. // Return Value:
  889. // None.
  890. //
  891. //--
  892. /////////////////////////////////////////////////////////////////////////////
  893. void CCluAdmExDll::UnloadExtension( void )
  894. {
  895. //
  896. // Release the interface pointers in the opposite order in which they
  897. //
  898. // were obtained.
  899. ReleaseInterface( &m_piExtendPropSheet );
  900. ReleaseInterface( &m_piExtendWizard );
  901. ReleaseInterface( &m_piExtendWizard97 );
  902. ReleaseInterface( &m_piExtendContextMenu );
  903. ReleaseInterface( &m_piInvokeCommand );
  904. m_strCLSID.Empty();
  905. } //*** CCluAdmExDll::UnloadExtension()
  906. /////////////////////////////////////////////////////////////////////////////
  907. //++
  908. //
  909. // CCluAdmExDll::CreatePropertySheetPages
  910. //
  911. // Routine Description:
  912. // Add pages to a property sheet.
  913. //
  914. // Arguments:
  915. // None.
  916. //
  917. // Return Value:
  918. // None.
  919. //
  920. // Exceptions Thrown:
  921. // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR
  922. //
  923. //--
  924. /////////////////////////////////////////////////////////////////////////////
  925. void CCluAdmExDll::CreatePropertySheetPages( void )
  926. {
  927. ATLASSERT( Pext() != NULL );
  928. ATLASSERT( Psht() != NULL );
  929. ATLASSERT( m_piExtendPropSheet == NULL );
  930. HRESULT hr;
  931. //
  932. // Load the interface.
  933. //
  934. m_piExtendPropSheet = reinterpret_cast< interface IWEExtendPropertySheet * >( LoadInterface( IID_IWEExtendPropertySheet ) );
  935. if ( m_piExtendPropSheet == NULL )
  936. {
  937. return;
  938. } // if: error loading the interface
  939. ATLASSERT( m_piExtendPropSheet != NULL );
  940. //
  941. // Add pages from the extension.
  942. //
  943. GetUnknown()->AddRef(); // Add a reference because extension is going to release.
  944. Pdo()->AddRef();
  945. try
  946. {
  947. hr = PiExtendPropSheet()->CreatePropertySheetPages( Pdo()->GetUnknown(), this );
  948. } // try
  949. catch ( ... )
  950. {
  951. hr = E_FAIL;
  952. } // catch
  953. if ( (hr != NOERROR) && (hr != E_NOTIMPL) )
  954. {
  955. ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() );
  956. } // if: error creating property sheet pages
  957. } //*** CCluAdmExDll::CreatePropertySheetPages()
  958. /////////////////////////////////////////////////////////////////////////////
  959. //++
  960. //
  961. // CCluAdmExDll::CreateWizardPages
  962. //
  963. // Routine Description:
  964. // Add pages to a wizard.
  965. //
  966. // Arguments:
  967. // None.
  968. //
  969. // Return Value:
  970. // None.
  971. //
  972. // Exceptions Thrown:
  973. // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR
  974. //
  975. //--
  976. /////////////////////////////////////////////////////////////////////////////
  977. void CCluAdmExDll::CreateWizardPages( void )
  978. {
  979. ATLASSERT( Pext() != NULL );
  980. ATLASSERT( Psht() != NULL );
  981. ATLASSERT( m_piExtendWizard == NULL );
  982. ATLASSERT( m_piExtendWizard97 == NULL );
  983. HRESULT hr;
  984. //
  985. // Load the interface. If it can't be loaded, try to load the
  986. // Wizard97 interface so that Wizard97 pages can be added.
  987. //
  988. m_piExtendWizard = reinterpret_cast< interface IWEExtendWizard * >( LoadInterface( IID_IWEExtendWizard ) );
  989. if ( m_piExtendWizard == NULL )
  990. {
  991. //
  992. // Try to load the Wizard97 interface.
  993. //
  994. m_piExtendWizard97 = reinterpret_cast< interface IWEExtendWizard97 * >( LoadInterface( IID_IWEExtendWizard97 ) );
  995. if ( m_piExtendWizard97 == NULL )
  996. {
  997. return;
  998. } // if: error loading the non-Wizard97 interface
  999. } // if: error loading the interface
  1000. ATLASSERT( (m_piExtendWizard != NULL) || (m_piExtendWizard97 != NULL) );
  1001. //
  1002. // Add pages from the extension.
  1003. //
  1004. GetUnknown()->AddRef(); // Add a reference because extension is going to release.
  1005. Pdo()->AddRef();
  1006. try
  1007. {
  1008. if ( PiExtendWizard() != NULL )
  1009. {
  1010. hr = PiExtendWizard()->CreateWizardPages( Pdo()->GetUnknown(), this );
  1011. } // if: extension supports non-Wizard97 interface
  1012. else
  1013. {
  1014. ATLASSERT( PiExtendWizard97() != NULL );
  1015. hr = PiExtendWizard97()->CreateWizard97Pages( Pdo()->GetUnknown(), this );
  1016. } // else: extension doesn't support non-Wizard97 interface
  1017. } // try
  1018. catch ( ... )
  1019. {
  1020. hr = E_FAIL;
  1021. } // catch
  1022. if ( (hr != NOERROR) && (hr != E_NOTIMPL) )
  1023. {
  1024. ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() );
  1025. } // if: error creating wizard pages
  1026. } //*** CCluAdmExDll::CreateWizardPages()
  1027. /////////////////////////////////////////////////////////////////////////////
  1028. //++
  1029. //
  1030. // CCluAdmExDll::CreateWizard97Pages
  1031. //
  1032. // Routine Description:
  1033. // Add pages to a Wizard 97 wizard.
  1034. //
  1035. // Arguments:
  1036. // None.
  1037. //
  1038. // Return Value:
  1039. // None.
  1040. //
  1041. // Exceptions Thrown:
  1042. // CNTException ADMC_IDS_EXT_ADD_PAGES_ERROR
  1043. //
  1044. //--
  1045. /////////////////////////////////////////////////////////////////////////////
  1046. void CCluAdmExDll::CreateWizard97Pages( void )
  1047. {
  1048. ATLASSERT( Pext() != NULL );
  1049. ATLASSERT( Psht() != NULL );
  1050. ATLASSERT( m_piExtendWizard == NULL );
  1051. ATLASSERT( m_piExtendWizard97 == NULL );
  1052. HRESULT hr;
  1053. //
  1054. // Load the interface. If it can't be loaded, try to load the non-
  1055. // Wizard97 interface so that non-Wizard97 pages can be added.
  1056. //
  1057. m_piExtendWizard97 = reinterpret_cast< interface IWEExtendWizard97 * >( LoadInterface( IID_IWEExtendWizard97 ) );
  1058. if ( m_piExtendWizard97 == NULL )
  1059. {
  1060. //
  1061. // Try to load the non-Wizard97 interface.
  1062. //
  1063. m_piExtendWizard = reinterpret_cast< interface IWEExtendWizard * >( LoadInterface( IID_IWEExtendWizard ) );
  1064. if ( m_piExtendWizard == NULL )
  1065. {
  1066. return;
  1067. } // if: error loading the non-Wizard97 interface
  1068. } // if: error loading the Wizard97 interface
  1069. ATLASSERT( (m_piExtendWizard97 != NULL) || (m_piExtendWizard != NULL) );
  1070. //
  1071. // Add pages from the extension.
  1072. //
  1073. GetUnknown()->AddRef(); // Add a reference because extension is going to release.
  1074. Pdo()->AddRef();
  1075. try
  1076. {
  1077. if ( PiExtendWizard97() != NULL )
  1078. {
  1079. hr = PiExtendWizard97()->CreateWizard97Pages( Pdo()->GetUnknown(), this );
  1080. } // if: extension supports Wizard97 interface
  1081. else
  1082. {
  1083. ATLASSERT( PiExtendWizard() != NULL );
  1084. hr = PiExtendWizard()->CreateWizardPages( Pdo()->GetUnknown(), this );
  1085. } // else: extension doesn't support Wizard97 interface
  1086. } // try
  1087. catch ( ... )
  1088. {
  1089. hr = E_FAIL;
  1090. } // catch
  1091. if ( (hr != NOERROR) && (hr != E_NOTIMPL) )
  1092. {
  1093. ThrowStaticException( hr, ADMC_IDS_EXT_ADD_PAGES_ERROR, StrCLSID() );
  1094. } // if: error creating wizard pages
  1095. } //*** CCluAdmExDll::CreateWizard97Pages()
  1096. /////////////////////////////////////////////////////////////////////////////
  1097. //++
  1098. //
  1099. // CCluAdmExDll::AddContextMenuItems
  1100. //
  1101. // Routine Description:
  1102. // Ask the extension DLL to add items to the menu.
  1103. //
  1104. // Arguments:
  1105. // None.
  1106. //
  1107. // Return Value:
  1108. // None.
  1109. //
  1110. // Exceptions Thrown:
  1111. // CNTException ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR
  1112. //
  1113. //--
  1114. /////////////////////////////////////////////////////////////////////////////
  1115. void CCluAdmExDll::AddContextMenuItems( void )
  1116. {
  1117. ATLASSERT( Pext() != NULL );
  1118. ATLASSERT( Pmenu() != NULL );
  1119. ATLASSERT( m_piExtendContextMenu == NULL );
  1120. HRESULT hr;
  1121. //
  1122. // Load the interfaces.
  1123. //
  1124. m_piExtendContextMenu = reinterpret_cast< interface IWEExtendContextMenu * >( LoadInterface( IID_IWEExtendContextMenu ) );
  1125. if ( m_piExtendContextMenu == NULL )
  1126. {
  1127. return;
  1128. } // if: error loading the interface
  1129. ATLASSERT( m_piExtendContextMenu != NULL );
  1130. hr = PiExtendContextMenu()->QueryInterface( IID_IWEInvokeCommand, (LPVOID *) &m_piInvokeCommand );
  1131. if ( hr != NOERROR )
  1132. {
  1133. PiExtendContextMenu()->Release();
  1134. m_piExtendContextMenu = NULL;
  1135. ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() );
  1136. } // if: error getting the InvokeCommand interface
  1137. //
  1138. // Add context menu items.
  1139. //
  1140. GetUnknown()->AddRef(); // Add a reference because extension is going to release.
  1141. Pdo()->AddRef();
  1142. // Trace( g_tagExtDll, _T("CCluAdmExDll::AddContextMenuItem() - Adding context menu items from '%s'"), StrCLSID() );
  1143. try
  1144. {
  1145. hr = PiExtendContextMenu()->AddContextMenuItems( Pdo()->GetUnknown(), this );
  1146. } // try
  1147. catch ( ... )
  1148. {
  1149. hr = E_FAIL;
  1150. } // catch
  1151. if ( hr != NOERROR )
  1152. {
  1153. ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() );
  1154. } // if: error occurred
  1155. //
  1156. // Add a separator after the extension's items.
  1157. //
  1158. // Trace( g_tagExtDll, _T("CCluAdmExDll::AddContextMenuItem() - Adding separator") );
  1159. try
  1160. {
  1161. hr = AddExtensionMenuItem( NULL, NULL, (ULONG) -1, 0, MF_SEPARATOR );
  1162. } // try
  1163. catch ( ... )
  1164. {
  1165. hr = E_FAIL;
  1166. } // catch
  1167. if ( hr != NOERROR )
  1168. {
  1169. ThrowStaticException( hr, ADMC_IDS_EXT_QUERY_CONTEXT_MENU_ERROR, StrCLSID() );
  1170. } // if: error adding a separator
  1171. } //*** CCluAdmExDll::AddContextMenuItems()
  1172. /////////////////////////////////////////////////////////////////////////////
  1173. //++
  1174. //
  1175. // CCluAdmExDll::InterfaceSupportsErrorInfo [ISupportsErrorInfo]
  1176. //
  1177. // Routine Description:
  1178. // Determines whether the interface supports error info (???).
  1179. //
  1180. // Arguments:
  1181. // riid [IN] Reference to the interface ID.
  1182. //
  1183. // Return Value:
  1184. // S_OK Interface supports error info.
  1185. // S_FALSE Interface does not support error info.
  1186. //
  1187. // Exceptions Thrown:
  1188. // None.
  1189. //
  1190. //--
  1191. /////////////////////////////////////////////////////////////////////////////
  1192. STDMETHODIMP CCluAdmExDll::InterfaceSupportsErrorInfo( REFIID riid )
  1193. {
  1194. static const IID * rgiid[] =
  1195. {
  1196. &IID_IWCPropertySheetCallback,
  1197. &IID_IWCWizardCallback,
  1198. &IID_IWCWizard97Callback,
  1199. &IID_IWCContextMenuCallback,
  1200. };
  1201. int iiid;
  1202. for ( iiid = 0 ; iiid < sizeof( rgiid ) / sizeof( rgiid[0] ) ; iiid++ )
  1203. {
  1204. if ( InlineIsEqualGUID( *rgiid[iiid], riid ) )
  1205. {
  1206. return S_OK;
  1207. } // if: found a match
  1208. }
  1209. return S_FALSE;
  1210. } //*** CCluAdmExDll::InterfaceSupportsErrorInfo()
  1211. /////////////////////////////////////////////////////////////////////////////
  1212. //++
  1213. //
  1214. // CCluAdmExDll::AddPropertySheetPage [IWCPropertySheetCallback]
  1215. //
  1216. // Routine Description:
  1217. // Add a page to the property sheet.
  1218. //
  1219. // Arguments:
  1220. // plong_hpage [IN] Page to add.
  1221. //
  1222. // Return Value:
  1223. // NOERROR Page added successfully.
  1224. // E_INVALIDARG NULL hpage.
  1225. // Any hresult returned from CBasePropertySheetWindow::HrAddExtensionPage().
  1226. //
  1227. // Exceptions Thrown:
  1228. // None.
  1229. //
  1230. //--
  1231. /////////////////////////////////////////////////////////////////////////////
  1232. STDMETHODIMP CCluAdmExDll::AddPropertySheetPage( IN LONG * plong_hpage )
  1233. {
  1234. ATLASSERT( plong_hpage != NULL );
  1235. ATLASSERT( Psht() != NULL );
  1236. HRESULT hr;
  1237. // Loop to avoid goto's.
  1238. do
  1239. {
  1240. //
  1241. // Do this for the release build.
  1242. //
  1243. if ( (plong_hpage == NULL)
  1244. || (Psht() == NULL) )
  1245. {
  1246. hr = E_INVALIDARG;
  1247. break;
  1248. } // if: no page or sheet
  1249. //
  1250. // Allocate a new page object.
  1251. //
  1252. CCluAdmExPropPage * ppp = new CCluAdmExPropPage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) );
  1253. ATLASSERT( ppp != NULL );
  1254. if ( ppp == NULL )
  1255. {
  1256. hr = E_OUTOFMEMORY;
  1257. break;
  1258. } // if: error allocating memory
  1259. //
  1260. // Initialize the page object.
  1261. //
  1262. if ( ! ppp->BInit( Psht() ) )
  1263. {
  1264. delete ppp;
  1265. hr = E_FAIL;
  1266. break;
  1267. } // if: error initializing the page object
  1268. //
  1269. // Add the page to the sheet.
  1270. //
  1271. CBasePropertySheetWindow * psht = dynamic_cast< CBasePropertySheetWindow * >( Psht() );
  1272. ATLASSERT( psht != NULL );
  1273. hr = psht->HrAddExtensionPage( ppp );
  1274. if ( hr != NOERROR )
  1275. {
  1276. delete ppp;
  1277. break;
  1278. } // if: error adding the extension page
  1279. } while ( 0 );
  1280. return hr;
  1281. } //*** CCluAdmExDll::AddPropertySheetPage()
  1282. /////////////////////////////////////////////////////////////////////////////
  1283. //++
  1284. //
  1285. // CCluAdmExDll::AddWizardPage [IWCWizardCallback]
  1286. //
  1287. // Routine Description:
  1288. // Add a page to the wizard.
  1289. //
  1290. // Arguments:
  1291. // plong_hpage [IN] Page to add.
  1292. //
  1293. // Return Value:
  1294. // NOERROR Page added successfully.
  1295. // E_INVALIDARG NULL hpage.
  1296. // Any hresult returned from CWizardWindow::HrAddExtensionPage().
  1297. //
  1298. // Exceptions Thrown:
  1299. // None.
  1300. //
  1301. //--
  1302. /////////////////////////////////////////////////////////////////////////////
  1303. STDMETHODIMP CCluAdmExDll::AddWizardPage( IN LONG * plong_hpage )
  1304. {
  1305. ATLASSERT( plong_hpage != NULL );
  1306. ATLASSERT( Psht() != NULL );
  1307. HRESULT hr;
  1308. // Loop to avoid goto's.
  1309. do
  1310. {
  1311. //
  1312. // Do this for the release build.
  1313. //
  1314. if ( (plong_hpage == NULL)
  1315. || (Psht() == NULL) )
  1316. {
  1317. hr = E_INVALIDARG;
  1318. break;
  1319. } // if: no page or sheet
  1320. //
  1321. // Allocate a new page object.
  1322. //
  1323. CCluAdmExWizPage * pwp = new CCluAdmExWizPage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) );
  1324. ATLASSERT( pwp != NULL );
  1325. if ( pwp == NULL )
  1326. {
  1327. hr = E_OUTOFMEMORY;
  1328. break;
  1329. } // if: error allocating memory
  1330. //
  1331. // Initialize the page object.
  1332. //
  1333. if ( ! pwp->BInit( Psht() ) )
  1334. {
  1335. delete pwp;
  1336. hr = E_FAIL;
  1337. break;
  1338. } // if: error initializing the page object
  1339. //
  1340. // Set the default buttons to display. This assumes that there is
  1341. // a non-extension page already in the sheet and that there will
  1342. // be a page added after all extension pages have been added.
  1343. //
  1344. pwp->SetDefaultWizardButtons( PSWIZB_BACK | PSWIZB_NEXT );
  1345. //
  1346. // Add the page to the sheet.
  1347. //
  1348. CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() );
  1349. ATLASSERT( pwiz != NULL );
  1350. hr = pwiz->HrAddExtensionPage( pwp );
  1351. if ( hr != NOERROR )
  1352. {
  1353. delete pwp;
  1354. break;
  1355. } // if: error adding the extension page
  1356. } while ( 0 );
  1357. return hr;
  1358. } //*** CCluAdmExDll::AddWizardPage()
  1359. /////////////////////////////////////////////////////////////////////////////
  1360. //++
  1361. //
  1362. // CCluAdmExDll::AddWizard97Page [IWCWizard97Callback]
  1363. //
  1364. // Routine Description:
  1365. // Add a page to the Wizard97 wizard.
  1366. //
  1367. // Arguments:
  1368. // plong_hpage [IN] Page to add.
  1369. //
  1370. // Return Value:
  1371. // NOERROR Page added successfully.
  1372. // E_INVALIDARG NULL hpage.
  1373. // Any hresult returned from CWizardWindow::HrAddExtensionPage().
  1374. //
  1375. // Exceptions Thrown:
  1376. // None.
  1377. //
  1378. //--
  1379. /////////////////////////////////////////////////////////////////////////////
  1380. STDMETHODIMP CCluAdmExDll::AddWizard97Page( IN LONG * plong_hpage )
  1381. {
  1382. ATLASSERT( plong_hpage != NULL );
  1383. ATLASSERT( Psht() != NULL );
  1384. HRESULT hr;
  1385. // Loop to avoid goto's.
  1386. do
  1387. {
  1388. //
  1389. // Do this for the release build.
  1390. //
  1391. if ( (plong_hpage == NULL)
  1392. || (Psht() == NULL) )
  1393. {
  1394. hr = E_INVALIDARG;
  1395. break;
  1396. } // if: no page or sheet
  1397. //
  1398. // Allocate a new page object.
  1399. //
  1400. CCluAdmExWiz97Page * pwp = new CCluAdmExWiz97Page( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) );
  1401. ATLASSERT( pwp != NULL );
  1402. if ( pwp == NULL )
  1403. {
  1404. hr = E_OUTOFMEMORY;
  1405. break;
  1406. } // if: error allocating memory
  1407. //
  1408. // Initialize the page object.
  1409. //
  1410. if ( ! pwp->BInit( Psht() ) )
  1411. {
  1412. delete pwp;
  1413. hr = E_FAIL;
  1414. break;
  1415. } // if: error initializing the page object
  1416. //
  1417. // Set the default buttons to display. This assumes that there is
  1418. // a non-extension page already in the sheet and that there will
  1419. // be a page added after all extension pages have been added.
  1420. //
  1421. pwp->SetDefaultWizardButtons( PSWIZB_BACK | PSWIZB_NEXT );
  1422. //
  1423. // Add the page to the sheet.
  1424. //
  1425. CWizardWindow * pwiz = dynamic_cast< CWizardWindow * >( Psht() );
  1426. ATLASSERT( pwiz != NULL );
  1427. hr = pwiz->HrAddExtensionPage( pwp );
  1428. if ( hr != NOERROR )
  1429. {
  1430. delete pwp;
  1431. break;
  1432. } // if: error adding the extension page
  1433. } while ( 0 );
  1434. return hr;
  1435. } //*** CCluAdmExDll::AddWizard97Page()
  1436. /////////////////////////////////////////////////////////////////////////////
  1437. //++
  1438. //
  1439. // CCluAdmExDll::EnableNext [IWCWizardCallback/IWCWizard97Callback]
  1440. //
  1441. // Routine Description:
  1442. // Enable or disable the NEXT button. If it is the last page, the
  1443. // FINISH button will be enabled or disabled.
  1444. //
  1445. // Arguments:
  1446. // hpage [IN] Page for which the button is being enabled or
  1447. // disabled.
  1448. // bEnable [IN] TRUE = Enable the button, FALSE = disable.
  1449. //
  1450. // Return Value:
  1451. // NOERROR Success.
  1452. // E_INVALIDARG Unknown hpage specified.
  1453. //
  1454. // Exceptions Thrown:
  1455. // None.
  1456. //
  1457. //--
  1458. /////////////////////////////////////////////////////////////////////////////
  1459. STDMETHODIMP CCluAdmExDll::EnableNext(
  1460. IN LONG * plong_hpage,
  1461. IN BOOL bEnable
  1462. )
  1463. {
  1464. ATLASSERT( plong_hpage != NULL );
  1465. ATLASSERT( Psht() != NULL );
  1466. //
  1467. // Find the page in the extension page list.
  1468. //
  1469. CWizardPageWindow * pwp = Pext()->PwpPageFromHpage( reinterpret_cast< HPROPSHEETPAGE >( plong_hpage ) );
  1470. if ( pwp == NULL )
  1471. {
  1472. return E_INVALIDARG;
  1473. } // if: page not found
  1474. //
  1475. // Let the page enable/disable the Next button.
  1476. //
  1477. pwp->EnableNext( bEnable );
  1478. return NOERROR;
  1479. } //*** CCluAdmExDll::EnableNext()
  1480. /////////////////////////////////////////////////////////////////////////////
  1481. //++
  1482. //
  1483. // CCluAdmExDll::AddExtensionMenuItem [IWCContextMenuCallback]
  1484. //
  1485. // Routine Description:
  1486. // Add a page to the wizard.
  1487. //
  1488. // Arguments:
  1489. // lpszName [IN] Name of item.
  1490. // lpszStatusBarText [IN] Text to appear on the status bar when the
  1491. // item is highlighted.
  1492. // nCommandID [IN] ID for the command when menu item is invoked.
  1493. // Must not be -1.
  1494. // nSubmenuCommandID [IN] ID for a submenu.
  1495. // uFlags [IN] Menu flags. The following are not supported:
  1496. // MF_OWNERDRAW, MF_POPUP
  1497. //
  1498. // Return Value:
  1499. // NOERROR Item added successfully.
  1500. // E_INVALIDARG MF_OWNERDRAW or MF_POPUP were specified.
  1501. // E_OUTOFMEMORY Error allocating the item.
  1502. //
  1503. // Exceptions Thrown:
  1504. // None.
  1505. //
  1506. //--
  1507. /////////////////////////////////////////////////////////////////////////////
  1508. STDMETHODIMP CCluAdmExDll::AddExtensionMenuItem(
  1509. IN BSTR lpszName,
  1510. IN BSTR lpszStatusBarText,
  1511. IN ULONG nCommandID,
  1512. IN ULONG nSubmenuCommandID,
  1513. IN ULONG uFlags
  1514. )
  1515. {
  1516. ATLASSERT( Pext() != NULL );
  1517. ATLASSERT( Pmenu() != NULL );
  1518. ATLASSERT( !(uFlags & (MF_OWNERDRAW | MF_POPUP)) );
  1519. HRESULT hr = NOERROR;
  1520. CCluAdmExMenuItem * pemi = NULL;
  1521. //
  1522. // Do this for the release build.
  1523. //
  1524. if ( (uFlags & (MF_OWNERDRAW | MF_POPUP)) != 0 )
  1525. {
  1526. hr = E_INVALIDARG;
  1527. } // if: invalid menu flags specified
  1528. else
  1529. {
  1530. ATLASSERT( Pext()->PemiFromExtCommandID( nCommandID ) == NULL );
  1531. try
  1532. {
  1533. // Trace( g_tagExtDll, _T("CCluAdmExDll::AddExtensionMenuItem() - Adding menu item '%s', ExtID = %d"), lpszName, nCommandID );
  1534. //
  1535. // Allocate a new item.
  1536. //
  1537. pemi = new CCluAdmExMenuItem(
  1538. OLE2CT( lpszName ),
  1539. OLE2CT( lpszStatusBarText ),
  1540. nCommandID,
  1541. NNextCommandID(),
  1542. NNextMenuID(),
  1543. uFlags,
  1544. FALSE, /*bMakeDefault*/
  1545. PiInvokeCommand()
  1546. );
  1547. if ( pemi == NULL )
  1548. {
  1549. ThrowStaticException( E_OUTOFMEMORY, (UINT) 0 );
  1550. } // if: error allocating memory
  1551. //
  1552. // Insert the item in the menu.
  1553. //
  1554. if ( ! Pmenu()->InsertMenu( NNextMenuID(), MF_BYPOSITION | uFlags, NNextCommandID(), pemi->StrName() ) )
  1555. {
  1556. ThrowStaticException( ::GetLastError(), ADMC_IDS_INSERT_MENU_ERROR, pemi->StrName() );
  1557. } // if: error inserting the menu
  1558. //
  1559. // Add the item to the tail of the list.
  1560. //
  1561. Pext()->PlMenuItems()->insert( Pext()->PlMenuItems()->end(), pemi );
  1562. pemi = NULL;
  1563. //
  1564. // Update the counters.
  1565. //
  1566. Pext()->m_nNextCommandID++;
  1567. Pext()->m_nNextMenuID++;
  1568. } // try
  1569. catch ( CNTException * pnte )
  1570. {
  1571. hr = pnte->Sc();
  1572. pnte->ReportError();
  1573. pnte->Delete();
  1574. } // catch: CNTException
  1575. catch ( CException * pe )
  1576. {
  1577. hr = E_OUTOFMEMORY;
  1578. pe->ReportError();
  1579. pe->Delete();
  1580. } // catch: CException
  1581. } // else: we can add the item
  1582. delete pemi;
  1583. return hr;
  1584. } //*** CCluAdmExDll::AddExtensionMenuItem()