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.

1749 lines
45 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. tfsnode.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "util.h"
  11. #include "tfsnode.h"
  12. DEBUG_DECLARE_INSTANCE_COUNTER(TFSNodeEnum);
  13. /*!--------------------------------------------------------------------------
  14. TFSNodeEnum::TFSNodeEnum
  15. -
  16. Author: EricDav
  17. ---------------------------------------------------------------------------*/
  18. TFSNodeEnum::TFSNodeEnum(TFSContainer * pContainer)
  19. : m_cRef(1)
  20. {
  21. DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNodeEnum);
  22. Assert(pContainer->IsContainer());
  23. pContainer->AddRef();
  24. m_pNode = pContainer;
  25. Reset();
  26. }
  27. TFSNodeEnum::~TFSNodeEnum()
  28. {
  29. DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNodeEnum);
  30. m_pNode->Release();
  31. m_pNode = NULL;
  32. }
  33. IMPLEMENT_ADDREF_RELEASE(TFSNodeEnum)
  34. /*!--------------------------------------------------------------------------
  35. TFSNodeEnum::QueryInterface
  36. -
  37. Author: EricDav
  38. ---------------------------------------------------------------------------*/
  39. STDMETHODIMP TFSNodeEnum::QueryInterface(REFIID riid, LPVOID *ppv)
  40. {
  41. // Is the pointer bad?
  42. if (ppv == NULL)
  43. return E_INVALIDARG;
  44. // Place NULL in *ppv in case of failure
  45. *ppv = NULL;
  46. // This is the non-delegating IUnknown implementation
  47. if (riid == IID_IUnknown || riid == IID_ITFSNodeEnum)
  48. *ppv = (LPVOID) this;
  49. // If we're going to return an interface, AddRef it first
  50. if (*ppv)
  51. {
  52. ((LPUNKNOWN) *ppv)->AddRef();
  53. return hrOK;
  54. }
  55. else
  56. return E_NOINTERFACE;
  57. }
  58. /*!--------------------------------------------------------------------------
  59. TFSNodeEnum::Next
  60. We always return one node
  61. Author: EricDav
  62. ---------------------------------------------------------------------------*/
  63. STDMETHODIMP
  64. TFSNodeEnum::Next
  65. (
  66. ULONG uNum,
  67. ITFSNode ** ppNode,
  68. ULONG * pNumReturned
  69. )
  70. {
  71. HRESULT hr = hrFalse;
  72. ULONG nNumReturned = 0;
  73. ITFSNode * pNode;
  74. COM_PROTECT_TRY
  75. {
  76. if (ppNode)
  77. *ppNode = NULL;
  78. if ((m_pNode->IsContainer()) && (uNum >= 1) && (m_pos != NULL))
  79. {
  80. while (m_pos)
  81. {
  82. pNode = m_pNode->m_listChildren.GetNext(m_pos);
  83. if (pNode &&
  84. ((pNode->GetVisibilityState() & TFS_VIS_DELETE) == 0))
  85. {
  86. *ppNode = pNode;
  87. break;
  88. }
  89. }
  90. if (*ppNode)
  91. {
  92. ((LPUNKNOWN)*ppNode)->AddRef();
  93. nNumReturned = 1;
  94. hr = S_OK;
  95. }
  96. }
  97. else
  98. {
  99. nNumReturned = 0;
  100. hr = S_FALSE;
  101. }
  102. if (pNumReturned)
  103. *pNumReturned = nNumReturned;
  104. }
  105. COM_PROTECT_CATCH
  106. if (FHrFailed(hr))
  107. {
  108. if (pNumReturned)
  109. *pNumReturned = 0;
  110. *ppNode = NULL;
  111. }
  112. return hr;
  113. }
  114. /*!--------------------------------------------------------------------------
  115. TFSNodeEnum::Skip
  116. -
  117. Author: EricDav
  118. ---------------------------------------------------------------------------*/
  119. STDMETHODIMP
  120. TFSNodeEnum::Skip
  121. (
  122. ULONG uNum
  123. )
  124. {
  125. return E_NOTIMPL;
  126. }
  127. /*!--------------------------------------------------------------------------
  128. TFSNodeEnum::Reset
  129. -
  130. Author: EricDav
  131. ---------------------------------------------------------------------------*/
  132. STDMETHODIMP
  133. TFSNodeEnum::Reset()
  134. {
  135. m_pos = m_pNode->m_listChildren.GetHeadPosition();
  136. return S_OK;
  137. }
  138. /*!--------------------------------------------------------------------------
  139. TFSNodeEnum::Clone
  140. -
  141. Author: EricDav
  142. ---------------------------------------------------------------------------*/
  143. STDMETHODIMP
  144. TFSNodeEnum::Clone
  145. (
  146. ITFSNodeEnum **ppEnum
  147. )
  148. {
  149. return E_NOTIMPL;
  150. }
  151. DEBUG_DECLARE_INSTANCE_COUNTER(TFSNode);
  152. /*!--------------------------------------------------------------------------
  153. TFSNode::TFSNode
  154. -
  155. Author: KennT
  156. ---------------------------------------------------------------------------*/
  157. TFSNode::TFSNode()
  158. : m_cRef(1),
  159. m_cPropSheet(0),
  160. m_pNodeType(NULL),
  161. m_uData(0),
  162. m_cookie(0),
  163. m_tfsVis(TFS_VIS_SHOW),
  164. m_fContainer(0),
  165. m_nImageIndex(0),
  166. m_nOpenImageIndex(0),
  167. m_lParam(0),
  168. m_fDirty(0),
  169. m_hScopeItem(0),
  170. m_hRelativeId(0),
  171. m_ulRelativeFlags(0),
  172. m_fScopeLeafNode(FALSE)
  173. {
  174. DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNode);
  175. IfDebug(m_bCookieSet=FALSE);
  176. }
  177. /*!--------------------------------------------------------------------------
  178. TFSNode::~TFSNode
  179. -
  180. Author: KennT
  181. ---------------------------------------------------------------------------*/
  182. TFSNode::~TFSNode()
  183. {
  184. DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNode);
  185. Assert(m_cPropSheet == 0);
  186. Assert(m_cRef == 0);
  187. }
  188. IMPLEMENT_ADDREF_RELEASE(TFSNode)
  189. /*!--------------------------------------------------------------------------
  190. TFSNode::QueryInterface
  191. -
  192. Author: KennT
  193. ---------------------------------------------------------------------------*/
  194. STDMETHODIMP TFSNode::QueryInterface(REFIID riid, LPVOID *ppv)
  195. {
  196. // Is the pointer bad?
  197. if (ppv == NULL)
  198. return E_INVALIDARG;
  199. // Place NULL in *ppv in case of failure
  200. *ppv = NULL;
  201. // This is the non-delegating IUnknown implementation
  202. if (riid == IID_IUnknown || riid == IID_ITFSNode)
  203. *ppv = (LPVOID) this;
  204. // If we're going to return an interface, AddRef it first
  205. if (*ppv)
  206. {
  207. ((LPUNKNOWN) *ppv)->AddRef();
  208. return hrOK;
  209. }
  210. else
  211. return E_NOINTERFACE;
  212. }
  213. /*!--------------------------------------------------------------------------
  214. TFSNode::Construct
  215. The pNodeType parameter must stay around for the lifetime of
  216. the node, we do not make a copy of it!
  217. Author: KennT
  218. ---------------------------------------------------------------------------*/
  219. HRESULT TFSNode::Construct(const GUID *pNodeType,
  220. ITFSNodeHandler *pHandler,
  221. ITFSResultHandler *pResultHandler,
  222. ITFSNodeMgr *pNodeMgr)
  223. {
  224. m_pNodeType = pNodeType;
  225. m_spNodeHandler.Set(pHandler);
  226. m_spResultHandler.Set(pResultHandler);
  227. m_spNodeMgr.Set(pNodeMgr);
  228. return hrOK;
  229. }
  230. /*!--------------------------------------------------------------------------
  231. TFSNode::Init
  232. Implementation of ITSFNode::Init
  233. Author: KennT
  234. ---------------------------------------------------------------------------*/
  235. STDMETHODIMP TFSNode::Init(int nImageIndex, int nOpenImageIndex,
  236. LPARAM lParam, MMC_COOKIE cookie
  237. )
  238. {
  239. m_nImageIndex = nImageIndex;
  240. m_nOpenImageIndex = nOpenImageIndex;
  241. m_lParam = lParam;
  242. m_cookie = cookie;
  243. return hrOK;
  244. }
  245. /*!--------------------------------------------------------------------------
  246. TFSNode::GetParent
  247. Implementation of ITFSNode::GetParent
  248. Author: KennT
  249. ---------------------------------------------------------------------------*/
  250. STDMETHODIMP TFSNode::GetParent(ITFSNode **ppNode)
  251. {
  252. Assert(ppNode);
  253. *ppNode = NULL;
  254. SetI((LPUNKNOWN *) ppNode, m_spNodeParent);
  255. return hrOK;
  256. }
  257. /*!--------------------------------------------------------------------------
  258. TFSNode::SetParent
  259. -
  260. Author: KennT
  261. ---------------------------------------------------------------------------*/
  262. STDMETHODIMP TFSNode::SetParent(ITFSNode *pNode)
  263. {
  264. m_spNodeParent.Set(pNode);
  265. return hrOK;
  266. }
  267. /*!--------------------------------------------------------------------------
  268. TFSNode::GetNodeMgr
  269. Implementation of ITFSNode::GetNodeMgr
  270. Author: KennT
  271. ---------------------------------------------------------------------------*/
  272. STDMETHODIMP TFSNode::GetNodeMgr(ITFSNodeMgr **ppNodeMgr)
  273. {
  274. Assert(ppNodeMgr);
  275. *ppNodeMgr = NULL;
  276. SetI((LPUNKNOWN *) ppNodeMgr, m_spNodeMgr);
  277. return hrOK;
  278. }
  279. /*!--------------------------------------------------------------------------
  280. TFSNode::IsVisible
  281. Implementation of ITFSNode::IsVisible
  282. Author: KennT
  283. ---------------------------------------------------------------------------*/
  284. STDMETHODIMP_(BOOL) TFSNode::IsVisible()
  285. {
  286. // If we are the root node, then we are ALWAYS visible
  287. // (actually it's kind of weird because the root node is never
  288. // shown to the user). It's an imaginary construct much as
  289. // software is (in a way) imaginary. Software is structure
  290. // imposed on a mass of random machine instructions and data.
  291. return (m_tfsVis & TFS_VIS_SHOW);
  292. }
  293. /*!--------------------------------------------------------------------------
  294. TFSNode::SetVisibilityState
  295. Implementation of ITFSNode::SetVisibilityState
  296. Author: KennT
  297. ---------------------------------------------------------------------------*/
  298. STDMETHODIMP TFSNode::SetVisibilityState(TFSVisibility vis)
  299. {
  300. m_tfsVis = vis;
  301. return hrOK;
  302. }
  303. STDMETHODIMP_(TFSVisibility) TFSNode::GetVisibilityState()
  304. {
  305. return m_tfsVis;
  306. }
  307. /*!--------------------------------------------------------------------------
  308. TFSNode::IsInUI
  309. Implementation of ITFSNode::IsInUI
  310. Author: KennT
  311. ---------------------------------------------------------------------------*/
  312. STDMETHODIMP_(BOOL) TFSNode::IsInUI()
  313. {
  314. // If we have been added to the UI, then return TRUE
  315. return (m_hScopeItem != 0);
  316. }
  317. /*!--------------------------------------------------------------------------
  318. TFSContainer::InternalRemoveFromUI
  319. Removes a node from the UI and sets its scope ID to zero
  320. Author: EricDav
  321. ---------------------------------------------------------------------------*/
  322. HRESULT TFSNode::InternalRemoveFromUI(ITFSNode *pNodeChild,
  323. BOOL fDeleteThis)
  324. {
  325. HRESULT hr = hrOK;
  326. SPIConsoleNameSpace spConsoleNS;
  327. m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS);
  328. hr = spConsoleNS->DeleteItem(pNodeChild->GetData(TFS_DATA_SCOPEID), TRUE);
  329. // Set the scope ID to 0 after we delete it from the UI
  330. // and set all of the children's scope ID's to zero so that they will
  331. // get added again later
  332. if (SUCCEEDED(hr))
  333. InternalZeroScopeID(pNodeChild, TRUE);
  334. return hr;
  335. }
  336. /*!--------------------------------------------------------------------------
  337. TFSNode::InternalZeroScopeID
  338. Recursively zeros the scope ID for all scope pane items
  339. (container nodes only)
  340. Author: EricDav
  341. ---------------------------------------------------------------------------*/
  342. HRESULT TFSNode::InternalZeroScopeID(ITFSNode *pNode, BOOL fZeroChildren)
  343. {
  344. HRESULT hr = hrOK;
  345. if (pNode->IsContainer())
  346. {
  347. if (fZeroChildren)
  348. {
  349. // recursively delete children
  350. SPITFSNodeEnum spNodeEnum;
  351. ITFSNode * pCurrentNode;
  352. ULONG nNumReturned = 0;
  353. pNode->GetEnum(&spNodeEnum);
  354. spNodeEnum->Next(1, &pCurrentNode, &nNumReturned);
  355. while (nNumReturned)
  356. {
  357. InternalZeroScopeID(pCurrentNode, fZeroChildren);
  358. pCurrentNode->Release();
  359. spNodeEnum->Next(1, &pCurrentNode, &nNumReturned);
  360. }
  361. }
  362. }
  363. // zero the scope ID for this node
  364. pNode->SetData(TFS_DATA_SCOPEID, 0);
  365. return hr;
  366. }
  367. /*!--------------------------------------------------------------------------
  368. TFSNode::Show
  369. This function changes the visiblity state of the node in the UI.
  370. Depending upon what has been set via SetVisibilityState, the function
  371. will add or remove the node from the UI.
  372. Author: KennT, EricDav
  373. ---------------------------------------------------------------------------*/
  374. STDMETHODIMP TFSNode::Show()
  375. {
  376. AFX_MANAGE_STATE(AfxGetModuleState());
  377. HRESULT hr = hrOK;
  378. SCOPEDATAITEM scopedataitem;
  379. SPIConsoleNameSpace spConsoleNS;
  380. COM_PROTECT_TRY
  381. {
  382. // check to see if we should remove this node from the UI
  383. if (IsInUI() && !IsVisible())
  384. {
  385. if (IsContainer())
  386. {
  387. CORg( InternalRemoveFromUI(this, TRUE) );
  388. }
  389. else
  390. {
  391. CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_DELETE_ITEM) );
  392. }
  393. }
  394. else
  395. if (!IsInUI() && IsVisible())
  396. {
  397. // this node isn't in the UI and needs to be shown
  398. if (IsContainer())
  399. {
  400. // If we're making this node visible, our parent should be also
  401. Assert(!m_spNodeParent || m_spNodeParent->IsInUI());
  402. //$ Review: kennt, what if our parent isn't visible?
  403. // Do we want to act on this? Do we show all of our parents?
  404. // add this node in the UI
  405. CORg( InitializeScopeDataItem(&scopedataitem,
  406. m_spNodeParent ?
  407. m_spNodeParent->GetData(TFS_DATA_SCOPEID) :
  408. NULL,
  409. GetData(TFS_DATA_COOKIE),
  410. m_nImageIndex,
  411. m_nOpenImageIndex,
  412. IsContainer(),
  413. m_ulRelativeFlags,
  414. m_hRelativeId));
  415. CORg( m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS) );
  416. CORg( spConsoleNS->InsertItem(&scopedataitem) );
  417. // Now that we've added the node to the scope pane, we have a HSCOPEITEM
  418. SetData( TFS_DATA_SCOPEID, scopedataitem.ID );
  419. }
  420. else
  421. {
  422. //
  423. // result pane item, has to go through IComponent interface
  424. //
  425. hr = UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_ADD_ITEM);
  426. }
  427. }
  428. COM_PROTECT_ERROR_LABEL;
  429. }
  430. COM_PROTECT_CATCH
  431. return hr;
  432. }
  433. /*!--------------------------------------------------------------------------
  434. TFSNode::ChangeNode
  435. Implementation of ITFSnode::ChangeNode
  436. Author: KennT
  437. ---------------------------------------------------------------------------*/
  438. HRESULT
  439. TFSNode::ChangeNode
  440. (
  441. LONG_PTR changeMask
  442. )
  443. {
  444. // will have to broadcast to all views
  445. return UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), changeMask);
  446. }
  447. /*!--------------------------------------------------------------------------
  448. TFSNode::UpdateAllViewsHelper
  449. Notifies the current view to do something. Add a node, change
  450. a node or delete a node.
  451. Author:
  452. ---------------------------------------------------------------------------*/
  453. HRESULT
  454. TFSNode::UpdateAllViewsHelper
  455. (
  456. LPARAM data,
  457. LONG_PTR hint
  458. )
  459. {
  460. HRESULT hr = hrOK;
  461. SPIComponentData spCompData;
  462. SPIConsole spConsole;
  463. IDataObject* pDataObject;
  464. COM_PROTECT_TRY
  465. {
  466. m_spNodeMgr->GetComponentData(&spCompData);
  467. CORg ( spCompData->QueryDataObject(NULL, CCT_RESULT, &pDataObject) );
  468. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  469. CORg ( spConsole->UpdateAllViews(pDataObject, data, hint) );
  470. pDataObject->Release();
  471. COM_PROTECT_ERROR_LABEL;
  472. }
  473. COM_PROTECT_CATCH
  474. return hr;
  475. }
  476. /*!--------------------------------------------------------------------------
  477. TFSNode::GetData
  478. Implementation of ITFSnode::GetData
  479. Author: KennT
  480. ---------------------------------------------------------------------------*/
  481. STDMETHODIMP_(LONG_PTR) TFSNode::GetData(int nIndex)
  482. {
  483. AFX_MANAGE_STATE(AfxGetModuleState());
  484. LONG_PTR uReturn = 0;
  485. switch (nIndex)
  486. {
  487. case TFS_DATA_COOKIE:
  488. Assert(m_bCookieSet);
  489. uReturn = m_cookie;
  490. break;
  491. case TFS_DATA_SCOPEID:
  492. uReturn = (LONG_PTR) m_hScopeItem;
  493. break;
  494. case TFS_DATA_IMAGEINDEX:
  495. uReturn = m_nImageIndex;
  496. break;
  497. case TFS_DATA_OPENIMAGEINDEX:
  498. uReturn = m_nOpenImageIndex;
  499. break;
  500. case TFS_DATA_PROPSHEETCOUNT:
  501. uReturn = m_cPropSheet;
  502. break;
  503. case TFS_DATA_RELATIVE_FLAGS:
  504. uReturn = m_ulRelativeFlags;
  505. break;
  506. case TFS_DATA_RELATIVE_SCOPEID:
  507. uReturn = m_hRelativeId;
  508. break;
  509. case TFS_DATA_SCOPE_LEAF_NODE:
  510. uReturn = m_fScopeLeafNode;
  511. break;
  512. case TFS_DATA_DIRTY:
  513. uReturn = m_fDirty;
  514. break;
  515. case TFS_DATA_USER:
  516. uReturn = m_uData;
  517. break;
  518. case TFS_DATA_TYPE:
  519. uReturn = m_uType;
  520. break;
  521. case TFS_DATA_PARENT:
  522. uReturn = m_uDataParent;
  523. break;
  524. default:
  525. Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::GetData",
  526. nIndex);
  527. break;
  528. }
  529. return uReturn;
  530. }
  531. /*!--------------------------------------------------------------------------
  532. TFSNode::SetData
  533. Implementaton of ITFSNode::SetData
  534. Author: KennT
  535. ---------------------------------------------------------------------------*/
  536. STDMETHODIMP_(LONG_PTR) TFSNode::SetData(int nIndex, LONG_PTR dwData)
  537. {
  538. AFX_MANAGE_STATE(AfxGetModuleState());
  539. LONG_PTR dwOldValue = 0;
  540. switch (nIndex)
  541. {
  542. case TFS_DATA_COOKIE:
  543. IfDebug(m_bCookieSet=TRUE);
  544. dwOldValue = m_cookie;
  545. m_cookie = dwData;
  546. break;
  547. case TFS_DATA_SCOPEID:
  548. dwOldValue = m_hScopeItem;
  549. m_hScopeItem = (HSCOPEITEM) dwData;
  550. break;
  551. case TFS_DATA_IMAGEINDEX:
  552. dwOldValue = m_nImageIndex;
  553. m_nImageIndex = (UINT) dwData;
  554. break;
  555. case TFS_DATA_OPENIMAGEINDEX:
  556. dwOldValue = m_nOpenImageIndex;
  557. m_nOpenImageIndex = (UINT) dwData;
  558. break;
  559. case TFS_DATA_PROPSHEETCOUNT:
  560. dwOldValue = m_cPropSheet;
  561. m_cPropSheet = (UINT) dwData;
  562. break;
  563. case TFS_DATA_DIRTY:
  564. dwOldValue = m_fDirty;
  565. m_fDirty = (UINT) dwData;
  566. break;
  567. case TFS_DATA_RELATIVE_FLAGS:
  568. dwOldValue = m_ulRelativeFlags;
  569. m_ulRelativeFlags = (UINT) dwData;
  570. break;
  571. case TFS_DATA_RELATIVE_SCOPEID:
  572. dwOldValue = m_hRelativeId;
  573. m_hRelativeId = (HSCOPEITEM) dwData;
  574. break;
  575. case TFS_DATA_SCOPE_LEAF_NODE:
  576. dwOldValue = m_fScopeLeafNode;
  577. m_fScopeLeafNode = (BOOL) dwData;
  578. break;
  579. case TFS_DATA_USER:
  580. dwOldValue = m_uData;
  581. m_uData = dwData;
  582. break;
  583. case TFS_DATA_TYPE:
  584. dwOldValue = m_uType;
  585. m_uType = dwData;
  586. break;
  587. case TFS_DATA_PARENT:
  588. dwOldValue = m_uDataParent;
  589. m_uDataParent = dwData;
  590. break;
  591. default:
  592. Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::SetData",
  593. nIndex);
  594. break;
  595. }
  596. return dwOldValue;
  597. }
  598. /*!--------------------------------------------------------------------------
  599. TFSNode::Notify
  600. Implementation of ITFSNode::Notify
  601. Author: KennT
  602. ---------------------------------------------------------------------------*/
  603. STDMETHODIMP_(LONG_PTR) TFSNode::Notify(int nIndex, LPARAM lParam)
  604. {
  605. AFX_MANAGE_STATE(AfxGetModuleState());
  606. LONG_PTR uReturn = 0;
  607. switch (nIndex)
  608. {
  609. case TFS_NOTIFY_CREATEPROPSHEET:
  610. {
  611. SPITFSNodeHandler spHandler;
  612. uReturn = InterlockedIncrement(&m_cPropSheet);
  613. GetHandler(&spHandler);
  614. if (spHandler)
  615. spHandler->UserNotify(this, TFS_MSG_CREATEPROPSHEET, lParam);
  616. }
  617. break;
  618. case TFS_NOTIFY_DELETEPROPSHEET:
  619. {
  620. SPITFSNodeHandler spHandler;
  621. uReturn = InterlockedDecrement(&m_cPropSheet);
  622. GetHandler(&spHandler);
  623. if (spHandler)
  624. spHandler->UserNotify(this, TFS_MSG_DELETEPROPSHEET, lParam);
  625. }
  626. break;
  627. case TFS_NOTIFY_RESULT_CREATEPROPSHEET:
  628. {
  629. SPITFSResultHandler spHandler;
  630. uReturn = InterlockedIncrement(&m_cPropSheet);
  631. GetResultHandler(&spHandler);
  632. if (spHandler)
  633. spHandler->UserResultNotify(this, TFS_MSG_CREATEPROPSHEET, lParam);
  634. }
  635. break;
  636. case TFS_NOTIFY_RESULT_DELETEPROPSHEET:
  637. {
  638. SPITFSResultHandler spHandler;
  639. uReturn = InterlockedDecrement(&m_cPropSheet);
  640. GetResultHandler(&spHandler);
  641. if (spHandler)
  642. spHandler->UserResultNotify(this, TFS_MSG_DELETEPROPSHEET, lParam);
  643. }
  644. break;
  645. case TFS_NOTIFY_REMOVE_DELETED_NODES:
  646. break;
  647. default:
  648. Panic1("Alert the troops!: invalid arg(%d) to ITFSNode::Notify",
  649. nIndex);
  650. break;
  651. }
  652. return uReturn;
  653. }
  654. /*!--------------------------------------------------------------------------
  655. TFSNode::GetHandler
  656. Implementation of ITFSNode::GetHandler
  657. Author: KennT
  658. ---------------------------------------------------------------------------*/
  659. STDMETHODIMP TFSNode::GetHandler(ITFSNodeHandler **ppNodeHandler)
  660. {
  661. Assert(ppNodeHandler);
  662. *ppNodeHandler = NULL;
  663. SetI((LPUNKNOWN *) ppNodeHandler, m_spNodeHandler);
  664. return hrOK;
  665. }
  666. /*!--------------------------------------------------------------------------
  667. TFSNode::SetHandler
  668. Implementation of ITFSNode::SetHandler
  669. Author: KennT
  670. ---------------------------------------------------------------------------*/
  671. STDMETHODIMP TFSNode::SetHandler(ITFSNodeHandler *pNodeHandler)
  672. {
  673. m_spNodeHandler.Set(pNodeHandler);
  674. return hrOK;
  675. }
  676. /*!--------------------------------------------------------------------------
  677. TFSNode::GetResultHandler
  678. Implementation of ITFSNode::GetResultHandler
  679. Author: KennT
  680. ---------------------------------------------------------------------------*/
  681. STDMETHODIMP TFSNode::GetResultHandler(ITFSResultHandler **ppResultHandler)
  682. {
  683. Assert(ppResultHandler);
  684. *ppResultHandler = NULL;
  685. SetI((LPUNKNOWN *) ppResultHandler, m_spResultHandler);
  686. return hrOK;
  687. }
  688. /*!--------------------------------------------------------------------------
  689. TFSNode::SetResultHandler
  690. -
  691. Author: KennT
  692. ---------------------------------------------------------------------------*/
  693. STDMETHODIMP TFSNode::SetResultHandler(ITFSResultHandler *pResultHandler)
  694. {
  695. m_spResultHandler.Set(pResultHandler);
  696. return hrOK;
  697. }
  698. /*!--------------------------------------------------------------------------
  699. TFSNode::GetString
  700. Implementation of ITFSNode::GetString
  701. Author: KennT
  702. ---------------------------------------------------------------------------*/
  703. STDMETHODIMP_(LPCTSTR) TFSNode::GetString(int nCol)
  704. {
  705. AFX_MANAGE_STATE(AfxGetModuleState());
  706. // Need to forward this onto the handler
  707. return m_spNodeHandler->GetString(static_cast<ITFSNode *>(this), nCol);
  708. }
  709. /*!--------------------------------------------------------------------------
  710. TFSNode::GetNodeType
  711. Implementation of ITFSNode::GetNodeType
  712. Author: KennT
  713. ---------------------------------------------------------------------------*/
  714. STDMETHODIMP_(const GUID *) TFSNode::GetNodeType()
  715. {
  716. return m_pNodeType;
  717. }
  718. /*!--------------------------------------------------------------------------
  719. TFSNode::SetNodeType
  720. Implementation of ITFSNode::SetNodeType
  721. Author: KennT
  722. ---------------------------------------------------------------------------*/
  723. STDMETHODIMP TFSNode::SetNodeType(const GUID *pGuid)
  724. {
  725. m_pNodeType = pGuid;
  726. return hrOK;
  727. }
  728. /*!--------------------------------------------------------------------------
  729. TFSNode::IsContainer
  730. Implementation of ITFSNode:;IsContainer
  731. Author: KennT
  732. ---------------------------------------------------------------------------*/
  733. STDMETHODIMP_(BOOL) TFSNode::IsContainer()
  734. {
  735. return FALSE;
  736. }
  737. STDMETHODIMP TFSNode::AddChild(ITFSNode *pNodeChild)
  738. {
  739. return E_NOTIMPL;
  740. }
  741. STDMETHODIMP TFSNode::InsertChild(ITFSNode *pInsertAfterNode, ITFSNode *pNodeChild)
  742. {
  743. return E_NOTIMPL;
  744. }
  745. STDMETHODIMP TFSNode::RemoveChild(ITFSNode *pNode)
  746. {
  747. return E_NOTIMPL;
  748. }
  749. STDMETHODIMP TFSNode::ExtractChild(ITFSNode *pNode)
  750. {
  751. return E_NOTIMPL;
  752. }
  753. STDMETHODIMP TFSNode::GetChildCount(int *pVisibleCount, int *pTotalCount)
  754. {
  755. if (pVisibleCount)
  756. *pVisibleCount = 0;
  757. if (pTotalCount)
  758. *pTotalCount = 0;
  759. return hrOK;
  760. }
  761. STDMETHODIMP TFSNode::GetEnum(ITFSNodeEnum **ppNodeEnum)
  762. {
  763. return E_NOTIMPL;
  764. }
  765. STDMETHODIMP TFSNode::DeleteAllChildren(BOOL fRemoveFromUI)
  766. {
  767. return E_NOTIMPL;
  768. }
  769. /*!--------------------------------------------------------------------------
  770. TFSNode::InitializeScopeDataItem
  771. -
  772. Author: EricDav, KennT
  773. ---------------------------------------------------------------------------*/
  774. HRESULT TFSNode::InitializeScopeDataItem(LPSCOPEDATAITEM pScopeDataItem,
  775. HSCOPEITEM pParentScopeItem,
  776. LPARAM lParam,
  777. int nImage,
  778. int nOpenImage,
  779. BOOL bHasChildren,
  780. ULONG ulRelativeFlags,
  781. HSCOPEITEM hSibling
  782. )
  783. {
  784. AFX_MANAGE_STATE(AfxGetModuleState());
  785. Assert(pScopeDataItem != NULL);
  786. ::ZeroMemory(pScopeDataItem, sizeof(SCOPEDATAITEM));
  787. // set parent scope item
  788. if (ulRelativeFlags & (SDI_NEXT | SDI_PREVIOUS))
  789. {
  790. pScopeDataItem->mask |= (ulRelativeFlags & (SDI_NEXT | SDI_PREVIOUS));
  791. pScopeDataItem->mask |= SDI_FIRST;
  792. pScopeDataItem->relativeID = hSibling;
  793. }
  794. else
  795. {
  796. if (ulRelativeFlags & SDI_FIRST)
  797. pScopeDataItem->mask |= SDI_FIRST;
  798. pScopeDataItem->mask |= SDI_PARENT;
  799. pScopeDataItem->relativeID = pParentScopeItem;
  800. }
  801. // Add node name, we implement callback
  802. pScopeDataItem->mask |= SDI_STR;
  803. pScopeDataItem->displayname = MMC_CALLBACK;
  804. // Add the lParam
  805. pScopeDataItem->mask |= SDI_PARAM;
  806. pScopeDataItem->lParam = lParam;
  807. // Add close image
  808. if (nImage != -1)
  809. {
  810. pScopeDataItem->mask |= SDI_IMAGE;
  811. pScopeDataItem->nImage = nImage;
  812. }
  813. // Add open image
  814. if (nOpenImage != -1)
  815. {
  816. pScopeDataItem->mask |= SDI_OPENIMAGE;
  817. pScopeDataItem->nOpenImage = nOpenImage;
  818. }
  819. // Add button to node if the folder has children
  820. if (bHasChildren == TRUE)
  821. {
  822. pScopeDataItem->mask |= SDI_CHILDREN;
  823. pScopeDataItem->cChildren = 1;
  824. if (m_fScopeLeafNode)
  825. {
  826. // Note: the bHasChildren flag is set because the node
  827. // is really a container node or is a result container.
  828. // If it is purely a result container, then the m_fScopeLeafNode
  829. // will be set and we can clear the '+' symbol.
  830. pScopeDataItem->cChildren = 0;
  831. }
  832. }
  833. return hrOK;
  834. }
  835. /*!--------------------------------------------------------------------------
  836. TFSContainer::~TFSContainer
  837. -
  838. Author: KennT
  839. ---------------------------------------------------------------------------*/
  840. TFSContainer::~TFSContainer()
  841. {
  842. DeleteAllChildren(FALSE);
  843. }
  844. /*!--------------------------------------------------------------------------
  845. TFSContainer::IsContainer
  846. Implementation of ITFSNode::IsContainer
  847. Author: KennT
  848. ---------------------------------------------------------------------------*/
  849. STDMETHODIMP_(BOOL) TFSContainer::IsContainer()
  850. {
  851. return TRUE;
  852. }
  853. /*!--------------------------------------------------------------------------
  854. TFSContainer::AddChild
  855. Implementation of ITFSContainer::AddChild
  856. Author: KennT
  857. ---------------------------------------------------------------------------*/
  858. STDMETHODIMP TFSContainer::AddChild(ITFSNode *pNodeChild)
  859. {
  860. return InsertChild(NULL, pNodeChild);
  861. }
  862. /*!--------------------------------------------------------------------------
  863. TFSContainer::InsertChild
  864. Implementation of ITFSContainer::InsertChild
  865. Author: EricDav
  866. ---------------------------------------------------------------------------*/
  867. STDMETHODIMP TFSContainer::InsertChild(ITFSNode *pInsertAfterNode, ITFSNode *pNodeChild)
  868. {
  869. AFX_MANAGE_STATE(AfxGetModuleState());
  870. SCOPEDATAITEM scopedataitem;
  871. HRESULT hr = hrOK;
  872. Assert(pNodeChild);
  873. Assert(IsContainer());
  874. // add the node to our internal tree
  875. CORg( pNodeChild->SetParent(this) );
  876. CORg( InternalAddToList(pInsertAfterNode, pNodeChild) );
  877. // if we're not visible yet, we can't add this to the UI
  878. if (!IsInUI())
  879. {
  880. return hrOK;
  881. }
  882. CORg( pNodeChild->Show() );
  883. Error:
  884. if (!FHrSucceeded(hr))
  885. {
  886. InternalRemoveFromList(pNodeChild);
  887. }
  888. return hr;
  889. }
  890. /*!--------------------------------------------------------------------------
  891. TFSContainer::RemoveChild
  892. Implementation of ITFSNode::RemoveChild
  893. Author: KennT
  894. ---------------------------------------------------------------------------*/
  895. STDMETHODIMP TFSContainer::RemoveChild(ITFSNode *pNodeChild)
  896. {
  897. AFX_MANAGE_STATE(AfxGetModuleState());
  898. HRESULT hr;
  899. SPITFSNode spNode;
  900. // This node must be kept alive during this operation
  901. spNode.Set(pNodeChild);
  902. hr = InternalRemoveChild(spNode, TRUE, TRUE, TRUE);
  903. spNode->Destroy();
  904. return hr;
  905. }
  906. /*!--------------------------------------------------------------------------
  907. TFSContainer::ExtractChild
  908. Implementation of ITFSNode::ExtractChild
  909. This function removes the node and all children from the UI, and
  910. removes the node from our internal tree. It does not destroy the
  911. node and it's children, call RemoveChild if that is required.
  912. Author: EricDav
  913. ---------------------------------------------------------------------------*/
  914. STDMETHODIMP TFSContainer::ExtractChild(ITFSNode *pNodeChild)
  915. {
  916. AFX_MANAGE_STATE(AfxGetModuleState());
  917. return InternalRemoveChild(pNodeChild, TRUE, TRUE, FALSE);
  918. }
  919. /*!--------------------------------------------------------------------------
  920. TFSContainer::GetChildCount
  921. -
  922. Author: KennT
  923. ---------------------------------------------------------------------------*/
  924. STDMETHODIMP TFSContainer::GetChildCount(int *pVisibleCount, int *pTotalCount)
  925. {
  926. AFX_MANAGE_STATE(AfxGetModuleState());
  927. HRESULT hr = hrOK;
  928. COM_PROTECT_TRY
  929. {
  930. if (pTotalCount)
  931. *pTotalCount = (int)m_listChildren.GetCount();
  932. // Enumerate through all of the nodes and count the visible ones
  933. if (pVisibleCount)
  934. {
  935. POSITION pos;
  936. ITFSNode * pNode = NULL;
  937. int cVisible = 0;
  938. *pVisibleCount = 0;
  939. pos = m_listChildren.GetHeadPosition();
  940. while (pos != NULL)
  941. {
  942. pNode = m_listChildren.GetNext(pos);
  943. if (pNode->IsInUI())
  944. cVisible++;
  945. }
  946. *pVisibleCount = cVisible;
  947. }
  948. }
  949. COM_PROTECT_CATCH
  950. if (FHrFailed(hr))
  951. {
  952. if (pTotalCount)
  953. *pTotalCount = 0;
  954. if (pVisibleCount)
  955. *pVisibleCount = 0;
  956. }
  957. return hr;
  958. }
  959. /*!--------------------------------------------------------------------------
  960. TFSContainer::GetEnum
  961. -
  962. Author: KennT
  963. ---------------------------------------------------------------------------*/
  964. STDMETHODIMP TFSContainer::GetEnum(ITFSNodeEnum **ppNodeEnum)
  965. {
  966. HRESULT hr = hrOK;
  967. TFSNodeEnum * pNodeEnum = NULL;
  968. COM_PROTECT_TRY
  969. {
  970. pNodeEnum = new TFSNodeEnum(this);
  971. }
  972. COM_PROTECT_CATCH
  973. *ppNodeEnum = pNodeEnum;
  974. return hr;
  975. }
  976. /*!--------------------------------------------------------------------------
  977. TFSContainer::DeleteAllChildren
  978. -
  979. Author: KennT
  980. ---------------------------------------------------------------------------*/
  981. STDMETHODIMP TFSContainer::DeleteAllChildren(BOOL fRemoveFromUI)
  982. {
  983. AFX_MANAGE_STATE(AfxGetModuleState());
  984. SPITFSNode spNode;
  985. HRESULT hr = hrOK;
  986. COM_PROTECT_TRY
  987. {
  988. if (fRemoveFromUI)
  989. CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(this), RESULT_PANE_DELETE_ALL) );
  990. while (!m_listChildren.IsEmpty())
  991. {
  992. BOOL bRemoveFromUI = FALSE;
  993. spNode = m_listChildren.RemoveHead();
  994. if (spNode->IsContainer() && fRemoveFromUI)
  995. bRemoveFromUI = TRUE;
  996. InternalRemoveChild(spNode, FALSE, bRemoveFromUI, TRUE);
  997. spNode->Destroy();
  998. spNode.Release();
  999. }
  1000. COM_PROTECT_ERROR_LABEL
  1001. }
  1002. COM_PROTECT_CATCH
  1003. return hr;
  1004. }
  1005. /*!--------------------------------------------------------------------------
  1006. TFSContainer::CompareChildNodes
  1007. -
  1008. Author: KennT
  1009. ---------------------------------------------------------------------------*/
  1010. STDMETHODIMP TFSContainer::CompareChildNodes(int *pnResult, ITFSNode *pNode1, ITFSNode *pNode2)
  1011. {
  1012. *pnResult = 0;
  1013. return hrOK;
  1014. }
  1015. /*!--------------------------------------------------------------------------
  1016. TFSContainer::ChangeNode
  1017. -
  1018. Author: KennT
  1019. ---------------------------------------------------------------------------*/
  1020. HRESULT
  1021. TFSContainer::ChangeNode
  1022. (
  1023. LONG_PTR changeMask
  1024. )
  1025. {
  1026. HRESULT hr = hrOK;
  1027. SCOPEDATAITEM dataitemScope;
  1028. SPITFSNode spRootNode;
  1029. SPIConsoleNameSpace spConsoleNS;
  1030. COM_PROTECT_TRY
  1031. {
  1032. Assert(changeMask & (SCOPE_PANE_CHANGE_ITEM | SCOPE_PANE_STATE_NORMAL | SCOPE_PANE_STATE_BOLD | SCOPE_PANE_STATE_EXPANDEDONCE | SCOPE_PANE_STATE_CLEAR));
  1033. // this node may have been removed from the UI, but something like a
  1034. // background thread may have been holding onto it... just exit gracefully
  1035. //Assert(m_hScopeItem != 0);
  1036. if (m_hScopeItem == 0)
  1037. return S_FALSE;
  1038. if (!(changeMask & (SCOPE_PANE_CHANGE_ITEM | SCOPE_PANE_STATE_NORMAL | SCOPE_PANE_STATE_BOLD | SCOPE_PANE_STATE_EXPANDEDONCE | SCOPE_PANE_STATE_CLEAR)))
  1039. {
  1040. // the change mask is not valid for this node
  1041. return S_FALSE;
  1042. }
  1043. ZeroMemory(&dataitemScope, sizeof(dataitemScope));
  1044. CORg ( m_spNodeMgr->GetConsoleNameSpace(&spConsoleNS) );
  1045. m_spNodeMgr->GetRootNode(&spRootNode);
  1046. dataitemScope.ID = GetData(TFS_DATA_SCOPEID);
  1047. ASSERT(dataitemScope.ID != 0);
  1048. if (changeMask & SCOPE_PANE_CHANGE_ITEM_DATA)
  1049. {
  1050. dataitemScope.mask |= SDI_STR;
  1051. dataitemScope.displayname = MMC_CALLBACK;
  1052. }
  1053. if (changeMask & SCOPE_PANE_CHANGE_ITEM_ICON)
  1054. {
  1055. dataitemScope.mask |= SDI_IMAGE;
  1056. dataitemScope.nImage = (UINT)GetData(TFS_DATA_IMAGEINDEX);
  1057. dataitemScope.mask |= SDI_OPENIMAGE;
  1058. dataitemScope.nOpenImage = (UINT)GetData(TFS_DATA_OPENIMAGEINDEX);
  1059. }
  1060. if (changeMask & SCOPE_PANE_STATE_NORMAL)
  1061. {
  1062. dataitemScope.mask |= SDI_STATE;
  1063. dataitemScope.nState = MMC_SCOPE_ITEM_STATE_NORMAL;
  1064. }
  1065. if (changeMask & SCOPE_PANE_STATE_BOLD)
  1066. {
  1067. dataitemScope.mask |= SDI_STATE;
  1068. dataitemScope.nState = MMC_SCOPE_ITEM_STATE_BOLD;
  1069. }
  1070. if (changeMask & SCOPE_PANE_STATE_EXPANDEDONCE)
  1071. {
  1072. dataitemScope.mask |= SDI_STATE;
  1073. dataitemScope.nState = MMC_SCOPE_ITEM_STATE_EXPANDEDONCE;
  1074. }
  1075. if (changeMask & SCOPE_PANE_STATE_CLEAR)
  1076. {
  1077. dataitemScope.mask |= SDI_STATE;
  1078. dataitemScope.nState = 0;
  1079. }
  1080. CORg ( spConsoleNS->SetItem(&dataitemScope) );
  1081. COM_PROTECT_ERROR_LABEL;
  1082. }
  1083. COM_PROTECT_CATCH
  1084. return hr;
  1085. }
  1086. /*!--------------------------------------------------------------------------
  1087. TFSContainer::InternalAddToList
  1088. -
  1089. Author: KennT
  1090. ---------------------------------------------------------------------------*/
  1091. HRESULT TFSContainer::InternalAddToList(ITFSNode * pInsertAfterNode, ITFSNode *pNode)
  1092. {
  1093. AFX_MANAGE_STATE(AfxGetModuleState());
  1094. if (pInsertAfterNode == NULL)
  1095. {
  1096. m_listChildren.AddHead(pNode);
  1097. }
  1098. else
  1099. {
  1100. POSITION pos = m_listChildren.Find(pInsertAfterNode);
  1101. if (pos)
  1102. m_listChildren.InsertAfter(pos, pNode);
  1103. else
  1104. m_listChildren.AddHead(pNode);
  1105. }
  1106. pNode->AddRef();
  1107. return hrOK;
  1108. }
  1109. /*!--------------------------------------------------------------------------
  1110. TFSContainer::InternalRemoveFromList
  1111. -
  1112. Author: KennT
  1113. ---------------------------------------------------------------------------*/
  1114. HRESULT TFSContainer::InternalRemoveFromList(ITFSNode *pNode)
  1115. {
  1116. AFX_MANAGE_STATE(AfxGetModuleState());
  1117. m_listChildren.RemoveNode(pNode);
  1118. pNode->Release();
  1119. return hrOK;
  1120. }
  1121. /*!--------------------------------------------------------------------------
  1122. TFSContainer::InternalRemoveChild
  1123. -
  1124. Author: KennT
  1125. ---------------------------------------------------------------------------*/
  1126. HRESULT TFSContainer::InternalRemoveChild(ITFSNode *pNodeChild,
  1127. BOOL fRemoveFromList,
  1128. BOOL fRemoveFromUI,
  1129. BOOL fRemoveChildren)
  1130. {
  1131. AFX_MANAGE_STATE(AfxGetModuleState());
  1132. HRESULT hr = hrOK;
  1133. Assert(pNodeChild);
  1134. // Call this recursively on the children of pNodeChild
  1135. if (fRemoveChildren && pNodeChild->IsContainer())
  1136. {
  1137. pNodeChild->DeleteAllChildren(fRemoveFromUI);
  1138. }
  1139. // Remove the node from the UI
  1140. if (fRemoveFromUI)
  1141. {
  1142. if (pNodeChild->IsContainer())
  1143. {
  1144. // Check to see if we need to remove the node from the UI
  1145. if (!pNodeChild->IsInUI())
  1146. return hrOK;
  1147. CORg( InternalRemoveFromUI(pNodeChild, TRUE) );
  1148. }
  1149. else
  1150. {
  1151. CORg( UpdateAllViewsHelper(reinterpret_cast<LPARAM>(pNodeChild), RESULT_PANE_DELETE_ITEM) );
  1152. }
  1153. }
  1154. if (fRemoveFromList)
  1155. InternalRemoveFromList(pNodeChild);
  1156. pNodeChild->SetParent(NULL);
  1157. Error:
  1158. return hr;
  1159. }
  1160. STDMETHODIMP_(LONG_PTR) TFSContainer::Notify(int nIndex, LPARAM lParam)
  1161. {
  1162. LONG_PTR uReturn = 0;
  1163. HRESULT hr = hrOK;
  1164. COM_PROTECT_TRY
  1165. {
  1166. if (nIndex == TFS_NOTIFY_REMOVE_DELETED_NODES)
  1167. {
  1168. ITFSNode * pNode;
  1169. POSITION pos;
  1170. pos = m_listChildren.GetHeadPosition();
  1171. while (pos)
  1172. {
  1173. pNode = m_listChildren.GetNext(pos);
  1174. if (pNode->GetVisibilityState() & TFS_VIS_DELETE)
  1175. {
  1176. RemoveChild(pNode);
  1177. }
  1178. }
  1179. }
  1180. else
  1181. uReturn = TFSNode::Notify(nIndex, lParam);
  1182. }
  1183. COM_PROTECT_CATCH;
  1184. return uReturn;
  1185. }
  1186. /*!--------------------------------------------------------------------------
  1187. CreateLeafTFSNode
  1188. -
  1189. Author: KennT
  1190. ---------------------------------------------------------------------------*/
  1191. TFSCORE_API(HRESULT) CreateLeafTFSNode(ITFSNode **ppNode,
  1192. const GUID *pNodeType,
  1193. ITFSNodeHandler *pNodeHandler,
  1194. ITFSResultHandler *pResultHandler,
  1195. ITFSNodeMgr *pNodeMgr)
  1196. {
  1197. AFX_MANAGE_STATE(AfxGetModuleState());
  1198. SPITFSNode spNode;
  1199. TFSNode * pNode = NULL;
  1200. HRESULT hr = hrOK;
  1201. COM_PROTECT_TRY
  1202. {
  1203. pNode = new TFSNode;
  1204. Assert(pNode);
  1205. spNode = pNode;
  1206. CORg(pNode->Construct(pNodeType, pNodeHandler, pResultHandler, pNodeMgr));
  1207. *ppNode = spNode.Transfer();
  1208. COM_PROTECT_ERROR_LABEL;
  1209. }
  1210. COM_PROTECT_CATCH
  1211. return hr;
  1212. }
  1213. /*!--------------------------------------------------------------------------
  1214. CreateContainerTFSNode
  1215. -
  1216. Author: KennT
  1217. ---------------------------------------------------------------------------*/
  1218. TFSCORE_API(HRESULT) CreateContainerTFSNode(ITFSNode **ppNode,
  1219. const GUID *pNodeType,
  1220. ITFSNodeHandler *pNodeHandler,
  1221. ITFSResultHandler *pResultHandler,
  1222. ITFSNodeMgr *pNodeMgr)
  1223. {
  1224. AFX_MANAGE_STATE(AfxGetModuleState());
  1225. SPITFSNode spNode;
  1226. TFSContainer * pContainer = NULL;
  1227. HRESULT hr = hrOK;
  1228. COM_PROTECT_TRY
  1229. {
  1230. pContainer = new TFSContainer;
  1231. Assert(pContainer);
  1232. spNode = pContainer;
  1233. CORg(pContainer->Construct(pNodeType, pNodeHandler, pResultHandler, pNodeMgr));
  1234. *ppNode = spNode.Transfer();
  1235. COM_PROTECT_ERROR_LABEL;
  1236. }
  1237. COM_PROTECT_CATCH
  1238. return hr;
  1239. }
  1240. DEBUG_DECLARE_INSTANCE_COUNTER(TFSNodeMgr);
  1241. /*---------------------------------------------------------------------------
  1242. TFSNodeMgr implementation
  1243. ---------------------------------------------------------------------------*/
  1244. TFSNodeMgr::TFSNodeMgr()
  1245. : m_cRef(1)
  1246. {
  1247. DEBUG_INCREMENT_INSTANCE_COUNTER(TFSNodeMgr);
  1248. }
  1249. TFSNodeMgr::~TFSNodeMgr()
  1250. {
  1251. DEBUG_DECREMENT_INSTANCE_COUNTER(TFSNodeMgr);
  1252. }
  1253. IMPLEMENT_ADDREF_RELEASE(TFSNodeMgr)
  1254. /*!--------------------------------------------------------------------------
  1255. TFSNode::QueryInterface
  1256. -
  1257. Author: KennT
  1258. ---------------------------------------------------------------------------*/
  1259. STDMETHODIMP TFSNodeMgr::QueryInterface(REFIID riid, LPVOID *ppv)
  1260. {
  1261. // Is the pointer bad?
  1262. if (ppv == NULL)
  1263. return E_INVALIDARG;
  1264. // Place NULL in *ppv in case of failure
  1265. *ppv = NULL;
  1266. // This is the non-delegating IUnknown implementation
  1267. if (riid == IID_IUnknown || riid == IID_ITFSNodeMgr)
  1268. *ppv = (LPVOID) this;
  1269. // If we're going to return an interface, AddRef it first
  1270. if (*ppv)
  1271. {
  1272. ((LPUNKNOWN) *ppv)->AddRef();
  1273. return hrOK;
  1274. }
  1275. else
  1276. return E_NOINTERFACE;
  1277. }
  1278. /*!--------------------------------------------------------------------------
  1279. TFSNodeMgr::Construct
  1280. -
  1281. Author: KennT
  1282. ---------------------------------------------------------------------------*/
  1283. HRESULT TFSNodeMgr::Construct(IComponentData *pCompData,
  1284. IConsoleNameSpace2 *pConsoleNS)
  1285. {
  1286. m_spComponentData.Set(pCompData);
  1287. m_spConsoleNS.Set(pConsoleNS);
  1288. return hrOK;
  1289. }
  1290. /*!--------------------------------------------------------------------------
  1291. TFSNodeMgr::GetRootNode
  1292. -
  1293. Author: KennT
  1294. ---------------------------------------------------------------------------*/
  1295. STDMETHODIMP TFSNodeMgr::GetRootNode(ITFSNode **ppTFSNode)
  1296. {
  1297. Assert(ppTFSNode);
  1298. SetI((LPUNKNOWN *) ppTFSNode, m_spRootNode);
  1299. return hrOK;
  1300. }
  1301. /*!--------------------------------------------------------------------------
  1302. TFSNodeMgr::SetRootNode
  1303. -
  1304. Author: KennT
  1305. ---------------------------------------------------------------------------*/
  1306. STDMETHODIMP TFSNodeMgr::SetRootNode(ITFSNode *pRootNode)
  1307. {
  1308. m_spRootNode.Set(pRootNode);
  1309. return hrOK;
  1310. }
  1311. /*!--------------------------------------------------------------------------
  1312. TFSNodeMgr::GetComponentData
  1313. -
  1314. Author: KennT
  1315. ---------------------------------------------------------------------------*/
  1316. STDMETHODIMP TFSNodeMgr::GetComponentData(IComponentData **ppComponentData)
  1317. {
  1318. Assert(ppComponentData);
  1319. SetI((LPUNKNOWN *) ppComponentData, m_spComponentData);
  1320. return hrOK;
  1321. }
  1322. /*!--------------------------------------------------------------------------
  1323. TFSNodeMgr::FindNode
  1324. -
  1325. Author: KennT
  1326. ---------------------------------------------------------------------------*/
  1327. STDMETHODIMP TFSNodeMgr::FindNode(MMC_COOKIE cookie, ITFSNode **ppTFSNode)
  1328. {
  1329. if (cookie == 0)
  1330. {
  1331. *ppTFSNode = m_spRootNode;
  1332. }
  1333. else
  1334. {
  1335. // Call the cookie lookup routines
  1336. *ppTFSNode = (ITFSNode *) cookie;
  1337. }
  1338. Assert(*ppTFSNode);
  1339. (*ppTFSNode)->AddRef();
  1340. return hrOK;
  1341. }
  1342. /*!--------------------------------------------------------------------------
  1343. TFSNodeMgr::RegisterCookieLookup
  1344. -
  1345. Author: KennT
  1346. ---------------------------------------------------------------------------*/
  1347. STDMETHODIMP TFSNodeMgr::RegisterCookieLookup()
  1348. {
  1349. return hrOK;
  1350. }
  1351. /*!--------------------------------------------------------------------------
  1352. TFSNodeMgr::UnregisterCookieLookup
  1353. -
  1354. Author: KennT
  1355. ---------------------------------------------------------------------------*/
  1356. STDMETHODIMP TFSNodeMgr::UnregisterCookieLookup()
  1357. {
  1358. return hrOK;
  1359. }
  1360. /*!--------------------------------------------------------------------------
  1361. TFSNodeMgr::IsCookieValid
  1362. -
  1363. Author: KennT
  1364. ---------------------------------------------------------------------------*/
  1365. STDMETHODIMP TFSNodeMgr::IsCookieValid(MMC_COOKIE cookie)
  1366. {
  1367. return hrOK;
  1368. }
  1369. /*!--------------------------------------------------------------------------
  1370. TFSNodeMgr::SelectNode
  1371. -
  1372. Author: KennT
  1373. ---------------------------------------------------------------------------*/
  1374. STDMETHODIMP TFSNodeMgr::SelectNode(ITFSNode *pNode)
  1375. {
  1376. return hrOK;
  1377. }
  1378. /*!--------------------------------------------------------------------------
  1379. TFSNodeMgr::SetResultPaneNode
  1380. -
  1381. Author: KennT
  1382. ---------------------------------------------------------------------------*/
  1383. STDMETHODIMP TFSNodeMgr::SetResultPaneNode(ITFSNode *pNode)
  1384. {
  1385. m_spResultPaneNode.Set(pNode);
  1386. return hrOK;
  1387. }
  1388. /*!--------------------------------------------------------------------------
  1389. TFSNodeMgr::GetResultPaneNode
  1390. -
  1391. Author: KennT
  1392. ---------------------------------------------------------------------------*/
  1393. STDMETHODIMP TFSNodeMgr::GetResultPaneNode(ITFSNode **ppNode)
  1394. {
  1395. Assert(ppNode);
  1396. SetI((LPUNKNOWN *) ppNode, m_spResultPaneNode);
  1397. return hrOK;
  1398. }
  1399. /*!--------------------------------------------------------------------------
  1400. TFSNodeMgr::GetConsoleNameSpace
  1401. -
  1402. Author: KennT
  1403. ---------------------------------------------------------------------------*/
  1404. STDMETHODIMP TFSNodeMgr::GetConsoleNameSpace(IConsoleNameSpace2 **ppConsoleNS)
  1405. {
  1406. Assert(ppConsoleNS);
  1407. SetI((LPUNKNOWN *) ppConsoleNS, m_spConsoleNS);
  1408. return hrOK;
  1409. }
  1410. /*!--------------------------------------------------------------------------
  1411. TFSNodeMgr::GetConsole
  1412. -
  1413. Author: KennT
  1414. ---------------------------------------------------------------------------*/
  1415. STDMETHODIMP TFSNodeMgr::GetConsole(IConsole2 **ppConsole)
  1416. {
  1417. Assert(ppConsole);
  1418. SetI((LPUNKNOWN *) ppConsole, m_spConsole);
  1419. return hrOK;
  1420. }
  1421. /*!--------------------------------------------------------------------------
  1422. TFSNodeMgr::SetConsole
  1423. -
  1424. Author: KennT
  1425. ---------------------------------------------------------------------------*/
  1426. STDMETHODIMP TFSNodeMgr::SetConsole(IConsoleNameSpace2 *pConsoleNS, IConsole2 *pConsole)
  1427. {
  1428. m_spConsoleNS.Set(pConsoleNS);
  1429. m_spConsole.Set(pConsole);
  1430. return hrOK;
  1431. }
  1432. STDMETHODIMP TFSNode::Destroy()
  1433. {
  1434. if (m_spNodeHandler)
  1435. {
  1436. m_spNodeHandler->DestroyHandler((ITFSNode *) this);
  1437. }
  1438. if (m_spResultHandler)
  1439. {
  1440. m_spResultHandler->DestroyResultHandler(m_cookie);
  1441. m_spResultHandler.Release();
  1442. }
  1443. //Bug 254167 We need to DestroyResultHander first before release NodeHandler
  1444. m_spNodeHandler.Release();
  1445. m_spNodeParent.Release();
  1446. m_spNodeMgr.Release();
  1447. return hrOK;
  1448. }
  1449. /*!--------------------------------------------------------------------------
  1450. CreateTFSNodeMgr
  1451. -
  1452. Author: KennT
  1453. ---------------------------------------------------------------------------*/
  1454. TFSCORE_API(HRESULT) CreateTFSNodeMgr(ITFSNodeMgr **ppNodeMgr,
  1455. IComponentData *pComponentData,
  1456. IConsole2 *pConsole,
  1457. IConsoleNameSpace2 *pConsoleNameSpace)
  1458. {
  1459. AFX_MANAGE_STATE(AfxGetModuleState());
  1460. SPITFSNodeMgr spNodeMgr;
  1461. TFSNodeMgr * pTFSNodeMgr = NULL;
  1462. HRESULT hr = hrOK;
  1463. COM_PROTECT_TRY
  1464. {
  1465. pTFSNodeMgr = new TFSNodeMgr;
  1466. // Do this so that it will get freed on error
  1467. spNodeMgr = pTFSNodeMgr;
  1468. CORg( pTFSNodeMgr->Construct(pComponentData, pConsoleNameSpace) );
  1469. *ppNodeMgr = spNodeMgr.Transfer();
  1470. COM_PROTECT_ERROR_LABEL;
  1471. }
  1472. COM_PROTECT_CATCH
  1473. return hr;
  1474. }