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.

847 lines
25 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: ComponentData.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 "DataObj.h"
  19. #include "BaseNode.h"
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CComponentData - This class is the interface to handle anything to do
  22. // with the scope pane. MMC calls the IComponent interfaces.
  23. // This class keeps a few pointers to interfaces that MMC
  24. // implements.
  25. CComponentData::CComponentData() : m_Initialized(FALSE)
  26. {
  27. ATLTRACE( _T("ComponentData::ComponentData()\n") );
  28. m_ipConsoleNameSpace2 = NULL;
  29. m_ipConsole2 = NULL;
  30. m_hbmpSNodes16 = NULL;
  31. m_hbmpSNodes32 = NULL;
  32. m_ipScopeImage = NULL;
  33. m_hWatermark1 = NULL;
  34. m_hHeader1 = NULL;
  35. #if USE_WIZARD97_WATERMARKS
  36. // Load the bitmaps for property sheet watermark and headers
  37. m_hWatermark1 = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_WATERMARK1));
  38. ASSERT( m_hWatermark1 );
  39. #endif
  40. #if USE_WIZARD97_HEADERS
  41. m_hHeader1 = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_HEADER1));
  42. ASSERT( m_hHeader1 );
  43. #endif
  44. // this needs to be dynamic/per instance because our snap-in can be added multiple times to the same console
  45. m_ptrRootNode = new CRootFolder();
  46. }
  47. CComponentData::~CComponentData()
  48. {
  49. // We release the cached interface pointers in Destroy()
  50. ATLTRACE( _T("ComponentData::~ComponentData()\n") );
  51. SAFE_RELEASE( m_ptrRootNode );
  52. if( NULL != m_hWatermark1 )
  53. ::DeleteObject( m_hWatermark1 );
  54. if( NULL != m_hHeader1 )
  55. ::DeleteObject( m_hHeader1);
  56. ATLTRACE( _T("ComponentData::~ComponentData() The End\n\n") );
  57. }
  58. /////////////////////////////////////////////////////////////////////////////
  59. // IComponentData methods
  60. //
  61. //---------------------------------------------------------------------------
  62. // We get here only once, when the user clicks on the snapin.
  63. //
  64. // This method should not change as we progress through further steps.
  65. // Here we get a chance to get pointer to some interfaces MMC provides.
  66. // We QueryInterface for pointers to the name space and console, which
  67. // we cache in local variables
  68. // The other task to acomplish here is the adding of a bitmap that contains
  69. // the icons to be used in the scope pane.
  70. //
  71. STDMETHODIMP CComponentData::Initialize
  72. (
  73. LPUNKNOWN pUnknown // [in] Pointer to the IConsole�s IUnknown interface
  74. )
  75. {
  76. ATLTRACE( _T("ComponentData::Initialize()\n") );
  77. ASSERT( NULL != pUnknown );
  78. if (!m_ptrRootNode)
  79. {
  80. ATLTRACE( _T(" ComponentData::Initialize() Failed - no root node!\n"));
  81. return E_UNEXPECTED;
  82. }
  83. ATLTRACE( _T(" RootFolder <%s>\n"), m_ptrRootNode->GetNodeName() );
  84. // MMC should only call ::Initialize once!
  85. ASSERT( NULL == m_ipConsoleNameSpace2 );
  86. if (!pUnknown)
  87. return E_UNEXPECTED;
  88. HRESULT hr;
  89. hr = pUnknown->QueryInterface(IID_IConsoleNameSpace2, (VOID**)(&m_ipConsoleNameSpace2));
  90. ASSERT( S_OK == hr );
  91. hr = pUnknown->QueryInterface(IID_IConsole2, (VOID**)(&m_ipConsole2));
  92. ASSERT( S_OK == hr );
  93. if (m_ipConsole2)
  94. {
  95. hr = m_ipConsole2->QueryScopeImageList(&m_ipScopeImage);
  96. ASSERT( S_OK == hr );
  97. }
  98. // Load the bitmaps from the dll
  99. m_hbmpSNodes16 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_16x16));
  100. ASSERT( NULL != m_hbmpSNodes16 );
  101. m_hbmpSNodes32 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_32x32));
  102. ASSERT( NULL != m_hbmpSNodes32 );
  103. // Set the images
  104. if (m_ipScopeImage)
  105. {
  106. hr = m_ipScopeImage->ImageListSetStrip( (LONG_PTR *) m_hbmpSNodes16,
  107. (LONG_PTR *) m_hbmpSNodes32,
  108. 0,
  109. RGB(255, 0, 255)
  110. );
  111. ASSERT( S_OK == hr );
  112. }
  113. if (hr == S_OK && m_ipConsoleNameSpace2 && m_ipConsole2 && m_ipScopeImage && m_hbmpSNodes16 && m_hbmpSNodes32)
  114. m_Initialized = TRUE;
  115. else if (hr == S_OK)
  116. hr = E_UNEXPECTED;
  117. ATLTRACE( _T(" ComponentData::Initialize() <%s>\n"), m_Initialized ? _T("Succeeded") : _T("Failed"));
  118. m_ptrRootNode->SetConsoleInterface(m_ipConsole2);
  119. return S_OK;
  120. } // end Initialize()
  121. //---------------------------------------------------------------------------
  122. // Release interfaces and clean up objects which allocated memory
  123. //
  124. STDMETHODIMP CComponentData::Destroy()
  125. {
  126. ATLTRACE( _T("ComponentData::Destroy()\n") );
  127. if (m_ptrRootNode)
  128. m_ptrRootNode->SetConsoleInterface(NULL);
  129. // Free interfaces
  130. SAFE_RELEASE(m_ipConsoleNameSpace2);
  131. SAFE_RELEASE(m_ipConsole2);
  132. SAFE_RELEASE(m_ipScopeImage);
  133. VERIFY( ::DeleteObject( m_hbmpSNodes16 ) );
  134. VERIFY( ::DeleteObject( m_hbmpSNodes32 ) );
  135. return S_OK;
  136. } // end Destroy()
  137. //---------------------------------------------------------------------------
  138. // Come in here once right after Initialize. MMC wants a pointer to the
  139. // IComponent interface.
  140. //
  141. STDMETHODIMP CComponentData::CreateComponent
  142. (
  143. LPCOMPONENT* ppComponent // [out] Pointer to the location that stores
  144. ) // the newly created pointer to IComponent
  145. {
  146. ATLTRACE( _T("ComponentData::CreateComponent()\n") );
  147. if (!m_Initialized)
  148. return E_UNEXPECTED;
  149. ASSERT( NULL != ppComponent );
  150. CComObject<CComponent>* pObject;
  151. CComObject<CComponent>::CreateInstance( &pObject );
  152. ASSERT( NULL != pObject );
  153. if (!pObject)
  154. return E_UNEXPECTED;
  155. pObject->SetComponentData( this );
  156. return pObject->QueryInterface( IID_IComponent, reinterpret_cast<void**>(ppComponent) );
  157. } // end CreateComponent()
  158. //---------------------------------------------------------------------------
  159. //
  160. //
  161. STDMETHODIMP CComponentData::Notify
  162. (
  163. LPDATAOBJECT ipDataObject, // [in] Points to the selected data object
  164. MMC_NOTIFY_TYPE Event, // [in] Identifies action taken by user.
  165. LPARAM Arg, // [in] Depends on the notification type
  166. LPARAM Param // [in] Depends on the notification type
  167. )
  168. {
  169. ATLTRACE( _T("ComponentData::Notify %p 0x%X %p %p\n"), ipDataObject, Event, Arg, Param );
  170. HRESULT hr = S_FALSE;
  171. switch( Event )
  172. {
  173. // documented IComponentData::Notify Event
  174. case MMCN_EXPAND:
  175. {
  176. CBaseNode *pNode = ExtractBaseObject(ipDataObject);
  177. if (pNode)
  178. {
  179. ATLTRACE(_T("ComponentData::Notify MMCN_EXPAND (%s) %s \n"), ((BOOL) Arg) ? _T("expand") : _T("collapse"), pNode->GetNodeName());
  180. hr = pNode->OnExpand( (BOOL) Arg, Param, m_ipConsoleNameSpace2 );
  181. }
  182. else
  183. {
  184. ATLTRACE(_T("ComponentData::Notify MMCN_EXPAND (%s)\n"), ((BOOL) Arg) ? _T("expand") : _T("collapse"));
  185. static UINT s_cfMachineName = ::RegisterClipboardFormat(_T("MMC_SNAPIN_MACHINE_NAME"));
  186. FORMATETC fmt = { (CLIPFORMAT) s_cfMachineName, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  187. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  188. stgmedium.hGlobal = GlobalAlloc( GMEM_SHARE, SNAPIN_MAX_COMPUTERNAME_LENGTH + 1 );
  189. if (stgmedium.hGlobal)
  190. {
  191. if (S_OK == ipDataObject->GetDataHere(&fmt, &stgmedium) &&
  192. m_ptrRootNode)
  193. {
  194. m_ptrRootNode->SetComputerName((TCHAR *)stgmedium.hGlobal);
  195. hr = m_ptrRootNode->OnParentExpand( (BOOL) Arg, Param, m_ipConsoleNameSpace2 );
  196. }
  197. GlobalFree(stgmedium.hGlobal);
  198. }
  199. /*
  200. HRESULT res = ipDataObject->QueryGetData(&fmt);
  201. ATLTRACE(_T(" QueryData 0x%p\n"), res);
  202. if (res == S_OK)
  203. {
  204. int x = 9;
  205. }
  206. IEnumFORMATETC *ipEnumFORMATETC = 0;
  207. HRESULT res = ipDataObject->EnumFormatEtc(DATADIR_GET, &ipEnumFORMATETC);
  208. if (res == S_OK && ipEnumFORMATETC)
  209. {
  210. ULONG out = 0;
  211. FORMATETC aFormat;
  212. res = ipEnumFORMATETC->Next(1, &aFormat, &out);
  213. while (res == S_OK && out == 1)
  214. {
  215. const CLIPFORMAT cf = aFormat.cfFormat;
  216. out = 0;
  217. _TCHAR szFormatName[246];
  218. if (!GetClipboardFormatName(cf, szFormatName, ARRAY_SIZE(szFormatName)))
  219. _tcscpy(szFormatName, _T("Unknown format") );
  220. ATLTRACE(_T(" %s\n"), szFormatName);
  221. res = ipEnumFORMATETC->Next(1, &aFormat, &out);
  222. }
  223. ipEnumFORMATETC->Release();
  224. }
  225. */
  226. }
  227. }
  228. break;
  229. // documented IComponentData::Notify Event (documented under Event but not Notify method)
  230. case MMCN_REMOVE_CHILDREN:
  231. {
  232. CBaseNode *pNode = ExtractBaseObject(ipDataObject);
  233. if (pNode) // it "our" node call the specific handler
  234. {
  235. ATLTRACE(_T("ComponentData::Notify MMCN_REMOVE_CHILDREN %s\n"), pNode->GetNodeName());
  236. hr = pNode->OnRemoveChildren( Arg );
  237. }
  238. else if (m_ptrRootNode) // extension--the data object is "our" parent
  239. {
  240. ATLTRACE(_T("ComponentData::Notify MMCN_REMOVE_CHILDREN -- extension\n"));
  241. hr = m_ptrRootNode->OnParentRemoveChildren( Arg );
  242. }
  243. else
  244. {
  245. ATLTRACE(_T("ComponentData::Notify MMCN_REMOVE_CHILDREN -- unexpected\n"));
  246. hr = E_UNEXPECTED;
  247. }
  248. }
  249. break;
  250. // documented IComponentData::Notify Event
  251. case MMCN_PROPERTY_CHANGE:
  252. ATLTRACE(_T("ComponentData::Notify MMCN_PROPERTY_CHANGE \n"));
  253. hr = OnPropertyChange( (BOOL) Arg, Param);
  254. break;
  255. case MMCN_HELP:
  256. // supposively NOT USED by MMC
  257. ATLTRACE( _T("ComponentData::Notify MMCN_HELP unimplemented\n") );
  258. hr = S_FALSE;
  259. break;
  260. case MMCN_SNAPINHELP:
  261. ATLTRACE( _T("ComponentData::Notify MMCN_SNAPINHELP unimplemented\n") );
  262. hr = S_FALSE;
  263. break;
  264. case MMCN_CONTEXTHELP:
  265. ATLTRACE( _T("ComponentData::Notify MMCN_CONTEXTHELP unimplemented\n") );
  266. hr = S_FALSE;
  267. break;
  268. case MMCN_EXPANDSYNC:
  269. {
  270. CBaseNode *pNode = ExtractBaseObject(ipDataObject);
  271. ASSERT(pNode);
  272. if (!pNode)
  273. return E_UNEXPECTED;
  274. ATLTRACE( _T("ComponentData::Notify MMCN_EXPANDSYNC %s unimplemented\n"), pNode->GetNodeName() );
  275. MMC_EXPANDSYNC_STRUCT *info = (MMC_EXPANDSYNC_STRUCT *) Param;
  276. hr = S_FALSE;
  277. }
  278. break;
  279. case MMCN_DELETE: // - shouldn't see
  280. ATLTRACE( _T("ComponentData::Notify MMCN_DELETE unimplemented\n") );
  281. hr = S_FALSE;
  282. break;
  283. /*
  284. // not seeing any of the NOTIFY events below/add as needed
  285. // NOT documented as a IComponentData::Notify Event
  286. case MMCN_REFRESH:
  287. ATLTRACE( _T("ComponentData::Notify MMCN_REFRESH unimplemented\n") );
  288. break;
  289. // CCF_SNAPIN_PRELOADS format specific
  290. case MMCN_PRELOAD:
  291. ATLTRACE( _T("ComponentData::Notify MMCN_PRELAOD unimplemented\n") );
  292. break;
  293. // documented IComponentData::Notify Event
  294. case MMCN_RENAME: // - shouldn't see
  295. ATLTRACE( _T("ComponentData::Notify MMCN_RENAME unimplemented\n") );
  296. hr = S_FALSE;
  297. break;
  298. case MMCN_DELETE: // - shouldn't see
  299. ATLTRACE( _T("ComponentData::Notify MMCN_DELETE unimplemented\n") );
  300. hr = S_FALSE;
  301. break;
  302. case MMCN_BTN_CLICK:
  303. case MMCN_CONTEXTHELP:
  304. case MMCN_CUTORMOVE:
  305. case MMCN_QUERY_PASTE:
  306. case MMCN_PASTE:
  307. case MMCN_PRINT:
  308. */
  309. default:
  310. ATLTRACE(_T("ComponentData::NOTIFY unhandled notify event 0x%X\n"), Event);
  311. hr = S_FALSE;
  312. break;
  313. }
  314. return hr;
  315. } // end Notify()
  316. //---------------------------------------------------------------------------
  317. // MMCN_PROPERTY_CHANGE notification
  318. //
  319. HRESULT CComponentData::OnPropertyChange
  320. (
  321. BOOL bScopeItem,
  322. LPARAM Param
  323. )
  324. {
  325. if (!bScopeItem)
  326. {
  327. ASSERT(FALSE); // what is this path being used by?
  328. return S_OK;
  329. }
  330. PROPERTY_CHANGE_HDR *pUpdate = reinterpret_cast<PROPERTY_CHANGE_HDR*>(Param);
  331. if (pUpdate)
  332. {
  333. if (pUpdate->pFolder && pUpdate->bScopeItem)
  334. pUpdate->pFolder->OnPropertyChange(pUpdate, m_ipConsole2);
  335. pUpdate = FreePropChangeInfo(pUpdate);
  336. }
  337. return S_OK;
  338. } // end OnPropertyChange()
  339. //---------------------------------------------------------------------------
  340. // This is where MMC asks us to provide IDataObjects for every node in the
  341. // scope pane. We have to QI the object so it gets AddRef'd. The node
  342. // manager handles deleting the objects.
  343. //
  344. STDMETHODIMP CComponentData::QueryDataObject
  345. (
  346. MMC_COOKIE Cookie, // [in] Data object's unique identifier
  347. DATA_OBJECT_TYPES Context, // [in] Data object's type
  348. LPDATAOBJECT* ppDataObject // [out] Points to the returned data object
  349. )
  350. {
  351. // check for magic multi-select cookie
  352. if (IS_SPECIAL_COOKIE(Cookie) )
  353. {
  354. if (Cookie == MMC_MULTI_SELECT_COOKIE)
  355. ATLTRACE( _T("ComponentData::QueryDataObject: MMC_MULTI_SELECT_COOKIE unimplemented\n") );
  356. else
  357. ATLTRACE( _T("ComponentData::QueryDataObject: special cookie 0x%X unimplemented\n"), Cookie );
  358. return E_UNEXPECTED;
  359. }
  360. ATLTRACE( _T("ComponentData::QueryDataObject\n") );
  361. ASSERT( CCT_SCOPE == Context || // Must have a context
  362. CCT_RESULT == Context || // we understand
  363. CCT_SNAPIN_MANAGER == Context
  364. );
  365. if (CCT_SNAPIN_MANAGER == Context ||
  366. CCT_SCOPE == Context)
  367. {
  368. CComObject<CDataObject>* pDataObj;
  369. CComObject<CDataObject>::CreateInstance( &pDataObj );
  370. if( ! pDataObj ) // DataObject was not created
  371. {
  372. ASSERT(pDataObj);
  373. return E_OUTOFMEMORY;
  374. }
  375. CBaseNode *pFolder;
  376. if (Cookie == NULL)
  377. {
  378. ASSERT(m_ptrRootNode);
  379. pFolder = m_ptrRootNode;
  380. }
  381. else
  382. {
  383. pFolder = reinterpret_cast<CBaseNode *> (Cookie);
  384. }
  385. // ATLTRACE( _T("%s-ComponentData::QueryDataObject: %s\n"), pFolder->GetNodeName(), (Context == CCT_SCOPE) ? _T("CCT_SCOPE") : _T("CCT_SNAPIN_MANAGER") );
  386. pDataObj->SetDataObject( Context, pFolder );
  387. HRESULT hr = pDataObj->QueryInterface( IID_IDataObject,
  388. reinterpret_cast<void**>(ppDataObject)
  389. );
  390. return hr;
  391. }
  392. else if (CCT_RESULT == Context)
  393. {
  394. // ATLTRACE( _T("ComponentData::QueryDataObject: CCT_RESULT unsupported\n") );
  395. return E_UNEXPECTED;
  396. }
  397. // CCT_UNINITIALIZED
  398. // ATLTRACE( _T("ComponentData::QueryDataObject: unsupported Context\n") );
  399. return E_UNEXPECTED;
  400. } // end QueryDataObject()
  401. //---------------------------------------------------------------------------
  402. // This is where we provide strings for nodes in the scope pane.
  403. // MMC handles the root node string.
  404. //
  405. STDMETHODIMP CComponentData::GetDisplayInfo
  406. (
  407. LPSCOPEDATAITEM pItem // [in, out] Points to a SCOPEDATAITEM struct
  408. )
  409. {
  410. ASSERT( NULL != pItem );
  411. HRESULT hr = S_OK;
  412. if (!pItem->mask) // doesn't need anything
  413. return S_OK;
  414. // the SDI_PARAM flag does not have to be set on input to indicate that the LPARAM is valid
  415. //if (! (pItem->mask & SDI_PARAM) )
  416. // return E_UNEXPECTED;
  417. //ASSERT( pItem->lParam);
  418. // get object from SCOPEITEM's lParam
  419. CBaseNode *pTmp = NULL;
  420. if (pItem->lParam)
  421. pTmp = reinterpret_cast<CBaseNode *>(pItem->lParam);
  422. else
  423. pTmp = dynamic_cast<CBaseNode *>(m_ptrRootNode);
  424. // this should never be called with the root node,
  425. // all scope items with lParam pointer to object derived from CBaseNode
  426. if (!pTmp)
  427. return E_UNEXPECTED;
  428. if ( pItem->mask & SDI_STR ) // wants the display name
  429. {
  430. pItem->displayname = const_cast<LPOLESTR>( pTmp->GetNodeName() );
  431. }
  432. if (pItem->mask & SDI_IMAGE)
  433. {
  434. pItem->nImage = pTmp->sImage();
  435. }
  436. if (pItem->mask & SDI_OPENIMAGE)
  437. {
  438. pItem->nOpenImage = pTmp->sOpenImage();
  439. }
  440. return hr;
  441. } // end GetDisplayInfo()
  442. //---------------------------------------------------------------------------
  443. //
  444. STDMETHODIMP CComponentData::CompareObjects
  445. (
  446. LPDATAOBJECT ipDataObjectA, // [in] First data object to compare
  447. LPDATAOBJECT ipDataObjectB // [in] Second data object to compare
  448. )
  449. {
  450. CBaseNode *pdoA;
  451. CBaseNode *pdoB;
  452. pdoA = ExtractBaseObject( ipDataObjectA );
  453. pdoB = ExtractBaseObject( ipDataObjectB );
  454. ASSERT( pdoA || pdoB );
  455. // If extraction failed for one of them, then that one is foreign and
  456. // can't be equal to the other one. (Or else ExtractOwnDataObject
  457. // returned NULL because it ran out of memory, but the most conservative
  458. // thing to do in that case is say they're not equal.)
  459. if( !pdoA || !pdoB )
  460. {
  461. ATLTRACE(_T("ComponentData::CompareObjects() - FALSE one or both objects not recognized\n") );
  462. return S_FALSE;
  463. }
  464. // If they have "our" same node type
  465. if( pdoA->GetNodeType() == pdoB->GetNodeType() )
  466. {
  467. ATLTRACE(_T("ComponentData::CompareObjects() - TRUE\n") );
  468. return S_OK;
  469. }
  470. ATLTRACE(_T("ComponentData::CompareObjects() - FALSE\n") );
  471. return S_FALSE;
  472. } // end CompareObjects()
  473. /////////////////////////////////////////////////////////////////////////////
  474. // IExtendContextMenu method implementations
  475. //
  476. STDMETHODIMP CComponentData::AddMenuItems
  477. (
  478. LPDATAOBJECT ipDataObject, // [in] Points to data object
  479. LPCONTEXTMENUCALLBACK piCallback, // [in] Pointer to IContextMenuCallback
  480. long* pInsertionAllowed // [in,out] Insertion flags
  481. )
  482. {
  483. ASSERT( NULL != ipDataObject );
  484. HRESULT hr = S_OK;
  485. if (IsMMCMultiSelectDataObject(ipDataObject))
  486. return E_UNEXPECTED;
  487. CBaseNode *pNode = ExtractBaseObject( ipDataObject );
  488. if (!pNode)
  489. return E_UNEXPECTED;
  490. return pNode->AddMenuItems(piCallback, pInsertionAllowed);
  491. } // end AddMenuItems()
  492. /////////////////////////////////////////////////////////////////////////////
  493. // IExtendContextMenu method implementations
  494. //
  495. STDMETHODIMP CComponentData::Command
  496. (
  497. long nCommandID, // [in] Command to handle
  498. LPDATAOBJECT ipDataObject // [in] Points to data object
  499. )
  500. {
  501. HRESULT hr = S_FALSE;
  502. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  503. CBaseNode *pNode = ExtractBaseObject( ipDataObject );
  504. ASSERT(pDO);
  505. if (!pDO || !pNode)
  506. return hr;
  507. // $$ not a desireable action to take but if this isn't done
  508. // the context menu for a node can be operated on, and the result pane doesn't reflect the
  509. // changes because the scope node selection wasn't changed when the context menu is obtained for
  510. // a different node.
  511. // i.e.
  512. // Processes scope node is selected,
  513. // right click on root node get a context menu (for the root node) and connect to a different computer
  514. // the system still shows the processes scope node selected and the result pane shows the
  515. // list of processes on the machine previously connected!
  516. m_ipConsole2->SelectScopeItem(pNode->GetID());
  517. /*
  518. {
  519. ATLTRACE( _T("Attempt patch of framework!\n"));
  520. //OnShow(ipDataObject, TRUE, pNode->GetID());
  521. m_ipConsole2->SelectScopeItem(pNode->GetID());
  522. }
  523. */
  524. CJobItemFolder *pJobItemFolder = dynamic_cast<CJobItemFolder *> (pNode);
  525. if (pJobItemFolder)
  526. hr = pJobItemFolder->OnMenuCommand(m_ipConsole2, m_ipConsoleNameSpace2, nCommandID );
  527. else
  528. hr = pNode->OnMenuCommand(m_ipConsole2, nCommandID );
  529. if (hr == S_OK)
  530. return hr;
  531. ATLTRACE(_T("ComponentData::Command - unrecognized or failed command %d\n"), nCommandID);
  532. return hr;
  533. } // end Command()
  534. STDMETHODIMP CComponentData::GetWatermarks
  535. (
  536. LPDATAOBJECT ipDataObject,
  537. HBITMAP *lphWatermark,
  538. HBITMAP * lphHeader,
  539. HPALETTE * lphPalette,
  540. BOOL* bStretch
  541. )
  542. {
  543. // invoked during addition of snapin
  544. // may be called prior to Initialize() method like
  545. // IComponentData::QueryDataObject() with CCT_SNAPIN_MANAGER context
  546. // note this may return NULL handles for watermark and header...this is suppose to be OK
  547. // see use of USE_WIZARD97_ precompiled headers
  548. // 10/8/1998 with MMC 1.1 RC4
  549. // MMC is calling this method with lphWatermark equal to IDataObject address
  550. // if we store anything at the addresss we corrupt the IDataObject,
  551. // MMC then calls another method with corrupt IDataObject (CreatePropertyPages()) and boom
  552. // access violation!
  553. // report to Microsoft Derek Jacoby (10/8/1998)
  554. //
  555. // 10/10/1998 Derek Jacoby
  556. // informed me the interface method has changed and now
  557. // includes an addition parameter....
  558. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  559. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  560. if (pDO && pNode)
  561. {
  562. ATLTRACE(_T("ComponentData::GetWatermarks() %s\n"), pNode->GetNodeName());
  563. *lphWatermark = m_hWatermark1;
  564. *lphHeader = m_hHeader1;
  565. *lphPalette = NULL;
  566. *bStretch = TRUE;
  567. return S_OK;
  568. }
  569. ATLTRACE(_T("ComponentData::GetWatermarks() %s\n"), _T("Unrecognized IDataObject"));
  570. return S_FALSE;
  571. } // end GetWatermarks()
  572. STDMETHODIMP CComponentData::QueryPagesFor
  573. (
  574. LPDATAOBJECT ipDataObject
  575. )
  576. {
  577. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  578. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  579. if (pDO && pDO->IsResultItem() )
  580. {
  581. ASSERT(FALSE); // WHY HERE?, why didn't Component::QueryPagesFor get asked?
  582. }
  583. if (pDO && pNode && !pDO->IsResultItem())
  584. {
  585. ATLTRACE(_T("ComponentData::QueryPagesFor() %s\n"), pNode->GetNodeName());
  586. return pNode->QueryPagesFor();
  587. }
  588. ATLTRACE(_T("ComponentData::QueryPagesFor() %s\n"), _T("Unrecognized IDataObject"));
  589. return S_FALSE;
  590. }
  591. STDMETHODIMP CComponentData::CreatePropertyPages
  592. (
  593. LPPROPERTYSHEETCALLBACK lpProvider,
  594. LONG_PTR handle,
  595. LPDATAOBJECT ipDataObject
  596. )
  597. {
  598. ASSERT( NULL != lpProvider );
  599. CDataObject *pDO = ExtractOwnDataObject( ipDataObject );
  600. CBaseNode *pNode = ExtractBaseObject( ipDataObject);
  601. if (pDO && pDO->IsResultItem() )
  602. {
  603. ASSERT(FALSE); // WHY HERE?
  604. }
  605. if (pDO && pNode && !pDO->IsResultItem())
  606. {
  607. ATLTRACE(_T("ComponentData::CreatePropertyPages() %s\n"), pNode->GetNodeName());
  608. return pNode->OnCreatePropertyPages(lpProvider, handle, pDO->GetContext());
  609. }
  610. ATLTRACE(_T("ComponentData::CreatePropertyPages() %s\n"), _T("Unrecognized IDataObject"));
  611. return S_FALSE;
  612. }
  613. /////////////////////////////////////////////////////////////////////////////
  614. // IStream implementation
  615. //
  616. STDMETHODIMP CComponentData::GetClassID(CLSID *pClassID)
  617. {
  618. ATLTRACE(_T("ComponentData::GetClassID()\n"));
  619. *pClassID = CLSID_ComponentData;
  620. return S_OK;
  621. }
  622. STDMETHODIMP CComponentData::IsDirty()
  623. {
  624. ATLTRACE(_T("ComponentData::IsDirty()\n"));
  625. HRESULT hr = S_FALSE; // default to no changes...
  626. if (m_ptrRootNode)
  627. hr = m_ptrRootNode->IsDirty();
  628. ATLTRACE(_T(" ComponentData::IsDirty() %s\n"), (hr == S_OK ? _T("Dirty") : _T("No Changes")));
  629. return hr;
  630. }
  631. STDMETHODIMP CComponentData::Load(IStream *pStm)
  632. {
  633. ATLTRACE(_T("\nComponentData::Load()\n"));
  634. if (m_ptrRootNode)
  635. return m_ptrRootNode->Load(pStm);
  636. return E_UNEXPECTED;
  637. }
  638. STDMETHODIMP CComponentData::Save(IStream *pStm, BOOL fClearDirty)
  639. {
  640. ATLTRACE(_T("\nComponentData::Save()\n"));
  641. if (m_ptrRootNode)
  642. return m_ptrRootNode->Save(pStm, fClearDirty);
  643. return E_UNEXPECTED;
  644. }
  645. STDMETHODIMP CComponentData::GetSizeMax(ULARGE_INTEGER *pcbSize)
  646. {
  647. ATLTRACE(_T("ComponentData::GetSizeMax()\n"));
  648. if (m_ptrRootNode)
  649. return m_ptrRootNode->GetSizeMax(pcbSize);
  650. return E_UNEXPECTED;
  651. }
  652. /////////////////////////////////////////////////////////////////////////////
  653. // ISnapinHelp2
  654. //
  655. STDMETHODIMP CComponentData::GetHelpTopic(LPOLESTR *lpCompiledHelpFile)
  656. {
  657. ATLTRACE(_T("ComponentData::GetHelpTopic()\n"));
  658. if (!lpCompiledHelpFile)
  659. return E_POINTER;
  660. *lpCompiledHelpFile = reinterpret_cast<LPOLESTR> (CoTaskMemAlloc(_MAX_PATH * sizeof(TCHAR)));
  661. if (!*lpCompiledHelpFile)
  662. return E_OUTOFMEMORY;
  663. DWORD len = ExpandEnvironmentStrings(HELP_FilePath, *lpCompiledHelpFile, _MAX_PATH);
  664. if (len && len <= _MAX_PATH)
  665. return S_OK;
  666. return E_UNEXPECTED;
  667. }
  668. STDMETHODIMP CComponentData::GetLinkedTopics(LPOLESTR *lpCompiledHelpFiles)
  669. {
  670. ATLTRACE(_T("ComponentData::GetLinkedTopics()\n"));
  671. if (!lpCompiledHelpFiles)
  672. return E_POINTER;
  673. *lpCompiledHelpFiles = reinterpret_cast<LPOLESTR> (CoTaskMemAlloc(_MAX_PATH * sizeof(TCHAR)));
  674. if (!*lpCompiledHelpFiles)
  675. return E_OUTOFMEMORY;
  676. DWORD len = ExpandEnvironmentStrings(HELP_LinkedFilePaths, *lpCompiledHelpFiles, _MAX_PATH);
  677. if (len && len <= _MAX_PATH)
  678. return S_OK;
  679. return E_UNEXPECTED;
  680. }