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.

1991 lines
46 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. SnapinNode.h
  6. Abstract:
  7. Implementation file for the CSnapinNode class.
  8. This is our virtual base class for an MMC Snap-in node.
  9. This is the implementation portion of an inline template class.
  10. Include it in the .cpp file of the class in which you want to
  11. use the template.
  12. Author:
  13. Michael A. Maguire 11/6/97
  14. Revision History:
  15. mmaguire 11/6/97 - created using MMC snap-in wizard
  16. --*/
  17. //////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19. // BEGIN INCLUDES
  20. //
  21. // standard includes:
  22. //
  23. //
  24. // where we can find declaration for main class in this file:
  25. //
  26. #include "SnapinNode.h"
  27. //
  28. //
  29. // where we can find declarations needed in this file:
  30. //
  31. //
  32. // END INCLUDES
  33. //////////////////////////////////////////////////////////////////////////////
  34. //////////////////////////////////////////////////////////////////////////////
  35. /*++
  36. CSnapinNode:CreatePropertyPages
  37. Adds pages to a property sheet.
  38. HRESULT CreatePropertyPages(
  39. LPPROPERTYSHEETCALLBACK lpProvider,
  40. // Pointer to the callback interface
  41. LONG_PTR handle, // Handle for routing notification
  42. LPDATAOBJECT lpIDataObject // Pointer to the data object
  43. );
  44. Remarks:
  45. DON'T Override in your derived class. Instead, override the AddPropertyPages
  46. method which this class uses in your derived class.
  47. This is because we have some standard processing to do for all nodes
  48. on CreatePropertyPages, namely to check to see whether the property
  49. sheet for the node is already up. If it is, we bring that page to the
  50. front and exit without needlessly recreating property pages.
  51. Parameters
  52. lpProvider
  53. [in] Pointer to the IPropertySheetCallback interface.
  54. handle
  55. [in] Specifies the handle used to route the MMCN_PROPERTY_CHANGE notification message to the appropriate IComponent or IComponentData.
  56. lpIDataObject
  57. [in] Pointer to the IDataObject interface on the object that contains context information about the node.
  58. Return Value
  59. S_OK
  60. The property sheet pages were successfully added.
  61. S_FALSE
  62. There were no pages added.
  63. E_UNEXPECTED
  64. An unexpected error occurred.
  65. E_INVALIDARG
  66. One or more parameters are invalid.
  67. --*/
  68. //////////////////////////////////////////////////////////////////////////////
  69. template <class T, class TComponentData, class TComponent>
  70. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::CreatePropertyPages(
  71. LPPROPERTYSHEETCALLBACK lpProvider
  72. , LONG_PTR handle
  73. , IUnknown* pUnk
  74. , DATA_OBJECT_TYPES type
  75. )
  76. {
  77. ATLTRACE(_T("# CSnapinNode::CreatePropertyPages -- override in your derived class\n"));
  78. return E_NOTIMPL;
  79. }
  80. //////////////////////////////////////////////////////////////////////////////
  81. /*++
  82. CSnapinNode:QueryPagesFor
  83. Determines whether the object requires pages.
  84. HRESULT QueryPagesFor( DATA_OBJECT_TYPES type );
  85. Parameters
  86. void
  87. Return Value
  88. S_OK
  89. Properties exist for this cookie.
  90. E_UNEXPECTED
  91. An unexpected error occurred.
  92. E_INVALID
  93. The parameter is invalid.
  94. ISSUE: So what do we return if an item doesn't have property pages?
  95. S_FALSE is used in sburns' localsec code
  96. Remarks
  97. The console calls this method to determine whether the Properties menu
  98. item should be added to the context menu.
  99. --*/
  100. //////////////////////////////////////////////////////////////////////////////
  101. template <class T, class TComponentData, class TComponent>
  102. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::QueryPagesFor( DATA_OBJECT_TYPES type )
  103. {
  104. ATLTRACE(_T("# CSnapinNode::QueryPagesFor -- override in your derived class if you have property pages\n"));
  105. // this method should be overriden and should return S_OK if you
  106. // have property pages for this node otherwise it should return S_FALSE.
  107. return S_FALSE;
  108. }
  109. //////////////////////////////////////////////////////////////////////////////
  110. /*++
  111. CSnapinNode:InitDataClass
  112. --*/
  113. //////////////////////////////////////////////////////////////////////////////
  114. template <class T, class TComponentData, class TComponent>
  115. void CSnapinNode<T, TComponentData, TComponent>::InitDataClass(IDataObject* pDataObject, CSnapInItem* pDefault)
  116. {
  117. // The default code stores off the pointer to the Dataobject the class is wrapping
  118. // at the time.
  119. // Alternatively you could convert the dataobject to the internal format
  120. // it represents and store that information
  121. m_pDataObject = pDataObject;
  122. }
  123. //////////////////////////////////////////////////////////////////////////////
  124. /*++
  125. CSnapinNode:GetResultPaneInfo
  126. ISSUE: what are the parameters to this function? Why not void?
  127. --*/
  128. //////////////////////////////////////////////////////////////////////////////
  129. template <class T, class TComponentData, class TComponent>
  130. void* CSnapinNode<T, TComponentData, TComponent>::GetDisplayName()
  131. {
  132. ATLTRACE(_T("# CSnapinNode::GetDisplayName\n"));
  133. // ISSUE: It looks as thought the m_SZDISPLAY_NAME is a totally
  134. // bogus variable -- we should think about eliminating it
  135. // Problematic -- const m_SZDISPLAY_NAME can't be localized
  136. // return (void*)m_SZDISPLAY_NAME;
  137. return (void*)m_bstrDisplayName;
  138. }
  139. // void* GetSnapInCLSID()
  140. // {
  141. // ATLTRACE(_T("# CSnapinNode::GetSnapInCLSID\n"));
  142. //
  143. // return (void*)m_SNAPIN_CLASSID;
  144. // }
  145. //////////////////////////////////////////////////////////////////////////////
  146. /*++
  147. CSnapinNode:GetScopePaneInfo
  148. --*/
  149. //////////////////////////////////////////////////////////////////////////////
  150. template <class T, class TComponentData, class TComponent>
  151. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::GetScopePaneInfo( SCOPEDATAITEM *pScopeDataItem )
  152. {
  153. ATLTRACE(_T("# CSnapinNode::GetScopePaneInfo\n"));
  154. if (pScopeDataItem->mask & SDI_STR)
  155. pScopeDataItem->displayname = m_bstrDisplayName;
  156. if (pScopeDataItem->mask & SDI_IMAGE)
  157. pScopeDataItem->nImage = m_scopeDataItem.nImage;
  158. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  159. pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage;
  160. if (pScopeDataItem->mask & SDI_PARAM)
  161. pScopeDataItem->lParam = m_scopeDataItem.lParam;
  162. if (pScopeDataItem->mask & SDI_STATE )
  163. pScopeDataItem->nState = m_scopeDataItem.nState;
  164. // TODO : Add code for SDI_CHILDREN
  165. return S_OK;
  166. }
  167. //////////////////////////////////////////////////////////////////////////////
  168. /*++
  169. CSnapinNode:GetResultPaneInfo
  170. --*/
  171. //////////////////////////////////////////////////////////////////////////////
  172. template <class T, class TComponentData, class TComponent>
  173. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::GetResultPaneInfo( RESULTDATAITEM *pResultDataItem )
  174. {
  175. ATLTRACE(_T("# CSnapinNode::GetResultPaneInfo\n"));
  176. if (pResultDataItem->bScopeItem)
  177. {
  178. if (pResultDataItem->mask & RDI_STR)
  179. {
  180. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  181. }
  182. if (pResultDataItem->mask & RDI_IMAGE)
  183. {
  184. pResultDataItem->nImage = m_scopeDataItem.nImage;
  185. }
  186. if (pResultDataItem->mask & RDI_PARAM)
  187. {
  188. pResultDataItem->lParam = m_scopeDataItem.lParam;
  189. }
  190. return S_OK;
  191. }
  192. if (pResultDataItem->mask & RDI_STR)
  193. {
  194. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  195. }
  196. if (pResultDataItem->mask & RDI_IMAGE)
  197. {
  198. pResultDataItem->nImage = m_resultDataItem.nImage;
  199. }
  200. if (pResultDataItem->mask & RDI_PARAM)
  201. {
  202. pResultDataItem->lParam = m_resultDataItem.lParam;
  203. }
  204. if (pResultDataItem->mask & RDI_INDEX)
  205. {
  206. pResultDataItem->nIndex = m_resultDataItem.nIndex;
  207. }
  208. return S_OK;
  209. }
  210. //////////////////////////////////////////////////////////////////////////////
  211. /*++
  212. CSnapinNode::Notify
  213. This method is this node's response to the MMC calling Notify on
  214. IComponent or IComponentData.
  215. STDMETHOD( Notify ) (
  216. MMC_NOTIFY_TYPE event
  217. , LPARAM arg
  218. , LPARAM param
  219. , IComponentData * pComponentData
  220. , IComponent * pComponent
  221. , DATA_OBJECT_TYPES type
  222. )
  223. Parameters
  224. event
  225. [in] Identifies an action taken by a user. IComponent::Notify and
  226. IComponentData::Notify can receive the following notifications for a
  227. specific node:
  228. MMCN_ACTIVATE
  229. MMCN_ADD_IMAGES
  230. MMCN_BTN_CLICK
  231. MMCN_CLICK
  232. MMCN_CONTEXTMENU
  233. MMCN_DBLCLICK
  234. MMCN_DELETE
  235. MMCN_EXPAND
  236. MMCN_HELP
  237. MMCN_MENU_BTNCLICK
  238. MMCN_MINIMIZED
  239. MMCN_PROPERTY_CHANGE
  240. MMCN_REFRESH
  241. MMCN_REMOVE_CHILDREN
  242. MMCN_RENAME
  243. MMCN_SELECT
  244. MMCN_SHOW
  245. MMCN_VIEW_CHANGE
  246. MMCN_CONTEXTHELP
  247. See CSnapinNode::OnActivate, OnAddImages, OnButtonClick, etc. for
  248. a detailed explanation of each of these notify events
  249. arg
  250. Depends on the notification type.
  251. param
  252. Depends on the notification type.
  253. Return Values
  254. S_OK
  255. Depends on the notification type.
  256. E_UNEXPECTED
  257. An unexpected error occurred.
  258. Remarks
  259. Our IComponentData and IComponent implementations were passed a LPDATAOBJECT
  260. which corresponds to a node. This was converted to a pointer to
  261. a node object. Below is the Notify method on this node object, were
  262. the node object can deal with the Notify event itself.
  263. Our implementation of Notify is a large switch statement which delegates the
  264. task of dealing with virtual OnXxxxxx methods which can overridden in
  265. derived classes. As all events are dealt with this way here, you shouldn't
  266. need to implement a Notify method for any of your derived nodes.
  267. --*/
  268. //////////////////////////////////////////////////////////////////////////////
  269. template <class T, class TComponentData, class TComponent>
  270. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>:: Notify (
  271. MMC_NOTIFY_TYPE event
  272. , LPARAM arg
  273. , LPARAM param
  274. , IComponentData * pComponentData
  275. , IComponent * pComponent
  276. , DATA_OBJECT_TYPES type
  277. )
  278. {
  279. ATLTRACE(_T("# CSnapinNode::Notify\n"));
  280. HRESULT hr = S_FALSE;
  281. // this makes for faster code.
  282. T* pT = static_cast<T*> (this);
  283. switch( event )
  284. {
  285. case MMCN_ACTIVATE:
  286. hr = pT->OnActivate( arg, param, pComponentData, pComponent, type );
  287. break;
  288. case MMCN_ADD_IMAGES:
  289. hr = pT->OnAddImages( arg, param, pComponentData, pComponent, type );
  290. break;
  291. case MMCN_BTN_CLICK:
  292. hr = pT->OnButtonClick( arg, param, pComponentData, pComponent, type );
  293. break;
  294. case MMCN_CLICK:
  295. hr = pT->OnClick( arg, param, pComponentData, pComponent, type );
  296. break;
  297. case MMCN_CONTEXTHELP:
  298. hr = pT->OnContextHelp( arg, param, pComponentData, pComponent, type );
  299. break;
  300. case MMCN_CONTEXTMENU:
  301. hr = pT->OnContextMenu( arg, param, pComponentData, pComponent, type );
  302. break;
  303. case MMCN_CUTORMOVE:
  304. hr = pT->OnDelete( arg, param, pComponentData, pComponent, type, TRUE );
  305. break;
  306. case MMCN_DBLCLICK:
  307. hr = pT->OnDoubleClick( arg, param, pComponentData, pComponent, type );
  308. break;
  309. case MMCN_DELETE:
  310. hr = pT->OnDelete( arg, param, pComponentData, pComponent, type, FALSE );
  311. break;
  312. case MMCN_EXPAND:
  313. hr = pT->OnExpand( arg, param, pComponentData, pComponent, type );
  314. break;
  315. case MMCN_HELP:
  316. hr = pT->OnHelp( arg, param, pComponentData, pComponent, type );
  317. break;
  318. case MMCN_MENU_BTNCLICK:
  319. hr = pT->OnMenuButtonClick( arg, param, pComponentData, pComponent, type );
  320. break;
  321. case MMCN_MINIMIZED:
  322. hr = pT->OnMinimized( arg, param, pComponentData, pComponent, type );
  323. break;
  324. case MMCN_PASTE:
  325. hr = pT->OnPaste( arg, param, pComponentData, pComponent, type );
  326. break;
  327. case MMCN_PROPERTY_CHANGE:
  328. hr = pT->OnPropertyChange( arg, param, pComponentData, pComponent, type );
  329. break;
  330. case MMCN_QUERY_PASTE:
  331. hr = pT->OnQueryPaste( arg, param, pComponentData, pComponent, type );
  332. break;
  333. case MMCN_REFRESH:
  334. hr = pT->OnRefresh( arg, param, pComponentData, pComponent, type );
  335. break;
  336. case MMCN_REMOVE_CHILDREN:
  337. hr = pT->OnRemoveChildren( arg, param, pComponentData, pComponent, type );
  338. break;
  339. case MMCN_RENAME:
  340. hr = pT->OnRename( arg, param, pComponentData, pComponent, type );
  341. break;
  342. case MMCN_SELECT:
  343. // For nodes with result-pane children
  344. hr = pT->OnSelect( arg, param, pComponentData, pComponent, type );
  345. break;
  346. case MMCN_SHOW:
  347. // For nodes with result-pane children
  348. // We call PreOnShow which will then call OnShow.
  349. // PreOnShow will save away the selected node in a member variable
  350. // of out CComponent class.
  351. hr = pT->PreOnShow( arg, param, pComponentData, pComponent, type );
  352. break;
  353. case MMCN_VIEW_CHANGE:
  354. hr = pT->OnViewChange( arg, param, pComponentData, pComponent, type );
  355. break;
  356. case MMCN_COLUMNS_CHANGED:
  357. hr = S_FALSE;
  358. break;
  359. default:
  360. // Unhandled notify event.
  361. // MMC wants E_NOTIMPL if you can't do something or it will crash
  362. hr = E_NOTIMPL;
  363. break;
  364. }
  365. return hr;
  366. }
  367. //////////////////////////////////////////////////////////////////////////////
  368. /*++
  369. CSnapinNode:CSnapinNode
  370. Constructor
  371. This class is to be the virtual base class for all our nodes
  372. We never want people instantiating it so the constructor is protected
  373. --*/
  374. //////////////////////////////////////////////////////////////////////////////
  375. template <class T, class TComponentData, class TComponent>
  376. CSnapinNode<T, TComponentData, TComponent>::CSnapinNode(
  377. CSnapInItem * pParentNode,
  378. unsigned int helpIndex
  379. )
  380. :CSnapInItemImpl<T>(helpIndex)
  381. {
  382. ATLTRACE(_T("# +++ CSnapinNode::CSnapinNode\n"));
  383. // Set the parent node below which this node is displayed.
  384. m_pParentNode = pParentNode;
  385. // We set cookie for both scope and result pane data items,
  386. // as this class can be subclassed for either a scope-pane
  387. // or a result-pane-only node.
  388. // Sridhar moved this initialization code out of SnapInItemImpl
  389. memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM));
  390. m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM;
  391. m_scopeDataItem.displayname = MMC_CALLBACK;
  392. m_scopeDataItem.nImage = 0; // May need modification
  393. m_scopeDataItem.nOpenImage = 0; // May need modification
  394. // If this node is inserted in to the scope pane using
  395. // IConsoleNamespace->InsertItem, the value stored in lParam
  396. // will be what MMC later passes back as the cookie for this node.
  397. m_scopeDataItem.lParam = (LPARAM) this;
  398. // Sridhar moved this initialization code out of SnapInItemImpl
  399. memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM));
  400. m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
  401. m_resultDataItem.str = MMC_CALLBACK;
  402. m_resultDataItem.nImage = 0; // May need modification
  403. // If this node is inserted in to the result pane using
  404. // IResultData->InsertItem, the value stored in lParam will
  405. // be what MMC later passes back as the cookie for this node.
  406. m_resultDataItem.lParam = (LPARAM) this;
  407. }
  408. //////////////////////////////////////////////////////////////////////////////
  409. /*++
  410. CSnapinNode:~CSnapinNode
  411. Destructor
  412. --*/
  413. //////////////////////////////////////////////////////////////////////////////
  414. template <class T, class TComponentData, class TComponent>
  415. CSnapinNode<T, TComponentData, TComponent>::~CSnapinNode()
  416. {
  417. ATLTRACE(_T("# --- CSnapinNode::~CSnapinNode\n"));
  418. }
  419. //////////////////////////////////////////////////////////////////////////////
  420. /*++
  421. CSnapinNode:GetResultPaneColInfo
  422. --*/
  423. //////////////////////////////////////////////////////////////////////////////
  424. template <class T, class TComponentData, class TComponent>
  425. LPOLESTR CSnapinNode<T, TComponentData, TComponent>::GetResultPaneColInfo(int nCol)
  426. {
  427. ATLTRACE(_T("# CSnapinNode::GetResultPaneColInf\n"));
  428. if (nCol == 0)
  429. {
  430. return m_bstrDisplayName;
  431. }
  432. // TODO : Return the text for other columns
  433. return OLESTR("CSnapinNode::GetResultPaneColInfo -- Override in your derived class");
  434. }
  435. /////////////////////////////////////////////////////////////////////////////
  436. /*++
  437. CSnapinNode::OnActivate
  438. virtual HRESULT OnActivate(
  439. LPARAM arg
  440. , LPARAM param
  441. , IComponentData * pComponentData
  442. , IComponent * pComponent
  443. , DATA_OBJECT_TYPES type
  444. )
  445. In our implementation, this method gets called when the MMCN_ACTIVATE
  446. Notify message is sent for this node.
  447. MMC sends this message to the snap-in's IComponent::Notify method when a window is
  448. being activated or deactivated.
  449. Parameters
  450. arg
  451. TRUE if the window is activated; otherwise, it is FALSE.
  452. param
  453. Not used.
  454. Return Values
  455. Not used.
  456. --*/
  457. //////////////////////////////////////////////////////////////////////////////
  458. template <class T, class TComponentData, class TComponent>
  459. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnActivate(
  460. LPARAM arg
  461. , LPARAM param
  462. , IComponentData * pComponentData
  463. , IComponent * pComponent
  464. , DATA_OBJECT_TYPES type
  465. )
  466. {
  467. ATLTRACE(_T("# CSnapinNode::OnActivate -- Override in your derived class\n"));
  468. return E_NOTIMPL;
  469. }
  470. /////////////////////////////////////////////////////////////////////////////
  471. /*++
  472. CSnapinNode::OnAddImages
  473. virtual HRESULT OnAddImages(
  474. LPARAM arg
  475. , LPARAM param
  476. , IComponentData * pComponentData
  477. , IComponent * pComponent
  478. , DATA_OBJECT_TYPES type
  479. )
  480. We have chosen to handle this on a per-IComponent object basis, since it has
  481. very little to do (for us at least) with the particular IDataObject.
  482. See CComponent::OnAddImages for where we add images.
  483. --*/
  484. //////////////////////////////////////////////////////////////////////////////
  485. template <class T, class TComponentData, class TComponent>
  486. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnAddImages(
  487. LPARAM arg
  488. , LPARAM param
  489. , IComponentData * pComponentData
  490. , IComponent * pComponent
  491. , DATA_OBJECT_TYPES type
  492. )
  493. {
  494. ATLTRACE(_T("# CSnapinNode::OnAddImages -- Override in your derived class\n"));
  495. return E_NOTIMPL;
  496. }
  497. /////////////////////////////////////////////////////////////////////////////
  498. /*++
  499. CSnapinNode::OnButtonClick
  500. virtual HRESULT OnButtonClick(
  501. LPARAM arg
  502. , LPARAM param
  503. , IComponentData * pComponentData
  504. , IComponent * pComponent
  505. , DATA_OBJECT_TYPES type
  506. )
  507. In our implementation, this method gets called when the MMCN_BTN_CLICK Notify message is
  508. sent for this node.
  509. MMC sends this message to the snap-in's IComponent, IComponentData,
  510. or IExtendControlbar implementation when a user clicks on one of the
  511. toolbar buttons.
  512. Parameters
  513. For IComponent::Notify or IComponentData::Notify:
  514. arg
  515. Must be zero.
  516. param
  517. CmdID of the button equal to a value of the MMC_CONSOLE_VERB enumeration.
  518. For IExtendControlBar::ControlbarNotify:
  519. arg
  520. Data object of the currently selected scope or result pane item.
  521. param
  522. [in] CmdID of the button equal to a value of the MMC_CONSOLE_VERB enumeration.
  523. Return Values
  524. Not used.
  525. --*/
  526. //////////////////////////////////////////////////////////////////////////////
  527. template <class T, class TComponentData, class TComponent>
  528. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnButtonClick(
  529. LPARAM arg
  530. , LPARAM param
  531. , IComponentData * pComponentData
  532. , IComponent * pComponent
  533. , DATA_OBJECT_TYPES type
  534. )
  535. {
  536. ATLTRACE(_T("# CSnapinNode::OnButtonClick -- Override in your derived class\n"));
  537. return E_NOTIMPL;
  538. }
  539. /////////////////////////////////////////////////////////////////////////////
  540. /*++
  541. CSnapinNode::OnClick
  542. virtual HRESULT OnClick(
  543. LPARAM arg
  544. , LPARAM param
  545. , IComponentData * pComponentData
  546. , IComponent * pComponent
  547. , DATA_OBJECT_TYPES type
  548. )
  549. In our implementation, this method gets called when the MMCN_CLICK Notify message is
  550. sent for this node.
  551. MMC sends this message to IComponent when a user clicks a mouse button
  552. on a list view item.
  553. Parameters
  554. arg
  555. Not used.
  556. param
  557. Not used.
  558. Return Values
  559. Not used.
  560. --*/
  561. //////////////////////////////////////////////////////////////////////////////
  562. template <class T, class TComponentData, class TComponent>
  563. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnClick(
  564. LPARAM arg
  565. , LPARAM param
  566. , IComponentData * pComponentData
  567. , IComponent * pComponent
  568. , DATA_OBJECT_TYPES type
  569. )
  570. {
  571. ATLTRACE(_T("# CSnapinNode::OnClick -- Override in your derived class\n"));
  572. return E_NOTIMPL;
  573. }
  574. /////////////////////////////////////////////////////////////////////////////
  575. /*++
  576. CSnapinNode::OnContextHelp
  577. virtual HRESULT OnContextHelp(
  578. LPARAM arg
  579. , LPARAM param
  580. , IComponentData * pComponentData
  581. , IComponent * pComponent
  582. , DATA_OBJECT_TYPES type
  583. )
  584. In our implementation, this method gets called when the MMCN_CONTEXTHELP Notify message is
  585. sent for this node.
  586. MMC sends this message when the user requests help about a selected item
  587. Parameters
  588. arg
  589. 0.
  590. param
  591. 0.
  592. Return Values
  593. Not used.
  594. --*/
  595. //////////////////////////////////////////////////////////////////////////////
  596. template <class T, class TComponentData, class TComponent>
  597. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnContextHelp(
  598. LPARAM arg
  599. , LPARAM param
  600. , IComponentData * pComponentData
  601. , IComponent * pComponent
  602. , DATA_OBJECT_TYPES type
  603. )
  604. {
  605. ATLTRACE(_T("# CSnapinNode::OnContextHelp -- Override in your derived class\n"));
  606. return E_NOTIMPL;
  607. }
  608. /////////////////////////////////////////////////////////////////////////////
  609. /*++
  610. CSnapinNode::OnContextMenu
  611. virtual HRESULT OnContextMenu(
  612. LPARAM arg
  613. , LPARAM param
  614. , IComponentData * pComponentData
  615. , IComponent * pComponent
  616. , DATA_OBJECT_TYPES type
  617. )
  618. In our implementation, this method gets called when the MMCN_CONTEXTMENU Notify
  619. message is sent for this node.
  620. In the Fall 97 Platform SDK documentation, this event is listed as not used.
  621. Parameters
  622. arg
  623. TBD
  624. param
  625. TBD
  626. Return Values
  627. Not used.
  628. --*/
  629. //////////////////////////////////////////////////////////////////////////////
  630. template <class T, class TComponentData, class TComponent>
  631. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnContextMenu(
  632. LPARAM arg
  633. , LPARAM param
  634. , IComponentData * pComponentData
  635. , IComponent * pComponent
  636. , DATA_OBJECT_TYPES type
  637. )
  638. {
  639. ATLTRACE(_T("# CSnapinNode::OnContextMenu -- Override in your derived class\n"));
  640. return E_NOTIMPL;
  641. }
  642. /////////////////////////////////////////////////////////////////////////////
  643. /*++
  644. CSnapinNode::OnDoubleClick
  645. virtual HRESULT OnDoubleClick(
  646. LPARAM arg
  647. , LPARAM param
  648. , IComponentData * pComponentData
  649. , IComponent * pComponent
  650. , DATA_OBJECT_TYPES type
  651. )
  652. In our implementation, this method gets called when the MMCN_DBLCLICK Notify message is
  653. sent for this node.
  654. MMC sends this message to IComponent when a user double clicks a mouse
  655. button on a list view item.
  656. Parameters
  657. arg
  658. Not used.
  659. param
  660. Not used.
  661. Return Values
  662. Not used.
  663. --*/
  664. //////////////////////////////////////////////////////////////////////////////
  665. template <class T, class TComponentData, class TComponent>
  666. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnDoubleClick(
  667. LPARAM arg
  668. , LPARAM param
  669. , IComponentData * pComponentData
  670. , IComponent * pComponent
  671. , DATA_OBJECT_TYPES type
  672. )
  673. {
  674. ATLTRACE(_T("# CSnapinNode::OnDoubleClick -- Override in your derived class if you don't want default verb action\n"));
  675. // Through speaking with Eugene Baucom, I discovered that if you return S_FALSE
  676. // here, the default verb action will occur when the user double clicks on a node.
  677. // For the most part we have Properties as default verb, so a double click
  678. // will cause property sheet on a node to pop up.
  679. // return E_NOTIMPL;
  680. return S_FALSE;
  681. }
  682. /////////////////////////////////////////////////////////////////////////////
  683. /*++
  684. CSnapinNode::OnDelete
  685. virtual HRESULT OnDelete(
  686. LPARAM arg
  687. , LPARAM param
  688. , IComponentData * pComponentData
  689. , IComponent * pComponent
  690. , DATA_OBJECT_TYPES type
  691. )
  692. In our implementation, this method gets called when the MMCN_DELETE Notify
  693. message is sent for this node.
  694. MMC sends this message to the snap-in's IComponent and IComponentData implementation to inform the snap-in that the object should be deleted.
  695. Parameters
  696. arg
  697. Not used.
  698. param
  699. Not used.
  700. Return Values
  701. Not used.
  702. Remarks
  703. This message is generated when the user presses the delete key or uses
  704. the mouse to click on the toolbar's delete button.
  705. --*/
  706. //////////////////////////////////////////////////////////////////////////////
  707. template <class T, class TComponentData, class TComponent>
  708. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnDelete(
  709. LPARAM arg
  710. , LPARAM param
  711. , IComponentData * pComponentData
  712. , IComponent * pComponent
  713. , DATA_OBJECT_TYPES type
  714. , BOOL fSilent
  715. )
  716. {
  717. ATLTRACE(_T("# CSnapinNode::OnDelete -- Override in your derived class\n"));
  718. return E_NOTIMPL;
  719. }
  720. /////////////////////////////////////////////////////////////////////////////
  721. /*++
  722. CSnapinNode::OnExpand
  723. virtual HRESULT OnExpand(
  724. LPARAM arg
  725. , LPARAM param
  726. , IComponentData * pComponentData
  727. , IComponent * pComponent
  728. , DATA_OBJECT_TYPES type
  729. )
  730. If your node will have scope-pane children,
  731. this method should be overidden in your derived class.
  732. In our implementation, this method gets called when the MMCN_EXPAND Notify message is
  733. sent for this node.
  734. MMC sends this message to the snap-in's IComponentData
  735. implementation when a folder node needs to be expanded or contracted.
  736. Parameters
  737. arg
  738. [in] If TRUE, the folder needs to be expanded. If FALSE, the folder needs to be contracted.
  739. Param
  740. [in] The HSCOPEITEM of the item that needs to be expanded.
  741. Return Values
  742. HRESULT
  743. Remarks
  744. On receipt of this notification the snap-in should enumerate the
  745. children (sub-containers only) of the specified scope item, if any,
  746. using IConsoleNameSpace methods. Subsequently, if a new item is added to
  747. or deleted from this scope object through some external means, then
  748. that item should also be added to or deleted from the console's
  749. namespace using IConsoleNameSpace methods.
  750. --*/
  751. //////////////////////////////////////////////////////////////////////////////
  752. template <class T, class TComponentData, class TComponent>
  753. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnExpand(
  754. LPARAM arg
  755. , LPARAM param
  756. , IComponentData * pComponentData
  757. , IComponent * pComponent
  758. , DATA_OBJECT_TYPES type
  759. )
  760. {
  761. ATLTRACE(_T("# CSnapinNode::OnExpand -- Override in your derived class\n"));
  762. return E_NOTIMPL;
  763. }
  764. /////////////////////////////////////////////////////////////////////////////
  765. /*++
  766. CSnapinNode::OnHelp
  767. virtual HRESULT OnHelp(
  768. LPARAM arg
  769. , LPARAM param
  770. , IComponentData * pComponentData
  771. , IComponent * pComponent
  772. , DATA_OBJECT_TYPES type
  773. )
  774. In our implementation, this method gets called when the MMCN_HELP Notify
  775. message is sent for this node.
  776. In the Fall 97 Platform SDK documentation, this event is listed as not used.
  777. MMC sends this message when the user presses the F1 help key.
  778. Parameters
  779. arg
  780. TBD
  781. param
  782. Pointer to a GUID. If NULL, the NodeType is used instead.
  783. Return Values
  784. Not used.
  785. --*/
  786. //////////////////////////////////////////////////////////////////////////////
  787. template <class T, class TComponentData, class TComponent>
  788. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnHelp(
  789. LPARAM arg
  790. , LPARAM param
  791. , IComponentData * pComponentData
  792. , IComponent * pComponent
  793. , DATA_OBJECT_TYPES type
  794. )
  795. {
  796. ATLTRACE(_T("# CSnapinNode::OnHelp -- Override in your derived class\n"));
  797. return E_NOTIMPL;
  798. }
  799. /////////////////////////////////////////////////////////////////////////////
  800. /*++
  801. CSnapinNode::OnMenuButtonClick
  802. virtual HRESULT OnMenuButtonClick(
  803. LPARAM arg
  804. , LPARAM param
  805. , IComponentData * pComponentData
  806. , IComponent * pComponent
  807. , DATA_OBJECT_TYPES type
  808. )
  809. In our implementation, this method gets called when the MMCN_MENU_BTNCLICK Notify
  810. message is sent for this node.
  811. MMC sends this ify message is sent Sent to the snap-in's IExtendControlbar
  812. interface when a user clicks on a menu button.
  813. Parameters
  814. arg
  815. Data object of currently selected scope or result pane item.
  816. param
  817. [in] Pointer to a MENUBUTTONDATA structure.
  818. Return Values
  819. Not Used.
  820. --*/
  821. //////////////////////////////////////////////////////////////////////////////
  822. template <class T, class TComponentData, class TComponent>
  823. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnMenuButtonClick(
  824. LPARAM arg
  825. , LPARAM param
  826. , IComponentData * pComponentData
  827. , IComponent * pComponent
  828. , DATA_OBJECT_TYPES type
  829. )
  830. {
  831. ATLTRACE(_T("# CSnapinNode::OnMenuButtonClick -- Override in your derived class\n"));
  832. return E_NOTIMPL;
  833. }
  834. /////////////////////////////////////////////////////////////////////////////
  835. /*++
  836. CSnapinNode::OnMinimized
  837. virtual HRESULT OnMinimized(
  838. LPARAM arg
  839. , LPARAM param
  840. , IComponentData * pComponentData
  841. , IComponent * pComponent
  842. , DATA_OBJECT_TYPES type
  843. )
  844. In our implementation, this method gets called when the MMCN_MINIMIZED Notify message is
  845. sent for this node.
  846. MMC sends this message to the snap-in's IComponent implementation when
  847. a window is being minimized or maximized.
  848. Parameters
  849. arg
  850. TRUE if the window has been minimized; otherwise, it is FALSE.
  851. Param
  852. Not used.
  853. Return Values
  854. Not Used
  855. --*/
  856. //////////////////////////////////////////////////////////////////////////////
  857. template <class T, class TComponentData, class TComponent>
  858. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnMinimized(
  859. LPARAM arg
  860. , LPARAM param
  861. , IComponentData * pComponentData
  862. , IComponent * pComponent
  863. , DATA_OBJECT_TYPES type
  864. )
  865. {
  866. ATLTRACE(_T("# CSnapinNode::OnMinimized -- Override in your derived class\n"));
  867. return E_NOTIMPL;
  868. }
  869. /////////////////////////////////////////////////////////////////////////////
  870. /*++
  871. CSnapinNode::OnPaste
  872. virtual HRESULT OnPaste(
  873. LPARAM arg
  874. , LPARAM param
  875. , IComponentData * pComponentData
  876. , IComponent * pComponent
  877. , DATA_OBJECT_TYPES type
  878. )
  879. In our implementation, this method gets called when the MMCN_PASTE
  880. Notify message is sent for this node.
  881. Called to ask the snap-ins folder to paste the selected items.
  882. Parameters
  883. pDataobject
  884. The data object in which to paste the selected items provided by the snap-in.
  885. arg
  886. The data object of the selected item(s) provided by the source snap-in that need to be pasted.
  887. param
  888. NULL for move (as opposed to cut).
  889. For a single-item paste:
  890. BOOL* pPasted = (BOOL*)param; Set this to TRUE here if the item was successfully pasted.
  891. For a multiitem paste:
  892. LPDATAOBJECT* ppDataObj = (LPDATAOBJECT*)param;
  893. Use this to return a pointer to a data object consisting of the items successfully pasted. See MMCN_CUTORMOVE.
  894. Return Values
  895. Not used.
  896. See Also
  897. MMCN_CUTORMOVE
  898. --*/
  899. //////////////////////////////////////////////////////////////////////////////
  900. template <class T, class TComponentData, class TComponent>
  901. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnPaste(
  902. LPARAM arg
  903. , LPARAM param
  904. , IComponentData * pComponentData
  905. , IComponent * pComponent
  906. , DATA_OBJECT_TYPES type
  907. )
  908. {
  909. ATLTRACE(_T("# CSnapinNode::OnPaste -- Override in your derived class\n"));
  910. return E_NOTIMPL;
  911. }
  912. /////////////////////////////////////////////////////////////////////////////
  913. /*++
  914. CSnapinNode::OnPropertyChange
  915. virtual HRESULT OnPropertyChange(
  916. LPARAM arg
  917. , LPARAM param
  918. , IComponentData * pComponentData
  919. , IComponent * pComponent
  920. , DATA_OBJECT_TYPES type
  921. )
  922. In our implementation, this method gets called when the MMCN_PROPERTY_CHANGE
  923. Notify message is sent for this node.
  924. When the snap-in uses the MMCPropertyChangeNotify function to notify it's
  925. views about changes, MMC_PROPERTY_CHANGE is sent to the snap-in's
  926. IComponentData and IComponent implementations.
  927. Parameters
  928. arg
  929. [in] TRUE if the property change is for a scope pane item.
  930. lParam
  931. This is the param passed into MMCPropertyChangeNotify.
  932. Return Values
  933. Not used.
  934. --*/
  935. //////////////////////////////////////////////////////////////////////////////
  936. template <class T, class TComponentData, class TComponent>
  937. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnPropertyChange(
  938. LPARAM arg
  939. , LPARAM param
  940. , IComponentData * pComponentData
  941. , IComponent * pComponent
  942. , DATA_OBJECT_TYPES type
  943. )
  944. {
  945. ATLTRACE(_T("# CSnapinNode::OnPropertyChange -- Override in your derived class\n"));
  946. return E_NOTIMPL;
  947. }
  948. /////////////////////////////////////////////////////////////////////////////
  949. /*++
  950. CSnapinNode::OnQueryPaste
  951. virtual HRESULT OnQueryPaste(
  952. LPARAM arg
  953. , LPARAM param
  954. , IComponentData * pComponentData
  955. , IComponent * pComponent
  956. , DATA_OBJECT_TYPES type
  957. )
  958. In our implementation, this method gets called when the MMCN_QUERY_PASTE
  959. Notify message is sent for this node.
  960. Sent to the snap-in before pasting into the snap-in's folder to determine if the
  961. snap-in can accept the data.
  962. Parameters
  963. pdataobject
  964. The dataobject of the selected item provided by the snap-in.
  965. arg
  966. The dataobject of the item(s) provided by the source snap-in that need to be pasted.
  967. param
  968. Not used.
  969. Return Values
  970. Not used.
  971. See Also
  972. MMCN_PASTE
  973. --*/
  974. //////////////////////////////////////////////////////////////////////////////
  975. template <class T, class TComponentData, class TComponent>
  976. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnQueryPaste(
  977. LPARAM arg
  978. , LPARAM param
  979. , IComponentData * pComponentData
  980. , IComponent * pComponent
  981. , DATA_OBJECT_TYPES type
  982. )
  983. {
  984. ATLTRACE(_T("# CSnapinNode::OnQueryPaste -- Override in your derived class\n"));
  985. return E_NOTIMPL;
  986. }
  987. /////////////////////////////////////////////////////////////////////////////
  988. /*++
  989. CSnapinNode::OnRefresh
  990. virtual HRESULT OnRefresh(
  991. LPARAM arg
  992. , LPARAM param
  993. , IComponentData * pComponentData
  994. , IComponent * pComponent
  995. , DATA_OBJECT_TYPES type
  996. )
  997. In our implementation, this method gets called when the MMCN_REFRESH
  998. Notify message is sent for this node.
  999. In the Fall 97 Platform SDK documentation, this event is listed as TBD.
  1000. Parameters
  1001. Return Values
  1002. Not used.
  1003. --*/
  1004. //////////////////////////////////////////////////////////////////////////////
  1005. template <class T, class TComponentData, class TComponent>
  1006. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnRefresh(
  1007. LPARAM arg
  1008. , LPARAM param
  1009. , IComponentData * pComponentData
  1010. , IComponent * pComponent
  1011. , DATA_OBJECT_TYPES type
  1012. )
  1013. {
  1014. ATLTRACE(_T("# CSnapinNode::OnRefresh -- Override in your derived class\n"));
  1015. return E_NOTIMPL;
  1016. }
  1017. /////////////////////////////////////////////////////////////////////////////
  1018. /*++
  1019. CSnapinNode::OnRemoveChildren
  1020. virtual HRESULT OnRemoveChildren(
  1021. LPARAM arg
  1022. , LPARAM param
  1023. , IComponentData * pComponentData
  1024. , IComponent * pComponent
  1025. , DATA_OBJECT_TYPES type
  1026. )
  1027. In our implementation, this method gets called when the MMCN_REMOVE_CHILDREN
  1028. Notify message is sent for this node.
  1029. MMC sends this message to the snap-in's IComponentData implementation to inform
  1030. the snap-in that it must delete all the cookies (the entire subtree) it has
  1031. added below the specified node.
  1032. Parameters
  1033. arg
  1034. Specifies the HSCOPEITEM of the node whose children need to be deleted.
  1035. param
  1036. Not used.
  1037. Return Values
  1038. Not used.
  1039. Remarks
  1040. Use IConsoleNameSpace methods GetChildItem and GetNextItem to traverse
  1041. the tree and determine the cookies to be deleted.
  1042. --*/
  1043. //////////////////////////////////////////////////////////////////////////////
  1044. template <class T, class TComponentData, class TComponent>
  1045. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnRemoveChildren(
  1046. LPARAM arg
  1047. , LPARAM param
  1048. , IComponentData * pComponentData
  1049. , IComponent * pComponent
  1050. , DATA_OBJECT_TYPES type
  1051. )
  1052. {
  1053. ATLTRACE(_T("# CSnapinNode::OnRemoveChildren -- Override in your derived class\n"));
  1054. return E_NOTIMPL;
  1055. }
  1056. /////////////////////////////////////////////////////////////////////////////
  1057. /*++
  1058. CSnapinNode::OnRename
  1059. virtual HRESULT OnRename(
  1060. LPARAM arg
  1061. , LPARAM param
  1062. , IComponentData * pComponentData
  1063. , IComponent * pComponent
  1064. , DATA_OBJECT_TYPES type
  1065. )
  1066. In our implementation, this method gets called when the MMCN_RENAME Notify
  1067. message is sent for this node.
  1068. ISSUE: I do not seem to be seeing the two-call behaviour documented below
  1069. MMC sends this message the first time to query for a rename and the
  1070. second time to do the rename.
  1071. Parameters
  1072. arg
  1073. Not used.
  1074. param
  1075. LPOLESTR for containing the new name.
  1076. Return Values
  1077. S_OK
  1078. Allows the rename.
  1079. S_FALSE
  1080. Disallows the rename.
  1081. --*/
  1082. //////////////////////////////////////////////////////////////////////////////
  1083. template <class T, class TComponentData, class TComponent>
  1084. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnRename(
  1085. LPARAM arg
  1086. , LPARAM param
  1087. , IComponentData * pComponentData
  1088. , IComponent * pComponent
  1089. , DATA_OBJECT_TYPES type
  1090. )
  1091. {
  1092. ATLTRACE(_T("# CSnapinNode::OnRename -- Override in your derived class\n"));
  1093. return E_NOTIMPL;
  1094. }
  1095. /////////////////////////////////////////////////////////////////////////////
  1096. /*++
  1097. CSnapinNode::OnSelect
  1098. virtual HRESULT OnSelect(
  1099. LPARAM arg
  1100. , LPARAM param
  1101. , IComponentData * pComponentData
  1102. , IComponent * pComponent
  1103. , DATA_OBJECT_TYPES type
  1104. )
  1105. You shouldn't need to override this method. The OnSelect method has common
  1106. behaviour for all nodes, only the verbs to be set are different. Rather
  1107. than overriding OnSelect in each node, simply override SetVerbs, which this
  1108. implementation of OnSelect calls.
  1109. In our implementation, this method gets called when the MMCN_SELECT Notify message is
  1110. sent through IComponent::Notify for this node.
  1111. Note: MMC also sends the MMCN_SELECT message through IExtendControlbar::ControlbarNotify
  1112. but we don't respond to that here -- See CSnapInItem::ControlbarNotify for that.
  1113. Parameters
  1114. For IComponent::Notify:
  1115. arg
  1116. BOOL bScope = (BOOL) LOWORD(arg);
  1117. BOOL bSelec = (BOOL) HIWORD(arg);
  1118. bScope
  1119. TRUE if an item in the scope pane is selected.
  1120. FALSE if an item in the result view pane is selected.
  1121. bSelect
  1122. TRUE if the item is selected.
  1123. FALSE if the item is deselected.
  1124. param
  1125. This parameter is ignored.
  1126. Return Values
  1127. Not used.
  1128. Remarks
  1129. When an IComponent::Notify method receives the MMCN_SELECT notification
  1130. it should update the standard verbs.
  1131. --*/
  1132. //////////////////////////////////////////////////////////////////////////////
  1133. template <class T, class TComponentData, class TComponent>
  1134. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnSelect(
  1135. LPARAM arg
  1136. , LPARAM param
  1137. , IComponentData * pComponentData
  1138. , IComponent * pComponent
  1139. , DATA_OBJECT_TYPES type
  1140. )
  1141. {
  1142. ATLTRACE(_T("# CSnapinNode::OnSelect\n"));
  1143. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  1144. HRESULT hr = S_FALSE;
  1145. CComPtr<IConsoleVerb> spConsoleVerb;
  1146. BOOL bSelected = (BOOL) HIWORD( arg );
  1147. if( bSelected )
  1148. {
  1149. // Need IConsoleVerb
  1150. // But to get that, first we need IConsole
  1151. CComPtr<IConsole> spConsole;
  1152. if( pComponentData != NULL )
  1153. {
  1154. spConsole = ((TComponentData*)pComponentData)->m_spConsole;
  1155. }
  1156. else
  1157. {
  1158. // We should have a non-null pComponent
  1159. spConsole = ((TComponent*)pComponent)->m_spConsole;
  1160. }
  1161. _ASSERTE( spConsole != NULL );
  1162. hr = spConsole->QueryConsoleVerb( &spConsoleVerb );
  1163. _ASSERT( SUCCEEDED( hr ) );
  1164. hr = SetVerbs( spConsoleVerb );
  1165. }
  1166. else
  1167. {
  1168. // Anything to do here? Don't think so -- see sburns localsec example.
  1169. hr = S_OK;
  1170. }
  1171. return hr;
  1172. }
  1173. /////////////////////////////////////////////////////////////////////////////
  1174. /*++
  1175. CSnapinNode::SetVerbs
  1176. virtual HRESULT SetVerbs( IConsoleVerb * pConsoleVerb )
  1177. Override this method in your derived class.
  1178. This method is called by our default implementation of OnSelect
  1179. when the verbs for this node need to be set.
  1180. Parameters
  1181. IConsoleVerb * pConsoleVerb
  1182. Return Values
  1183. HRESULT
  1184. Remarks
  1185. The OnSelect method has common behaviour for all nodes, only the verbs
  1186. to be set are different. Rather than duplicate code by implementing OnSelect
  1187. in each node, simply override this SetVerbs method
  1188. Every time an item is selected, the verb states for all the commands
  1189. are returned to disabled and visible. It is up to the snap-in writer
  1190. to use IConsoleVerb to update the verb state every time an item is selected.
  1191. --*/
  1192. //////////////////////////////////////////////////////////////////////////////
  1193. template <class T, class TComponentData, class TComponent>
  1194. HRESULT CSnapinNode<T, TComponentData, TComponent>::SetVerbs( IConsoleVerb * pConsoleVerb )
  1195. {
  1196. ATLTRACE(_T("# CSnapinNode::SetVerbs -- Override in your derived class\n"));
  1197. HRESULT hr = S_OK;
  1198. // Override in your derived class and do something like:
  1199. /*
  1200. // We want the user to be able to choose properties on this node
  1201. hr = pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
  1202. // We want the default verb to be Properties
  1203. hr = pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  1204. // We want the user to be able to rename this node
  1205. hr = pConsoleVerb->SetVerbState( MMC_VERB_RENAME, ENABLED, TRUE );
  1206. */
  1207. return hr;
  1208. }
  1209. /////////////////////////////////////////////////////////////////////////////
  1210. /*++
  1211. CSnapinNode::PreOnShow
  1212. virtual HRESULT PreOnShow(
  1213. LPARAM arg
  1214. , LPARAM param
  1215. , IComponentData * pComponentData
  1216. , IComponent * pComponent
  1217. , DATA_OBJECT_TYPES type
  1218. )
  1219. We call this instead of OnShow, so that we can save away the selected node.
  1220. This method will then just call OnShow.
  1221. --*/
  1222. //////////////////////////////////////////////////////////////////////////////
  1223. template <class T, class TComponentData, class TComponent>
  1224. HRESULT CSnapinNode<T, TComponentData, TComponent>::PreOnShow(
  1225. LPARAM arg
  1226. , LPARAM param
  1227. , IComponentData * pComponentData
  1228. , IComponent * pComponent
  1229. , DATA_OBJECT_TYPES type
  1230. )
  1231. {
  1232. ATLTRACE(_T("# CSnapinNode::PreOnShow -- Don't override in your derived class\n"));
  1233. if( NULL != pComponent )
  1234. {
  1235. TComponent * pMyComponent = static_cast<TComponent *>( pComponent );
  1236. if( arg )
  1237. {
  1238. // We are being selected.
  1239. // Save our 'this' pointer as the currently selected node for this result view.
  1240. pMyComponent->m_pSelectedNode = static_cast<CSnapInItem *>( this );
  1241. }
  1242. else
  1243. {
  1244. // We are being deselected.
  1245. // Check to make sure that our result view doesn't think
  1246. // this node is the currently selected one.
  1247. if( pMyComponent->m_pSelectedNode == static_cast<CSnapInItem *>( this ) )
  1248. {
  1249. // We don't want to be the selected node anymore.
  1250. pMyComponent->m_pSelectedNode = NULL;
  1251. }
  1252. }
  1253. }
  1254. return OnShow( arg, param, pComponentData, pComponent, type );
  1255. }
  1256. /////////////////////////////////////////////////////////////////////////////
  1257. /*++
  1258. CSnapinNode::OnShow
  1259. virtual HRESULT OnShow(
  1260. LPARAM arg
  1261. , LPARAM param
  1262. , IComponentData * pComponentData
  1263. , IComponent * pComponent
  1264. , DATA_OBJECT_TYPES type
  1265. )
  1266. If your node will have result-pane children,
  1267. this method should be overidden in your derived class.
  1268. In our implementation, this method gets called when the MMCN_SHOW Notify message is
  1269. sent for this node.
  1270. MMC sends this message when a scope item is selected or deselected for the
  1271. first time.
  1272. Parameters
  1273. arg
  1274. TRUE (<>0 ) if selecting; True indicates that the snap-in should set
  1275. up the result pane and add the enumerated items.
  1276. FALSE (0) if deselecting. indicates that the snap-in is going out of
  1277. focus and that it should clean up all cookies the right hand side
  1278. (the result pane), because current result pane will be replaced by a new one.
  1279. param
  1280. The HSCOPEITEM of the selected or deselected item.
  1281. Return Values
  1282. Not used.
  1283. --*/
  1284. //////////////////////////////////////////////////////////////////////////////
  1285. template <class T, class TComponentData, class TComponent>
  1286. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnShow(
  1287. LPARAM arg
  1288. , LPARAM param
  1289. , IComponentData * pComponentData
  1290. , IComponent * pComponent
  1291. , DATA_OBJECT_TYPES type
  1292. )
  1293. {
  1294. ATLTRACE(_T("# CSnapinNode::OnShow -- Override in your derived class\n"));
  1295. // Returning E_NOTIMPL seems to be a bad thing here.
  1296. // It caused all kinds of problems with toolbar buttons persisting to
  1297. // the wrong node, as well as verbs not getting set correctly for nodes.
  1298. // Basically, if you don't respond with S_OK to the MMCN_SHOW notification,
  1299. // you won't get sent the appropriate MMCN_SELECT notification.
  1300. // return E_NOTIMPL;
  1301. return S_OK;
  1302. }
  1303. /////////////////////////////////////////////////////////////////////////////
  1304. /*++
  1305. CSnapinNode::OnViewChange
  1306. virtual HRESULT OnViewChange(
  1307. LPARAM arg
  1308. , LPARAM param
  1309. , IComponentData * pComponentData
  1310. , IComponent * pComponent
  1311. , DATA_OBJECT_TYPES type
  1312. )
  1313. In our implementation, this method gets called when the MMCN_VIEW_CHANGE Notify
  1314. message is sent for this node.
  1315. MMC sends this message to the snap-in's IComponent implementation so it
  1316. can update all views when a change occurs. This node data object passed
  1317. to IConsole::UpdateAllViews.
  1318. Parameters
  1319. arg
  1320. [in] The data parameter passed to IConsole::UpdateAllViews.
  1321. param
  1322. [in] The hint parameter passed to IConsole::UpdateAllViews.
  1323. Return Values
  1324. Not used.
  1325. Remarks
  1326. This notification is generated when the snap-in (IComponent or
  1327. IComponentData) calls IConsole::UpdateAllViews.
  1328. --*/
  1329. //////////////////////////////////////////////////////////////////////////////
  1330. template <class T, class TComponentData, class TComponent>
  1331. HRESULT CSnapinNode<T, TComponentData, TComponent>::OnViewChange(
  1332. LPARAM arg
  1333. , LPARAM param
  1334. , IComponentData * pComponentData
  1335. , IComponent * pComponent
  1336. , DATA_OBJECT_TYPES type
  1337. )
  1338. {
  1339. ATLTRACE(_T("# CSnapinNode::OnViewChange -- Override in your derived class\n"));
  1340. return E_NOTIMPL;
  1341. }
  1342. /////////////////////////////////////////////////////////////////////////////
  1343. /*++
  1344. CSnapinNode::TaskNotify
  1345. Called when MMC wants to notify us that the user clicked on a task
  1346. on a taskpad belonging to this node.
  1347. --*/
  1348. //////////////////////////////////////////////////////////////////////////////
  1349. template <class T, class TComponentData, class TComponent>
  1350. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::TaskNotify(
  1351. IDataObject * pDataObject
  1352. , VARIANT * pvarg
  1353. , VARIANT * pvparam
  1354. )
  1355. {
  1356. ATLTRACENOTIMPL(_T("# CSnapInItemImpl::TaskNotify\n"));
  1357. }
  1358. /////////////////////////////////////////////////////////////////////////////
  1359. /*++
  1360. CSnapinNode::EnumTasks
  1361. Called when MMC wants us to enumerate the tasks on a taskpad
  1362. belonging to this node.
  1363. --*/
  1364. //////////////////////////////////////////////////////////////////////////////
  1365. template <class T, class TComponentData, class TComponent>
  1366. STDMETHODIMP CSnapinNode<T, TComponentData, TComponent>::EnumTasks(
  1367. IDataObject * pDataObject
  1368. , BSTR szTaskGroup
  1369. , IEnumTASK** ppEnumTASK
  1370. )
  1371. {
  1372. ATLTRACENOTIMPL(_T("# CSnapInItemImpl::EnumTasks\n"));
  1373. }