Leaked source code of windows server 2003
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.

807 lines
22 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. NodeWithScopeChildrenList.h
  6. Abstract:
  7. This is the header file for CNodeWithScopeChildrenList, a class which
  8. implements a node that has a list of scope pane children.
  9. This is an inline template class.
  10. Include NodeWithScopeChildrenList.cpp in the .cpp files
  11. of the classes in which you use this template.
  12. Author:
  13. Original: Michael A. Maguire
  14. Modifications: RaphiR
  15. Changes:
  16. Support for Extension snapins
  17. Enables multiple class of childs
  18. // Jun 14 1999 roytal used UNREFERENCED_PARAMETER to fix build wrn //
  19. // //
  20. // Sep 22 1999 yossg Welcome To Fax Server //
  21. // Dec 30 1999 yossg Fix RemoveChild //
  22. --*/
  23. //////////////////////////////////////////////////////////////////////////////
  24. #if !defined(_NODE_WITH_SCOPE_CHILDREN_LIST_H_)
  25. #define _NODE_WITH_SCOPE_CHILDREN_LIST_H_
  26. //////////////////////////////////////////////////////////////////////////////
  27. // BEGIN INCLUDES
  28. //
  29. // where we can find what this class derives from:
  30. //
  31. #include "snpnode.h"
  32. //
  33. //
  34. // where we can find what this class has or uses:
  35. //
  36. //
  37. // END INCLUDES
  38. //////////////////////////////////////////////////////////////////////////////
  39. template <class T,BOOL bIsExtension>
  40. class CNodeWithScopeChildrenList : public CSnapinNode< T, bIsExtension >
  41. {
  42. public:
  43. //////////////////////////////////////////////////////////////////////////////
  44. /*++
  45. CNodeWithScopeChildrenList::AddChild
  46. Adds a child to the list of children.
  47. This has to be public as it must be accessible even from a separate dialog
  48. (e.g. a Connect to Server dialog) that may want to add a child.
  49. Here we add the child item to the list of children and call InsertItem
  50. to add the child to the scope pane.
  51. This is one difference between adding nodes into the scope
  52. pane and the result pane. When we were inserting a child into
  53. the result pane, we didn't call InsertItem in the AddChild methods(s)
  54. because we needed to worry about sending an UpdataAllViews
  55. notification and repopulating the result pane in each view.
  56. Because MMC takes care of replicating scope pane changes to all views,
  57. we don't need to worry about this. Instead, we just do InsertItem once here.
  58. --*/
  59. //////////////////////////////////////////////////////////////////////////////
  60. virtual HRESULT AddChild(CSnapInItem * pChildNode, SCOPEDATAITEM* pScopeDataItem);
  61. //////////////////////////////////////////////////////////////////////////////
  62. /*++
  63. CNodeWithScopeChildrenList::RemoveChild
  64. Removes a child from the list of children.
  65. This has to be public so that child nodes can ask their parent to be deleted
  66. from the list of children when they receive the MMCN_DELETE notification.
  67. --*/
  68. //////////////////////////////////////////////////////////////////////////////
  69. virtual HRESULT RemoveChild(CSnapInItem * pChildNode );
  70. //////////////////////////////////////////////////////////////////////////////
  71. /*++
  72. CNodeWithScopeChildrenList::OnShow
  73. Don't override this in your derived class. Instead, override methods
  74. which it calls: InsertColumns
  75. This method is an override of CSnapinNode::OnShow. When MMC passes the
  76. MMCN_SHOW method for this node.
  77. For more information, see CSnapinNode::OnShow.
  78. --*/
  79. //////////////////////////////////////////////////////////////////////////////
  80. virtual HRESULT OnShow(
  81. LPARAM arg
  82. , LPARAM param
  83. , IComponentData * pComponentData
  84. , IComponent * pComponent
  85. , DATA_OBJECT_TYPES type
  86. );
  87. //////////////////////////////////////////////////////////////////////////////
  88. /*++
  89. CNodeWithScopeChildren::OnExpand
  90. Don't override this in your derived class. Instead, override methods
  91. which it calls: PopulateScopeChildrenList
  92. This method is an override of CSnapinNode::OnExpand. When MMC passes the
  93. MMCN_EXPAND method for this node, we are to add children into the
  94. scope pane. In this class we add them from a list we maintain.
  95. For more information, see CSnapinNode::OnExpand.
  96. --*/
  97. //////////////////////////////////////////////////////////////////////////////
  98. virtual HRESULT OnExpand(
  99. LPARAM arg
  100. , LPARAM param
  101. , IComponentData * pComponentData
  102. , IComponent * pComponent
  103. , DATA_OBJECT_TYPES type
  104. );
  105. protected:
  106. // Array of pointers to children nodes
  107. CSimpleArray<CSnapInItem*> m_ScopeChildrenList;
  108. // Flag indicating whether list has been initially populated
  109. BOOL m_bScopeChildrenListPopulated;
  110. /////////////////////////////////////////////////////////////////////////////
  111. /*++
  112. CNodeWithScopeChildrenList::CNodeWithScopeChildrenList
  113. Constructor
  114. This is an base class which we don't want instantiated on its own,
  115. so the contructor is protected
  116. --*/
  117. //////////////////////////////////////////////////////////////////////////////
  118. CNodeWithScopeChildrenList(CSnapInItem * pParentNode, CSnapin * pComponentData);
  119. /////////////////////////////////////////////////////////////////////////////
  120. /*++
  121. CNodeWithScopeChildrenList::~CNodeWithScopeChildrenList
  122. Destructor
  123. --*/
  124. //////////////////////////////////////////////////////////////////////////////
  125. ~CNodeWithScopeChildrenList();
  126. /////////////////////////////////////////////////////////////////////////////
  127. /*++
  128. CNodeWithScopeChildrenList::PopulateScopeChildrenList
  129. Override this in your derived class to populate the list of children nodes.
  130. --*/
  131. //////////////////////////////////////////////////////////////////////////////
  132. virtual HRESULT PopulateScopeChildrenList();
  133. // override in your derived class and do something like:
  134. /*
  135. virtual HRESULT PopulateScopeChildrenList( void )
  136. {
  137. CSomeChildNode *myChild1 = new CSomeChildNode();
  138. AddChild(myChild1);
  139. CSomeChildNode *myChild2 = new CSomeChildNode();
  140. AddChild(myChild2);
  141. CSomeChildNode *myChild3 = new CSomeChildNode();
  142. AddChild(myChild3);
  143. return S_OK;
  144. }
  145. */
  146. //////////////////////////////////////////////////////////////////////////////
  147. /*++
  148. CNodeWithScopeChildrenList::InsertColumns
  149. Override this in your derived class.
  150. This method is called by OnShow when it needs you to set the appropriate
  151. column headers to be displayed in the result pane for this node.
  152. --*/
  153. //////////////////////////////////////////////////////////////////////////////
  154. virtual HRESULT InsertColumns( IHeaderCtrl* pHeaderCtrl );
  155. //////////////////////////////////////////////////////////////////////////////
  156. /*++
  157. CNodeWithScopeChildrenList::OnUnSelect
  158. Override this in your derived class.
  159. This method is called by OnShow when the node is unselected.
  160. Useful to overidde this if to retreive columns header width for example
  161. --*/
  162. //////////////////////////////////////////////////////////////////////////////
  163. virtual HRESULT OnUnSelect( IHeaderCtrl* pHeaderCtrl );
  164. /////////////////////////////////////////////////////////////////////////////
  165. /*++
  166. CNodeWithScopeChildrenList::EnumerateScopeChildren
  167. Don't override this in your derived class. Instead, override the method
  168. it calls, PopulateScopeChildrenList.
  169. --*/
  170. //////////////////////////////////////////////////////////////////////////////
  171. virtual HRESULT EnumerateScopeChildren( IConsoleNameSpace* pConsoleNameSpace );
  172. };
  173. //////////////////////////////////////////////////////////////////////////////
  174. /*++
  175. CNodeWithScopeChildrenList::AddChild
  176. Adds a child to the list of children.
  177. This has to be public as it must be accessible even from a separate dialog
  178. (e.g. a Connect to Server dialog) that may want to add a child.
  179. Here we add the child item to the list of children and call InsertItem
  180. to add the child to the scope pane.
  181. This is one difference between adding nodes into the scope
  182. pane and the result pane. When we were inserting a child into
  183. the result pane, we didn't call InsertItem in the AddChild methods(s)
  184. because we needed to worry about sending an UpdataAllViews
  185. notification and repopulating the result pane in each view.
  186. Because MMC takes care of replicating scope pane changes to all views,
  187. we don't need to worry about this. Instead, we just do InsertItem once here.
  188. --*/
  189. //////////////////////////////////////////////////////////////////////////////
  190. template <class T, BOOL bIsExtension>
  191. HRESULT CNodeWithScopeChildrenList<T,bIsExtension>::AddChild(
  192. CSnapInItem* pChildNode,
  193. SCOPEDATAITEM* pScopeDataItem)
  194. {
  195. DEBUG_FUNCTION_NAME(
  196. _T("CNodeWithScopeChildrenList::AddChild"));
  197. // Check for preconditions:
  198. // None.
  199. HRESULT hr = S_OK;
  200. if( m_ScopeChildrenList.Add( pChildNode ) )
  201. {
  202. //
  203. // Get the Console
  204. //
  205. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(m_pComponentData->m_spConsole);
  206. // We hand our HSCOPEITEM as the parent ID for this child.
  207. pScopeDataItem->relativeID = (HSCOPEITEM) m_scopeDataItem.ID;
  208. hr = spConsoleNameSpace->InsertItem(pScopeDataItem);
  209. if (FAILED(hr))
  210. {
  211. return hr;
  212. }
  213. // Check: On return, the ID member of 'm_scopeDataItem'
  214. // contains the handle to the newly inserted item.
  215. _ASSERT( NULL != pScopeDataItem->ID);
  216. }
  217. else
  218. {
  219. // Failed to add => out of memory
  220. hr = E_OUTOFMEMORY;
  221. }
  222. return hr;
  223. }
  224. //////////////////////////////////////////////////////////////////////////////
  225. /*++
  226. CNodeWithScopeChildrenList::RemoveChild
  227. Removes a child from the list of children.
  228. This has to be public so that child nodes can ask their parent to be deleted
  229. from the list of children when they receive the MMCN_DELETE notification.
  230. --*/
  231. //////////////////////////////////////////////////////////////////////////////
  232. template <class T, BOOL bIsExtension>
  233. HRESULT CNodeWithScopeChildrenList<T, bIsExtension>::RemoveChild(CSnapInItem * pChildNode )
  234. {
  235. DEBUG_FUNCTION_NAME(
  236. _T("CNodeWithScopeChildrenList::RemoveChild"));
  237. // Check for preconditions:
  238. // None.
  239. HRESULT hr = S_OK;
  240. if( m_ScopeChildrenList.Remove( pChildNode ) )
  241. {
  242. //
  243. // Need IConsoleNameSpace
  244. //
  245. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(m_pComponentData->m_spConsole);
  246. //
  247. // Need pScopeDataItem
  248. //
  249. SCOPEDATAITEM *pScopeDataItem;
  250. pChildNode->GetScopeData(&pScopeDataItem);
  251. //
  252. // DeleteItem
  253. //
  254. hr = spConsoleNameSpace->DeleteItem(pScopeDataItem->ID, TRUE );
  255. if (FAILED(hr))
  256. {
  257. return hr;
  258. }
  259. }
  260. else
  261. {
  262. // If we failed to remove, probably the child was never in the list
  263. // ISSUE: determine what do here -- this should never happen
  264. _ASSERTE( FALSE );
  265. hr = S_FALSE;
  266. }
  267. return hr;
  268. }
  269. /////////////////////////////////////////////////////////////////////////////
  270. /*++
  271. CNodeWithScopeChildrenList::CNodeWithScopeChildrenList
  272. Constructor
  273. This is an base class which we don't want instantiated on its own,
  274. so the contructor is protected
  275. --*/
  276. //////////////////////////////////////////////////////////////////////////////
  277. template <class T, BOOL bIsExtension>
  278. CNodeWithScopeChildrenList<T,bIsExtension>::CNodeWithScopeChildrenList(CSnapInItem * pParentNode, CSnapin * pComponentData):
  279. CSnapinNode< T, bIsExtension >(pParentNode, pComponentData)
  280. {
  281. DEBUG_FUNCTION_NAME(
  282. _T("CNodeWithScopeChildrenList::CNodeWithScopeChildrenList"));
  283. // Check for preconditions:
  284. // None.
  285. // We have not yet loaded the child nodes' data
  286. m_bScopeChildrenListPopulated = FALSE;
  287. }
  288. /////////////////////////////////////////////////////////////////////////////
  289. /*++
  290. CNodeWithScopeChildrenList::~CNodeWithScopeChildrenList
  291. Destructor
  292. --*/
  293. //////////////////////////////////////////////////////////////////////////////
  294. template <class T, BOOL bIsExtension>
  295. CNodeWithScopeChildrenList<T, bIsExtension>::~CNodeWithScopeChildrenList()
  296. {
  297. DEBUG_FUNCTION_NAME(
  298. _T("CNodeWithScopeChildrenList::~CNodeWithScopeChildrenList"));
  299. // Check for preconditions:
  300. // None.
  301. // Delete each node in the list of children
  302. CSnapInItem* pChildNode;
  303. for (int i = 0; i < m_ScopeChildrenList.GetSize(); i++)
  304. {
  305. pChildNode = m_ScopeChildrenList[i];
  306. delete pChildNode;
  307. }
  308. // Empty the list
  309. m_ScopeChildrenList.RemoveAll();
  310. }
  311. /////////////////////////////////////////////////////////////////////////////
  312. /*++
  313. CNodeWithScopeChildrenList::PopulateScopeChildrenList
  314. Override this in your derived class to populate the list of children nodes.
  315. --*/
  316. //////////////////////////////////////////////////////////////////////////////
  317. template <class T, BOOL bIsExtension>
  318. HRESULT CNodeWithScopeChildrenList<T, bIsExtension>::PopulateScopeChildrenList()
  319. {
  320. DEBUG_FUNCTION_NAME(
  321. _T("CNodeWithScopeChildrenList::PopulateScopeChildren -- override in your derived class"));
  322. // Check for preconditions:
  323. // None.
  324. // override in your derived class and do something like:
  325. /*
  326. CSomeChildNode *myChild1 = new CSomeChildNode();
  327. m_CChildrenList.Add(myChild1);
  328. CSomeChildNode *myChild2 = new CSomeChildNode();
  329. m_CChildrenList.Add(myChild2);
  330. CSomeChildNode *myChild3 = new CSomeChildNode();
  331. m_CChildrenList.Add(myChild3);
  332. */
  333. return S_OK;
  334. }
  335. //////////////////////////////////////////////////////////////////////////////
  336. /*++
  337. CNodeWithScopeChildrenList::OnShow
  338. Don't override this in your derived class. Instead, override methods
  339. which it calls: InsertColumns
  340. This method is an override of CSnapinNode::OnShow. When MMC passes the
  341. MMCN_SHOW method for this node.
  342. For more information, see CSnapinNode::OnShow.
  343. --*/
  344. //////////////////////////////////////////////////////////////////////////////
  345. template <class T, BOOL bIsExtension>
  346. HRESULT CNodeWithScopeChildrenList<T, bIsExtension>::OnShow(
  347. LPARAM arg
  348. , LPARAM param
  349. , IComponentData * pComponentData
  350. , IComponent * pComponent
  351. , DATA_OBJECT_TYPES type
  352. )
  353. {
  354. DEBUG_FUNCTION_NAME(
  355. _T("CNodeScopeChildrenList::OnShow"));
  356. UNREFERENCED_PARAMETER (param);
  357. UNREFERENCED_PARAMETER (type);
  358. // Check for preconditions:
  359. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  360. HRESULT hr = S_FALSE;
  361. // Need IHeaderCtrl.
  362. // But to get that, first we need IConsole
  363. CComPtr<IConsole> spConsole;
  364. if( pComponentData != NULL )
  365. {
  366. spConsole = ((CSnapin*)pComponentData)->m_spConsole;
  367. }
  368. else
  369. {
  370. // We should have a non-null pComponent
  371. spConsole = ((CSnapinComponent*)pComponent)->m_spConsole;
  372. }
  373. _ASSERTE( spConsole != NULL );
  374. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeaderCtrl(spConsole);
  375. _ASSERT( spHeaderCtrl != NULL );
  376. if( arg )
  377. {
  378. // arg <> 0 => we are being selected.
  379. hr = InsertColumns( spHeaderCtrl );
  380. _ASSERT( S_OK == hr );
  381. }
  382. else
  383. {
  384. //
  385. // We are unselected
  386. //
  387. hr = OnUnSelect(spHeaderCtrl);
  388. _ASSERT( S_OK == hr );
  389. }
  390. return hr;
  391. }
  392. //////////////////////////////////////////////////////////////////////////////
  393. /*++
  394. CNodeWithScopeChildrenList::InsertColumns
  395. Override this in your derived class.
  396. This method is called by OnShow when it needs you to set the appropriate
  397. column headers to be displayed in the result pane for this node.
  398. --*/
  399. //////////////////////////////////////////////////////////////////////////////
  400. template <class T, BOOL bIsExtension>
  401. HRESULT CNodeWithScopeChildrenList<T,bIsExtension>::InsertColumns( IHeaderCtrl* pHeaderCtrl )
  402. {
  403. DEBUG_FUNCTION_NAME(
  404. _T("CNodeWithScopeChildrenList::InsertColumns -- override in your derived class"));
  405. // Check for preconditions:
  406. _ASSERTE( pHeaderCtrl != NULL );
  407. HRESULT hr;
  408. // override in your derived class and do something like:
  409. hr = pHeaderCtrl->InsertColumn( 0, L"@Column 1 -- override CNodeWithResultChildrenList::OnShowInsertColumns", 0, 120 );
  410. _ASSERT( S_OK == hr );
  411. hr = pHeaderCtrl->InsertColumn( 1, L"@Column 2 -- override CNodeWithResultChildrenList::OnShowInsertColumns", 0, 300 );
  412. _ASSERT( S_OK == hr );
  413. return hr;
  414. }
  415. //////////////////////////////////////////////////////////////////////////////
  416. /*++
  417. CNodeWithScopeChildrenList::OnUnSelect
  418. Override this in your derived class.
  419. This method is called by OnShow when the node is unselected.
  420. Useful to overidde this if to retreive columns header width for example
  421. --*/
  422. //////////////////////////////////////////////////////////////////////////////
  423. template <class T, BOOL bIsExtension>
  424. HRESULT CNodeWithScopeChildrenList<T,bIsExtension>::OnUnSelect( IHeaderCtrl* pHeaderCtrl )
  425. {
  426. UNREFERENCED_PARAMETER (pHeaderCtrl);
  427. DEBUG_FUNCTION_NAME(
  428. _T("CNodeWithScopeChildrenList::OnUnSelect -- override in your derived class"));
  429. // Check for preconditions:
  430. _ASSERTE( pHeaderCtrl != NULL );
  431. HRESULT hr = S_OK;
  432. return hr;
  433. }
  434. //////////////////////////////////////////////////////////////////////////////
  435. /*++
  436. CNodeWithScopeChildren::OnExpand
  437. Don't override this in your derived class. Instead, override methods
  438. which it calls: PopulateScopeChildrenList
  439. This method is an override of CSnapinNode::OnExpand. When MMC passes the
  440. MMCN_EXPAND method for this node, we are to add children into the
  441. scope pane. In this class we add them from a list we maintain.
  442. For more information, see CSnapinNode::OnExpand.
  443. --*/
  444. //////////////////////////////////////////////////////////////////////////////
  445. template <class T, BOOL bIsExtension>
  446. HRESULT CNodeWithScopeChildrenList<T,bIsExtension>::OnExpand(
  447. LPARAM arg
  448. , LPARAM param
  449. , IComponentData * pComponentData
  450. , IComponent * pComponent
  451. , DATA_OBJECT_TYPES type
  452. )
  453. {
  454. DEBUG_FUNCTION_NAME(
  455. _T("CNodeWithScopeChildren::OnExpand"));
  456. UNREFERENCED_PARAMETER (type);
  457. // Check for preconditions:
  458. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  459. HRESULT hr = S_FALSE;
  460. if( TRUE == arg )
  461. {
  462. // Need IConsoleNameSpace
  463. // But to get that, first we need IConsole
  464. CComPtr<IConsole> spConsole;
  465. if( pComponentData != NULL )
  466. {
  467. spConsole = ((CSnapin*)pComponentData)->m_spConsole;
  468. }
  469. else
  470. {
  471. // We should have a non-null pComponent
  472. spConsole = ((CSnapinComponent*)pComponent)->m_spConsole;
  473. }
  474. _ASSERTE( spConsole != NULL );
  475. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  476. _ASSERT( spConsoleNameSpace != NULL );
  477. if(bIsExtension)
  478. {
  479. //
  480. // For extensions, keep the scope
  481. //
  482. ATLASSERT(m_scopeDataItem.ID == 0);
  483. m_scopeDataItem.ID = (HSCOPEITEM) param;
  484. }
  485. else
  486. {
  487. m_scopeDataItem.ID = (HSCOPEITEM) param;
  488. }
  489. hr = EnumerateScopeChildren( spConsoleNameSpace );
  490. }
  491. else // arg != TRUE so not expanding
  492. {
  493. // do nothing for now -- I don't think arg = FALSE is even implemented
  494. // for MMC v. 1.0 or 1.1
  495. }
  496. return hr;
  497. }
  498. /////////////////////////////////////////////////////////////////////////////
  499. /*++
  500. CNodeWithScopeChildrenList::EnumerateScopeChildren
  501. Don't override this in your derived class. Instead, override the method
  502. it calls, PopulateScopeChildrenList.
  503. --*/
  504. //////////////////////////////////////////////////////////////////////////////
  505. template <class T, BOOL bIsExtension>
  506. HRESULT CNodeWithScopeChildrenList<T,bIsExtension>::EnumerateScopeChildren( IConsoleNameSpace* pConsoleNameSpace )
  507. {
  508. DEBUG_FUNCTION_NAME(
  509. _T("CNodeWithScopeChildrenList::EnumerateScopeChildren"));
  510. UNREFERENCED_PARAMETER (pConsoleNameSpace);
  511. // Check for preconditions:
  512. // None.
  513. HRESULT hr;
  514. if ( FALSE == m_bScopeChildrenListPopulated )
  515. {
  516. // We have not yet loaded all of our children into our list.
  517. hr = PopulateScopeChildrenList();
  518. if( FAILED(hr) )
  519. {
  520. return( hr );
  521. }
  522. // We've already loaded our children objects with
  523. // data necessary to populate the result pane.
  524. m_bScopeChildrenListPopulated = TRUE; // We only want to do this once.
  525. }
  526. // We don't need any code here to InsertItem the children into the
  527. // scope pane as we did in the EnumerateScopeChildren method
  528. // for CNodeWithResultChildrenList.
  529. // This is one difference between adding nodes into the scope
  530. // pane and the result pane. Because MMC takes care of replicating
  531. // scope pane changes to all views, we don't need to worry about
  532. // sending an UpdateAllViews notification and handling insertion
  533. // there for each result pane. Instead, we just do InsertItem once.
  534. // So for CNodeWithScopePaneChildren, we call InsertItem
  535. // in the AddChild method which is called by PopulateScopeChildrenList
  536. // above.
  537. return S_OK;
  538. }
  539. #endif // _NODE_WITH_SCOPE_CHILDREN_LIST_H_