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.

946 lines
27 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: Component.cpp //
  7. | //
  8. |Description: //
  9. | //
  10. |Created: Paul Skoglund 07-1998 //
  11. | //
  12. |Rev History: //
  13. | //
  14. |=======================================================================================*/
  15. #include "StdAfx.h"
  16. #include "ProcCon.h"
  17. #include "Component.h"
  18. #include "BaseNode.h"
  19. #include "DataObj.h"
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CComponent
  22. CComponent::CComponent()
  23. {
  24. ATLTRACE( _T("Component::Component\n"));
  25. m_ipConsole2 = NULL;
  26. m_ipHeaderCtrl2 = NULL;
  27. m_ipResultData = NULL;
  28. m_ipConsoleVerb = NULL;
  29. m_ipConsoleNameSpace2 = NULL;
  30. m_ipDisplayHelp = NULL;
  31. m_pCompData = NULL; // Points to parent object not an interface
  32. m_hbmp16x16 = NULL;
  33. m_hbmp32x32 = NULL;
  34. m_hSelectedScope = NULL;
  35. m_bInitializedAndNotDestroyed = FALSE;
  36. } // end Constructor()
  37. //---------------------------------------------------------------------------
  38. //
  39. CComponent::~CComponent()
  40. {
  41. ATLTRACE( _T("Component::~Component\n") );
  42. } // end Destructor()
  43. /////////////////////////////////////////////////////////////////////////////
  44. // IComponent implementation
  45. //
  46. //---------------------------------------------------------------------------
  47. // IComponent::Initialize is called when a snap-in is being created and
  48. // has items in the result pane to enumerate. The pointer to IConsole that
  49. // is passed in is used to make QueryInterface calls to the console for
  50. // interfaces such as IResultData.
  51. //
  52. STDMETHODIMP CComponent::Initialize
  53. (
  54. LPCONSOLE ipConsole // [in] Pointer to IConsole's IUnknown interface
  55. )
  56. {
  57. ATLTRACE( _T("Component::Initialize()\n") );
  58. ASSERT( NULL != ipConsole );
  59. HRESULT hr = S_OK;
  60. // Save away all the interfaces we'll need.
  61. // Fail if we can't QI the required interfaces.
  62. hr = ipConsole->QueryInterface( IID_IConsole2,
  63. (VOID**)&m_ipConsole2
  64. );
  65. if( FAILED(hr) )
  66. return hr;
  67. hr = m_ipConsole2->QueryInterface( IID_IResultData,
  68. (VOID**)&m_ipResultData
  69. );
  70. if( FAILED(hr) )
  71. return hr;
  72. hr = m_ipConsole2->QueryInterface( IID_IHeaderCtrl2,
  73. (VOID**)&m_ipHeaderCtrl2
  74. );
  75. if( FAILED(hr) )
  76. return hr; // Console needs the header
  77. else // control pointer
  78. m_ipConsole2->SetHeader( m_ipHeaderCtrl2 );
  79. hr = m_ipConsole2->QueryConsoleVerb( &m_ipConsoleVerb );
  80. if( FAILED(hr) )
  81. return hr;
  82. hr = m_ipConsole2->QueryInterface( IID_IConsoleNameSpace2,
  83. (VOID**)&m_ipConsoleNameSpace2
  84. );
  85. if( FAILED(hr) )
  86. return hr;
  87. hr = m_ipConsole2->QueryInterface( IID_IDisplayHelp,
  88. (VOID**)&m_ipDisplayHelp
  89. );
  90. if( FAILED(hr) )
  91. return hr;
  92. // Load the bitmaps from the dll for the results pane
  93. m_hbmp16x16 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_16x16));
  94. ASSERT( m_hbmp16x16 );
  95. m_hbmp32x32 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_32x32));
  96. ASSERT( m_hbmp32x32 );
  97. m_bInitializedAndNotDestroyed = TRUE;
  98. return hr;
  99. } // end Initialize()
  100. //---------------------------------------------------------------------------
  101. // Store the parent CComponetData object.
  102. //
  103. void CComponent::SetComponentData
  104. (
  105. CComponentData* pCompData // [in] Parent CComponentData object
  106. )
  107. {
  108. ATLTRACE( _T("Component::SetComponentData\n") );
  109. ASSERT( NULL != pCompData );
  110. ASSERT( NULL == m_pCompData ); // Can't do this twice
  111. m_pCompData = pCompData; // Cache a way to get to the
  112. // parent CComponentData
  113. } // end SetComponentData()
  114. //---------------------------------------------------------------------------
  115. // Releases all references to the console.
  116. // Only the console should call this method.
  117. //
  118. STDMETHODIMP CComponent::Destroy
  119. (
  120. MMC_COOKIE Cookie // Reserved, not in use at this time
  121. )
  122. {
  123. ATLTRACE( _T("Component::Destroy\n") );
  124. m_bInitializedAndNotDestroyed = FALSE;
  125. // Release the interfaces that we QI'ed
  126. m_ipConsole2->SetHeader(NULL);
  127. SAFE_RELEASE( m_ipHeaderCtrl2 );
  128. SAFE_RELEASE( m_ipResultData );
  129. SAFE_RELEASE( m_ipConsoleVerb );
  130. SAFE_RELEASE( m_ipConsoleNameSpace2 );
  131. SAFE_RELEASE( m_ipConsole2 );
  132. SAFE_RELEASE( m_ipDisplayHelp );
  133. if( NULL != m_hbmp16x16 )
  134. DeleteObject(m_hbmp16x16);
  135. if( NULL != m_hbmp32x32 )
  136. DeleteObject(m_hbmp32x32);
  137. return S_OK;
  138. } // end Destroy()
  139. //---------------------------------------------------------------------------
  140. // Returns a data object that can be used to retrieve context information
  141. // for the specified cookie.
  142. //ok, now believe this interface is only queried about items added to the result pane.
  143. STDMETHODIMP CComponent::QueryDataObject
  144. (
  145. MMC_COOKIE Cookie, // [in] Specifies the unique identifier
  146. DATA_OBJECT_TYPES Context, // [in] Type of data object
  147. LPDATAOBJECT* ppDataObject // [out] Points to address of returned data
  148. )
  149. {
  150. if (!m_bInitializedAndNotDestroyed)
  151. {
  152. ASSERT(FALSE);
  153. return E_UNEXPECTED;
  154. }
  155. // check for magic multi-select cookie
  156. if (IS_SPECIAL_COOKIE(Cookie) )
  157. {
  158. if (Cookie == MMC_MULTI_SELECT_COOKIE)
  159. ATLTRACE( _T("Component::QueryDataObject: MMC_MULTI_SELECT_COOKIE unimplemented\n") );
  160. else
  161. ATLTRACE( _T("Component::QueryDataObject: special cookie %p unimplemented\n"), Cookie );
  162. return E_UNEXPECTED;
  163. }
  164. ASSERT( CCT_SCOPE == Context || // Must have a context
  165. CCT_RESULT == Context || // we understand
  166. CCT_SNAPIN_MANAGER == Context
  167. );
  168. if (Context == CCT_SCOPE)
  169. {
  170. ASSERT(FALSE);
  171. ATLTRACE( _T("Component::QueryDataObject: asking for CCT_SCOPE Context??\n") );
  172. return m_pCompData->QueryDataObject(Cookie, Context, ppDataObject);
  173. }
  174. else if (Context == CCT_RESULT)
  175. {
  176. ATLTRACE( _T("Component::QueryDataObject: CCT_RESULT \n") );
  177. CComObject<CDataObject>* pDataObj;
  178. CComObject<CDataObject>::CreateInstance( &pDataObj );
  179. if( ! pDataObj ) // DataObject was not created
  180. {
  181. ASSERT(pDataObj);
  182. return E_OUTOFMEMORY;
  183. }
  184. // use selected node to get, "parent" folder
  185. SCOPEDATAITEM Item;
  186. memset(&Item, 0, sizeof(Item));
  187. Item.mask = SDI_PARAM;
  188. Item.ID = m_hSelectedScope;
  189. if ( S_OK != m_ipConsoleNameSpace2->GetItem(&Item) )
  190. return E_UNEXPECTED;
  191. CBaseNode *pFolder = reinterpret_cast<CBaseNode *>(Item.lParam);
  192. pDataObj->SetDataObject( Context, pFolder, Cookie );
  193. //ATLTRACE( _T("%s-Component::QueryDataObject: CCT_RESULT \n"), pFolder->GetNodeName() );
  194. return pDataObj->QueryInterface( IID_IDataObject,
  195. reinterpret_cast<void**>(ppDataObject) );
  196. }
  197. // else ...
  198. // CCT_SNAPIN_MANAGER
  199. // CCT_UNITIALIZED
  200. ASSERT( Context == 0); //
  201. return E_UNEXPECTED;
  202. } // end QueryDataObject()
  203. //---------------------------------------------------------------------------
  204. //
  205. STDMETHODIMP CComponent::GetDisplayInfo
  206. (
  207. LPRESULTDATAITEM pResultItem // [in,out] Type of info required
  208. )
  209. {
  210. ASSERT( NULL != pResultItem );
  211. if( NULL == pResultItem)
  212. return E_UNEXPECTED;
  213. if (!m_bInitializedAndNotDestroyed)
  214. {
  215. ASSERT(FALSE);
  216. return E_UNEXPECTED;
  217. }
  218. HRESULT hr = S_OK;
  219. // the RDI_PARAM flag does not have to be set on input to indicate that the LPARAM is valid
  220. //if (!(pResultItem->mask & RDI_PARAM))
  221. // return E_UNEXPECTED;
  222. if (pResultItem->bScopeItem)
  223. {
  224. ASSERT(pResultItem->lParam);
  225. CBaseNode *pData= reinterpret_cast<CBaseNode *>(pResultItem->lParam);
  226. if (!pData)
  227. return E_UNEXPECTED;
  228. hr = pData->GetDisplayInfo(*pResultItem);
  229. }
  230. else
  231. {
  232. SCOPEDATAITEM Item;
  233. memset(&Item, 0, sizeof(Item));
  234. Item.mask = SDI_PARAM;
  235. Item.ID = m_hSelectedScope;
  236. if ( !m_hSelectedScope || S_OK != m_ipConsoleNameSpace2->GetItem(&Item) || !Item.lParam)
  237. return E_UNEXPECTED;
  238. CBaseNode *pData = reinterpret_cast<CBaseNode *>(Item.lParam);
  239. hr = pData->GetDisplayInfo(*pResultItem);
  240. }
  241. return hr;
  242. } // end GetDisplayInfo()
  243. //---------------------------------------------------------------------------
  244. // Determines what the result pane view should be
  245. //
  246. STDMETHODIMP CComponent::GetResultViewType
  247. (
  248. MMC_COOKIE Cookie, // [in] Specifies the unique identifier
  249. BSTR* ppViewType, // [out] Points to address of the returned view type
  250. long* pViewOptions // [out] Pointer to the MMC_VIEW_OPTIONS enumeration
  251. )
  252. {
  253. ATLTRACE(_T("Component::GetResultViewType Cookie 0x%lX\n"), Cookie);
  254. if (!Cookie) // root node
  255. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  256. else
  257. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  258. return S_FALSE; // Ask for default listview.
  259. } // end GetResultViewType()
  260. //---------------------------------------------------------------------------
  261. //
  262. //
  263. HRESULT CComponent::CompareObjects
  264. (
  265. LPDATAOBJECT ipDataObjectA, // [in] First data object to compare
  266. LPDATAOBJECT ipDataObjectB // [in] Second data object to compare
  267. )
  268. {
  269. ATLTRACE(_T("Component::CompareObjects\n"));
  270. if (!m_bInitializedAndNotDestroyed)
  271. {
  272. ASSERT(FALSE);
  273. return E_UNEXPECTED;
  274. }
  275. CDataObject *pdoA;
  276. CDataObject *pdoB;
  277. pdoA = ExtractOwnDataObject( ipDataObjectA );
  278. pdoB = ExtractOwnDataObject( ipDataObjectB );
  279. ASSERT( pdoA || pdoB );
  280. // If extraction failed for one of them, then that one is foreign and
  281. // can't be equal to the other one. (Or else ExtractOwnDataObject
  282. // returned NULL because it ran out of memory, but the most conservative
  283. // thing to do in that case is say they're not equal.)
  284. if( !pdoA || !pdoB )
  285. {
  286. ATLTRACE(_T("Component::CompareObjects() - FALSE one or both objects not recognized\n") );
  287. return S_FALSE;
  288. }
  289. // If they differ then the objects refer to different things.
  290. CBaseNode *pNodeA = pdoA->GetBaseObject();
  291. CBaseNode *pNodeB = pdoB->GetBaseObject();
  292. if( pNodeA && pNodeB && pNodeA->GetNodeType() == pNodeB->GetNodeType() )
  293. {
  294. if (!pdoA->IsResultItem() && !pdoB->IsResultItem())
  295. {
  296. ATLTRACE(_T("Component::CompareObjects() - TRUE both nodes %s\n"), pNodeA->GetNodeName() );
  297. return S_OK;
  298. }
  299. if ( pdoA->GetResultItemCookie() == pdoB->GetResultItemCookie() )
  300. {
  301. ATLTRACE(_T("Component::CompareObjects() - TRUE both %s\n"), pNodeA->GetNodeName() );
  302. return S_OK;
  303. }
  304. ATLTRACE(_T("Component::CompareObjects() - FALSE both %s\n"), pNodeA->GetNodeName() );
  305. }
  306. else
  307. {
  308. ATLTRACE(_T("Component::CompareObjects() - FALSE\n") );
  309. }
  310. return S_FALSE;
  311. } // end CompareObjects()
  312. //---------------------------------------------------------------------------
  313. // Handle notifications from the console
  314. //
  315. STDMETHODIMP CComponent::Notify
  316. (
  317. LPDATAOBJECT ipDataObject, // [in] Points to data object
  318. MMC_NOTIFY_TYPE Event, // [in] Identifies action taken by user
  319. LPARAM Arg, // [in] Depends on the notification type
  320. LPARAM Param // [in] Depends on the notification type
  321. )
  322. {
  323. ATLTRACE( _T("Component::Notify %p 0x%X %p %p\n"), ipDataObject, Event, Arg, Param );
  324. if (!m_bInitializedAndNotDestroyed)
  325. {
  326. ASSERT(FALSE);
  327. return E_UNEXPECTED;
  328. }
  329. HRESULT hr = S_OK;
  330. /*
  331. // not all notifies set ipDataObject...
  332. MMCN_ACTIVATE
  333. MMCN_BTN_CLICK
  334. //MMCN_CLICK
  335. MMCN_COLUMN_CLICK
  336. //MMCN_CONTEXTMENU
  337. MMCN_CUTORMOVE
  338. MMCN_DELETE
  339. MMCN_EXPAND
  340. //MMCN_HELP
  341. MMCN_MENU_BTNCLICK
  342. MMCN_PASTE
  343. MMCN_QUERY_PASTE
  344. MMCN_REMOVE_CHILDREN
  345. MMCN_RENAME
  346. MMCN_SELECT
  347. MMCN_SHOW
  348. MMCN_VIEW_CHANGE
  349. MMCN_SNAPINHELP
  350. MMCN_CONTEXTHELP
  351. MMCN_INITOCX
  352. MMCN_FILTER_CHANGE
  353. MMCN_FILTERBTN_CLICK
  354. MMCN_RESTORE_VIEW
  355. MMCN_PRINT
  356. MMCN_PRELOAD
  357. MMCN_LISTPAD
  358. */
  359. CDataObject* pDO = NULL;
  360. CBaseNode *pNode = NULL;
  361. MMC_NOTIFY_TYPE NeedDataObject[] = { MMCN_VIEW_CHANGE, MMCN_SHOW, MMCN_DBLCLICK, MMCN_SELECT, MMCN_REFRESH, MMCN_DELETE, MMCN_CONTEXTHELP };
  362. for(int i = 0; i < ARRAY_SIZE(NeedDataObject); i++)
  363. {
  364. if (Event == NeedDataObject[i])
  365. {
  366. pDO = ExtractOwnDataObject(ipDataObject);
  367. pNode = ExtractBaseObject(ipDataObject);
  368. if (!pDO || !pNode)
  369. {
  370. ASSERT(FALSE);
  371. return E_UNEXPECTED;
  372. }
  373. break;
  374. }
  375. }
  376. switch( Event )
  377. {
  378. case MMCN_ADD_IMAGES: //ok
  379. hr = OnAddImages( ipDataObject, (IImageList *) Arg, Param );
  380. break;
  381. case MMCN_SHOW: //ok
  382. //ATLTRACE( _T("Component::Notify: MMCN_SHOW\n") );
  383. hr = OnShow( ipDataObject, (BOOL) Arg, Param );
  384. break;
  385. case MMCN_SELECT: //fair
  386. //ATLTRACE( _T("Component::Notify: MMCN_SELECT\n") );
  387. hr = OnSelect( ipDataObject, Arg, Param );
  388. break;
  389. case MMCN_REFRESH:
  390. //ATLTRACE( _T("Component::Notify: MMCN_REFRESH\n") );
  391. hr = OnRefresh( ipDataObject );
  392. break;
  393. case MMCN_DELETE: // Arg and Param have no meaning
  394. if (pNode && pDO->IsResultItem() )
  395. hr = pNode->OnDelete(m_ipConsole2, pDO->GetResultItemCookie());
  396. else
  397. hr = E_UNEXPECTED;
  398. break;
  399. case MMCN_VIEW_CHANGE:
  400. ATLTRACE( _T("Component::Notify: MMCN_VIEW_CHANGE\n") );
  401. if (m_hSelectedScope == pNode->GetID() )
  402. hr = pNode->OnViewChange(m_ipResultData, Arg, Param);
  403. break;
  404. case MMCN_PROPERTY_CHANGE:
  405. ATLTRACE( _T("Component::Notify: MMCN_PROPERTY_CHANGE\n") );
  406. hr = OnPropertyChange( (BOOL) Arg, Param);
  407. break;
  408. case MMCN_HELP: // obsolete
  409. ATLTRACE( _T("Component::Notify: MMCN_HELP unimplemented\n") );
  410. hr = S_FALSE;
  411. break;
  412. case MMCN_SNAPINHELP: // obsolete
  413. // 11/1998
  414. // nolonger used: implement ISnapinHelp interface, then MMC will merge the snapin's help and MMC help
  415. ATLTRACE( _T("Component::Notify: MMCN_SNAPINHELP unimplemented\n") );
  416. hr = S_FALSE;
  417. break;
  418. case MMCN_CONTEXTHELP:
  419. // return S_FALSE for default behavior... actually, any return value other than S_OK
  420. // invokes HTMLHelp with MMC overview topic.
  421. ATLTRACE( _T("Component::Notify: MMCN_CONTEXTHELP\n") );
  422. if (pNode)
  423. hr = pNode->OnHelpCmd(m_ipDisplayHelp );
  424. else
  425. hr = E_UNEXPECTED;
  426. break;
  427. case MMCN_CLICK:
  428. ATLTRACE( _T("Component::Notify: MMCN_CLICK unimplemented\n") );
  429. break;
  430. case MMCN_DBLCLICK: // return S_FALSE to have MMC do the default verb action...
  431. if (pNode && pDO->IsResultItem() )
  432. hr = pNode->OnDblClick(m_ipConsole2, pDO->GetResultItemCookie());
  433. else
  434. hr = S_FALSE;
  435. break;
  436. case MMCN_ACTIVATE:
  437. ATLTRACE( _T("Component::Notify: MMCN_ACTIVATE (%s) unimplemented\n"), Arg ? _T("activate") : _T("deactivate") );
  438. break;
  439. case MMCN_MINIMIZED:
  440. ATLTRACE( _T("Component::Notify: MMCN_MINIMIZED unimplemented\n") );
  441. break;
  442. case MMCN_BTN_CLICK:
  443. ATLTRACE( _T("Component::Notify: MMCN_BTN_CLICK unimplemented\n") );
  444. break;
  445. case MMCN_COLUMN_CLICK:
  446. ATLTRACE( _T("Component::Notify: MMCN_COLUMN_CLICK col: %p %s\n"), Arg, (Param == RSI_DESCENDING ) ? _T("Descending") : _T("Ascending") );
  447. break;
  448. case MMCN_COLUMNS_CHANGED:
  449. ATLTRACE( _T("Component::Notify: MMCN_COLUMNS_CHANGED Arg: %p, Param: %p\n"), Arg, Param );
  450. hr = S_OK;
  451. break;
  452. default:
  453. ATLTRACE( _T("Component::Notify: unhandled notify event 0x%X\n"), Event );
  454. hr = S_OK;
  455. break;
  456. }
  457. return hr;
  458. } // end Notify()
  459. /////////////////////////////////////////////////////////////////////////////
  460. // Support methods
  461. //
  462. //---------------------------------------------------------------------------
  463. // handle the MMCN_SHOW message.
  464. //
  465. HRESULT CComponent::OnShow
  466. (
  467. LPDATAOBJECT ipDataObject, // [in] Points to data object
  468. BOOL bSelected, // [in] selected/deselected scope
  469. HSCOPEITEM hScopeID // [in] HSCOPEITEM
  470. )
  471. {
  472. ASSERT( NULL != ipDataObject );
  473. ASSERT( NULL != m_ipResultData );
  474. CBaseNode *pNode = ExtractBaseObject( ipDataObject) ;
  475. ASSERT(pNode);
  476. if (!pNode)
  477. {
  478. m_hSelectedScope = NULL;
  479. return S_FALSE;
  480. }
  481. ATLTRACE(_T("%s-MMCN_SHOW Selected=%s\n"), pNode->GetNodeName(), (bSelected ? _T("true") : _T("false")) );
  482. if (!bSelected) // deselected scope pane item
  483. m_hSelectedScope = NULL;
  484. else // selected scope pane item
  485. {
  486. VERIFY(S_OK == m_ipResultData->SetViewMode( MMCLV_VIEWSTYLE_REPORT ) );
  487. m_hSelectedScope = hScopeID;
  488. }
  489. CJobFolder *pJobFolder = dynamic_cast<CJobFolder *> (pNode);
  490. if (pJobFolder)
  491. return pJobFolder->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2, m_ipConsoleNameSpace2);
  492. CJobItemFolder *pJobItemFolder = dynamic_cast<CJobItemFolder *> (pNode);
  493. if (pJobItemFolder)
  494. return pJobItemFolder->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2, m_ipConsoleNameSpace2);
  495. return pNode->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2);
  496. } // end OnShow()
  497. //---------------------------------------------------------------------------
  498. //
  499. HRESULT CComponent::OnAddImages
  500. (
  501. LPDATAOBJECT ipDataObject, // [in] Points to the data object
  502. IImageList *ipImageList, // [in] Interface pointer to IImageList
  503. HSCOPEITEM hID // [in] HSCOPEITEM of item currently selected or deselected
  504. )
  505. {
  506. ASSERT( ipImageList );
  507. if (!ipImageList)
  508. return E_UNEXPECTED;
  509. HRESULT hr = ipImageList->ImageListSetStrip( (LONG_PTR *) m_hbmp16x16, (LONG_PTR *) m_hbmp32x32, 0, RGB(255,0, 255) );
  510. ASSERT( S_OK == hr );
  511. return hr;
  512. } // end OnAddImages()
  513. //---------------------------------------------------------------------------
  514. // This is a handler for the MMCN_SELECT notification.
  515. // MMC 1.1 documentation for IComponent::Notify MMCN_SELECT
  516. // claims the LPDATAOBJECT is for the scope item but
  517. // in reality appears to be the dataobject for whatever item/node is selected
  518. //
  519. HRESULT CComponent::OnSelect
  520. (
  521. LPDATAOBJECT ipDataObject, // [in] Points to the data object
  522. LPARAM Arg, // [in] Contains flags about the selected item
  523. LPARAM Param // [in] Not used
  524. )
  525. {
  526. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  527. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  528. if( !m_ipConsoleVerb || !pDO || !pNode)
  529. return E_UNEXPECTED;
  530. ATLTRACE(_T("%s-MMCN_SELECT: Scope=%s, Select=%s, ResultItem=%s\n"),
  531. pNode->GetNodeName(),
  532. (LOWORD(Arg) ? _T("true") : _T("false")),
  533. (HIWORD(Arg) ? _T("true") : _T("false")),
  534. pDO->IsResultItem() ? _T("yes") : _T("no"));
  535. ASSERT(!(pDO->IsResultItem()) == (BOOL) LOWORD(Arg) );
  536. if (pDO->IsResultItem())
  537. return pNode->OnSelect(LOWORD(Arg), HIWORD(Arg), m_ipConsoleVerb, pDO->GetResultItemCookie());
  538. else
  539. return pNode->OnSelect(LOWORD(Arg), HIWORD(Arg), m_ipConsoleVerb);
  540. } // end OnSelect()
  541. //---------------------------------------------------------------------------
  542. // MMCN_REFRESH notification
  543. //
  544. HRESULT CComponent::OnRefresh
  545. (
  546. LPDATAOBJECT ipDataObject // [in] Points to the data object
  547. )
  548. {
  549. CBaseNode* pNode = ExtractBaseObject( ipDataObject );
  550. ASSERT(pNode);
  551. if (!pNode )
  552. return E_UNEXPECTED;
  553. ATLTRACE( _T("%s-Component::Notify: MMCN_REFRESH\n"), pNode->GetNodeName() );
  554. if (m_hSelectedScope != pNode->GetID() )
  555. {
  556. ATLTRACE( _T("Attempt patch of framework!\n"));
  557. //OnShow(ipDataObject, TRUE, pNode->GetID());
  558. m_ipConsole2->SelectScopeItem(pNode->GetID());
  559. }
  560. CJobFolder *pJobFolder = dynamic_cast<CJobFolder *> (pNode);
  561. if (pJobFolder)
  562. return pJobFolder->OnRefresh(m_ipConsole2, m_ipConsoleNameSpace2);
  563. return pNode->OnRefresh(m_ipConsole2);
  564. } // end OnRefresh()
  565. //---------------------------------------------------------------------------
  566. // MMCN_PROPERTY_CHANGE notification
  567. //
  568. HRESULT CComponent::OnPropertyChange
  569. (
  570. BOOL bScopeItem,
  571. LPARAM Param
  572. )
  573. {
  574. if (bScopeItem)
  575. {
  576. ASSERT(FALSE); // what is this path being used by?
  577. return S_OK;
  578. }
  579. PROPERTY_CHANGE_HDR *pUpdate = reinterpret_cast<PROPERTY_CHANGE_HDR*>(Param);
  580. if (pUpdate )
  581. {
  582. if (pUpdate->pFolder && !pUpdate->bScopeItem)
  583. {
  584. SCOPEDATAITEM Item;
  585. memset(&Item, 0, sizeof(Item));
  586. Item.mask = SDI_PARAM;
  587. Item.ID = m_hSelectedScope;
  588. if ( m_hSelectedScope && S_OK == m_ipConsoleNameSpace2->GetItem(&Item) &&
  589. reinterpret_cast<CBaseNode *>(Item.lParam) == pUpdate->pFolder )
  590. {
  591. pUpdate->pFolder->OnPropertyChange(pUpdate, m_ipConsole2);
  592. }
  593. }
  594. pUpdate = FreePropChangeInfo(pUpdate);
  595. }
  596. return S_OK;
  597. } // end OnPropertyChange()
  598. #ifdef USE_IRESULTDATACOMPARE
  599. /////////////////////////////////////////////////////////////////////////////
  600. // IResultDataCompare method implementations
  601. //
  602. STDMETHODIMP CComponent::Compare(LPARAM lUserParam, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int * pnResult )
  603. {
  604. ATLTRACE( _T("Component::Compare %p %p %p\n"), lUserParam, cookieA, cookieB );
  605. SCOPEDATAITEM Item;
  606. memset(&Item, 0, sizeof(Item));
  607. Item.mask = SDI_PARAM;
  608. Item.ID = m_hSelectedScope;
  609. if ( S_OK != m_ipConsoleNameSpace2->GetItem(&Item) )
  610. return E_UNEXPECTED;
  611. CBaseNode *pFolder = reinterpret_cast<CBaseNode *>(Item.lParam);
  612. if (!pFolder)
  613. return E_UNEXPECTED;
  614. return pFolder->ResultDataCompare(lUserParam, cookieA, cookieB, pnResult);
  615. }
  616. #endif
  617. /////////////////////////////////////////////////////////////////////////////
  618. // IExtendContextMenu method implementations
  619. //
  620. STDMETHODIMP CComponent::AddMenuItems
  621. (
  622. LPDATAOBJECT ipDataObject, // [in] Points to data object
  623. LPCONTEXTMENUCALLBACK piCallback, // [in] Pointer to IContextMenuCallback
  624. long* pInsertionAllowed // [in,out] Insertion flags
  625. )
  626. {
  627. ASSERT( NULL != ipDataObject );
  628. if (!m_bInitializedAndNotDestroyed)
  629. {
  630. ASSERT(FALSE);
  631. return E_UNEXPECTED;
  632. }
  633. if (IsMMCMultiSelectDataObject(ipDataObject))
  634. return E_UNEXPECTED;
  635. CDataObject *pDO;
  636. CBaseNode *pNode;
  637. VERIFY(pDO = ExtractOwnDataObject( ipDataObject ));
  638. VERIFY(pNode = ExtractBaseObject( ipDataObject ));
  639. if (!pDO || !pNode)
  640. return E_UNEXPECTED;
  641. if (pDO->IsResultItem())
  642. return pNode->AddMenuItems(piCallback, pInsertionAllowed, pDO->GetResultItemCookie() );
  643. else
  644. return pNode->AddMenuItems(piCallback, pInsertionAllowed );
  645. } // end AddMenuItems()
  646. /////////////////////////////////////////////////////////////////////////////
  647. // IExtendContextMenu method implementations
  648. //
  649. STDMETHODIMP CComponent::Command
  650. (
  651. long nCommandID, // [in] Command to handle
  652. LPDATAOBJECT ipDataObject // [in] Points to data object, pass through
  653. )
  654. {
  655. if (!m_bInitializedAndNotDestroyed)
  656. {
  657. ASSERT(FALSE);
  658. return E_UNEXPECTED;
  659. }
  660. HRESULT hr = S_FALSE;
  661. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  662. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  663. if (!pDO || !pNode)
  664. return S_FALSE;
  665. if ( pDO->IsResultItem() )
  666. hr = pNode->OnMenuCommand(m_ipConsole2, nCommandID, pDO->GetResultItemCookie() );
  667. else
  668. {
  669. CJobFolder *pJobFolder = dynamic_cast<CJobFolder *> (pNode);
  670. if (pJobFolder)
  671. hr = pJobFolder->OnMenuCommand(m_ipConsole2, m_ipConsoleNameSpace2, nCommandID);
  672. else
  673. hr = pNode->OnMenuCommand(m_ipConsole2, nCommandID );
  674. }
  675. if (hr == S_OK) // already successfully handled
  676. return hr;
  677. ATLTRACE(_T("Component::Command - unrecognized or failed command %d\n"), nCommandID);
  678. return hr;
  679. } // end Command()
  680. /////////////////////////////////////////////////////////////////////////////
  681. // IExtendPropertySheet2 implementation
  682. //
  683. //---------------------------------------------------------------------------
  684. // The console calls this method to determine whether the Properties menu
  685. // item should be added to the context menu. We added the Properties item
  686. // by enabling the verb. So long as we have a vaild DataObject we
  687. // can return OK.
  688. //
  689. HRESULT CComponent::QueryPagesFor
  690. (
  691. LPDATAOBJECT ipDataObject // [in] Points to IDataObject for selected node
  692. )
  693. {
  694. if (!m_bInitializedAndNotDestroyed)
  695. {
  696. ASSERT(FALSE);
  697. return E_UNEXPECTED;
  698. }
  699. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  700. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  701. if (!pDO || !pNode)
  702. return S_FALSE;
  703. if (pDO->IsResultItem())
  704. return pNode->QueryPagesFor(pDO->GetResultItemCookie());
  705. else
  706. return pNode->QueryPagesFor();
  707. } // end QueryPagesFor()
  708. HRESULT CComponent::CreatePropertyPages
  709. (
  710. LPPROPERTYSHEETCALLBACK lpProvider, // Pointer to the callback interface
  711. LONG_PTR handle, // Handle for routing notification
  712. LPDATAOBJECT ipDataObject // Pointer to the data object
  713. )
  714. {
  715. ASSERT( NULL != lpProvider );
  716. if (!m_bInitializedAndNotDestroyed)
  717. {
  718. ASSERT(FALSE);
  719. return E_UNEXPECTED;
  720. }
  721. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  722. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  723. if (!pDO || !pNode)
  724. return S_FALSE;
  725. if (pDO->IsResultItem())
  726. return pNode->OnCreatePropertyPages(lpProvider, handle, pDO->GetContext(), pDO->GetResultItemCookie());
  727. else
  728. return pNode->OnCreatePropertyPages(lpProvider, handle, pDO->GetContext());
  729. } // end CreatePropertyPages()
  730. HRESULT CComponent::GetWatermarks
  731. (
  732. LPDATAOBJECT lpIDataObject,
  733. HBITMAP *lphWatermark,
  734. HBITMAP * lphHeader,
  735. HPALETTE * lphPalette,
  736. BOOL* bStretch
  737. )
  738. {
  739. ATLTRACE(_T("\n\nComponent::GetWatermarks\n\n"));
  740. if (!m_bInitializedAndNotDestroyed)
  741. {
  742. ASSERT(FALSE);
  743. return E_UNEXPECTED;
  744. }
  745. // no indication this method has ever been invoked
  746. *lphWatermark = NULL;
  747. *lphHeader = NULL;
  748. *lphPalette = NULL;
  749. *bStretch = FALSE;
  750. return S_OK;
  751. } // end GetWatermarks()