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.

4340 lines
122 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: Node.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 9/16/1996 RaviR Created
  15. //
  16. //____________________________________________________________________________
  17. #include "stdafx.h"
  18. #include "macros.h"
  19. #include "strings.h"
  20. #include "ndmgr.h"
  21. #include "regutil.h"
  22. #include "taskenum.h"
  23. #include "nodemgr.h"
  24. #include "multisel.h"
  25. #include "rsltitem.h"
  26. #include "colwidth.h"
  27. #include "viewpers.h"
  28. #include "tasks.h"
  29. #include "conview.h"
  30. #include "columninfo.h"
  31. #include "util.h" // for CoTaskDupString
  32. #include "mmcprotocol.h"
  33. #include "nodemgrdebug.h"
  34. #include "copypast.h"
  35. #ifdef _DEBUG
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. /*+-------------------------------------------------------------------------*
  40. * class CConsoleTaskpadViewExtension
  41. *
  42. *
  43. * PURPOSE: Implements console taskpads as a view extension
  44. *
  45. *+-------------------------------------------------------------------------*/
  46. class CConsoleTaskpadViewExtension
  47. {
  48. public:
  49. /*+-------------------------------------------------------------------------*
  50. *
  51. * ScGetViews
  52. *
  53. * PURPOSE: Adds all console taskpad views to the view extension callback.
  54. *
  55. * PARAMETERS:
  56. * CNode * pNode :
  57. * LPVIEWEXTENSIONCALLBACK pViewExtensionCallback :
  58. *
  59. * RETURNS:
  60. * SC
  61. *
  62. *+-------------------------------------------------------------------------*/
  63. static SC ScGetViews(CNode *pNode, LPVIEWEXTENSIONCALLBACK pViewExtensionCallback)
  64. {
  65. DECLARE_SC(sc, TEXT("CConsoleTaskpadViewExtension::ScGetViews"));
  66. CScopeTree* pScopeTree = CScopeTree::GetScopeTree();
  67. sc = ScCheckPointers(pNode, pViewExtensionCallback, pScopeTree, E_FAIL);
  68. if(sc)
  69. return sc;
  70. // get a filtered list of taskpads that apply to this node.
  71. CConsoleTaskpadFilteredList filteredList;
  72. sc = pScopeTree->GetConsoleTaskpadList()->ScGetTaskpadList(pNode, filteredList);
  73. if(sc)
  74. return sc;
  75. for(CConsoleTaskpadFilteredList::iterator iter = filteredList.begin(); iter!= filteredList.end(); ++iter)
  76. {
  77. CConsoleTaskpad *pConsoleTaskpad = *iter;
  78. sc = ScAddViewForTaskpad(pConsoleTaskpad, pViewExtensionCallback);
  79. if(sc)
  80. return sc;
  81. }
  82. return sc;
  83. }
  84. /*+-------------------------------------------------------------------------*
  85. * ScGetTaskpadViewExtension
  86. *
  87. * Returns S_OK if the given CLSID matches the CLSID of any taskpad view
  88. * extension for the given node, S_FALSE or error otherwise.
  89. *--------------------------------------------------------------------------*/
  90. static SC ScGetViewExtensionTaskpad (CNode* pNode, const CLSID& clsid, CConsoleTaskpad*& pConsoleTaskpad)
  91. {
  92. DECLARE_SC (sc, _T("CConsoleTaskpadViewExtension::ScGetTaskpadViewExtension"));
  93. /*
  94. * initialize output
  95. */
  96. pConsoleTaskpad = NULL;
  97. /*
  98. * check input
  99. */
  100. sc = ScCheckPointers (pNode);
  101. if(sc)
  102. return sc;
  103. CScopeTree* pScopeTree = CScopeTree::GetScopeTree();
  104. sc = ScCheckPointers (pScopeTree, E_UNEXPECTED);
  105. if (sc)
  106. return (sc);
  107. // get a filtered list of taskpads that apply to this node.
  108. CConsoleTaskpadFilteredList filteredList;
  109. sc = pScopeTree->GetConsoleTaskpadList()->ScGetTaskpadList(pNode, filteredList);
  110. if(sc)
  111. return sc;
  112. for(CConsoleTaskpadFilteredList::iterator iter = filteredList.begin(); iter!= filteredList.end(); ++iter)
  113. {
  114. CConsoleTaskpad* pTempConsoleTaskpad = *iter;
  115. sc = ScCheckPointers (pTempConsoleTaskpad, E_UNEXPECTED);
  116. if (sc)
  117. return (sc);
  118. /*
  119. * if the CLSID matches the ID of this taskpad, CLSID refers to
  120. * a taskpad view extension
  121. */
  122. if (clsid == pTempConsoleTaskpad->GetID())
  123. {
  124. pConsoleTaskpad = pTempConsoleTaskpad;
  125. break;
  126. }
  127. }
  128. return (sc);
  129. }
  130. private:
  131. /*+-------------------------------------------------------------------------*
  132. *
  133. * ScAddViewForTaskpad
  134. *
  135. * PURPOSE: Adds a view based on a console taskpad to the view extension
  136. * callback.
  137. *
  138. * PARAMETERS:
  139. * CConsoleTaskpad * pConsoleTaskpad :
  140. * LPVIEWEXTENSIONCALLBACK pViewExtensionCallback :
  141. *
  142. * RETURNS:
  143. * SC
  144. *
  145. *+-------------------------------------------------------------------------*/
  146. static SC ScAddViewForTaskpad(CConsoleTaskpad *pConsoleTaskpad, LPVIEWEXTENSIONCALLBACK pViewExtensionCallback)
  147. {
  148. DECLARE_SC(sc, TEXT("CConsoleTaskpadViewExtension::ScAddViewForTaskpad"));
  149. // validate inputs
  150. sc = ScCheckPointers(pConsoleTaskpad, pViewExtensionCallback);
  151. if(sc)
  152. return sc;
  153. MMC_EXT_VIEW_DATA extViewData = {0};
  154. // get the string form of the taskpad ID.
  155. CCoTaskMemPtr<WCHAR> spszTaskpadID;
  156. sc = StringFromCLSID (pConsoleTaskpad->GetID(), &spszTaskpadID);
  157. if (sc)
  158. return sc;
  159. std::wstring strTaskpad = _W(MMC_PROTOCOL_SCHEMA_NAME) _W(":");
  160. strTaskpad += spszTaskpadID;
  161. extViewData.pszURL = strTaskpad.c_str();
  162. extViewData.bReplacesDefaultView = pConsoleTaskpad->FReplacesDefaultView() ? TRUE : FALSE; // convert from bool to BOOL
  163. extViewData.viewID = pConsoleTaskpad->GetID(); // set the GUID identifier of the view
  164. USES_CONVERSION;
  165. tstring strName = pConsoleTaskpad->GetName();
  166. extViewData.pszViewTitle = T2COLE(strName.data()); // set the title of the view
  167. if(!extViewData.pszViewTitle)
  168. return (sc = E_OUTOFMEMORY).ToHr();
  169. sc = pViewExtensionCallback->AddView(&extViewData);
  170. return sc;
  171. }
  172. };
  173. //############################################################################
  174. //############################################################################
  175. //
  176. // Implementation of class CComponent
  177. //
  178. //############################################################################
  179. //############################################################################
  180. DEBUG_DECLARE_INSTANCE_COUNTER(CComponent);
  181. void CComponent::Construct(CSnapIn * pSnapIn, CComponent* pComponent)
  182. {
  183. ASSERT(pSnapIn);
  184. DEBUG_INCREMENT_INSTANCE_COUNTER(CComponent);
  185. m_spSnapIn = pSnapIn;
  186. m_ComponentID = -1;
  187. m_bIComponentInitialized = false;
  188. if (pComponent)
  189. {
  190. ASSERT(pComponent->m_spIComponent != NULL);
  191. ASSERT(pComponent->m_spIFrame != NULL);
  192. m_spIComponent = pComponent->m_spIComponent;
  193. m_spIFrame = pComponent->m_spIFrame;
  194. m_spIRsltImageList = pComponent->m_spIRsltImageList;
  195. m_ComponentID = pComponent->GetComponentID();
  196. }
  197. }
  198. CComponent::~CComponent()
  199. {
  200. DECLARE_SC(sc, TEXT("CComponent::~CComponent"));
  201. DEBUG_DECREMENT_INSTANCE_COUNTER(CComponent);
  202. if (m_spIFrame)
  203. {
  204. sc = m_spIFrame->SetHeader(NULL);
  205. if (sc)
  206. sc.TraceAndClear();
  207. }
  208. if (m_spIComponent)
  209. {
  210. sc = m_spIComponent->Destroy(NULL);
  211. if (sc)
  212. sc.TraceAndClear();
  213. }
  214. }
  215. HRESULT CComponent::Init(IComponentData* pIComponentData, HMTNODE hMTNode,
  216. HNODE lNode,
  217. COMPONENTID nComponentID, int viewID)
  218. {
  219. DECLARE_SC(sc, TEXT("CComponent::Init"));
  220. ASSERT(hMTNode != 0);
  221. ASSERT(lNode != 0);
  222. sc = ScCheckPointers( pIComponentData, E_POINTER );
  223. if (sc)
  224. return sc.ToHr();
  225. do
  226. {
  227. sc = pIComponentData->CreateComponent(&m_spIComponent);
  228. if (sc)
  229. break;
  230. // recheck the pointers
  231. sc = ScCheckPointers( m_spIComponent, E_UNEXPECTED );
  232. if (sc)
  233. break;
  234. // Create an IFrame for this IComponent
  235. #if _MSC_VER>=1100
  236. sc = m_spIFrame.CreateInstance(CLSID_NodeInit, NULL, MMC_CLSCTX_INPROC);
  237. #else
  238. sc = m_spIFrame.CreateInstance(CLSID_NodeInit, MMC_CLSCTX_INPROC);
  239. #endif
  240. if (sc)
  241. break;
  242. // recheck the pointer
  243. sc = ScCheckPointers( m_spIFrame, E_UNEXPECTED );
  244. if (sc)
  245. break;
  246. Debug_SetNodeInitSnapinName(m_spSnapIn, m_spIFrame.GetInterfacePtr());
  247. // Cache the IComponent in the NodeInit object
  248. sc = m_spIFrame->SetComponent(m_spIComponent);
  249. if (sc)
  250. break;
  251. // recheck the pointer
  252. sc = ScCheckPointers( m_spSnapIn, E_UNEXPECTED );
  253. if (sc)
  254. break;
  255. // Create scope image list
  256. sc = m_spIFrame->CreateScopeImageList(m_spSnapIn->GetSnapInCLSID());
  257. if (sc)
  258. break;
  259. sc = m_spIFrame->SetNode(hMTNode, lNode);
  260. if (sc)
  261. break;
  262. ASSERT(nComponentID == GetComponentID());
  263. sc = m_spIFrame->SetComponentID(nComponentID);
  264. if (sc)
  265. break;
  266. // Result Image list is optional
  267. m_spIRsltImageList = m_spIFrame;
  268. sc = ScCheckPointers( m_spIRsltImageList, E_FAIL );
  269. if (sc)
  270. sc.TraceAndClear();
  271. // Complete IComponent initialization.
  272. // Init m_spIComponent with m_spIFrame.
  273. sc = m_spIComponent->Initialize(m_spIFrame);
  274. if (sc)
  275. break;
  276. CMTNode* const pMTNode = CMTNode::FromHandle (hMTNode);
  277. sc = ScCheckPointers( pMTNode, E_UNEXPECTED );
  278. if (sc)
  279. break;
  280. CMTSnapInNode* const pSnapInNode = pMTNode->GetStaticParent();
  281. sc = ScCheckPointers( pSnapInNode, E_UNEXPECTED );
  282. if (sc)
  283. break;
  284. sc = pSnapInNode->ScInitIComponent(this, viewID);
  285. if (sc)
  286. break;
  287. } while (0);
  288. if (sc)
  289. {
  290. m_spIComponent = NULL;
  291. m_spIFrame = NULL;
  292. m_spIRsltImageList = NULL;
  293. }
  294. return sc.ToHr();
  295. }
  296. inline HRESULT CComponent::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event,
  297. LONG_PTR arg, LPARAM param)
  298. {
  299. ASSERT(m_spIComponent != NULL);
  300. if (m_spIComponent == NULL)
  301. return E_FAIL;
  302. HRESULT hr = S_OK;
  303. __try
  304. {
  305. hr = m_spIComponent->Notify(lpDataObject, event, arg, param);
  306. }
  307. __except (EXCEPTION_EXECUTE_HANDLER)
  308. {
  309. hr = E_FAIL;
  310. if (m_spSnapIn)
  311. TraceSnapinException(m_spSnapIn->GetSnapInCLSID(), TEXT("IComponent::Notify"), event);
  312. }
  313. return hr;
  314. }
  315. SC CComponent::ScQueryDispatch(MMC_COOKIE cookie,
  316. DATA_OBJECT_TYPES type,
  317. PPDISPATCH ppSelectedObject)
  318. {
  319. DECLARE_SC(sc, _T("CComponent::ScQueryDispatch"));
  320. sc = ScCheckPointers(m_spIComponent, E_UNEXPECTED);
  321. if (sc)
  322. return sc;
  323. IComponent2Ptr spComponent2 = m_spIComponent;
  324. sc = ScCheckPointers(spComponent2.GetInterfacePtr(), E_NOINTERFACE);
  325. if (sc)
  326. return sc;
  327. sc = spComponent2->QueryDispatch(cookie, type, ppSelectedObject);
  328. return sc;
  329. }
  330. //+-------------------------------------------------------------------
  331. //
  332. // Member: CComponent::ScResetConsoleVerbStates
  333. //
  334. // Synopsis: Reset the verbstates in the CConsoleVerbImpl (the one
  335. // snapin is aware of).
  336. //
  337. // Arguments: None
  338. //
  339. // Returns: SC
  340. //
  341. //--------------------------------------------------------------------
  342. SC CComponent::ScResetConsoleVerbStates ()
  343. {
  344. DECLARE_SC(sc, _T("CComponent::ScResetConsoleVerbStates"));
  345. IFramePrivate* pIFP = GetIFramePrivate();
  346. sc = ScCheckPointers(pIFP, E_UNEXPECTED);
  347. if (sc)
  348. return sc;
  349. IConsoleVerbPtr spConsoleVerb;
  350. sc = pIFP->QueryConsoleVerb(&spConsoleVerb);
  351. if (sc)
  352. return sc;
  353. sc = ScCheckPointers(spConsoleVerb, E_UNEXPECTED);
  354. if (sc)
  355. return sc;
  356. CConsoleVerbImpl* pCVI = dynamic_cast<CConsoleVerbImpl*>(
  357. static_cast<IConsoleVerb*>(spConsoleVerb));
  358. sc = ScCheckPointers(pCVI, E_UNEXPECTED);
  359. if (sc)
  360. return sc;
  361. pCVI->SetDisabledAll();
  362. return (sc);
  363. }
  364. //############################################################################
  365. //############################################################################
  366. //
  367. // Implementation of class CNode
  368. //
  369. //############################################################################
  370. //############################################################################
  371. DEBUG_DECLARE_INSTANCE_COUNTER(CNode);
  372. CNode::CNode (
  373. CMTNode* pMTNode,
  374. CViewData* pViewData,
  375. bool fRootNode) :
  376. m_pMTNode (pMTNode),
  377. m_pViewData (pViewData),
  378. m_hri (0),
  379. m_dwFlags (0),
  380. m_pPrimaryComponent (NULL),
  381. m_bInitComponents (TRUE),
  382. m_fRootNode (fRootNode),
  383. m_fStaticNode (false)
  384. {
  385. CommonConstruct();
  386. }
  387. CNode::CNode (
  388. CMTNode* pMTNode,
  389. CViewData* pViewData,
  390. bool fRootNode,
  391. bool fStaticNode) :
  392. m_pMTNode (pMTNode),
  393. m_pViewData (pViewData),
  394. m_hri (0),
  395. m_dwFlags (0),
  396. m_pPrimaryComponent (NULL),
  397. m_bInitComponents (TRUE),
  398. m_fRootNode (fRootNode),
  399. m_fStaticNode (fStaticNode)
  400. {
  401. CommonConstruct();
  402. }
  403. CNode::CNode(const CNode& other) :
  404. m_pMTNode (other.m_pMTNode),
  405. m_pViewData (other.m_pViewData),
  406. m_hri (other.m_hri),
  407. m_dwFlags (other.m_dwFlags),
  408. m_pPrimaryComponent (other.m_pPrimaryComponent),
  409. m_bInitComponents (other.m_bInitComponents),
  410. m_fRootNode (other.m_fRootNode),
  411. m_fStaticNode (other.m_fStaticNode)
  412. {
  413. CommonConstruct();
  414. }
  415. void CNode::CommonConstruct ()
  416. {
  417. DEBUG_INCREMENT_INSTANCE_COUNTER(CNode);
  418. ASSERT (m_pMTNode != NULL);
  419. m_pMTNode->AddRef();
  420. }
  421. CNode::~CNode()
  422. {
  423. DEBUG_DECREMENT_INSTANCE_COUNTER(CNode);
  424. CDataObjectCleanup::ScUnadviseNode( this );
  425. /*
  426. * if this is a non-static root node, delete the static
  427. * parent node that was created for us in CMTNode::GetNode
  428. */
  429. if (IsRootNode() && !IsStaticNode())
  430. delete GetStaticParent();
  431. ASSERT (m_pMTNode != NULL);
  432. m_pMTNode->Release();
  433. }
  434. /*+-------------------------------------------------------------------------*
  435. * CNode::FromResultItem
  436. *
  437. * Converts a CResultItem to the CNode it references. This should only
  438. * be called for CResultItems that represent scope items.
  439. *
  440. * This function is out-of-line to eliminate coupling between node.h and
  441. * rsltitem.h.
  442. *--------------------------------------------------------------------------*/
  443. CNode* CNode::FromResultItem (CResultItem* pri)
  444. {
  445. CNode* pNode = NULL;
  446. if (pri != NULL)
  447. {
  448. /*
  449. * only call for scope items
  450. */
  451. ASSERT (pri->IsScopeItem());
  452. if (pri->IsScopeItem())
  453. pNode = CNode::FromHandle (pri->GetScopeNode());
  454. }
  455. return (pNode);
  456. }
  457. HRESULT
  458. CNode::OnExpand(bool fExpand)
  459. {
  460. HRESULT hr = S_OK;
  461. if (fExpand == FALSE)
  462. {
  463. return (WasExpandedAtLeastOnce() == TRUE) ? S_OK : S_FALSE;
  464. }
  465. if (WasExpandedAtLeastOnce() == TRUE)
  466. return S_FALSE;
  467. CMTNode* pMTNode = GetMTNode();
  468. if (pMTNode->WasExpandedAtLeastOnce() == FALSE)
  469. hr = pMTNode->Expand();
  470. return hr;
  471. }
  472. void CNode::ResetControlbars(BOOL bSelect, SELECTIONINFO* pSelInfo)
  473. {
  474. ASSERT(pSelInfo != NULL);
  475. CViewData* pVD = GetViewData();
  476. ASSERT(pVD != NULL);
  477. if (!pVD)
  478. return;
  479. // Reset controlbars
  480. CControlbarsCache* pCtrlbarsCache =
  481. dynamic_cast<CControlbarsCache*>(GetControlbarsCache());
  482. ASSERT(pCtrlbarsCache != NULL);
  483. if (pCtrlbarsCache != NULL)
  484. {
  485. if (pSelInfo->m_bScope == TRUE)
  486. pCtrlbarsCache->OnScopeSelChange(this, bSelect);
  487. else if (pSelInfo->m_bBackground == FALSE)
  488. pCtrlbarsCache->OnResultSelChange(this, pSelInfo->m_lCookie,
  489. bSelect);
  490. }
  491. }
  492. //+-------------------------------------------------------------------
  493. //
  494. // Member: CNode::ScInitializeVerbs
  495. //
  496. // Synopsis: Selection has changed so initialize the verbs for given
  497. // selection information.
  498. //
  499. // Arguments: [bSelect] - [in] Select or Deselect of an item.
  500. // [pSelInfo] - [in] SELECTIONINFO ptr.
  501. //
  502. // Returns: SC
  503. //
  504. //--------------------------------------------------------------------
  505. SC CNode::ScInitializeVerbs (bool bSelect, SELECTIONINFO* pSelInfo)
  506. {
  507. DECLARE_SC(sc, _T("CNode::ScInitializeVerbs"));
  508. sc = ScCheckPointers(pSelInfo);
  509. if (sc)
  510. return sc;
  511. CViewData *pViewData = GetViewData();
  512. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  513. if (sc)
  514. return sc;
  515. CVerbSet *pVerbSet = dynamic_cast<CVerbSet*>(pViewData->GetVerbSet());
  516. sc = ScCheckPointers(pVerbSet, E_UNEXPECTED);
  517. if (sc)
  518. return sc;
  519. sc = pVerbSet->ScInitialize(this, pSelInfo->m_bScope, bSelect,
  520. pSelInfo->m_bBackground, pSelInfo->m_lCookie);
  521. if (sc)
  522. return sc;
  523. return (sc);
  524. }
  525. HRESULT CNode::GetDispInfo(LV_ITEMW* plvi)
  526. {
  527. ASSERT(plvi != NULL);
  528. if (plvi->iSubItem == 0)
  529. {
  530. if (plvi->mask & LVIF_IMAGE)
  531. {
  532. plvi->iImage = GetResultImage();
  533. ASSERT (plvi->iImage != -1);
  534. if (plvi->iImage == -1)
  535. plvi->iImage = 0;
  536. }
  537. if (plvi->mask & LVIF_TEXT)
  538. {
  539. tstring strName = GetDisplayName();
  540. if (!strName.empty())
  541. {
  542. USES_CONVERSION;
  543. wcsncpy (plvi->pszText, T2CW (strName.data()), plvi->cchTextMax);
  544. }
  545. else
  546. plvi->pszText[0] = 0;
  547. }
  548. }
  549. else if ((plvi->mask & LVIF_TEXT) && (plvi->cchTextMax > 0))
  550. {
  551. plvi->pszText[0] = 0;
  552. }
  553. return S_OK;
  554. }
  555. //+-------------------------------------------------------------------
  556. //
  557. // Member: ScGetDataObject
  558. //
  559. // Synopsis: Given scope/result and cookie (lParam, if it is result item),
  560. // get the dataobject of the item.
  561. //
  562. // Arguments:
  563. // [bScopePane] - [in] Scope or Result.
  564. // [lResultItemCookie] - [in] If Result pane is selected the item param.
  565. // [bScopeItem] - [out] Is the dataobject returned for scope or result item.
  566. // The scope item can be in result pane.
  567. // [ppDataObject] - [out] The data-object (return val)
  568. // [ppCComponent] - [out] NULL def parameter. The CComponent of the item. In case
  569. // of multiselection, the items may belong to more than one
  570. // component so a NULL is returned.
  571. //
  572. // Returns: SC
  573. //
  574. //--------------------------------------------------------------------
  575. SC CNode::ScGetDataObject(bool bScopePane, LPARAM lResultItemCookie, bool& bScopeItem,
  576. LPDATAOBJECT* ppDataObject, CComponent **ppCComponent /*= NULL*/)
  577. {
  578. DECLARE_SC(sc, _T("CNode::ScGetDataObject"));
  579. IDataObjectPtr spDataObject;
  580. CComponent *pCC = NULL;
  581. if (ppDataObject == NULL)
  582. return (sc = E_POINTER);
  583. *ppDataObject = NULL; // init
  584. if (ppCComponent)
  585. *ppCComponent = NULL;
  586. bScopeItem = bScopePane;
  587. // In MMC1.0 when result pane background is selected, for any
  588. // toolbar operation we pass the dataobject of scope selected item.
  589. // The following code is added for this compatibility.
  590. if (lResultItemCookie == LVDATA_BACKGROUND) // =>Result background has focus
  591. {
  592. bScopeItem = TRUE;
  593. }
  594. if (bScopeItem) // => Scope pane has focus
  595. {
  596. CMTNode* pMTNode = GetMTNode();
  597. if (NULL == pMTNode)
  598. return (sc = E_UNEXPECTED);
  599. sc = pMTNode->QueryDataObject(CCT_SCOPE, &spDataObject);
  600. if (sc)
  601. return sc;
  602. pCC = GetPrimaryComponent();
  603. }
  604. else if (lResultItemCookie == LVDATA_CUSTOMOCX) // => Custom OCX has focus
  605. {
  606. *ppDataObject = DOBJ_CUSTOMOCX;
  607. pCC = GetPrimaryComponent();
  608. }
  609. else if (lResultItemCookie == LVDATA_CUSTOMWEB) // => Web has focus
  610. {
  611. *ppDataObject = DOBJ_CUSTOMWEB;
  612. pCC = GetPrimaryComponent();
  613. }
  614. else if (lResultItemCookie == LVDATA_MULTISELECT) // => multi selection
  615. {
  616. // Do not calculate CComponent for multisel dataobject as there are multiple
  617. // items and they can be from different snapins (so different components).
  618. CViewData* pVD = GetViewData();
  619. if (NULL == pVD)
  620. return (sc = E_UNEXPECTED);
  621. CMultiSelection* pMS = pVD->GetMultiSelection();
  622. if (NULL == pMS)
  623. return (sc = E_UNEXPECTED);
  624. sc = pMS->GetMultiSelDataObject(ppDataObject);
  625. if (sc)
  626. return sc;
  627. }
  628. else // result item has focus
  629. {
  630. CViewData* pVD = GetViewData();
  631. if (NULL == pVD)
  632. return (sc = E_UNEXPECTED);
  633. if (! pVD->IsVirtualList())
  634. {
  635. CResultItem* pri = CResultItem::FromHandle (lResultItemCookie);
  636. if (pri != NULL)
  637. {
  638. bScopeItem = pri->IsScopeItem();
  639. lResultItemCookie = pri->GetSnapinData();
  640. if (! bScopeItem)
  641. pCC = GetComponent(pri->GetOwnerID());
  642. }
  643. }
  644. else
  645. pCC = GetPrimaryComponent();
  646. if (bScopeItem)
  647. {
  648. CNode* pNode = CNode::FromHandle((HNODE) lResultItemCookie);
  649. CMTNode* pMTNode = pNode ? pNode->GetMTNode() : NULL;
  650. if (NULL == pMTNode)
  651. return (sc = E_UNEXPECTED);
  652. sc = pMTNode->QueryDataObject(CCT_SCOPE, &spDataObject);
  653. if (sc)
  654. return sc;
  655. pCC = pNode->GetPrimaryComponent();
  656. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  657. if (sc)
  658. return sc;
  659. }
  660. else
  661. {
  662. if (NULL == pCC)
  663. return (sc = E_UNEXPECTED);
  664. sc = pCC->QueryDataObject(lResultItemCookie, CCT_RESULT, &spDataObject);
  665. if (sc)
  666. return sc;
  667. }
  668. }
  669. // if required, get the component of this node
  670. if (ppCComponent)
  671. {
  672. *ppCComponent = pCC;
  673. sc = ScCheckPointers( *ppCComponent, E_UNEXPECTED );
  674. if (sc)
  675. return sc;
  676. }
  677. if (SUCCEEDED(sc.ToHr()) && *ppDataObject == NULL)
  678. *ppDataObject = spDataObject.Detach();
  679. return sc;
  680. }
  681. //+-------------------------------------------------------------------
  682. //
  683. // Member: CNode::ScGetDropTargetDataObject
  684. //
  685. // Synopsis: Given the context get the data object that allows the
  686. // to be drop target (allows paste).
  687. //
  688. // In MMC1.2 the drop target is always scope node. In MMC2.0
  689. // it can be any non-virtual (??) result item. If the snapin
  690. // has RVTI_LIST_OPTIONS_ALLOWPASTE set, then if the item selected
  691. // is in result pane then data object corresponds to result item
  692. // else it is scope item.
  693. //
  694. // Arguments:
  695. // [bScopePane] - Scope or Result.
  696. // [lResultItemCookie] - If Result pane is selected the item param.
  697. // [ppDataObject] - The data-object (return val)
  698. //
  699. // Returns: SC
  700. //
  701. //--------------------------------------------------------------------
  702. SC CNode::ScGetDropTargetDataObject(bool bScopePane, LPARAM lResultItemCookie, LPDATAOBJECT *ppDataObject)
  703. {
  704. DECLARE_SC(sc, _T("CNode::ScGetDropTargetDataObject"));
  705. sc = ScCheckPointers(ppDataObject);
  706. if (sc)
  707. return sc;
  708. *ppDataObject = NULL;
  709. CViewData *pViewData = GetViewData();
  710. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  711. if (sc)
  712. return sc;
  713. if (pViewData->GetListOptions() & RVTI_LIST_OPTIONS_ALLOWPASTE)
  714. {
  715. bool bScopeItem;
  716. // MMC2.0 use the given context.
  717. sc = ScGetDataObject(bScopePane, lResultItemCookie, bScopeItem, ppDataObject);
  718. if (sc)
  719. return sc;
  720. }
  721. else
  722. {
  723. // MMC1.2 Always scope node.
  724. sc = QueryDataObject(CCT_SCOPE, ppDataObject);
  725. if (sc)
  726. return sc;
  727. }
  728. return (sc);
  729. }
  730. /*+-------------------------------------------------------------------------*
  731. *
  732. * CNode::ScGetPropertyFromINodeProperties
  733. *
  734. * PURPOSE:
  735. *
  736. * PARAMETERS:
  737. * BOOL bForScopeItem :
  738. * LPARAM resultItemParam :
  739. * BSTR bstrPropertyName :
  740. * PBSTR pbstrPropertyValue :
  741. *
  742. * RETURNS:
  743. * SC
  744. *
  745. *+-------------------------------------------------------------------------*/
  746. SC
  747. CNode::ScGetPropertyFromINodeProperties(LPDATAOBJECT pDataObject, BOOL bForScopeItem, LPARAM resultItemParam, BSTR bstrPropertyName, PBSTR pbstrPropertyValue)
  748. {
  749. //DECLARE_SC(sc, TEXT("CNode::ScGetPropertyFromINodeProperties"));
  750. SC sc; // do not use DECLARE_SC here - want to silently ignore errors
  751. sc = ScCheckPointers(pDataObject, bstrPropertyName, pbstrPropertyValue);
  752. if(sc)
  753. return sc;
  754. if(bForScopeItem)
  755. {
  756. // get the MTNode
  757. CMTNode * pMTNode = GetMTNode();
  758. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  759. if(sc)
  760. return sc;
  761. // ask MTNode to get it
  762. sc = pMTNode->ScGetPropertyFromINodeProperties(pDataObject, bstrPropertyName, pbstrPropertyValue);
  763. if(sc)
  764. return sc;
  765. // done!
  766. return sc;
  767. }
  768. // for result item.
  769. CComponent *pComponent = GetPrimaryComponent();
  770. sc = ScCheckPointers(pComponent);
  771. if(sc)
  772. {
  773. SC scRet = sc; // returns but does not trace the error
  774. sc.Clear();
  775. return scRet;
  776. }
  777. // get the IComponent and QI for INodeProperties
  778. INodePropertiesPtr spNodeProperties = pComponent->GetIComponent();
  779. // at this point we should have a valid interface if it is supported
  780. sc = ScCheckPointers(spNodeProperties, E_NOINTERFACE);
  781. if(sc)
  782. return sc;
  783. sc = spNodeProperties->GetProperty(pDataObject, bstrPropertyName, pbstrPropertyValue);
  784. return sc;
  785. }
  786. /*+-------------------------------------------------------------------------*
  787. *
  788. * CNode::ScExecuteShellCommand
  789. *
  790. * PURPOSE: Executes a shell command with the specified parameters in the
  791. * specified directory with the correct window size
  792. *
  793. * PARAMETERS:
  794. * BSTR Command :
  795. * BSTR Directory :
  796. * BSTR Parameters :
  797. * BSTR WindowState :
  798. *
  799. * RETURNS:
  800. * SC
  801. *
  802. *+-------------------------------------------------------------------------*/
  803. SC
  804. CNode::ScExecuteShellCommand(BSTR Command, BSTR Directory, BSTR Parameters, BSTR WindowState)
  805. {
  806. DECLARE_SC(sc, TEXT("CNode::ScExecuteShellCommand"));
  807. sc = ScCheckPointers(Command, Directory, Parameters, WindowState);
  808. if(sc)
  809. return sc;
  810. USES_CONVERSION;
  811. CStr strParameters = W2T(Parameters);
  812. CStr strWindowState= W2T(WindowState);
  813. if(strWindowState.GetLength()==0)
  814. strWindowState= XML_ENUM_WINDOW_STATE_RESTORED; // normal
  815. SHELLEXECUTEINFO sei;
  816. ZeroMemory (&sei, sizeof(sei));
  817. sei.cbSize = sizeof(sei);
  818. sei.lpFile = W2T(Command);
  819. sei.lpParameters = strParameters;
  820. sei.lpDirectory = W2T(Directory);
  821. sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_DOENVSUBST;
  822. sei.nShow = (strWindowState == XML_ENUM_WINDOW_STATE_MAXIMIZED) ? SW_SHOWMAXIMIZED :
  823. (strWindowState == XML_ENUM_WINDOW_STATE_MINIMIZED) ? SW_SHOWMINIMIZED :
  824. SW_SHOWNORMAL ;
  825. if (ShellExecuteEx(&sei))
  826. CloseHandle (sei.hProcess);
  827. else
  828. sc = ScFromWin32((GetLastError ()));
  829. return sc;
  830. }
  831. //############################################################################
  832. //############################################################################
  833. //
  834. // Implementation of class COCX
  835. //
  836. //############################################################################
  837. //############################################################################
  838. DEBUG_DECLARE_INSTANCE_COUNTER(COCX);
  839. //############################################################################
  840. //############################################################################
  841. //
  842. // Implementation of class COCXNode
  843. //
  844. //############################################################################
  845. //############################################################################
  846. DEBUG_DECLARE_INSTANCE_COUNTER(COCXNode);
  847. HRESULT CNode::InitComponents()
  848. {
  849. DECLARE_SC(sc, TEXT("CNode::InitComponents"));
  850. if (m_bInitComponents == FALSE)
  851. return S_OK;
  852. HRESULT hr = S_OK;
  853. // Initialize the component.
  854. CMTNode * pMTNode = GetMTNode();
  855. if (pMTNode == NULL)
  856. return (E_UNEXPECTED);
  857. // Ensure the master node is initialized.
  858. if (!pMTNode->IsInitialized())
  859. hr = pMTNode->Init();
  860. if (FAILED(hr))
  861. return hr;
  862. CMTSnapInNode* pMTSnapInNode = pMTNode->GetStaticParent();
  863. if (pMTSnapInNode == NULL)
  864. return (E_UNEXPECTED);
  865. HMTNODE hMTNode = CMTNode::ToHandle(pMTSnapInNode);
  866. HNODE hNode = CNode::ToHandle(GetStaticParent());
  867. CSnapIn* pSnapIn = pMTNode->GetPrimarySnapIn();
  868. if (pSnapIn == NULL)
  869. return (E_UNEXPECTED);
  870. CComponentData* pCCD = pMTSnapInNode->GetComponentData(pSnapIn->GetSnapInCLSID());
  871. if (pCCD == NULL)
  872. return E_FAIL;
  873. if (m_pPrimaryComponent == NULL)
  874. m_pPrimaryComponent = pMTSnapInNode->GetComponent(GetViewID(),
  875. pCCD->GetComponentID(), pSnapIn);
  876. if(m_pPrimaryComponent == NULL)
  877. return E_UNEXPECTED;
  878. ASSERT(m_pPrimaryComponent != NULL);
  879. //
  880. // Init PRIMARY Component.
  881. //
  882. if (!m_pPrimaryComponent->IsInitialized())
  883. {
  884. ASSERT(pCCD->GetComponentID() == m_pPrimaryComponent->GetComponentID());
  885. hr = m_pPrimaryComponent->Init(pCCD->GetIComponentData(), hMTNode, hNode,
  886. pCCD->GetComponentID(), GetViewID());
  887. // Abort if PRIMARY Component fails to init.
  888. if (FAILED(hr))
  889. return hr;
  890. }
  891. m_bInitComponents = FALSE;
  892. //
  893. // Now initalize the extension components. (create them if necessary)
  894. //
  895. // Get the node-type of this node
  896. GUID guidNodeType;
  897. //hr = pCCD->GetNodeType(pMTNode->GetUserParam(), &guidNodeType);
  898. hr = pMTNode->GetNodeType(&guidNodeType);
  899. CHECK_HRESULT(hr);
  900. if (FAILED(hr))
  901. return hr;
  902. LPCLSID pDynExtCLSID;
  903. int cDynExt = pMTNode->GetDynExtCLSID(&pDynExtCLSID);
  904. CExtensionsIterator it;
  905. // TODO: try to use the easier form of it.ScInitialize()
  906. sc = it.ScInitialize(pSnapIn, guidNodeType, g_szNameSpace, pDynExtCLSID, cDynExt);
  907. if(sc)
  908. return S_FALSE;
  909. BOOL fProblem = FALSE;
  910. for (; it.IsEnd() == FALSE; it.Advance())
  911. {
  912. pCCD = pMTSnapInNode->GetComponentData(it.GetCLSID());
  913. if (pCCD == NULL)
  914. continue;
  915. CComponent* pCC = pMTSnapInNode->GetComponent(GetViewID(),
  916. pCCD->GetComponentID(), pCCD->GetSnapIn());
  917. if (pCC->IsInitialized() == TRUE)
  918. continue;
  919. hr = pCC->Init(pCCD->GetIComponentData(), hMTNode, hNode,
  920. pCCD->GetComponentID(), GetViewID());
  921. CHECK_HRESULT(hr);
  922. if (FAILED(hr))
  923. fProblem = TRUE; // Continue even on error.
  924. }
  925. if (fProblem == TRUE)
  926. {
  927. // TODO: Put up an error message.
  928. hr = S_FALSE;
  929. }
  930. return hr;
  931. }
  932. /*+-------------------------------------------------------------------------*
  933. *
  934. * CNode::OnInitOCX
  935. *
  936. * PURPOSE: Sends the MMCN_INITOCX notification when an OCX is created.
  937. *
  938. * PARAMETERS:
  939. * IUnknown* pUnk :
  940. *
  941. * RETURNS:
  942. * HRESULT
  943. *
  944. *+-------------------------------------------------------------------------*/
  945. HRESULT
  946. CNode::OnInitOCX(IUnknown* pUnk)
  947. {
  948. DECLARE_SC(sc, TEXT("CNode::OnInitOCX"));
  949. IDataObjectPtr spdtobj;
  950. sc = QueryDataObject(CCT_SCOPE, &spdtobj);
  951. if(sc)
  952. return sc.ToHr();
  953. CComponent* pCC = GetPrimaryComponent();
  954. sc = ScCheckPointers(pCC);
  955. if(sc)
  956. return sc.ToHr();
  957. sc = pCC->Notify(spdtobj, MMCN_INITOCX, 0, reinterpret_cast<LPARAM>(pUnk));
  958. sc.Clear(); // must ignore errors here - Disk management returns E_UNEXPECTED.!
  959. return sc.ToHr();
  960. }
  961. HRESULT CNode::OnCacheHint(int nStartIndex, int nEndIndex)
  962. {
  963. CComponent* pCC = GetPrimaryComponent();
  964. ASSERT(pCC != NULL);
  965. if (pCC == NULL)
  966. return E_FAIL;
  967. IResultOwnerDataPtr spIResultOwnerData = pCC->GetIComponent();
  968. if (spIResultOwnerData == NULL)
  969. return S_FALSE;
  970. return spIResultOwnerData->CacheHint(nStartIndex, nEndIndex);
  971. }
  972. /***************************************************************************\
  973. *
  974. * METHOD: CNode::ScInitializeViewExtension
  975. *
  976. * PURPOSE: Sets callback representing view extension
  977. *
  978. * PARAMETERS:
  979. * const CLSID& clsid - [in] view extension CLSID
  980. * CViewData *pViewData - [in] view data
  981. *
  982. * RETURNS:
  983. * SC - result code
  984. *
  985. \***************************************************************************/
  986. SC CNode::ScInitializeViewExtension(const CLSID& clsid, CViewData *pViewData)
  987. {
  988. DECLARE_SC(sc, TEXT("CNode::ScInitializeViewExtension"));
  989. sc = ScCheckPointers(pViewData);
  990. if (sc)
  991. return sc;
  992. /*
  993. * Get the CConsoleTaskpad that goes with it this view extension.
  994. * If this is an ordinary (i.e. not taskpad) view extension,
  995. * ScGetViewExtensionTaskpad will set pConsoleTaskpad to NULL.
  996. */
  997. CConsoleTaskpad* pConsoleTaskpad = NULL;
  998. sc = CConsoleTaskpadViewExtension::ScGetViewExtensionTaskpad (this, clsid, pConsoleTaskpad);
  999. if (sc)
  1000. return (sc);
  1001. typedef CComObject<CConsoleTaskCallbackImpl> t_ViewExtensionCallbackImpl;
  1002. t_ViewExtensionCallbackImpl* pViewExtensionCallbackImpl = NULL;
  1003. sc = t_ViewExtensionCallbackImpl::CreateInstance(&pViewExtensionCallbackImpl);
  1004. if (sc)
  1005. return sc;
  1006. // recheck pointer
  1007. sc = ScCheckPointers(pViewExtensionCallbackImpl, E_UNEXPECTED);
  1008. if (sc)
  1009. return sc;
  1010. pViewData->m_spTaskCallback = pViewExtensionCallbackImpl; // this addrefs/releases the object.
  1011. /*
  1012. * If this is a taskpad, initialize the view extension callback as
  1013. * a taskpad view extension. Otherwise initialize it as an ordinary
  1014. * view extension.
  1015. */
  1016. if (pConsoleTaskpad != NULL)
  1017. {
  1018. sc = pViewExtensionCallbackImpl->ScInitialize (pConsoleTaskpad,
  1019. CScopeTree::GetScopeTree(),
  1020. this);
  1021. }
  1022. else
  1023. sc = pViewExtensionCallbackImpl->ScInitialize(clsid);
  1024. return sc;
  1025. }
  1026. /*+-------------------------------------------------------------------------*
  1027. *
  1028. * CNode::ScSetViewExtension
  1029. *
  1030. * PURPOSE: Forces a display of the given view extension.
  1031. *
  1032. * PARAMETERS:
  1033. * GUID * pGuidViewId : [IN]: The view extension to display.
  1034. * bool bUseDefaultTaskpad : [IN}
  1035. * bool bSetViewSettingDirty : [IN] (See below notes)
  1036. *
  1037. * Note:
  1038. * The view-extension-ID comes from
  1039. *
  1040. * 1. Viewsetting if one exists.
  1041. * 2. Given by CONUI when user changes tab for different taskpad.
  1042. * 3. There are cases in which a new view-extension installed (after the console
  1043. * file was created) that will be default. (This will be calculated in this method).
  1044. *
  1045. * In cases 1 & 3 viewsetting should not be made dirty.
  1046. *
  1047. * RETURNS:
  1048. * SC
  1049. *
  1050. *+-------------------------------------------------------------------------*/
  1051. SC
  1052. CNode::ScSetViewExtension(GUID *pGuidViewId, bool bUseDefaultTaskpad, bool bSetViewSettingDirty)
  1053. {
  1054. DECLARE_SC(sc, TEXT("CNode::ScSetViewExtension"));
  1055. CViewData * pViewData = GetViewData();
  1056. sc = ScCheckPointers(pGuidViewId, pViewData);
  1057. if(sc)
  1058. return sc;
  1059. // collect the view extensions
  1060. CViewExtCollection vecExtensions;
  1061. CViewExtInsertIterator itExtensions(vecExtensions, vecExtensions.begin());
  1062. sc = ScGetViewExtensions(itExtensions);
  1063. if (sc)
  1064. sc.Trace_();
  1065. if ( bUseDefaultTaskpad )
  1066. {
  1067. // setup proper taskpad (tab to be selected)
  1068. CViewExtCollection::iterator it = vecExtensions.begin();
  1069. if (it != vecExtensions.end())
  1070. *pGuidViewId = it->viewID; // first one if such exist
  1071. else
  1072. *pGuidViewId = GUID_NULL; // default
  1073. }
  1074. else // locate the extension we need to select
  1075. {
  1076. // see if the extension really exist
  1077. CViewExtCollection::iterator it = vecExtensions.begin();
  1078. bool bDefaultIsReplaced = false;
  1079. while (it != vecExtensions.end() && !IsEqualGUID(*pGuidViewId, it->viewID) )
  1080. {
  1081. bDefaultIsReplaced = bDefaultIsReplaced || it->bReplacesDefaultView;
  1082. ++it;
  1083. }
  1084. // found it?
  1085. bool bFound = (it != vecExtensions.end());
  1086. // one more chance - we were looking for default and one will be added!
  1087. bFound = bFound || ( IsEqualGUID( *pGuidViewId, GUID_NULL ) && !bDefaultIsReplaced );
  1088. if ( !bFound )
  1089. {
  1090. sc = E_FAIL;
  1091. }
  1092. }
  1093. if (sc) // extension missing! need to find the substitute
  1094. {
  1095. sc.Clear(); // ignore error
  1096. // default to first extension or NORMAL view here
  1097. CViewExtCollection::iterator it = vecExtensions.begin();
  1098. if (it != vecExtensions.end())
  1099. *pGuidViewId = it->viewID; // first available
  1100. else
  1101. *pGuidViewId = GUID_NULL; // "normal" if it's the only choice
  1102. }
  1103. // set the view extension if one really exist
  1104. if (*pGuidViewId != GUID_NULL)
  1105. {
  1106. sc = ScInitializeViewExtension(*pGuidViewId, GetViewData());
  1107. if (sc)
  1108. sc.TraceAndClear(); // ignore and proceed
  1109. }
  1110. else
  1111. {
  1112. pViewData->m_spTaskCallback = NULL;
  1113. }
  1114. sc = ScSetTaskpadID(*pGuidViewId, bSetViewSettingDirty);
  1115. if (sc)
  1116. return sc;
  1117. return sc;
  1118. }
  1119. //+-------------------------------------------------------------------
  1120. //
  1121. // Member: ScGetResultPane
  1122. //
  1123. // Synopsis: Get the result pane data from snapin or persisted data.
  1124. //
  1125. // Arguments: [strResultPane] - Result pane name (If it is OCX/WEB)
  1126. // [pViewOptions] - View options.
  1127. // [pGuidTaskpadID] - If there is a task-pad the ID.
  1128. //
  1129. // Returns: SC
  1130. //
  1131. // History: 04-29-1999 AnandhaG Created
  1132. //
  1133. //--------------------------------------------------------------------
  1134. SC
  1135. CNode::ScGetResultPane(CResultViewType &rvt, GUID *pGuidTaskpadID)
  1136. {
  1137. DECLARE_SC(sc, TEXT("CNode::ScGetResultPane"));
  1138. sc = ScCheckPointers(pGuidTaskpadID);
  1139. if (sc)
  1140. return sc;
  1141. CComponent *pComponent = GetPrimaryComponent();
  1142. CViewData *pViewData = GetViewData();
  1143. sc = ScCheckPointers(pComponent, pViewData, E_UNEXPECTED);
  1144. if(sc)
  1145. return sc;
  1146. IComponent* pIComponent = pComponent->GetIComponent();
  1147. sc = ScCheckPointers(pIComponent, E_FAIL);
  1148. if (sc)
  1149. return sc;
  1150. // 1. Setup any persisted/default console taskpads or view extensions.
  1151. sc = ScSetupTaskpad(pGuidTaskpadID);
  1152. if (sc)
  1153. return sc;
  1154. // 2. Get the persisted CResultViewType information.
  1155. sc = ScGetResultViewType(rvt);
  1156. if (sc)
  1157. return sc;
  1158. bool bResultViewDataIsPersisted = (sc == S_OK);
  1159. bool bSnapinChangingView = pViewData->IsSnapinChangingView();
  1160. CResultViewType rvtOriginal;
  1161. CStr strResultPane = _T(""); // init
  1162. // 3. If there is persisted result-view-type data then ask the snapin if it
  1163. // wants to restore the result-view with this data. If snapin is changing
  1164. // its view (by re-selection of node) then dont ask this question.
  1165. if (!bSnapinChangingView && bResultViewDataIsPersisted )
  1166. {
  1167. // 3.a) Ask snapin if it wants to restore the result-view with persisted data.
  1168. sc = ScRestoreResultView(rvt);
  1169. if (sc)
  1170. return sc;
  1171. if (S_OK == sc.ToHr()) // snapin accepted the resultviewtype settings so return.
  1172. return sc;
  1173. // 3.b) Snapin refused the persisted CResultViewType data so...
  1174. // cache the data to see if we need to modify the settings
  1175. rvtOriginal = rvt;
  1176. // Throw away the data as it is not accepted by snapin.
  1177. sc = rvt.ScReset();
  1178. if (sc)
  1179. return sc;
  1180. }
  1181. // 4. Ask the snapin for result-view-type data.
  1182. IComponent2Ptr spIComponent2 = pIComponent;
  1183. if(spIComponent2 != NULL)
  1184. {
  1185. // should be able to move all this to a separate function.
  1186. RESULT_VIEW_TYPE_INFO rvti;
  1187. ZeroMemory(&rvti, sizeof(rvti));
  1188. // the snapin supports IComponent2. Use it to get the result view type.
  1189. sc = spIComponent2->GetResultViewType2(GetUserParam(), &rvti);
  1190. if(sc)
  1191. return sc;
  1192. // at this point, we have a valid RESULT_VIEW_TYPE_INFO structure. Initialize the contents into rvt, which zeros out the structure
  1193. // and releases all the allocated strings
  1194. sc = rvt.ScInitialize(rvti);
  1195. if(sc)
  1196. return sc;
  1197. }
  1198. else
  1199. {
  1200. // the snapin does not support IComponent2. Use IComponent to
  1201. // get the result view type from the snapin.
  1202. LPOLESTR pszView = NULL;
  1203. long lViewOptions = 0;
  1204. sc = pIComponent->GetResultViewType(GetUserParam(), &pszView, &lViewOptions);
  1205. if(sc)
  1206. return sc;
  1207. sc = rvt.ScInitialize(pszView, lViewOptions); // this also calls CoTaskMemFree on pszView
  1208. if(sc)
  1209. return sc;
  1210. }
  1211. /*
  1212. * 5. Persist ResultViewType information only if
  1213. * a. Snapin is changing the view OR
  1214. * b. Snapin rejected the persisted view setting (we already
  1215. * made sure it is not changing the view above) and new view setting
  1216. * given is different from original one.
  1217. */
  1218. if ( bSnapinChangingView ||
  1219. (bResultViewDataIsPersisted && (rvtOriginal != rvt)) )
  1220. {
  1221. sc = ScSetResultViewType(rvt);
  1222. if (sc)
  1223. return sc;
  1224. }
  1225. return sc;
  1226. }
  1227. //+-------------------------------------------------------------------
  1228. //
  1229. // Member: ScRestoreResultView
  1230. //
  1231. // Synopsis: Restore the result pane from given persisted data.
  1232. //
  1233. // Arguments: [rvt] - CResultViewType data used to restore result pane.
  1234. //
  1235. // Returns: SC, S_OK if successfully restored.
  1236. // S_FALSE if snapin refused to restore.
  1237. //
  1238. // History: 04-29-1999 AnandhaG Created
  1239. //
  1240. //--------------------------------------------------------------------
  1241. SC CNode::ScRestoreResultView(const CResultViewType& rvt)
  1242. {
  1243. DECLARE_SC(sc, _T("CNode::ScRestoreResultView"));
  1244. CComponent* pComponent = GetPrimaryComponent();
  1245. sc = ScCheckPointers(pComponent, E_UNEXPECTED);
  1246. if (sc)
  1247. return sc;
  1248. IComponent2Ptr spIComponent2 = pComponent->GetIComponent();
  1249. if( (spIComponent2 != NULL) && (!rvt.IsMMC12LegacyData()))
  1250. {
  1251. RESULT_VIEW_TYPE_INFO rvti;
  1252. ZeroMemory(&rvti, sizeof(rvti));
  1253. sc = rvt.ScGetResultViewTypeInfo (rvti);
  1254. if (sc)
  1255. return sc;
  1256. // the snapin supports IComponent2. Use it to get the result view type.
  1257. sc = spIComponent2->RestoreResultView(GetUserParam(), &rvti);
  1258. if(sc)
  1259. {
  1260. // If snapin returns error, trace it and translate it to S_FALSE (snapin refused to restore).
  1261. TraceSnapinError(TEXT("Snapin returned error from IComponent2::RestoreResultView"), sc);
  1262. sc = S_FALSE;
  1263. return sc;
  1264. }
  1265. }
  1266. else
  1267. {
  1268. // the snapin does not support IComponent2. Use IComponent to
  1269. // to restore the result view.
  1270. LPCOLESTR pszView = NULL;
  1271. long lViewOptions = 0;
  1272. sc = rvt.ScGetOldTypeViewOptions(&lViewOptions);
  1273. if (sc)
  1274. return sc;
  1275. IDataObjectPtr spdtobj;
  1276. sc = QueryDataObject(CCT_SCOPE, &spdtobj);
  1277. if (sc)
  1278. return sc;
  1279. // Notify MMC of persisted view being restored.
  1280. MMC_RESTORE_VIEW mrv;
  1281. ::ZeroMemory(&mrv, sizeof(mrv));
  1282. mrv.cookie = GetUserParam();
  1283. mrv.dwSize = sizeof(mrv);
  1284. mrv.lViewOptions = lViewOptions;
  1285. if (rvt.HasOCX())
  1286. {
  1287. pszView = rvt.GetOCX();
  1288. }
  1289. else if (rvt.HasWebBrowser())
  1290. {
  1291. pszView = rvt.GetURL();
  1292. }
  1293. if (pszView)
  1294. {
  1295. mrv.pViewType = (LPOLESTR)CoTaskMemAlloc( (wcslen(pszView) + 1) * sizeof(OLECHAR) );
  1296. sc = ScCheckPointers(mrv.pViewType, E_OUTOFMEMORY);
  1297. if (sc)
  1298. return sc;
  1299. wcscpy(mrv.pViewType, pszView);
  1300. pszView = NULL; // Dont want to abuse it later.
  1301. }
  1302. // If the snapin handles this notification we use the persisted
  1303. // data else call GetResultViewType of the snapin.
  1304. BOOL bHandledRestoreView = FALSE;
  1305. pComponent->Notify(spdtobj, MMCN_RESTORE_VIEW, (LPARAM)&mrv, (LPARAM)&bHandledRestoreView);
  1306. CoTaskMemFree(mrv.pViewType);
  1307. sc = (bHandledRestoreView) ? S_OK : S_FALSE;
  1308. }
  1309. return sc;
  1310. }
  1311. //+-------------------------------------------------------------------
  1312. //
  1313. // Member: ScRestoreViewMode
  1314. //
  1315. // Synopsis: If the view mode is persisted restore it.
  1316. //
  1317. // Arguments: None.
  1318. //
  1319. // Returns: SC
  1320. //
  1321. //--------------------------------------------------------------------
  1322. SC CNode::ScRestoreViewMode()
  1323. {
  1324. DECLARE_SC(sc, _T("CNode::ScRestoreViewMode"));
  1325. ULONG ulViewMode = 0;
  1326. sc = ScGetViewMode(ulViewMode);
  1327. if (sc != S_OK) // data not found or some error.
  1328. return sc;
  1329. CViewData *pViewData = GetViewData();
  1330. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  1331. if (sc)
  1332. return sc;
  1333. // tell conui to change the list mode.
  1334. CConsoleView* pConsoleView = pViewData->GetConsoleView();
  1335. sc = ScCheckPointers(pConsoleView, E_UNEXPECTED);
  1336. if (sc)
  1337. return sc;
  1338. sc = pConsoleView->ScChangeViewMode (ulViewMode);
  1339. if (sc)
  1340. return sc;
  1341. return sc;
  1342. }
  1343. /*+-------------------------------------------------------------------------*
  1344. *
  1345. * CNode::ScSetupTaskpad
  1346. *
  1347. * PURPOSE:
  1348. *
  1349. * PARAMETERS:
  1350. * GUID * pTaskpadID : [OUT]: The guid of the taskpad, else GUID_NULL
  1351. *
  1352. * RETURNS:
  1353. * SC
  1354. *
  1355. *+-------------------------------------------------------------------------*/
  1356. SC
  1357. CNode::ScSetupTaskpad(GUID *pGuidTaskpadID)
  1358. {
  1359. DECLARE_SC(sc, _T("CNode::SetupTaskpad"));
  1360. sc = ScCheckPointers(pGuidTaskpadID);
  1361. if (sc)
  1362. return sc.ToHr();
  1363. *pGuidTaskpadID = GUID_NULL;
  1364. // Get the persisted taskpad id if there is one.
  1365. sc = ScGetTaskpadID(*pGuidTaskpadID);
  1366. if (sc)
  1367. return sc;
  1368. // restore the taskpad if we've got a ViewSettings object.
  1369. // do not use default tab even in case view seting does not have a valid guid
  1370. // it only means the "Default" tab needs to be selected
  1371. // see bug #97001 - MMC does not persist select CTP when user returns to a node
  1372. bool bUseDefaultTaskpad = ( sc == S_FALSE );
  1373. // See ScSetViewExtension for parameter meaning.
  1374. sc = ScSetViewExtension(pGuidTaskpadID, bUseDefaultTaskpad, /*bSetViewSettingDirty*/ false);
  1375. return sc.ToHr();
  1376. }
  1377. /*+-------------------------------------------------------------------------*
  1378. *
  1379. * CNode::ShowStandardListView
  1380. *
  1381. * PURPOSE:
  1382. *
  1383. * RETURNS:
  1384. * HRESULT
  1385. *
  1386. *+-------------------------------------------------------------------------*/
  1387. HRESULT CNode::ShowStandardListView()
  1388. {
  1389. CComponent* pCC = GetPrimaryComponent();
  1390. ASSERT(pCC != NULL);
  1391. if (pCC == NULL)
  1392. return E_FAIL;
  1393. IDataObjectPtr spDataObject = NULL;
  1394. HRESULT hr = QueryDataObject(CCT_SCOPE, &spDataObject);
  1395. ASSERT(SUCCEEDED(hr));
  1396. if (FAILED(hr))
  1397. return hr;
  1398. IExtendContextMenuPtr spIExtendContextMenu = pCC->GetIComponent();
  1399. if(!spIExtendContextMenu.GetInterfacePtr())
  1400. return S_FALSE;
  1401. hr = spIExtendContextMenu->Command(MMCC_STANDARD_VIEW_SELECT, spDataObject);
  1402. return hr;
  1403. }
  1404. HRESULT
  1405. CNode::OnListPad(LONG_PTR arg, LPARAM param)
  1406. {
  1407. HRESULT hr = S_OK;
  1408. IDataObjectPtr spdtobj;
  1409. hr = QueryDataObject(CCT_SCOPE, &spdtobj);
  1410. ASSERT(SUCCEEDED(hr));
  1411. if (SUCCEEDED(hr))
  1412. {
  1413. CComponent* pCC = GetPrimaryComponent();
  1414. ASSERT(pCC != NULL);
  1415. hr = pCC->Notify(spdtobj, MMCN_LISTPAD, arg, param);
  1416. CHECK_HRESULT(hr);
  1417. }
  1418. return hr;
  1419. }
  1420. HRESULT
  1421. CNode::OnGetPrimaryTask(IExtendTaskPad **ppExtendTaskPad)
  1422. {
  1423. HRESULT hr = S_OK;
  1424. IExtendTaskPadPtr spExtendTaskPad = GetPrimaryComponent()->GetIComponent();
  1425. if (spExtendTaskPad == NULL)
  1426. return E_NOINTERFACE;
  1427. *ppExtendTaskPad = spExtendTaskPad.Detach();
  1428. return hr;
  1429. }
  1430. IFramePrivate *
  1431. CNode::GetIFramePrivate()
  1432. {
  1433. CComponent* pCC = GetPrimaryComponent();
  1434. if (pCC == NULL)
  1435. return (NULL);
  1436. IFramePrivate* pFramePrivate = pCC->GetIFramePrivate();
  1437. ASSERT (pFramePrivate != NULL);
  1438. return (pFramePrivate);
  1439. }
  1440. HRESULT
  1441. CNode::GetTaskEnumerator(LPOLESTR pszTaskGroup, IEnumTASK** ppEnumTask)
  1442. {
  1443. DECLARE_SC(sc, TEXT("CNode::GetTaskEnumerator"));
  1444. ASSERT(pszTaskGroup != NULL);
  1445. ASSERT(ppEnumTask != NULL);
  1446. if (!pszTaskGroup|| !ppEnumTask)
  1447. return E_INVALIDARG;
  1448. *ppEnumTask = NULL; // init
  1449. if (GetPrimaryComponent() == NULL)
  1450. {
  1451. ASSERT(0 && "UNexpected");
  1452. return S_FALSE;
  1453. }
  1454. CMTNode* pMTNode = GetMTNode();
  1455. ASSERT(pMTNode != NULL);
  1456. CMTSnapInNode* pMTSnapIn = pMTNode->GetStaticParent();
  1457. ASSERT(pMTSnapIn != NULL);
  1458. CComponentData* pComponentData = pMTNode->GetPrimaryComponentData();
  1459. ASSERT(pComponentData != NULL);
  1460. GUID guidNodeType;
  1461. HRESULT hr = pMTNode->GetNodeType(&guidNodeType);
  1462. ASSERT(SUCCEEDED(hr));
  1463. if (FAILED(hr))
  1464. return hr;
  1465. //
  1466. // Add primary task pad.
  1467. //
  1468. IExtendTaskPadPtr spExtendTaskPad =
  1469. GetPrimaryComponent()->GetIComponent();
  1470. if (spExtendTaskPad == NULL)
  1471. return S_FALSE;
  1472. IDataObjectPtr spDataObject;
  1473. hr = pMTNode->QueryDataObject(CCT_SCOPE, &spDataObject);
  1474. ASSERT(SUCCEEDED(hr));
  1475. if (FAILED(hr))
  1476. return hr;
  1477. IEnumTASKPtr spEnumTASK;
  1478. hr = spExtendTaskPad->EnumTasks(spDataObject, pszTaskGroup, &spEnumTASK);
  1479. ASSERT(SUCCEEDED(hr));
  1480. if (FAILED(hr))
  1481. return hr;
  1482. CComObject<CTaskEnumerator>* pTaskEnumerator = new CComObject<CTaskEnumerator>;
  1483. ASSERT(pTaskEnumerator != NULL);
  1484. pTaskEnumerator->AddTaskEnumerator(pComponentData->GetCLSID(), spEnumTASK);
  1485. IEnumTASKPtr spEnumTask = pTaskEnumerator;
  1486. ASSERT(spEnumTask != NULL);
  1487. if (spEnumTask)
  1488. *ppEnumTask = spEnumTask.Detach();
  1489. //
  1490. // Add extension task pads.
  1491. //
  1492. CArray<GUID,GUID&> DynExtens;
  1493. ExtractDynExtensions(spDataObject, DynExtens);
  1494. CExtensionsIterator it;
  1495. sc = it.ScInitialize(pComponentData->GetSnapIn(), guidNodeType, g_szTask, DynExtens.GetData(), DynExtens.GetSize());
  1496. if (sc.IsError() || it.IsEnd() == TRUE)
  1497. return S_OK;
  1498. for (; it.IsEnd() == FALSE; it.Advance())
  1499. {
  1500. CComponentData* pCCD = pMTSnapIn->GetComponentData(it.GetCLSID());
  1501. if (pCCD == NULL)
  1502. {
  1503. // See if taskpad extension supports IComponentData. If so, we will add the it to
  1504. // the static node's component list and reuse the same instance each time its needed.
  1505. IComponentDataPtr spIComponentData;
  1506. hr = CreateSnapIn(it.GetCLSID(), &spIComponentData, FALSE);
  1507. if (SUCCEEDED(hr))
  1508. {
  1509. CSnapInPtr spSnapIn;
  1510. // If a dynamic extension, we have to get the snap-in ourselves
  1511. // otherwise the iterator has it
  1512. if (it.IsDynamic())
  1513. {
  1514. CSnapInsCache* const pCache = theApp.GetSnapInsCache();
  1515. ASSERT(pCache != NULL);
  1516. SC sc = pCache->ScGetSnapIn(it.GetCLSID(), &spSnapIn);
  1517. ASSERT(!sc.IsError());
  1518. // On failure, continue with other extensions
  1519. if (sc)
  1520. continue;
  1521. }
  1522. else
  1523. {
  1524. spSnapIn = it.GetSnapIn();
  1525. }
  1526. ASSERT(spSnapIn != NULL);
  1527. pCCD = new CComponentData(spSnapIn);
  1528. if (pCCD != NULL)
  1529. {
  1530. pCCD->SetIComponentData(spIComponentData);
  1531. pMTSnapIn->AddComponentDataToArray(pCCD);
  1532. }
  1533. }
  1534. }
  1535. // Initialize and load component data if not already done
  1536. if (pCCD != NULL && pCCD->IsInitialized() == FALSE)
  1537. {
  1538. sc = pCCD->Init(CMTNode::ToHandle(pMTSnapIn));
  1539. if ( !sc.IsError() )
  1540. {
  1541. sc = pMTSnapIn->ScInitIComponentData(pCCD);
  1542. if (sc)
  1543. {
  1544. sc.TraceAndClear();
  1545. // On failure, continue with other extensions
  1546. continue;
  1547. }
  1548. }
  1549. else
  1550. {
  1551. // if failed to initialize, remove it from the component data array
  1552. pMTSnapIn->CompressComponentDataArray();
  1553. sc.TraceAndClear();
  1554. // On failure, continue with other extensions
  1555. continue;
  1556. }
  1557. }
  1558. IExtendTaskPadPtr spExtendTaskPad;
  1559. if (pCCD)
  1560. {
  1561. CComponent* pCC = pMTSnapIn->GetComponent(GetViewID(),
  1562. pCCD->GetComponentID(), pCCD->GetSnapIn());
  1563. ASSERT(pCC != NULL);
  1564. if (pCC)
  1565. {
  1566. // Ensure the IComponent is initialized.
  1567. if (!pCC->IsInitialized())
  1568. {
  1569. ASSERT(pCCD->GetComponentID() == pCC->GetComponentID());
  1570. hr = pCC->Init(pCCD->GetIComponentData(),
  1571. CMTNode::ToHandle(pMTSnapIn),
  1572. ToHandle(this),
  1573. pCCD->GetComponentID(),
  1574. GetViewID());
  1575. // Abort if PRIMARY Component fails to init.
  1576. if (FAILED(hr))
  1577. return hr;
  1578. }
  1579. spExtendTaskPad = pCC->GetIComponent();
  1580. }
  1581. }
  1582. else
  1583. {
  1584. hr = spExtendTaskPad.CreateInstance(it.GetCLSID(),
  1585. #if _MSC_VER >= 1100
  1586. NULL,
  1587. #endif
  1588. MMC_CLSCTX_INPROC);
  1589. ASSERT(SUCCEEDED(hr));
  1590. if (FAILED(hr))
  1591. continue;
  1592. }
  1593. if (spExtendTaskPad != NULL)
  1594. {
  1595. IEnumTASKPtr spEnumTASK;
  1596. HRESULT hr = spExtendTaskPad->EnumTasks(spDataObject, pszTaskGroup,
  1597. &spEnumTASK);
  1598. ASSERT(SUCCEEDED(hr));
  1599. if (hr == S_OK)
  1600. pTaskEnumerator->AddTaskEnumerator(it.GetCLSID(), spEnumTASK);
  1601. }
  1602. } // end for
  1603. // Return S_OK rather than hr because a failed extension shouldn't prevent the
  1604. // taskpad from coming up
  1605. return S_OK;
  1606. }
  1607. HRESULT
  1608. CNode::GetListPadInfo(IExtendTaskPad* pExtendTaskPad, LPOLESTR szTaskGroup,
  1609. MMC_ILISTPAD_INFO* pIListPadInfo)
  1610. {
  1611. if ((GetPrimaryComponent() == NULL) )
  1612. {
  1613. ASSERT(0 && "Asking for ListPadInfo on a node that has no snapin");
  1614. return S_FALSE;
  1615. }
  1616. // get primary snapin's IComponentData...
  1617. CMTNode* pMTNode = GetMTNode();
  1618. ASSERT(pMTNode != NULL);
  1619. CComponentData* pComponentData = pMTNode->GetPrimaryComponentData();
  1620. ASSERT(pComponentData != NULL);
  1621. // ... so we can get CLSID
  1622. pIListPadInfo->szClsid = NULL;
  1623. HRESULT hr = StringFromCLSID (pComponentData->GetCLSID(), &pIListPadInfo->szClsid);
  1624. ASSERT (pIListPadInfo->szClsid != NULL);
  1625. if (pIListPadInfo->szClsid == NULL) {
  1626. if (hr) return hr;
  1627. else return E_FAIL; // just in case.
  1628. }
  1629. // finally call taskpad extension for info
  1630. return pExtendTaskPad->GetListPadInfo (szTaskGroup, (MMC_LISTPAD_INFO*)pIListPadInfo);
  1631. }
  1632. void
  1633. CNode::OnTaskNotify(LONG_PTR arg, LPARAM param)
  1634. {
  1635. CSnapInNode* pSINode = dynamic_cast<CSnapInNode*>(GetStaticParent());
  1636. ASSERT(pSINode != NULL);
  1637. IDataObjectPtr spDataObject;
  1638. QueryDataObject(CCT_SCOPE, &spDataObject);
  1639. IExtendTaskPadPtr spExtendTaskPad;
  1640. CComponent* pCC;
  1641. LPOLESTR pszClsid = reinterpret_cast<LPOLESTR>(arg);
  1642. if (pszClsid[0] == 0)
  1643. {
  1644. pCC = GetPrimaryComponent();
  1645. if (!pCC)
  1646. return;
  1647. spExtendTaskPad = pCC->GetIComponent();
  1648. }
  1649. else
  1650. {
  1651. CLSID clsid;
  1652. HRESULT hr = ::CLSIDFromString(pszClsid, &clsid);
  1653. ASSERT(SUCCEEDED(hr));
  1654. if (FAILED(hr))
  1655. return;
  1656. // try to get IExtendTaskPad from IComponent, first;
  1657. // if that fails, just create using CLSID
  1658. pCC = pSINode->GetComponent(const_cast<const CLSID&>(clsid));
  1659. if (pCC)
  1660. spExtendTaskPad = pCC->GetIComponent();
  1661. if (spExtendTaskPad == NULL)
  1662. hr = spExtendTaskPad.CreateInstance(clsid,
  1663. #if _MSC_VER >= 1100
  1664. NULL,
  1665. #endif
  1666. MMC_CLSCTX_INPROC);
  1667. }
  1668. ASSERT (spExtendTaskPad != NULL);
  1669. if (spExtendTaskPad != NULL)
  1670. {
  1671. VARIANT** ppvarg = reinterpret_cast<VARIANT**>(param);
  1672. spExtendTaskPad->TaskNotify(spDataObject, ppvarg[0], ppvarg[1]);
  1673. }
  1674. }
  1675. HRESULT
  1676. CNode::OnScopeSelect(bool bSelect, SELECTIONINFO* pSelInfo)
  1677. {
  1678. DECLARE_SC (sc, _T("CNode::OnScopeSelect"));
  1679. sc = ScCheckPointers(pSelInfo);
  1680. if (sc)
  1681. return sc.ToHr();
  1682. /*
  1683. * Bug 178484: reset the sort parameters when scope selection changes
  1684. */
  1685. if (bSelect)
  1686. {
  1687. CComponent *pCC = GetPrimaryComponent();
  1688. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  1689. if (sc)
  1690. return sc.ToHr();
  1691. IFramePrivate *pFrame = pCC->GetIFramePrivate();
  1692. sc = ScCheckPointers(pFrame, E_UNEXPECTED);
  1693. if (sc)
  1694. return sc.ToHr();
  1695. pFrame->ResetSortParameters();
  1696. }
  1697. if (bSelect == TRUE && WasExpandedAtLeastOnce() == FALSE)
  1698. {
  1699. sc = OnExpand(TRUE);
  1700. if (sc)
  1701. return (sc.ToHr());
  1702. }
  1703. ASSERT(IsInitialized() == TRUE);
  1704. sc = OnSelect(pSelInfo->m_pView, bSelect, pSelInfo->m_bResultPaneIsWeb);
  1705. if (sc)
  1706. return (sc.ToHr());
  1707. return (sc.ToHr());
  1708. }
  1709. HRESULT CNode::OnActvate(LONG_PTR lActivate)
  1710. {
  1711. return (DeepNotify (MMCN_ACTIVATE, lActivate, 0));
  1712. }
  1713. HRESULT CNode::OnMinimize(LONG_PTR fMinimized)
  1714. {
  1715. return (DeepNotify (MMCN_MINIMIZED, fMinimized, 0));
  1716. }
  1717. //+-------------------------------------------------------------------
  1718. //
  1719. // Member: SendShowEvent
  1720. //
  1721. // Synopsis: Send MMCN_SHOW notification to snapin, persist column
  1722. // data if necessary.
  1723. //
  1724. // Arguments: [bSelect] - TRUE if the node is selected.
  1725. //
  1726. //--------------------------------------------------------------------
  1727. HRESULT CNode::SendShowEvent(BOOL bSelect)
  1728. {
  1729. DECLARE_SC(sc, _T("CNode::SendShowEvent"));
  1730. CComponent* pCC = m_pPrimaryComponent;
  1731. ASSERT(pCC != NULL);
  1732. // Get the data object for the node and pass it to the primary snap-in
  1733. // and all the namespace extensions to the node.
  1734. IDataObjectPtr spDataObject;
  1735. HRESULT hr = QueryDataObject(CCT_SCOPE, &spDataObject);
  1736. if (FAILED(hr))
  1737. return hr;
  1738. CMTNode* pMTNode = GetMTNode();
  1739. IFramePrivatePtr spFrame = pCC->GetIFramePrivate();
  1740. sc = ScCheckPointers(spFrame, E_UNEXPECTED);
  1741. if (sc)
  1742. return sc.ToHr();
  1743. IImageListPrivatePtr spImageList;
  1744. hr = spFrame->QueryResultImageList(reinterpret_cast<LPIMAGELIST*>(&spImageList));
  1745. ASSERT(SUCCEEDED(hr));
  1746. ASSERT(spImageList != NULL);
  1747. HSCOPEITEM hScopeItem = CMTNode::ToScopeItem(pMTNode);
  1748. if (bSelect == TRUE)
  1749. {
  1750. hr = pCC->Notify(spDataObject, MMCN_ADD_IMAGES,
  1751. reinterpret_cast<LPARAM>((LPIMAGELIST)spImageList),
  1752. hScopeItem);
  1753. CHECK_HRESULT(hr);
  1754. //if (FAILED(hr))
  1755. // return hr;
  1756. }
  1757. hr = pCC->Notify(spDataObject, MMCN_SHOW, bSelect, hScopeItem);
  1758. CHECK_HRESULT(hr);
  1759. if (FAILED(hr))
  1760. return hr;
  1761. if (bSelect)
  1762. {
  1763. CViewData *pViewData = GetViewData();
  1764. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  1765. if (sc)
  1766. return sc.ToHr();
  1767. if (pViewData->HasList() || pViewData->HasListPad())
  1768. {
  1769. sc = ScRestoreSortFromPersistedData();
  1770. if (sc)
  1771. return sc.ToHr();
  1772. // Now try to restore the view mode.
  1773. sc =ScRestoreViewMode();
  1774. if (sc)
  1775. return sc.ToHr();
  1776. }
  1777. }
  1778. return hr;
  1779. }
  1780. HRESULT CNode::DeepNotify(MMC_NOTIFY_TYPE event, LONG_PTR arg, LPARAM param)
  1781. {
  1782. DECLARE_SC(sc, TEXT("CNode::DeepNotify"));
  1783. CComponent* pCC = m_pPrimaryComponent;
  1784. ASSERT(pCC != NULL);
  1785. if (pCC == NULL)
  1786. return E_UNEXPECTED;
  1787. // Get the data object for the node and pass it to the primary snap-in
  1788. // and all the namespace extensions to the node.
  1789. IDataObjectPtr spDataObject;
  1790. HRESULT hr = QueryDataObject(CCT_SCOPE, &spDataObject);
  1791. if (FAILED(hr))
  1792. return hr;
  1793. hr = pCC->Notify(spDataObject, event, arg, param);
  1794. CHECK_HRESULT(hr);
  1795. //if (FAILED(hr))
  1796. // return hr;
  1797. //
  1798. // Notify extensions.
  1799. //
  1800. CMTNode* pMTNode = GetMTNode();
  1801. // Get the node-type of this node
  1802. GUID guidNodeType;
  1803. hr = pMTNode->GetNodeType(&guidNodeType);
  1804. CHECK_HRESULT(hr);
  1805. if (FAILED(hr))
  1806. return hr;
  1807. LPCLSID pDynExtCLSID;
  1808. int cDynExt = pMTNode->GetDynExtCLSID(&pDynExtCLSID);
  1809. CExtensionsIterator it;
  1810. sc = it.ScInitialize(pMTNode->GetPrimarySnapIn(), guidNodeType, g_szNameSpace, pDynExtCLSID, cDynExt);
  1811. if (sc)
  1812. return S_FALSE;
  1813. BOOL fProblem = FALSE;
  1814. CSnapInNode* pSINode = GetStaticParent();
  1815. for (; it.IsEnd() == FALSE; it.Advance())
  1816. {
  1817. CComponent* pCC = pSINode->GetComponent(it.GetCLSID());
  1818. if (pCC == NULL)
  1819. continue;
  1820. hr = pCC->Notify(spDataObject, event, arg, param);
  1821. CHECK_HRESULT(hr);
  1822. // continue even if an error occurs with extension snapins
  1823. if (FAILED(hr))
  1824. fProblem = TRUE;
  1825. }
  1826. return (fProblem == TRUE) ? S_FALSE : S_OK;
  1827. }
  1828. HRESULT CNode::OnSelect(LPUNKNOWN lpView, BOOL bSelect,
  1829. BOOL bResultPaneIsWeb)
  1830. {
  1831. DECLARE_SC(sc, TEXT("CNode::OnSelect"));
  1832. #ifdef DBG
  1833. if (lpView == NULL)
  1834. ASSERT(bSelect == FALSE);
  1835. else
  1836. ASSERT(bSelect == TRUE);
  1837. #endif
  1838. sc = ScCheckPointers(m_pPrimaryComponent, E_UNEXPECTED);
  1839. if (sc)
  1840. {
  1841. sc.TraceAndClear();
  1842. return sc.ToHr();
  1843. }
  1844. CComponent* pCC = m_pPrimaryComponent;
  1845. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  1846. if (sc)
  1847. return sc.ToHr();
  1848. IFramePrivate *pFrame = pCC->GetIFramePrivate();
  1849. sc = ScCheckPointers(pFrame, E_UNEXPECTED);
  1850. if (sc)
  1851. return sc.ToHr();
  1852. // set the correct view in the primary snap-in before it adds items
  1853. if (bSelect == TRUE)
  1854. pFrame->SetResultView(lpView);
  1855. IDataObjectPtr spDataObject;
  1856. sc = QueryDataObject(CCT_SCOPE, &spDataObject);
  1857. if (sc)
  1858. return sc.ToHr();
  1859. CMTNode* pMTNode = GetMTNode();
  1860. LPARAM hScopeItem = CMTNode::ToScopeItem(pMTNode);
  1861. // Send only the MMCN_SHOW message if result pane is the web view.
  1862. if (bResultPaneIsWeb)
  1863. {
  1864. return pCC->Notify(spDataObject, MMCN_SHOW, bSelect, hScopeItem);
  1865. }
  1866. // Send necessary events like MMCN_ADD_IMAGES and MMCN_SHOW to snapin
  1867. sc = SendShowEvent(bSelect);
  1868. if (sc)
  1869. return sc.ToHr();
  1870. // set the correct view in the primary snap-in after it's notified
  1871. if (bSelect == FALSE)
  1872. pFrame->SetResultView(NULL); //
  1873. // Deal with extension ssnap-ins
  1874. //
  1875. // Get the node-type of this node
  1876. GUID guidNodeType;
  1877. sc = pMTNode->GetNodeType(&guidNodeType);
  1878. if (sc)
  1879. return sc.ToHr();
  1880. LPCLSID pDynExtCLSID;
  1881. int cDynExt = pMTNode->GetDynExtCLSID(&pDynExtCLSID);
  1882. CExtensionsIterator it;
  1883. sc = it.ScInitialize(pMTNode->GetPrimarySnapIn(), guidNodeType, g_szNameSpace, pDynExtCLSID, cDynExt);
  1884. if (sc)
  1885. return S_FALSE;
  1886. BOOL fProblem = FALSE;
  1887. CSnapInNode* pSINode = GetStaticParent();
  1888. for (; it.IsEnd() == FALSE; it.Advance())
  1889. {
  1890. CComponent* pCCExtnSnapin = pSINode->GetComponent(it.GetCLSID());
  1891. if (pCCExtnSnapin == NULL)
  1892. continue;
  1893. IFramePrivate *pFrameExtnSnapin = pCCExtnSnapin->GetIFramePrivate();
  1894. sc = ScCheckPointers(pFrameExtnSnapin, E_UNEXPECTED);
  1895. if (sc)
  1896. {
  1897. sc.TraceAndClear();
  1898. continue;
  1899. }
  1900. // set the correct view in the snap-in before it adds items
  1901. if (bSelect == FALSE)
  1902. {
  1903. pFrameExtnSnapin->SetResultView(NULL);
  1904. continue;
  1905. }
  1906. else
  1907. {
  1908. pFrameExtnSnapin->SetResultView(lpView);
  1909. IImageListPrivatePtr spImageList;
  1910. sc = pCCExtnSnapin->GetIFramePrivate()->QueryResultImageList(
  1911. reinterpret_cast<LPIMAGELIST*>(&spImageList));
  1912. if (sc)
  1913. {
  1914. sc.TraceAndClear();
  1915. fProblem = TRUE;
  1916. continue;
  1917. }
  1918. sc = ScCheckPointers(spImageList, E_UNEXPECTED);
  1919. if (sc)
  1920. {
  1921. sc.TraceAndClear();
  1922. fProblem = TRUE;
  1923. continue;
  1924. }
  1925. SC scNoTrace = pCCExtnSnapin->Notify(spDataObject, MMCN_ADD_IMAGES,
  1926. reinterpret_cast<LPARAM>((LPIMAGELIST)spImageList),
  1927. hScopeItem);
  1928. if (scNoTrace)
  1929. {
  1930. TraceSnapinError(TEXT("Snapin returned error from IComponent::Notify MMCN_ADD_IMAGES"), scNoTrace);
  1931. }
  1932. }
  1933. }
  1934. return (fProblem == TRUE) ? S_FALSE : S_OK;
  1935. }
  1936. void CNode::Reset()
  1937. {
  1938. m_pPrimaryComponent = NULL;
  1939. m_bInitComponents = TRUE;
  1940. }
  1941. HRESULT CNode::GetDispInfoForListItem(LV_ITEMW* plvi)
  1942. {
  1943. ASSERT(plvi != NULL);
  1944. RESULTDATAITEM rdi;
  1945. ZeroMemory(&rdi, sizeof(rdi));
  1946. if (plvi->mask & LVIF_TEXT)
  1947. {
  1948. ASSERT (!IsBadWritePtr (plvi->pszText, plvi->cchTextMax * sizeof (TCHAR)));
  1949. rdi.mask |= RDI_STR;
  1950. }
  1951. if (plvi->mask & LVIF_IMAGE)
  1952. rdi.mask |= RDI_IMAGE;
  1953. if (plvi->mask & LVIF_STATE)
  1954. rdi.mask |= RDI_STATE;
  1955. rdi.nCol = plvi->iSubItem;
  1956. CComponent* pCC = NULL;
  1957. // if virtual list
  1958. if (GetViewData()->IsVirtualList())
  1959. {
  1960. pCC = GetPrimaryComponent();
  1961. ASSERT(pCC != NULL);
  1962. // all we can pass is the item index
  1963. rdi.nIndex = plvi->iItem;
  1964. // no default for virtual lists
  1965. rdi.nImage = MMCLV_NOICON;
  1966. }
  1967. else
  1968. {
  1969. CResultItem* pri = CResultItem::FromHandle (plvi->lParam);
  1970. if (pri != NULL)
  1971. {
  1972. if (pri->IsScopeItem()) // Folder
  1973. {
  1974. // convert to real type
  1975. CNode* pNodeSubFldr = CNode::FromResultItem (pri);
  1976. ASSERT(IsBadReadPtr(pNodeSubFldr, sizeof(CNode)) == FALSE);
  1977. if (pNodeSubFldr->IsStaticNode() == TRUE) // Static folders
  1978. {
  1979. return pNodeSubFldr->GetDispInfo(plvi);
  1980. }
  1981. else // Enumerated folders
  1982. {
  1983. // Remap the LParam information.
  1984. rdi.lParam = pNodeSubFldr->GetUserParam();
  1985. rdi.bScopeItem = TRUE;
  1986. pCC = pNodeSubFldr->GetPrimaryComponent();
  1987. rdi.nImage = pNodeSubFldr->GetResultImage();
  1988. }
  1989. }
  1990. else // Leaf item
  1991. {
  1992. // Remap the LParam information.
  1993. rdi.nImage = pri->GetImageIndex();
  1994. rdi.lParam = pri->GetSnapinData();
  1995. pCC = GetPrimaryComponent();
  1996. ASSERT(GetComponent(pri->GetOwnerID()) == GetPrimaryComponent());
  1997. ASSERT(pCC != NULL);
  1998. }
  1999. }
  2000. }
  2001. HRESULT hr = pCC->GetDisplayInfo(&rdi);
  2002. if (hr == S_OK)
  2003. {
  2004. if (rdi.mask & RDI_IMAGE)
  2005. {
  2006. if (rdi.nImage == MMCLV_NOICON)
  2007. {
  2008. plvi->iImage = rdi.bScopeItem ? eStockImage_Folder : eStockImage_File;
  2009. }
  2010. else
  2011. {
  2012. IImageListPrivate *pIL = pCC->GetIImageListPrivate();
  2013. HRESULT hr2 = pIL->MapRsltImage(pCC->GetComponentID(), rdi.nImage,
  2014. &(plvi->iImage));
  2015. if (FAILED(hr2))
  2016. {
  2017. Dbg(DEB_USER1, "can't map image provided by snapin. Using default image.\n");
  2018. plvi->iImage = rdi.bScopeItem ? eStockImage_Folder : eStockImage_File;
  2019. }
  2020. }
  2021. }
  2022. // Move all other info from rdi into lviItem
  2023. if (rdi.mask & RDI_STR)
  2024. {
  2025. if (!IsBadStringPtrW (rdi.str, plvi->cchTextMax))
  2026. {
  2027. wcsncpy (plvi->pszText, rdi.str, plvi->cchTextMax);
  2028. // always terminate the string!
  2029. // see bug #416888 (ntraid9) 6/15/2001
  2030. if ( plvi->cchTextMax != 0 )
  2031. plvi->pszText[ plvi->cchTextMax - 1 ] = 0;
  2032. }
  2033. else if (plvi->cchTextMax > 0)
  2034. plvi->pszText[0] = 0;
  2035. }
  2036. if (rdi.mask & RDI_STATE)
  2037. plvi->state = rdi.nState;
  2038. }
  2039. return hr;
  2040. }
  2041. //+-------------------------------------------------------------------
  2042. //
  2043. // Member: CNode::ScSaveSortData
  2044. //
  2045. // Synopsis: Save the given sort data for persistence.
  2046. //
  2047. // Arguments: [nCol] - sort column.
  2048. // [dwOptions] - sort options.
  2049. //
  2050. // Returns: SC
  2051. //
  2052. //--------------------------------------------------------------------
  2053. SC CNode::ScSaveSortData (int nCol, DWORD dwOptions)
  2054. {
  2055. DECLARE_SC(sc, _T("CNode::ScSaveSortData"));
  2056. CViewData *pViewData = GetViewData();
  2057. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  2058. if (sc)
  2059. return sc;
  2060. CLSID guidSnapin;
  2061. CXMLAutoBinary columnID;
  2062. sc = ScGetSnapinAndColumnDataID(guidSnapin, columnID);
  2063. if (sc)
  2064. return sc;
  2065. CXMLBinaryLock sLock(columnID);
  2066. SColumnSetID* pColID = NULL;
  2067. sc = sLock.ScLock(&pColID);
  2068. if (sc)
  2069. return sc;
  2070. sc = ScCheckPointers(pColID, E_UNEXPECTED);
  2071. if (sc)
  2072. return sc;
  2073. CColumnSortInfo colSortInfo;
  2074. colSortInfo.m_nCol = nCol;
  2075. colSortInfo.m_dwSortOptions = dwOptions;
  2076. colSortInfo.m_lpUserParam = NULL;
  2077. sc = pViewData->ScSaveColumnSortData(guidSnapin, *pColID, colSortInfo);
  2078. if (sc)
  2079. return sc;
  2080. // Column data when saved includes the width/order data (column info list) and sort data.
  2081. // The width/order data should always be saved regardless of whether sort data is
  2082. // persisted or not. So save the width/order data.
  2083. CColumnInfoList columnInfoList;
  2084. TStringVector strColNames; // unused
  2085. // get the current data
  2086. sc = ScGetCurrentColumnData( columnInfoList, strColNames );
  2087. if (sc)
  2088. return sc;
  2089. sc = pViewData->ScSaveColumnInfoList(guidSnapin, *pColID, columnInfoList);
  2090. if (sc)
  2091. return sc;
  2092. return (sc);
  2093. }
  2094. //+-------------------------------------------------------------------
  2095. //
  2096. // Member: OnColumnClicked
  2097. //
  2098. // Synopsis: Ask snapin to sort.
  2099. //
  2100. // Arguments: [nCol] - Column to be sorted.
  2101. //
  2102. // Note: When column is clicked sort options and user param
  2103. // are unknown. So we set them to 0 (zero). In InternalSort
  2104. // the sort option is computed.
  2105. //
  2106. // Returns: HRESULT
  2107. //
  2108. // History: RaviR Created
  2109. // 07-27-1999 AnandhaG renamed OnSort to OnColumnClicked
  2110. //--------------------------------------------------------------------
  2111. HRESULT CNode::OnColumnClicked(LONG_PTR nCol)
  2112. {
  2113. CComponent* pComponent = GetPrimaryComponent();
  2114. ASSERT(pComponent != NULL);
  2115. if (NULL == pComponent)
  2116. return E_FAIL;
  2117. IResultDataPrivatePtr pResult = pComponent->GetIFramePrivate();
  2118. ASSERT(pResult != NULL);
  2119. if (NULL == pResult)
  2120. return E_FAIL;
  2121. HRESULT hr = pResult->InternalSort( nCol, 0, NULL,
  2122. TRUE /*column header clicked*/);
  2123. if (hr == S_OK)
  2124. {
  2125. BOOL bAscending = TRUE;
  2126. hr = pResult->GetSortDirection(&bAscending);
  2127. if (hr == S_OK)
  2128. hr = ScSaveSortData(nCol, bAscending ? 0 : RSI_DESCENDING).ToHr();
  2129. }
  2130. return S_OK;
  2131. }
  2132. //+-------------------------------------------------------------------
  2133. //
  2134. // Member: RestoreSort
  2135. //
  2136. // Synopsis: Sort the list view with persisted data.
  2137. // Restore the sort with saved column # and
  2138. // sort-options (User param is NULL as this
  2139. // is user initiated MMCN_COLUMN_CLICK)*/
  2140. //
  2141. // Arguments: [nCol] - Column to be sorted.
  2142. // [dwSortOptions] - Sortoptions, ascend/descend...
  2143. //
  2144. // Note: Unlike OnColumnClicked this method wont set columns dirty
  2145. // after successful sort.
  2146. //
  2147. // Returns: HRESULT
  2148. //
  2149. //--------------------------------------------------------------------
  2150. HRESULT CNode::RestoreSort(INT nCol, DWORD dwSortOptions)
  2151. {
  2152. CComponent* pComponent = GetPrimaryComponent();
  2153. ASSERT(pComponent != NULL);
  2154. if (NULL == pComponent)
  2155. return E_FAIL;
  2156. IResultDataPrivatePtr pResult = pComponent->GetIFramePrivate();
  2157. ASSERT(pResult != NULL);
  2158. if (NULL == pResult)
  2159. return E_FAIL;
  2160. HRESULT hr = pResult->InternalSort( nCol, dwSortOptions,
  2161. NULL /*NULL user param as this is user initiated*/,
  2162. FALSE /* Let us not send MMCN_COLUMN_CLICK*/);
  2163. return S_OK;
  2164. }
  2165. //+-------------------------------------------------------------------
  2166. //
  2167. // Member: CNode::ScRestoreSortFromPersistedData
  2168. //
  2169. // Synopsis: Get persisted sort data if any and apply it to list-view.
  2170. //
  2171. // Returns: SC
  2172. //
  2173. //--------------------------------------------------------------------
  2174. SC CNode::ScRestoreSortFromPersistedData ()
  2175. {
  2176. DECLARE_SC(sc, _T("CNode::ScRestoreSortFromPersistedData"));
  2177. CViewData *pViewData = GetViewData();
  2178. if (! pViewData->HasList() && ! pViewData->HasListPad() )
  2179. return (sc = S_FALSE); // OCX gets MMCN_SHOW which may try to restore sort so this is no failure.
  2180. // To get CColumnSetData first get the column-id & snapin guid.
  2181. CLSID guidSnapin;
  2182. CXMLAutoBinary columnID;
  2183. sc = ScGetSnapinAndColumnDataID(guidSnapin, columnID);
  2184. if (sc)
  2185. return sc;
  2186. CXMLBinaryLock sLock(columnID);
  2187. SColumnSetID* pColID = NULL;
  2188. sc = sLock.ScLock(&pColID);
  2189. if (sc)
  2190. return sc;
  2191. sc = ScCheckPointers(pColID, E_UNEXPECTED);
  2192. if (sc)
  2193. return sc;
  2194. // Get persisted data.
  2195. CColumnSetData columnSetData;
  2196. BOOL bRet = pViewData->RetrieveColumnData(guidSnapin, *pColID, columnSetData);
  2197. if (!bRet)
  2198. return (sc = S_FALSE);
  2199. CColumnInfoList* pColInfoList = columnSetData.get_ColumnInfoList();
  2200. if (!pColInfoList)
  2201. return (sc = S_FALSE);
  2202. IFramePrivatePtr spFrame = GetIFramePrivate();
  2203. sc = ScCheckPointers(spFrame, E_UNEXPECTED);
  2204. if (sc)
  2205. return sc;
  2206. // First check if the number of columns inserted are same as the
  2207. // number that is persisted. If not remove the persisted data.
  2208. IHeaderCtrlPrivatePtr spHeader = spFrame;
  2209. sc = ScCheckPointers(spHeader, E_UNEXPECTED);
  2210. if (sc)
  2211. return sc;
  2212. int cColumns = 0;
  2213. sc = spHeader->GetColumnCount(&cColumns);
  2214. if (sc)
  2215. return sc;
  2216. // If the persisted columns and number of columns inserted
  2217. // do not match remove the persisted data.
  2218. if (pColInfoList->size() != cColumns)
  2219. {
  2220. pViewData->DeleteColumnData(guidSnapin, *pColID);
  2221. return sc;
  2222. }
  2223. // Set sorting column, order
  2224. CColumnSortList* pSortList = columnSetData.get_ColumnSortList();
  2225. if (pSortList && ( pSortList->size() > 0))
  2226. {
  2227. CColumnSortList::iterator itSortInfo = pSortList->begin();
  2228. // Restore the sort with saved column # and
  2229. // sort-options (User param is NULL as this
  2230. // is user initiated MMCN_COLUMN_CLICK)*/
  2231. RestoreSort(itSortInfo->getColumn(), itSortInfo->getSortOptions());
  2232. }
  2233. return (sc);
  2234. }
  2235. /***************************************************************************\
  2236. *
  2237. * METHOD: CNode::ScGetCurrentColumnData
  2238. *
  2239. * PURPOSE: collects current column data to collections passed as args
  2240. * [ initially code used to be in OnColumns method ]
  2241. *
  2242. * PARAMETERS:
  2243. * CColumnInfoList& columnInfoList
  2244. * TStringVector& strColNames
  2245. *
  2246. * RETURNS:
  2247. * SC - result code
  2248. *
  2249. \***************************************************************************/
  2250. SC CNode::ScGetCurrentColumnData( CColumnInfoList& columnInfoList, TStringVector& strColNames)
  2251. {
  2252. DECLARE_SC(sc, TEXT("CNode::ScGetCurrentColumnData"));
  2253. columnInfoList.clear();
  2254. strColNames.clear();
  2255. IHeaderCtrlPrivatePtr spHeader = GetIFramePrivate();
  2256. sc = ScCheckPointers(spHeader, E_UNEXPECTED);
  2257. if (sc)
  2258. return sc;
  2259. sc = spHeader->GetColumnInfoList(&columnInfoList);
  2260. if (sc)
  2261. return sc;
  2262. int cColumns = columnInfoList.size();
  2263. USES_CONVERSION;
  2264. for (int i = 0; i < cColumns; i++)
  2265. {
  2266. CCoTaskMemPtr<OLECHAR> spColumnText;
  2267. sc = spHeader->GetColumnText(i, &spColumnText);
  2268. if (sc)
  2269. return sc;
  2270. strColNames.push_back(OLE2T(spColumnText));
  2271. }
  2272. return sc;
  2273. }
  2274. /***************************************************************************\
  2275. *
  2276. * METHOD: CNode::ScSetUpdatedColumnData
  2277. *
  2278. * PURPOSE: updates column by data specified in collections passed as args
  2279. * [ initially code used to be in OnColumns method ]
  2280. *
  2281. * PARAMETERS:
  2282. * CColumnInfoList& oldColumnInfoList - column data befor the change
  2283. * CColumnInfoList& newColumnInfoList - updated column data
  2284. *
  2285. * RETURNS:
  2286. * SC - result code
  2287. *
  2288. \***************************************************************************/
  2289. SC CNode::ScSetUpdatedColumnData( CColumnInfoList& oldColumnInfoList, CColumnInfoList& newColumnInfoList)
  2290. {
  2291. DECLARE_SC(sc, TEXT("CNode::ScSetUpdatedColumnData"));
  2292. CColumnInfoList::iterator itColInfo1, itColInfo2;
  2293. // Check if there is any change in visible/hidden columns.
  2294. // If so send MMCN_COLUMNS_CHANGE notification
  2295. for (itColInfo1 = newColumnInfoList.begin(); itColInfo1 != newColumnInfoList.end(); ++itColInfo1)
  2296. {
  2297. // Get the same column from old list.
  2298. itColInfo2 = find_if(oldColumnInfoList.begin(), oldColumnInfoList.end(),
  2299. bind2nd( ColPosCompare(), itColInfo1->GetColIndex()) );
  2300. if (itColInfo2 == oldColumnInfoList.end())
  2301. return sc = E_UNEXPECTED;
  2302. // Compare the hidden flag.
  2303. if ( itColInfo2->IsColHidden() != itColInfo1->IsColHidden() )
  2304. {
  2305. // Send MMCN_COLUMNS_CHANGED notification
  2306. sc = OnColumnsChange(newColumnInfoList);
  2307. if (sc)
  2308. return sc;
  2309. break; // done anyway
  2310. }
  2311. }
  2312. sc = ScSaveColumnInfoList(newColumnInfoList);
  2313. if (sc)
  2314. return sc;
  2315. IHeaderCtrlPrivatePtr spHeader = GetIFramePrivate();
  2316. sc = ScCheckPointers(spHeader, E_UNEXPECTED);
  2317. if (sc)
  2318. return sc;
  2319. sc = spHeader->ModifyColumns(newColumnInfoList);
  2320. if (sc)
  2321. return sc;
  2322. sc = ScRestoreSortFromPersistedData();
  2323. if (sc)
  2324. return sc;
  2325. return sc;
  2326. }
  2327. //+-------------------------------------------------------------------
  2328. //
  2329. // Member: OnColumns
  2330. //
  2331. // Synopsis: Display Columns customization dialog and if necessary
  2332. // apply changes made by the user.
  2333. //
  2334. //--------------------------------------------------------------------
  2335. void CNode::OnColumns()
  2336. {
  2337. DECLARE_SC(sc, TEXT("CNode::OnColumns"));
  2338. // first - get the columns
  2339. CColumnInfoList columnInfoList;
  2340. TStringVector strColNames;
  2341. // 1. get the current data
  2342. sc = ScGetCurrentColumnData( columnInfoList, strColNames );
  2343. if (sc)
  2344. return;
  2345. // 2. Cache the column data.
  2346. CColumnInfoList columnInfoListOld = columnInfoList;
  2347. // 3. get the default column settings.
  2348. CViewData *pViewData = GetViewData();
  2349. IHeaderCtrlPrivatePtr spHeader = GetIFramePrivate();
  2350. sc = ScCheckPointers(pViewData, spHeader, E_UNEXPECTED);
  2351. if (sc)
  2352. return;
  2353. CColumnInfoList defaultColumnInfoList;
  2354. sc = spHeader->GetDefaultColumnInfoList(defaultColumnInfoList);
  2355. if (sc)
  2356. return;
  2357. // 5. display the dialog
  2358. CColumnsDlg dlg(&columnInfoList, &strColNames, defaultColumnInfoList);
  2359. INT_PTR nRet = dlg.DoModal();
  2360. if (nRet == -1)
  2361. {
  2362. sc = E_UNEXPECTED;
  2363. return;
  2364. }
  2365. if (nRet == IDOK)
  2366. {
  2367. // update columns by modified data
  2368. sc = ScSetUpdatedColumnData( columnInfoListOld, columnInfoList );
  2369. if (sc)
  2370. return;
  2371. }
  2372. // If reset is true then throw away present persisted column data
  2373. // and apply the default settings.
  2374. if (nRet == IDC_RESTORE_DEFAULT_COLUMNS)
  2375. {
  2376. // To get CColumnSetData first get the column-id & snapin guid.
  2377. CLSID guidSnapin;
  2378. CXMLAutoBinary columnID;
  2379. sc = ScGetSnapinAndColumnDataID(guidSnapin, columnID);
  2380. if (sc)
  2381. return;
  2382. CXMLBinaryLock sLock(columnID);
  2383. SColumnSetID* pColID = NULL;
  2384. sc = sLock.ScLock(&pColID);
  2385. if (sc)
  2386. return;
  2387. sc = ScCheckPointers(pColID, E_UNEXPECTED);
  2388. if (sc)
  2389. return;
  2390. pViewData->DeleteColumnData(guidSnapin, *pColID);
  2391. sc = spHeader->ModifyColumns(defaultColumnInfoList);
  2392. if (sc)
  2393. return;
  2394. }
  2395. }
  2396. /***************************************************************************\
  2397. *
  2398. * METHOD: CNode::ScShowColumn
  2399. *
  2400. * PURPOSE: shows/hides column. notifies snapin on action
  2401. *
  2402. * PARAMETERS:
  2403. * int iColIndex - index of column to change
  2404. * bool bVisible - show/hide flag
  2405. *
  2406. * RETURNS:
  2407. * SC - result code
  2408. *
  2409. \***************************************************************************/
  2410. SC CNode::ScShowColumn(int iColIndex, bool bShow)
  2411. {
  2412. DECLARE_SC(sc, TEXT("CNode::ScShowColumn"));
  2413. // first - get the current column data
  2414. CColumnInfoList columnInfoList;
  2415. TStringVector strColNames;
  2416. sc = ScGetCurrentColumnData( columnInfoList, strColNames );
  2417. if (sc)
  2418. return sc;
  2419. // Save the column data.
  2420. CColumnInfoList columnInfoListOld = columnInfoList;
  2421. // find the column and change its status
  2422. CColumnInfoList::iterator itColInfo = find_if(columnInfoList.begin(), columnInfoList.end(),
  2423. bind2nd( ColPosCompare(), iColIndex) );
  2424. // check if we did find the column
  2425. if (itColInfo == columnInfoList.end())
  2426. return sc = E_INVALIDARG; // assume it's not a valid index
  2427. // now modify the column status acording to parameters
  2428. if (bShow)
  2429. {
  2430. itColInfo->SetColHidden(false);
  2431. // move column to the end
  2432. columnInfoList.splice(columnInfoList.end(), columnInfoList, itColInfo);
  2433. }
  2434. else
  2435. {
  2436. itColInfo->SetColHidden();
  2437. }
  2438. // update columns by modified data
  2439. sc = ScSetUpdatedColumnData( columnInfoListOld, columnInfoList);
  2440. if (sc)
  2441. return sc;
  2442. return sc;
  2443. }
  2444. /***************************************************************************\
  2445. *
  2446. * METHOD: CNode::ScGetSortColumn
  2447. *
  2448. * PURPOSE: return currently used sort column
  2449. *
  2450. * PARAMETERS:
  2451. * int *piSortCol - sort column index [retval]
  2452. *
  2453. * RETURNS:
  2454. * SC - result code
  2455. *
  2456. \***************************************************************************/
  2457. SC CNode::ScGetSortColumn(int *piSortCol)
  2458. {
  2459. DECLARE_SC(sc, TEXT("CNode::ScGetSortColumn"));
  2460. // parameter check
  2461. sc = ScCheckPointers(piSortCol);
  2462. if (sc)
  2463. return sc;
  2464. // retrieve IResultDataPrivate interface
  2465. CComponent* pComponent = GetPrimaryComponent();
  2466. sc = ScCheckPointers(pComponent, E_UNEXPECTED);
  2467. if (sc)
  2468. return sc;
  2469. IResultDataPrivatePtr pResult = pComponent->GetIFramePrivate();
  2470. sc = ScCheckPointers(pResult, E_UNEXPECTED);
  2471. if (sc)
  2472. return sc;
  2473. // forward the call to IResultDataPrivate
  2474. sc = pResult->GetSortColumn(piSortCol);
  2475. if (sc)
  2476. return sc;
  2477. return sc;
  2478. }
  2479. /***************************************************************************\
  2480. *
  2481. * METHOD: CNode::ScSetSortColumn
  2482. *
  2483. * PURPOSE: sorts result data by specified column
  2484. * [uses private result data interface to implement]
  2485. *
  2486. * PARAMETERS:
  2487. * int iSortCol - index of column to sort by
  2488. * bool bAscending - sorting order
  2489. *
  2490. * RETURNS:
  2491. * SC - result code
  2492. *
  2493. \***************************************************************************/
  2494. SC CNode::ScSetSortColumn(int iSortCol, bool bAscending)
  2495. {
  2496. DECLARE_SC(sc, TEXT("CNode::ScSetSortColumn"));
  2497. // retrieve IResultDataPrivate interface
  2498. CComponent* pComponent = GetPrimaryComponent();
  2499. sc = ScCheckPointers(pComponent, E_UNEXPECTED);
  2500. if (sc)
  2501. return sc;
  2502. IResultDataPrivatePtr pResult = pComponent->GetIFramePrivate();
  2503. sc = ScCheckPointers(pResult, E_UNEXPECTED);
  2504. if (sc)
  2505. return sc;
  2506. DWORD dwSortOptions = bAscending ? 0 : RSI_DESCENDING;
  2507. // forward the call to IResultDataPrivate
  2508. sc = pResult->InternalSort( iSortCol, dwSortOptions, NULL, FALSE );
  2509. if (sc)
  2510. return sc;
  2511. // If sort went thru - save.
  2512. if (sc == SC(S_OK))
  2513. sc = ScSaveSortData(iSortCol, dwSortOptions);
  2514. if (sc)
  2515. return sc;
  2516. return sc;
  2517. }
  2518. //+-------------------------------------------------------------------
  2519. //
  2520. // Member: OnColumnsChange
  2521. //
  2522. // Synopsis: Send MMCN_COLUMNS_CHANGE notification to snapin.
  2523. //
  2524. // Arguments: [colInfoList] - Columns data.
  2525. //
  2526. //--------------------------------------------------------------------
  2527. HRESULT CNode::OnColumnsChange(CColumnInfoList& colInfoList)
  2528. {
  2529. CComponent* pCC = m_pPrimaryComponent;
  2530. ASSERT(pCC != NULL);
  2531. // Get the data object for the node and pass it to the primary snap-in
  2532. // and all the namespace extensions to the node.
  2533. IDataObjectPtr spDataObject;
  2534. HRESULT hr = QueryDataObject(CCT_SCOPE, &spDataObject);
  2535. if (FAILED(hr))
  2536. return hr;
  2537. int nVisibleColumns = 0;
  2538. // Count the number of columns that are visible.
  2539. CColumnInfoList::iterator itColInfo;
  2540. for (itColInfo = colInfoList.begin(); itColInfo != colInfoList.end();
  2541. ++itColInfo)
  2542. {
  2543. if (! itColInfo->IsColHidden())
  2544. nVisibleColumns++;
  2545. }
  2546. int size = sizeof(MMC_VISIBLE_COLUMNS) + nVisibleColumns * sizeof(INT);
  2547. HGLOBAL hGlobal = ::GlobalAlloc(GPTR, size);
  2548. if (! hGlobal)
  2549. return E_OUTOFMEMORY;
  2550. MMC_VISIBLE_COLUMNS* pColData = reinterpret_cast<MMC_VISIBLE_COLUMNS*>(hGlobal);
  2551. pColData->nVisibleColumns = nVisibleColumns;
  2552. // Get the list of visible columns into MMC_VISIBLE_COLUMNS struct.
  2553. int i = 0;
  2554. for (itColInfo = colInfoList.begin(); itColInfo != colInfoList.end();
  2555. ++itColInfo)
  2556. {
  2557. if (! itColInfo->IsColHidden())
  2558. pColData->rgVisibleCols[i++] = itColInfo->GetColIndex();
  2559. }
  2560. LPARAM lParam = reinterpret_cast<LPARAM>(pColData);
  2561. hr = pCC->Notify(spDataObject, MMCN_COLUMNS_CHANGED, 0, lParam);
  2562. ::GlobalFree(hGlobal);
  2563. CHECK_HRESULT(hr);
  2564. if (FAILED(hr))
  2565. return hr;
  2566. return hr;
  2567. }
  2568. //+-------------------------------------------------------------------
  2569. //
  2570. // Member: ScSaveColumnInfoList
  2571. //
  2572. // Synopsis: Save the column data in internal data structures.
  2573. //
  2574. // Arguments: [colInfoList] - Columns data.
  2575. //
  2576. // Returns: SC
  2577. //
  2578. //--------------------------------------------------------------------
  2579. SC CNode::ScSaveColumnInfoList(CColumnInfoList& columnInfoList)
  2580. {
  2581. DECLARE_SC(sc, TEXT("CNode::ScSaveColumnInfoList"));
  2582. CViewData *pViewData = GetViewData();
  2583. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  2584. if (sc)
  2585. return sc;
  2586. CLSID clsidSnapin;
  2587. CXMLAutoBinary columnID;
  2588. sc = ScGetSnapinAndColumnDataID(clsidSnapin, columnID);
  2589. if (sc)
  2590. return sc;
  2591. CXMLBinaryLock sLock(columnID);
  2592. SColumnSetID* pColID = NULL;
  2593. sc = sLock.ScLock(&pColID);
  2594. if (sc)
  2595. return sc;
  2596. sc = ScCheckPointers(pColID, E_UNEXPECTED);
  2597. if (sc)
  2598. return sc;
  2599. sc = pViewData->ScSaveColumnInfoList(clsidSnapin, *pColID, columnInfoList);
  2600. if (sc)
  2601. return sc;
  2602. return sc;
  2603. }
  2604. //+-------------------------------------------------------------------
  2605. //
  2606. // Member: ScGetSnapinAndColumnDataID
  2607. //
  2608. // Synopsis: Returns the snapin guid & column-id in CXMLAutoBinary for this node.
  2609. //
  2610. // Arguments: [snapinGuid] - [out], snapin guid.
  2611. // [columnID] - [out], column-id in CXMLAutoBinary.
  2612. //
  2613. // Note: Pass in a CXMLAutoBinary object, will return column id in that object.
  2614. //
  2615. // Returns: SC
  2616. //
  2617. //--------------------------------------------------------------------
  2618. SC CNode::ScGetSnapinAndColumnDataID(GUID& snapinGuid, CXMLAutoBinary& columnID)
  2619. {
  2620. DECLARE_SC(sc, TEXT("CNode::ScGetSnapinAndColumnDataID"));
  2621. // Get Snapin Guid
  2622. snapinGuid = GetPrimarySnapInCLSID();
  2623. columnID.ScFree(); // clear any data.
  2624. IDataObjectPtr spDataObject;
  2625. sc = QueryDataObject(CCT_SCOPE, &spDataObject);
  2626. if (sc)
  2627. return sc;
  2628. HGLOBAL hGlobal;
  2629. sc = ExtractColumnConfigID(spDataObject, hGlobal);
  2630. if (! sc.IsError())
  2631. {
  2632. int cbSize = GlobalSize(hGlobal);
  2633. if (0 == cbSize)
  2634. return sc.FromLastError();
  2635. columnID.Attach(hGlobal, cbSize);
  2636. }
  2637. else
  2638. {
  2639. // Let us use the NodeTypeGUID as the Column Data Identifier
  2640. CLSID clsidColID;
  2641. sc = GetNodeType(&clsidColID);
  2642. if (sc)
  2643. return sc;
  2644. int cbSize = sizeof(SColumnSetID) + sizeof(CLSID) - 1;
  2645. sc = columnID.ScAlloc(cbSize, true);
  2646. if (sc)
  2647. return sc;
  2648. CXMLBinaryLock sLock(columnID);
  2649. SColumnSetID* pColID = NULL;
  2650. sc = sLock.ScLock(&pColID);
  2651. if (sc)
  2652. return sc;
  2653. sc = ScCheckPointers(pColID, E_UNEXPECTED);
  2654. if (sc)
  2655. return sc;
  2656. pColID->cBytes = sizeof(CLSID);
  2657. pColID->dwFlags = 0;
  2658. CopyMemory(pColID->id, (BYTE*)&clsidColID, pColID->cBytes);
  2659. }
  2660. return sc;
  2661. }
  2662. /*+-------------------------------------------------------------------------*
  2663. * class CViewExtensionCallback
  2664. *
  2665. *
  2666. * PURPOSE: Implements IViewExtensionCallback
  2667. *
  2668. *+-------------------------------------------------------------------------*/
  2669. class CViewExtensionCallback :
  2670. public CComObjectRoot,
  2671. public IViewExtensionCallback
  2672. {
  2673. public:
  2674. typedef CViewExtensionCallback ThisClass;
  2675. BEGIN_COM_MAP(ThisClass)
  2676. COM_INTERFACE_ENTRY(IViewExtensionCallback)
  2677. END_COM_MAP()
  2678. DECLARE_NOT_AGGREGATABLE(ThisClass)
  2679. IMPLEMENTS_SNAPIN_NAME_FOR_DEBUG()
  2680. CViewExtensionCallback() : m_pItExt(NULL) {}
  2681. SC ScInitialize(CViewExtInsertIterator & itExt)
  2682. {
  2683. DECLARE_SC(sc, TEXT("CViewExtensionCallback::ScInitialize"));
  2684. m_pItExt = &itExt;
  2685. return sc;
  2686. }
  2687. SC ScDeinitialize()
  2688. {
  2689. DECLARE_SC (sc, _T("CViewExtensionCallback::ScDeinitialize"));
  2690. m_pItExt = NULL;
  2691. return (sc);
  2692. }
  2693. public:
  2694. STDMETHODIMP AddView(PMMC_EXT_VIEW_DATA pExtViewData) {return ScAddView(pExtViewData).ToHr();}
  2695. private:
  2696. SC ScAddView(PMMC_EXT_VIEW_DATA pExtViewData)
  2697. {
  2698. DECLARE_SC(sc, TEXT("CViewExtensionCallback::ScAddView"));
  2699. sc = ScCheckPointers(pExtViewData, pExtViewData->pszURL, pExtViewData->pszViewTitle);
  2700. if(sc)
  2701. return sc; // TODO add snapin error
  2702. sc = ScCheckPointers(m_pItExt, E_UNEXPECTED);
  2703. if(sc)
  2704. return sc; // TODO add snapin error, e.g. "IExtendViewCallback::AddView called outside of IExtendView::GetViews"
  2705. /*
  2706. * prep the input to IConsoleView::ScAddViewExtension
  2707. */
  2708. CViewExtensionData ved;
  2709. ved.strURL = pExtViewData->pszURL;
  2710. ved.strName = pExtViewData->pszViewTitle;
  2711. ved.viewID = pExtViewData->viewID;
  2712. ved.bReplacesDefaultView = pExtViewData->bReplacesDefaultView;
  2713. /*
  2714. * std::basic_string's can't assign from NULL, so we have to check first
  2715. */
  2716. if (pExtViewData->pszTooltipText)
  2717. ved.strTooltip = pExtViewData->pszTooltipText;
  2718. /*
  2719. * validate output: URL and title are required, tooltip is optional
  2720. */
  2721. if (ved.strURL.empty())
  2722. {
  2723. TraceSnapinError(TEXT("Invalid parameter to IViewExtensionCallback::AddView (empty URL)"), E_INVALIDARG);
  2724. return (sc = E_INVALIDARG);
  2725. }
  2726. if (ved.strName.empty())
  2727. {
  2728. TraceSnapinError(TEXT("Invalid parameter to IViewExtensionCallback::AddView (empty title)"), E_INVALIDARG);
  2729. return (sc = E_INVALIDARG);
  2730. }
  2731. /*
  2732. * add the extension to the view
  2733. */
  2734. *(*m_pItExt)++ = ved;
  2735. return sc;
  2736. }
  2737. private:
  2738. CViewExtInsertIterator *m_pItExt;
  2739. };
  2740. /*+-------------------------------------------------------------------------*
  2741. * CNode::ScGetViewExtensions
  2742. *
  2743. *
  2744. *--------------------------------------------------------------------------*/
  2745. SC CNode::ScGetViewExtensions (CViewExtInsertIterator itExt)
  2746. {
  2747. DECLARE_SC (sc, _T("CNode::ScGetViewExtensions"));
  2748. IDataObjectPtr spDataObject;
  2749. bool bScopeItem ;
  2750. sc = ScGetDataObject(/*bScopePane*/ true, NULL /*lResultItemCookie*/, bScopeItem, &spDataObject);
  2751. if(sc)
  2752. return sc;
  2753. CSnapIn* pSnapIn = GetPrimarySnapIn();
  2754. sc = ScCheckPointers (pSnapIn, E_FAIL);
  2755. if (sc)
  2756. return (sc);
  2757. CArray<GUID, GUID&> DynExtens;
  2758. ExtractDynExtensions(spDataObject, DynExtens);
  2759. GUID guidNodeType;
  2760. sc = ::ExtractObjectTypeGUID(spDataObject, &guidNodeType);
  2761. if(sc)
  2762. return sc;
  2763. CExtensionsIterator it;
  2764. sc = it.ScInitialize(pSnapIn, guidNodeType, g_szView, DynExtens.GetData(), DynExtens.GetSize());
  2765. if(sc)
  2766. return sc;
  2767. typedef CComObject<CViewExtensionCallback> t_ViewExtensionCallback;
  2768. t_ViewExtensionCallback *pViewExtensionCallback = NULL;
  2769. sc = t_ViewExtensionCallback::CreateInstance(&pViewExtensionCallback);
  2770. if(sc)
  2771. return sc;
  2772. if(NULL == pViewExtensionCallback)
  2773. return (sc = E_UNEXPECTED);
  2774. sc = pViewExtensionCallback->ScInitialize(itExt);
  2775. if(sc)
  2776. return sc;
  2777. IViewExtensionCallbackPtr spViewExtensionCallback = pViewExtensionCallback;
  2778. // add all the console taskpads first
  2779. sc = CConsoleTaskpadViewExtension::ScGetViews(this, spViewExtensionCallback);
  2780. if(sc)
  2781. return sc;
  2782. for (; !it.IsEnd(); it.Advance())
  2783. {
  2784. // any errors in this block should just go on to the next snap-in. Can't let one snap-in
  2785. // hose all the others.
  2786. /*
  2787. * create the extension
  2788. */
  2789. IExtendViewPtr spExtendView;
  2790. sc = spExtendView.CreateInstance(it.GetCLSID(), NULL, MMC_CLSCTX_INPROC);
  2791. if(sc)
  2792. {
  2793. #ifdef DBG
  2794. USES_CONVERSION;
  2795. tstring strMsg = _T("Failed to create snapin ");
  2796. CCoTaskMemPtr<WCHAR> spszCLSID;
  2797. if (SUCCEEDED (StringFromCLSID (it.GetCLSID(), &spszCLSID)))
  2798. strMsg += W2T(spszCLSID);
  2799. TraceSnapinError(strMsg.data(), sc);
  2800. #endif
  2801. sc.Clear();
  2802. continue;
  2803. }
  2804. /*
  2805. * get the view extension data from the extension
  2806. */
  2807. sc = spExtendView->GetViews(spDataObject, spViewExtensionCallback);
  2808. if(sc)
  2809. {
  2810. TraceSnapinError(TEXT("Snapin returned error on call to IExtendView::GetView"), sc);
  2811. sc.Clear();
  2812. continue;
  2813. }
  2814. }
  2815. /*
  2816. * View extensions aren't supposed to hold onto IExtendViewCallback,
  2817. * but buggy view extensions might. This will neuter the callback
  2818. * so buggy view extensions won't reference stale data.
  2819. */
  2820. sc = pViewExtensionCallback->ScDeinitialize();
  2821. if (sc)
  2822. return (sc);
  2823. return (sc);
  2824. }
  2825. /*******************************************************\
  2826. | helper function to avoid too many stack allocations
  2827. \*******************************************************/
  2828. static std::wstring T2W_ForLoop(const tstring& str)
  2829. {
  2830. #if defined(_UNICODE)
  2831. return str;
  2832. #else
  2833. USES_CONVERSION;
  2834. return A2CW(str.c_str());
  2835. #endif
  2836. }
  2837. /***************************************************************************\
  2838. |
  2839. | Implementation of subclass CNode::CDataObjectCleanup
  2840. | Responsible for data object clenup
  2841. |
  2842. | Cleanup works by these rules:
  2843. |
  2844. | 1. Data object created for cut , copy or dragdrop registers every node added to it
  2845. | 2. Nodes are registered in the static multimap, mapping node to the data object it belongs to.
  2846. | 3. Node destructor checks the map and triggers cleanup for all affected data objects.
  2847. | 4. Data Object cleanup is: a) unregistering its nodes,
  2848. | b) release contained data objects
  2849. | b) entering invalid state (allowing only removal of cut objects to succeed)
  2850. | c) revoking itself from clipboard if it is on the clipboard.
  2851. | It will not do any of following: a) release references to IComponents as long as is alive
  2852. | b) prevent MMCN_CUTORMOVE to be send by invoking RemoveCutItems()
  2853. |
  2854. \***************************************************************************/
  2855. // declare static variable
  2856. CNode::CDataObjectCleanup::CMapOfNodes CNode::CDataObjectCleanup::s_mapOfNodes;
  2857. /***************************************************************************\
  2858. *
  2859. * METHOD: CNode::CDataObjectCleanup::ScRegisterNode
  2860. *
  2861. * PURPOSE: registers node to trigger clipboard clenup on destructor
  2862. *
  2863. * PARAMETERS:
  2864. * CNode *pNode [in] - node to register
  2865. * CMMCClipBoardDataObject *pObject [in] - data object to remove from clipboard
  2866. *
  2867. * RETURNS:
  2868. * SC - result code
  2869. *
  2870. \***************************************************************************/
  2871. SC CNode::CDataObjectCleanup::ScRegisterNode(CNode *pNode, CMMCClipBoardDataObject *pObject)
  2872. {
  2873. DECLARE_SC(sc, TEXT("CNode::CClipboardClenup::ScRegisterNode"));
  2874. // parameter check
  2875. sc = ScCheckPointers( pNode, pObject );
  2876. if (sc)
  2877. return sc;
  2878. // add to the multimap
  2879. s_mapOfNodes.insert( CMapOfNodes::value_type( pNode, pObject ) );
  2880. return sc;
  2881. }
  2882. /***************************************************************************\
  2883. *
  2884. * METHOD: CNode::CDataObjectCleanup::ScUnadviseDataObject
  2885. *
  2886. * PURPOSE: Removes nodes-'clenup triggers' kept for the object
  2887. *
  2888. * PARAMETERS:
  2889. * CMMCClipBoardDataObject *pObject [in] object going away
  2890. * bool bForceDataObjectCleanup [in] whether need to ask DO to clenup / unregister itself
  2891. *
  2892. * RETURNS:
  2893. * SC - result code
  2894. *
  2895. \***************************************************************************/
  2896. SC CNode::CDataObjectCleanup::ScUnadviseDataObject(CMMCClipBoardDataObject *pObject, bool bForceDataObjectCleanup /*= true*/)
  2897. {
  2898. DECLARE_SC(sc, TEXT("CNode::CDataObjectCleanup::ScUnadviseDataObject"));
  2899. // remove all nodes associated with the data object
  2900. CMapOfNodes::iterator it = s_mapOfNodes.begin();
  2901. while ( it != s_mapOfNodes.end() )
  2902. {
  2903. // remove or skip the entry
  2904. if ( it->second == pObject )
  2905. it = s_mapOfNodes.erase( it );
  2906. else
  2907. ++it;
  2908. }
  2909. // invalidate data object when required
  2910. if ( bForceDataObjectCleanup )
  2911. {
  2912. sc = pObject->ScInvalidate();
  2913. if (sc)
  2914. return sc;
  2915. }
  2916. return sc;
  2917. }
  2918. /***************************************************************************\
  2919. *
  2920. * METHOD: CNode::CDataObjectCleanup::ScUnadviseNode
  2921. *
  2922. * PURPOSE: Does data object claenup triggered by the node
  2923. *
  2924. * PARAMETERS:
  2925. * CNode *pNode [in] - node initiating cleanup
  2926. *
  2927. * RETURNS:
  2928. * SC - result code
  2929. *
  2930. \***************************************************************************/
  2931. SC CNode::CDataObjectCleanup::ScUnadviseNode(CNode *pNode)
  2932. {
  2933. DECLARE_SC(sc, TEXT("CNode::CClipboardClenup::ScUnadviseNode"));
  2934. // parameter check
  2935. sc = ScCheckPointers(pNode);
  2936. if (sc)
  2937. return sc;
  2938. // find the node in the map
  2939. CMapOfNodes::iterator it;
  2940. while ( s_mapOfNodes.end() != ( it = s_mapOfNodes.find(pNode) ) )
  2941. {
  2942. // one node triggers clenup for whole data object
  2943. sc = ScUnadviseDataObject( it->second );
  2944. if (sc)
  2945. return sc;
  2946. }
  2947. return sc;
  2948. }
  2949. //############################################################################
  2950. //############################################################################
  2951. //
  2952. // Implementation of class CSnapInNode
  2953. //
  2954. //############################################################################
  2955. //############################################################################
  2956. DEBUG_DECLARE_INSTANCE_COUNTER(CSnapInNode);
  2957. CSnapInNode::CSnapInNode(
  2958. CMTSnapInNode* pMTNode,
  2959. CViewData* pViewData,
  2960. bool fRootNode)
  2961. : CNode(pMTNode, pViewData, fRootNode, true)
  2962. {
  2963. m_spData.CreateInstance();
  2964. ASSERT(pMTNode != NULL);
  2965. DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapInNode);
  2966. pMTNode->AddNode(this);
  2967. }
  2968. CSnapInNode::CSnapInNode(const CSnapInNode& other) :
  2969. CNode (other),
  2970. m_spData (other.m_spData)
  2971. {
  2972. DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapInNode);
  2973. }
  2974. void CSnapInNode::Reset()
  2975. {
  2976. m_spData->Reset();
  2977. ResetFlags();
  2978. CNode::Reset();
  2979. }
  2980. CSnapInNode::~CSnapInNode()
  2981. {
  2982. DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapInNode);
  2983. CMTSnapInNode* pMTSINode = dynamic_cast<CMTSnapInNode*>(GetMTNode());
  2984. ASSERT(pMTSINode != NULL);
  2985. if (pMTSINode)
  2986. pMTSINode->RemoveNode(this);
  2987. }
  2988. void CSnapInNode::AddComponentToArray(CComponent* pCC)
  2989. {
  2990. ASSERT((pCC->GetComponentID() >= GetComponentArray().size()) ||
  2991. (GetComponentArray().size() > 0) &&
  2992. (GetComponentArray()[pCC->GetComponentID()] == NULL));
  2993. if (pCC->GetComponentID() >= GetComponentArray().size())
  2994. GetComponentArray().resize(pCC->GetComponentID() + 1);
  2995. GetComponentArray()[pCC->GetComponentID()] = pCC;
  2996. }
  2997. CComponent* CSnapInNode::CreateComponent(CSnapIn* pSnapIn, int nID)
  2998. {
  2999. ASSERT(pSnapIn != NULL);
  3000. CComponent* pCC = new CComponent(pSnapIn);
  3001. if ( pCC != NULL )
  3002. {
  3003. pCC->SetComponentID(nID);
  3004. AddComponentToArray(pCC);
  3005. }
  3006. return pCC;
  3007. }
  3008. //+-------------------------------------------------------------------
  3009. //
  3010. // Member: CSnapInNode::GetResultImage
  3011. //
  3012. // Synopsis: Get the image-index in result-image list for this node.
  3013. //
  3014. // Note: The CSnapInNode member ImageListPrivate is not set all
  3015. // the time (if the window is rooted at snapin node), so
  3016. // set it temporarily when we need the icon index.
  3017. // The member is set while adding sub-folders
  3018. // The only other case this will affect is when called for
  3019. // the image index for static snapin nodes displayed in result-pane.
  3020. // But when static snapin nodes are displayed in result-pane the
  3021. // AddSubFolders added it so the imagelist is already set.
  3022. //
  3023. // Arguments:
  3024. //
  3025. // Returns: Image index for this item in result-pane.
  3026. //
  3027. //--------------------------------------------------------------------
  3028. UINT CSnapInNode::GetResultImage()
  3029. {
  3030. IImageListPrivate *pImageList = GetImageList();
  3031. if (!pImageList)
  3032. {
  3033. CComponent *pCC = GetPrimaryComponent();
  3034. if (pCC)
  3035. pImageList = pCC->GetIImageListPrivate();
  3036. }
  3037. CMTSnapInNode* pMTSnapInNode = dynamic_cast<CMTSnapInNode*>(GetMTNode());
  3038. if (pMTSnapInNode)
  3039. return pMTSnapInNode->GetResultImage ((CNode*)this, pImageList);
  3040. return CNode::GetResultImage();
  3041. }
  3042. /*+-------------------------------------------------------------------------*
  3043. *
  3044. * CSnapInNode::GetControl
  3045. *
  3046. * PURPOSE: Given the CLSID of the OCX, see if we have stored this
  3047. * OCX, if so return the OCXWrapper's IUnknown ptr.
  3048. *
  3049. * PARAMETERS:
  3050. * CLSID clsid: class-id of the OCX.
  3051. *
  3052. * RETURNS:
  3053. * LPUNKNOWN of wrapper OCX.
  3054. *
  3055. *+-------------------------------------------------------------------------*/
  3056. LPUNKNOWN CSnapInNode::GetControl(CLSID& clsid)
  3057. {
  3058. for (int i=0; i <= GetOCXArray().GetUpperBound(); i++)
  3059. {
  3060. if (GetOCXArray()[i].IsControlCLSID(clsid) == TRUE)
  3061. return GetOCXArray()[i].GetControlUnknown();
  3062. }
  3063. return NULL;
  3064. }
  3065. /*+-------------------------------------------------------------------------*
  3066. *
  3067. * CSnapInNode::SetControl
  3068. *
  3069. * PURPOSE: Given the CLSID of the OCX and of the wrapper.
  3070. *
  3071. * PARAMETERS:
  3072. * CLSID clsid : of a OCX.
  3073. * IUnknown *pUnknown: of OCX wrapper.
  3074. *
  3075. * RETURNS:
  3076. * void
  3077. *
  3078. *+-------------------------------------------------------------------------*/
  3079. void CSnapInNode::SetControl(CLSID& clsid, IUnknown* pUnknown)
  3080. {
  3081. // check for slot in cache
  3082. int iLast = GetOCXArray().GetUpperBound();
  3083. for (int i=0; i <= iLast; i++)
  3084. {
  3085. if (GetOCXArray()[i].IsControlCLSID(clsid) == TRUE)
  3086. break;
  3087. }
  3088. // if not in cache, add one more entry
  3089. if (i > iLast)
  3090. GetOCXArray().SetSize(i + 1);
  3091. GetOCXArray()[i].SetControl(clsid, pUnknown);
  3092. }
  3093. /*+-------------------------------------------------------------------------*
  3094. *
  3095. * CSnapInNode::GetControl
  3096. *
  3097. * PURPOSE: Given the IUnknown of the OCX, see if we have stored this
  3098. * OCX, if so return the OCXWrapper's IUnknown ptr.
  3099. *
  3100. * PARAMETERS:
  3101. * IUnknown *pUnkOCX : of a OCX.
  3102. *
  3103. * RETURNS:
  3104. * LPUNKNOWN of wrapper OCX.
  3105. *
  3106. *+-------------------------------------------------------------------------*/
  3107. LPUNKNOWN CSnapInNode::GetControl(LPUNKNOWN pUnkOCX)
  3108. {
  3109. for (int i=0; i <= GetOCXArray().GetUpperBound(); i++)
  3110. {
  3111. // Compare IUnknowns.
  3112. if (GetOCXArray()[i].IsSameOCXIUnknowns(pUnkOCX) == TRUE)
  3113. return GetOCXArray()[i].GetControlUnknown();
  3114. }
  3115. return NULL;
  3116. }
  3117. /*+-------------------------------------------------------------------------*
  3118. *
  3119. * CSnapInNode::SetControl
  3120. *
  3121. * PURPOSE: Given the IUnknown of the OCX and of the wrapper.
  3122. *
  3123. * PARAMETERS:
  3124. * IUnknown *pUnkOCX : of a OCX.
  3125. * IUnknown *pUnknown: of OCX wrapper.
  3126. *
  3127. * RETURNS:
  3128. * void
  3129. *
  3130. *+-------------------------------------------------------------------------*/
  3131. void CSnapInNode::SetControl(LPUNKNOWN pUnkOCX, IUnknown* pUnknown)
  3132. {
  3133. // check for slot in cache
  3134. int iLast = GetOCXArray().GetUpperBound();
  3135. for (int i=0; i <= iLast; i++)
  3136. {
  3137. if (GetOCXArray()[i].IsSameOCXIUnknowns(pUnkOCX) == TRUE)
  3138. break; // found the OCX, so replace with given OCXwrapper.
  3139. }
  3140. // if not in cache, add one more entry
  3141. if (i > iLast)
  3142. GetOCXArray().SetSize(i + 1);
  3143. GetOCXArray()[i].SetControl(pUnkOCX, pUnknown);
  3144. }
  3145. //+-------------------------------------------------------------------
  3146. //
  3147. // Member: CNode::ScGetConsoleTaskpad
  3148. //
  3149. // Synopsis: Get the console taskpad identified by given GUID for this node.
  3150. //
  3151. // Arguments: [guidTaskpad] - [in param]
  3152. // [ppTaskpad] - [out param]
  3153. //
  3154. // Returns: SC, S_FALSE if none exists
  3155. //
  3156. //--------------------------------------------------------------------
  3157. SC CNode::ScGetConsoleTaskpad (const GUID& guidTaskpad, CConsoleTaskpad **ppTaskpad)
  3158. {
  3159. DECLARE_SC(sc, _T("CNode::ScGetConsoleTaskpad"));
  3160. sc = ScCheckPointers(ppTaskpad);
  3161. if (sc)
  3162. return sc;
  3163. *ppTaskpad = NULL;
  3164. CScopeTree* pScopeTree = CScopeTree::GetScopeTree();
  3165. sc = ScCheckPointers(pScopeTree, E_UNEXPECTED);
  3166. if(sc)
  3167. return sc;
  3168. CConsoleTaskpadList *pConsoleTaskpadList = pScopeTree->GetConsoleTaskpadList();
  3169. sc = ScCheckPointers(pConsoleTaskpadList, E_UNEXPECTED);
  3170. if (sc)
  3171. return sc;
  3172. // get a filtered list of taskpads that apply to this node.
  3173. CConsoleTaskpadFilteredList filteredList;
  3174. sc = pConsoleTaskpadList->ScGetTaskpadList(this, filteredList);
  3175. if(sc)
  3176. return sc;
  3177. for(CConsoleTaskpadFilteredList::iterator iter = filteredList.begin(); iter!= filteredList.end(); ++iter)
  3178. {
  3179. CConsoleTaskpad *pTaskpad = *iter;
  3180. sc = ScCheckPointers(pTaskpad, E_UNEXPECTED);
  3181. if (sc)
  3182. return sc;
  3183. if (pTaskpad->GetID() == guidTaskpad)
  3184. {
  3185. *ppTaskpad = pTaskpad;
  3186. return sc; // found
  3187. }
  3188. }
  3189. return (sc = S_FALSE); // not found
  3190. }
  3191. /*************************************************************************
  3192. *
  3193. * There is only one CViewSettingsPersistor object per document.
  3194. *
  3195. * The object stored as static variable inside CNode as CNode needs
  3196. * to access this object frequently.
  3197. *
  3198. * The Document needs to initialize/save the object by loading/savind
  3199. * from/to console file. It calls below ScQueryViewSettingsPersistor.
  3200. *
  3201. * The object is created with first call to ScQueryViewSettingsPersistor.
  3202. * The object is destroyed when DocumentClosed event is received.
  3203. *
  3204. *************************************************************************/
  3205. CComObject<CViewSettingsPersistor>* CNode::m_pViewSettingsPersistor = NULL;
  3206. //+-------------------------------------------------------------------
  3207. //
  3208. // Member: CNode::ScQueryViewSettingsPersistor
  3209. //
  3210. // Synopsis: Static method to get IPersistStream to load CViewSettingsPersistor
  3211. // object from old style console file.
  3212. //
  3213. // If the CViewSettingsObject is not created then create one.
  3214. //
  3215. // Arguments: [ppStream] - [out]
  3216. //
  3217. // Returns: SC
  3218. //
  3219. //--------------------------------------------------------------------
  3220. SC CNode::ScQueryViewSettingsPersistor (IPersistStream **ppStream)
  3221. {
  3222. DECLARE_SC(sc, _T("CNode::ScQueryViewSettingsPersistor"));
  3223. sc = ScCheckPointers(ppStream);
  3224. if (sc)
  3225. return sc;
  3226. // Create new CViewSettingsPersistor if none exists
  3227. if (NULL == m_pViewSettingsPersistor)
  3228. {
  3229. sc = CComObject<CViewSettingsPersistor>::CreateInstance (&m_pViewSettingsPersistor);
  3230. if (sc)
  3231. goto ObjectCreationFailed;
  3232. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3233. if (sc)
  3234. goto ObjectCreationFailed;
  3235. m_pViewSettingsPersistor->AddRef();
  3236. }
  3237. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3238. if (sc)
  3239. goto ObjectCreationFailed;
  3240. *ppStream = static_cast<IPersistStream*>(m_pViewSettingsPersistor);
  3241. if (NULL == *ppStream)
  3242. return (sc = E_UNEXPECTED);
  3243. (*ppStream)->AddRef();
  3244. Cleanup:
  3245. return (sc);
  3246. ObjectCreationFailed:
  3247. CStr strMsg;
  3248. strMsg.LoadString(GetStringModule(), IDS_ViewSettingCouldNotBePersisted);
  3249. ::MessageBox(NULL, strMsg, NULL, MB_OK|MB_SYSTEMMODAL);
  3250. goto Cleanup;
  3251. }
  3252. //+-------------------------------------------------------------------
  3253. //
  3254. // Member: CNode::ScQueryViewSettingsPersistor
  3255. //
  3256. // Synopsis: Static method to get CXMLObject to load or save
  3257. // CViewSettingsPersistor object from XML console file.
  3258. //
  3259. // If the CViewSettingsObject is not created then create one.
  3260. //
  3261. // Arguments: [ppXMLObject] - [out]
  3262. //
  3263. // Returns: SC
  3264. //
  3265. //--------------------------------------------------------------------
  3266. SC CNode::ScQueryViewSettingsPersistor (CXMLObject **ppXMLObject)
  3267. {
  3268. DECLARE_SC(sc, _T("CNode::ScQueryViewSettingsPersistor"));
  3269. sc = ScCheckPointers(ppXMLObject);
  3270. if (sc)
  3271. return sc;
  3272. // Create new CViewSettingsPersistor if none exists
  3273. if (NULL == m_pViewSettingsPersistor) // Create new one
  3274. {
  3275. sc = CComObject<CViewSettingsPersistor>::CreateInstance (&m_pViewSettingsPersistor);
  3276. if (sc)
  3277. goto ObjectCreationFailed;
  3278. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3279. if (sc)
  3280. goto ObjectCreationFailed;
  3281. m_pViewSettingsPersistor->AddRef();
  3282. }
  3283. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3284. if (sc)
  3285. goto ObjectCreationFailed;
  3286. *ppXMLObject = static_cast<CXMLObject*>(m_pViewSettingsPersistor);
  3287. if (NULL == *ppXMLObject)
  3288. return (sc = E_UNEXPECTED);
  3289. Cleanup:
  3290. return (sc);
  3291. ObjectCreationFailed:
  3292. CStr strMsg;
  3293. strMsg.LoadString(GetStringModule(), IDS_ViewSettingCouldNotBePersisted);
  3294. ::MessageBox(NULL, strMsg, NULL, MB_OK|MB_SYSTEMMODAL);
  3295. goto Cleanup;
  3296. return (sc);
  3297. }
  3298. //+-------------------------------------------------------------------
  3299. //
  3300. // Member: CNode::ScDeleteViewSettings
  3301. //
  3302. // Synopsis: Delete the CViewSettings object for given view-id as the
  3303. // view is being closed.
  3304. //
  3305. // Arguments: [nViewID] -
  3306. //
  3307. // Returns: SC
  3308. //
  3309. //--------------------------------------------------------------------
  3310. SC CNode::ScDeleteViewSettings (int nViewID)
  3311. {
  3312. DECLARE_SC(sc, _T("CNode::ScDeleteViewSettings"));
  3313. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3314. if (sc)
  3315. return sc;
  3316. sc = m_pViewSettingsPersistor->ScDeleteDataOfView(nViewID);
  3317. if (sc)
  3318. return sc;
  3319. return (sc);
  3320. }
  3321. //+-------------------------------------------------------------------
  3322. //
  3323. // Member: CNode::ScOnDocumentClosing
  3324. //
  3325. // Synopsis: The document is closing, destroy any document related
  3326. // objects like CViewSettingsPersistor.
  3327. //
  3328. // Arguments: None
  3329. //
  3330. // Returns: SC
  3331. //
  3332. //--------------------------------------------------------------------
  3333. SC CNode::ScOnDocumentClosing ()
  3334. {
  3335. DECLARE_SC(sc, _T("CNode::ScOnDocumentClosing"));
  3336. if (m_pViewSettingsPersistor)
  3337. {
  3338. m_pViewSettingsPersistor->Release();
  3339. m_pViewSettingsPersistor = NULL;
  3340. }
  3341. return (sc);
  3342. }
  3343. //+-------------------------------------------------------------------
  3344. //
  3345. // Member: CNode::ScSetFavoriteViewSettings
  3346. //
  3347. // Synopsis: A favorite is selected and it sets viewsettings
  3348. // before re-selecting the node so that after re-selection
  3349. // the new settings are set for the view.
  3350. //
  3351. // Arguments: [nViewID] -
  3352. // [bookmark] -
  3353. // [viewSettings] -
  3354. //
  3355. // Returns: SC
  3356. //
  3357. //--------------------------------------------------------------------
  3358. SC CNode::ScSetFavoriteViewSettings (int nViewID, const CBookmark& bookmark,
  3359. const CViewSettings& viewSettings)
  3360. {
  3361. DECLARE_SC(sc, _T("CNode::ScSetFavoriteViewSettings"));
  3362. sc = ScCheckPointers(m_pViewSettingsPersistor, E_UNEXPECTED);
  3363. if (sc)
  3364. return sc;
  3365. sc = m_pViewSettingsPersistor->ScSetFavoriteViewSettings (nViewID, bookmark, viewSettings);
  3366. if (sc)
  3367. return sc;
  3368. return (sc);
  3369. }
  3370. //+-------------------------------------------------------------------
  3371. //
  3372. // Member: CNode::ScGetViewMode
  3373. //
  3374. // Synopsis: Get the viewmode if any persisted for this node.
  3375. //
  3376. // Arguments: [ulViewMode] - [out]
  3377. //
  3378. // Returns: SC, S_FALSE if none persisted.
  3379. //
  3380. //--------------------------------------------------------------------
  3381. SC CNode::ScGetViewMode (ULONG& ulViewMode)
  3382. {
  3383. DECLARE_SC(sc, _T("CNode::ScGetViewMode"));
  3384. CMTNode *pMTNode = GetMTNode();
  3385. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3386. if (sc)
  3387. return sc;
  3388. CBookmark *pBookmark = pMTNode->GetBookmark();
  3389. CViewData *pViewData = GetViewData();
  3390. sc = ScCheckPointers(m_pViewSettingsPersistor, pBookmark, pViewData, E_UNEXPECTED);
  3391. if (sc)
  3392. return sc;
  3393. sc = m_pViewSettingsPersistor->ScGetViewMode (pViewData->GetViewID(),
  3394. *pBookmark,
  3395. ulViewMode);
  3396. if (sc)
  3397. return sc;
  3398. return (sc);
  3399. }
  3400. //+-------------------------------------------------------------------
  3401. //
  3402. // Member: CNode::ScSetViewMode
  3403. //
  3404. // Synopsis: Set the viewmode in persisted viewsettings.
  3405. //
  3406. // Arguments: [ulViewMode] - [in]
  3407. //
  3408. // Returns: SC
  3409. //
  3410. //--------------------------------------------------------------------
  3411. SC CNode::ScSetViewMode (ULONG ulViewMode)
  3412. {
  3413. DECLARE_SC(sc, _T("CNode::ScSetViewMode"));
  3414. CMTNode *pMTNode = GetMTNode();
  3415. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3416. if (sc)
  3417. return sc;
  3418. CBookmark *pBookmark = pMTNode->GetBookmark();
  3419. CViewData *pViewData = GetViewData();
  3420. sc = ScCheckPointers(m_pViewSettingsPersistor, pBookmark, pViewData, E_UNEXPECTED);
  3421. if (sc)
  3422. return sc;
  3423. sc = m_pViewSettingsPersistor->ScSetViewMode (pViewData->GetViewID(),
  3424. *pBookmark,
  3425. ulViewMode);
  3426. if (sc)
  3427. return sc;
  3428. return (sc);
  3429. }
  3430. //+-------------------------------------------------------------------
  3431. //
  3432. // Member: CNode::ScGetResultViewType
  3433. //
  3434. // Synopsis: Get the CResultViewType if any persisted for this node.
  3435. //
  3436. // Arguments: [rvt] - [out]
  3437. //
  3438. // Returns: SC, S_FALSE if none persisted.
  3439. //
  3440. //--------------------------------------------------------------------
  3441. SC CNode::ScGetResultViewType (CResultViewType& rvt)
  3442. {
  3443. DECLARE_SC(sc, _T("CNode::ScGetResultViewType"));
  3444. CMTNode *pMTNode = GetMTNode();
  3445. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3446. if (sc)
  3447. return sc;
  3448. CBookmark *pBookmark = pMTNode->GetBookmark();
  3449. CViewData *pViewData = GetViewData();
  3450. sc = ScCheckPointers(m_pViewSettingsPersistor, pBookmark, pViewData, E_UNEXPECTED);
  3451. if (sc)
  3452. return sc;
  3453. sc = m_pViewSettingsPersistor->ScGetResultViewType (pViewData->GetViewID(),
  3454. *pBookmark,
  3455. rvt);
  3456. if (sc)
  3457. return sc;
  3458. return (sc);
  3459. }
  3460. //+-------------------------------------------------------------------
  3461. //
  3462. // Member: CNode::ScSetResultViewType
  3463. //
  3464. // Synopsis: Set the CResultViewType in persisted viewsettings.
  3465. //
  3466. // Arguments: [rvt] - [in]
  3467. //
  3468. // Returns: SC
  3469. //
  3470. //--------------------------------------------------------------------
  3471. SC CNode::ScSetResultViewType (const CResultViewType& rvt)
  3472. {
  3473. DECLARE_SC(sc, _T("CNode::ScSetResultViewType"));
  3474. CMTNode *pMTNode = GetMTNode();
  3475. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3476. if (sc)
  3477. return sc;
  3478. CBookmark *pBookmark = pMTNode->GetBookmark();
  3479. CViewData *pViewData = GetViewData();
  3480. sc = ScCheckPointers(m_pViewSettingsPersistor, pBookmark, pViewData, E_UNEXPECTED);
  3481. if (sc)
  3482. return sc;
  3483. sc = m_pViewSettingsPersistor->ScSetResultViewType (pViewData->GetViewID(),
  3484. *pBookmark,
  3485. rvt);
  3486. if (sc)
  3487. return sc;
  3488. return (sc);
  3489. }
  3490. //+-------------------------------------------------------------------
  3491. //
  3492. // Member: CNode::ScGetTaskpadID
  3493. //
  3494. // Synopsis: Get the taskpad-id if any persisted for this node.
  3495. // First see if there are any node-specific taskpad-id
  3496. // else get the node-type-specific setting if one exists.
  3497. //
  3498. // Arguments: [rvt] - [out]
  3499. //
  3500. // Returns: SC, S_FALSE if none persisted.
  3501. //
  3502. //--------------------------------------------------------------------
  3503. SC CNode::ScGetTaskpadID (GUID& guidTaskpad)
  3504. {
  3505. DECLARE_SC(sc, _T("CNode::ScGetTaskpadID"));
  3506. CMTNode *pMTNode = GetMTNode();
  3507. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3508. if (sc)
  3509. return sc;
  3510. CViewData *pViewData = GetViewData();
  3511. CBookmark *pBookmark = pMTNode->GetBookmark();
  3512. sc = ScCheckPointers(m_pViewSettingsPersistor, pViewData, pBookmark, E_UNEXPECTED);
  3513. if (sc)
  3514. return sc;
  3515. // 1. Try to get node-specific taskpad-id
  3516. sc = m_pViewSettingsPersistor->ScGetTaskpadID (pViewData->GetViewID(),
  3517. *pBookmark,
  3518. guidTaskpad);
  3519. if (sc == S_OK)
  3520. return sc;
  3521. // 2. Try to get nodetype specific taskpad-id.
  3522. GUID guidNodeType;
  3523. sc = pMTNode->GetNodeType(&guidNodeType);
  3524. if (sc)
  3525. return sc;
  3526. sc = m_pViewSettingsPersistor->ScGetTaskpadID(pViewData->GetViewID(),
  3527. guidNodeType,
  3528. guidTaskpad);
  3529. if (sc)
  3530. return sc;
  3531. return (sc);
  3532. }
  3533. //+-------------------------------------------------------------------
  3534. //
  3535. // Member: CNode::ScSetTaskpadID
  3536. //
  3537. // Synopsis: Set the taskpad-id in persisted viewsettings. Also see if
  3538. // the taskpad is node-specific or nodetype-specific and persist
  3539. // accordingly.
  3540. //
  3541. // Arguments: [guidTaskpad] - [in]
  3542. // [bSetDirty] - [in], set the console file dirty.
  3543. //
  3544. // Returns: SC
  3545. //
  3546. //--------------------------------------------------------------------
  3547. SC CNode::ScSetTaskpadID (const GUID& guidTaskpad, bool bSetDirty)
  3548. {
  3549. DECLARE_SC(sc, _T("CNode::ScSetTaskpadID"));
  3550. CMTNode *pMTNode = GetMTNode();
  3551. sc = ScCheckPointers(pMTNode, E_UNEXPECTED);
  3552. if (sc)
  3553. return sc;
  3554. CViewData *pViewData = GetViewData();
  3555. sc = ScCheckPointers(m_pViewSettingsPersistor, pViewData, E_UNEXPECTED);
  3556. if (sc)
  3557. return sc;
  3558. // Need to know if this task-pad is nodespecific or not.
  3559. bool bNodeSpecific = false;
  3560. CConsoleTaskpad *pTaskpad = NULL;
  3561. sc = ScGetConsoleTaskpad (guidTaskpad, &pTaskpad);
  3562. if (sc == S_OK) // S_OK if taskpad exists
  3563. {
  3564. sc = ScCheckPointers(pTaskpad, E_UNEXPECTED);
  3565. if (sc)
  3566. return sc;
  3567. bNodeSpecific = pTaskpad->IsNodeSpecific();
  3568. }
  3569. // else it may be viewextension or normal view (which are nodetype-specific).
  3570. CBookmark *pBookmark = pMTNode->GetBookmark();
  3571. sc = ScCheckPointers(pBookmark, E_UNEXPECTED);
  3572. if (sc)
  3573. return sc;
  3574. if (bNodeSpecific)
  3575. {
  3576. // Per node taskpad
  3577. sc = m_pViewSettingsPersistor->ScSetTaskpadID (pViewData->GetViewID(),
  3578. *pBookmark,
  3579. guidTaskpad,
  3580. bSetDirty);
  3581. }
  3582. else
  3583. {
  3584. // Per nodetype taskpad.
  3585. GUID guidNodeType;
  3586. sc = pMTNode->GetNodeType(&guidNodeType);
  3587. if (sc)
  3588. return sc;
  3589. sc = m_pViewSettingsPersistor->ScSetTaskpadID(pViewData->GetViewID(),
  3590. guidNodeType,
  3591. *pBookmark,
  3592. guidTaskpad,
  3593. bSetDirty);
  3594. }
  3595. if (sc)
  3596. return sc;
  3597. return (sc);
  3598. }