Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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