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.

509 lines
13 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. NodeWithScopeChildrenList.cpp
  6. Abstract:
  7. Implementation file for the CNodeWithScopeChildrenList subclass.
  8. This is the implementation portion of an inline template class.
  9. Include it in the .cpp file of the class in which you want to
  10. use the template.
  11. Author:
  12. Michael A. Maguire 12/01/97
  13. Revision History:
  14. mmaguire 12/01/97 - abstracted from CRootNode, which will be changed to subclass this class
  15. --*/
  16. //////////////////////////////////////////////////////////////////////////////
  17. //////////////////////////////////////////////////////////////////////////////
  18. // BEGIN INCLUDES
  19. //
  20. // standard includes:
  21. //
  22. //
  23. // where we can find declaration for main class in this file:
  24. //
  25. #include "NodeWithScopeChildrenList.h"
  26. //
  27. //
  28. // where we can find declarations needed in this file:
  29. //
  30. #include "SnapinNode.cpp" // Template class implementation
  31. //
  32. // END INCLUDES
  33. //////////////////////////////////////////////////////////////////////////////
  34. //////////////////////////////////////////////////////////////////////////////
  35. /*++
  36. CNodeWithScopeChildrenList::AddChild
  37. Adds a child to the list of children.
  38. This has to be public as it must be accessible even from a separate dialog
  39. (e.g. a Connect to Server dialog) that may want to add a child.
  40. Here we add the child item to the list of children and call InsertItem
  41. to add the child to the scope pane.
  42. This is one difference between adding nodes into the scope
  43. pane and the result pane. When we were inserting a child into
  44. the result pane, we didn't call InsertItem in the AddChild methods(s)
  45. because we needed to worry about sending an UpdataAllViews
  46. notification and repopulating the result pane in each view.
  47. Because MMC takes care of replicating scope pane changes to all views,
  48. we don't need to worry about this. Instead, we just do InsertItem once here.
  49. --*/
  50. //////////////////////////////////////////////////////////////////////////////
  51. template < class T, class CChildNode >
  52. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::AddChild( CChildNode * pChildNode )
  53. {
  54. ATLTRACE(_T("# CNodeWithScopeChildrenList::AddChild\n"));
  55. // Check for preconditions:
  56. // None.
  57. HRESULT hr = S_OK;
  58. if( m_ScopeChildrenList.Add( pChildNode ) )
  59. {
  60. // Insert the item into the result pane now
  61. // so that the new item will show up immediately
  62. CComponentData *pComponentData = GetComponentData();
  63. _ASSERTE(pComponentData != NULL );
  64. // Need IConsoleNameSpace
  65. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace( pComponentData->m_spConsole );
  66. _ASSERT( spConsoleNameSpace != NULL );
  67. // We hand our HSCOPEITEM as the parent ID for this child.
  68. pChildNode->m_scopeDataItem.relativeID = (HSCOPEITEM) m_scopeDataItem.ID;
  69. hr = spConsoleNameSpace->InsertItem( &(pChildNode->m_scopeDataItem) );
  70. if (FAILED(hr))
  71. {
  72. return hr;
  73. }
  74. // Check: On return, the ID member of 'm_scopeDataItem'
  75. // contains the handle to the newly inserted item.
  76. _ASSERT( NULL != pChildNode->m_scopeDataItem.ID );
  77. }
  78. else
  79. {
  80. // Failed to add => out of memory
  81. hr = E_OUTOFMEMORY;
  82. }
  83. return hr;
  84. }
  85. //////////////////////////////////////////////////////////////////////////////
  86. /*++
  87. CNodeWithScopeChildrenList::RemoveChild
  88. Removes a child from the list of children.
  89. This has to be public so that child nodes can ask their parent to be deleted
  90. from the list of children when they receive the MMCN_DELETE notification.
  91. --*/
  92. //////////////////////////////////////////////////////////////////////////////
  93. template < class T, class CChildNode >
  94. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::RemoveChild( CChildNode * pChildNode )
  95. {
  96. ATLTRACE(_T("# CNodeWithScopeChildrenList::RemoveChild\n"));
  97. // Check for preconditions:
  98. // None.
  99. HRESULT hr = S_OK;
  100. if( m_ScopeChildrenList.Remove( pChildNode ) )
  101. {
  102. // Need IConsoleNameSpace
  103. CComponentData *pComponentData = GetComponentData();
  104. _ASSERTE(pComponentData != NULL );
  105. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace( pComponentData->m_spConsole );
  106. _ASSERT( spConsoleNameSpace != NULL );
  107. hr = spConsoleNameSpace->DeleteItem( pChildNode->m_scopeDataItem.ID, TRUE );
  108. if (FAILED(hr))
  109. {
  110. return hr;
  111. }
  112. }
  113. else
  114. {
  115. // If we failed to remove, probably the child was never in the list
  116. // ISSUE: determine what do here -- this should never happen
  117. _ASSERTE( FALSE );
  118. hr = S_FALSE;
  119. }
  120. return hr;
  121. }
  122. /////////////////////////////////////////////////////////////////////////////
  123. /*++
  124. CNodeWithScopeChildrenList::CNodeWithScopeChildrenList
  125. Constructor
  126. This is an base class which we don't want instantiated on its own,
  127. so the contructor is protected
  128. --*/
  129. //////////////////////////////////////////////////////////////////////////////
  130. template < class T, class CChildNode >
  131. CNodeWithScopeChildrenList<T,CChildNode>::CNodeWithScopeChildrenList( CSnapInItem * pParentNode ): CSnapinNode< T >( pParentNode )
  132. {
  133. ATLTRACE(_T("# +++ CNodeWithScopeChildrenList::CNodeWithScopeChildrenList\n"));
  134. // Check for preconditions:
  135. // None.
  136. // We have not yet loaded the child nodes' data
  137. m_bScopeChildrenListPopulated = FALSE;
  138. }
  139. /////////////////////////////////////////////////////////////////////////////
  140. /*++
  141. CNodeWithScopeChildrenList::~CNodeWithScopeChildrenList
  142. Destructor
  143. --*/
  144. //////////////////////////////////////////////////////////////////////////////
  145. template < class T, class CChildNode >
  146. CNodeWithScopeChildrenList<T,CChildNode>::~CNodeWithScopeChildrenList()
  147. {
  148. ATLTRACE(_T("# --- CNodeWithScopeChildrenList::~CNodeWithScopeChildrenList\n"));
  149. // Check for preconditions:
  150. // None.
  151. // Delete each node in the list of children
  152. CChildNode* pChildNode;
  153. for (int i = 0; i < m_ScopeChildrenList.GetSize(); i++)
  154. {
  155. pChildNode = m_ScopeChildrenList[i];
  156. delete pChildNode;
  157. }
  158. // Empty the list
  159. m_ScopeChildrenList.RemoveAll();
  160. }
  161. /////////////////////////////////////////////////////////////////////////////
  162. /*++
  163. CNodeWithScopeChildrenList::PopulateScopeChildrenList
  164. Override this in your derived class to populate the list of children nodes.
  165. --*/
  166. //////////////////////////////////////////////////////////////////////////////
  167. template < class T, class CChildNode >
  168. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::PopulateScopeChildrenList( void )
  169. {
  170. ATLTRACE(_T("# CNodeWithScopeChildrenList::PopulateScopeChildren -- override in your derived class\n"));
  171. // Check for preconditions:
  172. // None.
  173. // override in your derived class and do something like:
  174. /*
  175. CSomeChildNode *myChild1 = new CSomeChildNode();
  176. m_CChildrenList.Add(myChild1);
  177. CSomeChildNode *myChild2 = new CSomeChildNode();
  178. m_CChildrenList.Add(myChild2);
  179. CSomeChildNode *myChild3 = new CSomeChildNode();
  180. m_CChildrenList.Add(myChild3);
  181. */
  182. return S_OK;
  183. }
  184. //////////////////////////////////////////////////////////////////////////////
  185. /*++
  186. CNodeWithScopeChildrenList::OnShow
  187. Don't override this in your derived class. Instead, override methods
  188. which it calls: InsertColumns
  189. This method is an override of CSnapinNode::OnShow. When MMC passes the
  190. MMCN_SHOW method for this node.
  191. For more information, see CSnapinNode::OnShow.
  192. --*/
  193. //////////////////////////////////////////////////////////////////////////////
  194. template < class T, class CChildNode >
  195. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::OnShow(
  196. LPARAM arg
  197. , LPARAM param
  198. , IComponentData * pComponentData
  199. , IComponent * pComponent
  200. , DATA_OBJECT_TYPES type
  201. )
  202. {
  203. ATLTRACE(_T("# CNodeScopeChildrenList::OnShow\n"));
  204. // Check for preconditions:
  205. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  206. HRESULT hr = S_FALSE;
  207. //ISSUE: only do this if selected (arg = TRUE) -- what should we do if not selected?
  208. // See sburns' localsec example
  209. if( arg )
  210. {
  211. // arg <> 0 => we are being selected.
  212. // Need IHeaderCtrl.
  213. // But to get that, first we need IConsole
  214. CComPtr<IConsole> spConsole;
  215. if( pComponentData != NULL )
  216. {
  217. spConsole = ((CComponentData*)pComponentData)->m_spConsole;
  218. }
  219. else
  220. {
  221. // We should have a non-null pComponent
  222. spConsole = ((CComponent*)pComponent)->m_spConsole;
  223. }
  224. _ASSERTE( spConsole != NULL );
  225. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeaderCtrl(spConsole);
  226. _ASSERT( spHeaderCtrl != NULL );
  227. hr = InsertColumns( spHeaderCtrl );
  228. _ASSERT( S_OK == hr );
  229. }
  230. return hr;
  231. }
  232. //////////////////////////////////////////////////////////////////////////////
  233. /*++
  234. CNodeWithScopeChildrenList::InsertColumns
  235. Override this in your derived class.
  236. This method is called by OnShow when it needs you to set the appropriate
  237. column headers to be displayed in the result pane for this node.
  238. --*/
  239. //////////////////////////////////////////////////////////////////////////////
  240. template < class T, class CChildNode >
  241. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::InsertColumns( IHeaderCtrl* pHeaderCtrl )
  242. {
  243. ATLTRACE(_T("# CNodeWithScopeChildrenList::InsertColumns -- override in your derived class\n"));
  244. // Check for preconditions:
  245. _ASSERTE( pHeaderCtrl != NULL );
  246. HRESULT hr;
  247. // override in your derived class and do something like:
  248. hr = pHeaderCtrl->InsertColumn( 0, L"@Column 1 -- override CNodeWithResultChildrenList::OnShowInsertColumns", 0, 120 );
  249. _ASSERT( S_OK == hr );
  250. hr = pHeaderCtrl->InsertColumn( 1, L"@Column 2 -- override CNodeWithResultChildrenList::OnShowInsertColumns", 0, 300 );
  251. _ASSERT( S_OK == hr );
  252. return hr;
  253. }
  254. //////////////////////////////////////////////////////////////////////////////
  255. /*++
  256. CNodeWithScopeChildren::OnExpand
  257. Don't override this in your derived class. Instead, override methods
  258. which it calls: PopulateScopeChildrenList
  259. This method is an override of CSnapinNode::OnExpand. When MMC passes the
  260. MMCN_EXPAND method for this node, we are to add children into the
  261. scope pane. In this class we add them from a list we maintain.
  262. For more information, see CSnapinNode::OnExpand.
  263. --*/
  264. //////////////////////////////////////////////////////////////////////////////
  265. template < class T, class CChildNode >
  266. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::OnExpand(
  267. LPARAM arg
  268. , LPARAM param
  269. , IComponentData * pComponentData
  270. , IComponent * pComponent
  271. , DATA_OBJECT_TYPES type
  272. )
  273. {
  274. ATLTRACE(_T("# CNodeWithScopeChildren::OnExpand\n"));
  275. // Check for preconditions:
  276. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  277. HRESULT hr = S_FALSE;
  278. if( TRUE == arg )
  279. {
  280. // Need IConsoleNameSpace
  281. // But to get that, first we need IConsole
  282. CComPtr<IConsole> spConsole;
  283. if( pComponentData != NULL )
  284. {
  285. spConsole = ((CComponentData*)pComponentData)->m_spConsole;
  286. }
  287. else
  288. {
  289. // We should have a non-null pComponent
  290. spConsole = ((CComponent*)pComponent)->m_spConsole;
  291. }
  292. _ASSERTE( spConsole != NULL );
  293. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  294. _ASSERT( spConsoleNameSpace != NULL );
  295. hr = EnumerateScopeChildren( spConsoleNameSpace );
  296. }
  297. else // arg != TRUE so not expanding
  298. {
  299. // do nothing for now -- I don't think arg = FALSE is even implemented
  300. // for MMC v. 1.0 or 1.1
  301. }
  302. return hr;
  303. }
  304. /////////////////////////////////////////////////////////////////////////////
  305. /*++
  306. CNodeWithScopeChildrenList::EnumerateScopeChildren
  307. Don't override this in your derived class. Instead, override the method
  308. it calls, PopulateScopeChildrenList.
  309. --*/
  310. //////////////////////////////////////////////////////////////////////////////
  311. template < class T, class CChildNode >
  312. HRESULT CNodeWithScopeChildrenList<T,CChildNode>::EnumerateScopeChildren( IConsoleNameSpace* pConsoleNameSpace )
  313. {
  314. ATLTRACE(_T("# CNodeWithScopeChildrenList::EnumerateScopeChildren\n"));
  315. // Check for preconditions:
  316. // None.
  317. HRESULT hr;
  318. if ( FALSE == m_bScopeChildrenListPopulated )
  319. {
  320. // We have not yet loaded all of our children into our list.
  321. hr = PopulateScopeChildrenList();
  322. if( FAILED(hr) )
  323. {
  324. return( hr );
  325. }
  326. // We've already loaded our children objects with
  327. // data necessary to populate the result pane.
  328. m_bScopeChildrenListPopulated = TRUE; // We only want to do this once.
  329. }
  330. // We don't need any code here to InsertItem the children into the
  331. // scope pane as we did in the EnumerateScopeChildren method
  332. // for CNodeWithResultChildrenList.
  333. // This is one difference between adding nodes into the scope
  334. // pane and the result pane. Because MMC takes care of replicating
  335. // scope pane changes to all views, we don't need to worry about
  336. // sending an UpdateAllViews notification and handling insertion
  337. // there for each result pane. Instead, we just do InsertItem once.
  338. // So for CNodeWithScopePaneChildren, we call InsertItem
  339. // in the AddChild method which is called by PopulateScopeChildrenList
  340. // above.
  341. return S_OK;
  342. }