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.

1346 lines
37 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. Winshand.cpp
  7. WINS specifc handler base classes
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "winshand.h"
  12. #include "snaputil.h"
  13. MMC_CONSOLE_VERB g_ConsoleVerbs[] =
  14. {
  15. MMC_VERB_OPEN,
  16. MMC_VERB_COPY,
  17. MMC_VERB_PASTE,
  18. MMC_VERB_DELETE,
  19. MMC_VERB_PROPERTIES,
  20. MMC_VERB_RENAME,
  21. MMC_VERB_REFRESH,
  22. MMC_VERB_PRINT
  23. };
  24. #define HI HIDDEN
  25. #define EN ENABLED
  26. // StatusRemove
  27. MMC_BUTTON_STATE g_ConsoleVerbStates[WINSSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  28. {
  29. {HI, HI, HI, HI, EN, HI, HI, HI}, // WINSSNAP_ROOT
  30. {HI, HI, HI, EN, EN, HI, EN, HI}, // WINSSNAP_SERVER
  31. {HI, HI, HI, HI, HI, HI, EN, HI}, // WINSSNAP_ACTIVEREG
  32. {HI, HI, HI, HI, EN, HI, EN, HI}, // WINSSNAP_REPLICATION_PARTNERS
  33. {HI, HI, HI, HI, EN, HI, EN, HI}, // WINSSNAP_SERVER_STATUS
  34. {HI, HI, HI, EN, EN, HI, HI, HI}, // WINSSNAP_REGISTRATION
  35. {HI, HI, HI, EN, EN, HI, HI, HI}, // WINSSNAP_REPLICATION_PARTNER
  36. {HI, HI, HI, HI, HI, HI, HI, HI} // WINSSNAP_STATUS_LEAF_NODE
  37. };
  38. //Status Remove
  39. MMC_BUTTON_STATE g_ConsoleVerbStatesMultiSel[WINSSNAP_NODETYPE_MAX][ARRAYLEN(g_ConsoleVerbs)] =
  40. {
  41. {HI, HI, HI, HI, HI, HI, HI, HI}, // WINSSNAP_ROOT
  42. {HI, HI, HI, HI, HI, HI, HI, HI}, // WINSSNAP_SERVER
  43. {HI, HI, HI, HI, HI, HI, EN, HI}, // WINSSNAP_ACTIVEREG
  44. {HI, HI, HI, EN, HI, HI, HI, HI}, // WINSSNAP_REPLICATION_PARTNERS
  45. {HI, HI, HI, HI, HI, HI, HI, HI}, // WINSSNAP_SERVER_STATUS
  46. {HI, HI, HI, EN, HI, HI, HI, HI}, // WINSSNAP_REGISTRATION
  47. {HI, HI, HI, EN, HI, HI, HI, HI}, // WINSSNAP_REPLICATION_PARTNER
  48. {HI, HI, HI, HI, HI, HI, HI, HI} // WINSSNAP_STATUS_LEAF_NODE
  49. };
  50. // Help ID array for help on scope items
  51. DWORD g_dwMMCHelp[WINSSNAP_NODETYPE_MAX] =
  52. {
  53. WINSSNAP_HELP_ROOT, // WINSSNAP_ROOT
  54. WINSSNAP_HELP_SERVER, // WINSSNAP_SERVER
  55. WINSSNAP_HELP_ACT_REG_NODE, // WINSSNAP_ACTIVEREG
  56. WINSSNAP_HELP_REP_PART_NODE, // WINSSNAP_REPLICATION_PARTNERS
  57. WINSSNAP_HELP_ACTREG_ENTRY, // WINSSNAP_SCOPE
  58. WINSSNAP_HELP_REP_PART_ENTRY // WINSSNAP_REPLICATION_PARTNER
  59. };
  60. /*---------------------------------------------------------------------------
  61. Class: CMTWinsHandler
  62. ---------------------------------------------------------------------------*/
  63. //
  64. // Called by the result handler when a command comes in that isn't handled
  65. // by the result handler. If appropriate it passes it to the scope pane hander.
  66. //
  67. HRESULT
  68. CMTWinsHandler::HandleScopeCommand
  69. (
  70. MMC_COOKIE cookie,
  71. int nCommandID,
  72. LPDATAOBJECT pDataObject
  73. )
  74. {
  75. HRESULT hr = hrOK;
  76. SPITFSNode spNode;
  77. DATA_OBJECT_TYPES dwType = CCT_RESULT;
  78. if (IS_SPECIAL_DATAOBJECT(pDataObject))
  79. {
  80. dwType = CCT_SCOPE;
  81. }
  82. else
  83. {
  84. if (pDataObject)
  85. {
  86. SPINTERNAL spInternal;
  87. spInternal = ::ExtractInternalFormat(pDataObject);
  88. if (spInternal)
  89. dwType = spInternal->m_type;
  90. }
  91. }
  92. if (dwType == CCT_SCOPE)
  93. {
  94. // call the handler to take care of this
  95. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  96. hr = OnCommand(spNode, nCommandID, dwType, pDataObject, (ULONG) spNode->GetData(TFS_DATA_TYPE));
  97. }
  98. Error:
  99. return hr;
  100. }
  101. //
  102. // Called by the result handler to add the scope pane menu items to the menu
  103. // where appropriate. Puts scope pane menu items in when action menu is clicked
  104. // and the message view has focus as well as when a right click happens in the white
  105. // space of the result pane.
  106. //
  107. HRESULT
  108. CMTWinsHandler::HandleScopeMenus
  109. (
  110. MMC_COOKIE cookie,
  111. LPDATAOBJECT pDataObject,
  112. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  113. long * pInsertionAllowed
  114. )
  115. {
  116. HRESULT hr = hrOK;
  117. SPITFSNode spNode;
  118. DATA_OBJECT_TYPES dwType = CCT_RESULT;
  119. if (IS_SPECIAL_DATAOBJECT(pDataObject))
  120. {
  121. dwType = CCT_SCOPE;
  122. }
  123. else
  124. {
  125. if (pDataObject)
  126. {
  127. SPINTERNAL spInternal;
  128. spInternal = ::ExtractInternalFormat(pDataObject);
  129. if (spInternal)
  130. dwType = spInternal->m_type;
  131. }
  132. }
  133. if (dwType == CCT_SCOPE)
  134. {
  135. // call the normal handler to put up the menu items
  136. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  137. hr = OnAddMenuItems(spNode, pContextMenuCallback, pDataObject, CCT_SCOPE, (ULONG) spNode->GetData(TFS_DATA_TYPE), pInsertionAllowed);
  138. }
  139. Error:
  140. return hr;
  141. }
  142. /*---------------------------------------------------------------------------
  143. CMTWinsHandler::OnChangeState
  144. Description
  145. Author: EricDav
  146. ---------------------------------------------------------------------------*/
  147. void CMTWinsHandler::OnChangeState
  148. (
  149. ITFSNode * pNode
  150. )
  151. {
  152. // Increment the state to the next position
  153. switch (m_nState)
  154. {
  155. case notLoaded:
  156. case loaded:
  157. case unableToLoad:
  158. {
  159. m_nState = loading;
  160. m_dwErr = 0;
  161. }
  162. break;
  163. case loading:
  164. {
  165. m_nState = (m_dwErr != 0) ? unableToLoad : loaded;
  166. if (m_dwErr)
  167. {
  168. CString strTitle, strBody;
  169. IconIdentifier icon;
  170. GetErrorInfo(strTitle, strBody, &icon);
  171. ShowMessage(pNode, strTitle, strBody, icon);
  172. }
  173. else
  174. {
  175. ClearMessage(pNode);
  176. }
  177. m_fSilent = FALSE;
  178. }
  179. break;
  180. default:
  181. ASSERT(FALSE);
  182. }
  183. // check to make sure we are still the visible node in the UI
  184. if (m_bSelected)
  185. {
  186. UpdateStandardVerbs(pNode, pNode->GetData(TFS_DATA_TYPE));
  187. }
  188. // Now check and see if there is a new image for this state for this handler
  189. int nImage, nOpenImage;
  190. nImage = GetImageIndex(FALSE);
  191. nOpenImage = GetImageIndex(TRUE);
  192. if (nImage >= 0)
  193. pNode->SetData(TFS_DATA_IMAGEINDEX, nImage);
  194. if (nOpenImage >= 0)
  195. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, nOpenImage);
  196. VERIFY(SUCCEEDED(pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_ICON)));
  197. }
  198. /*!--------------------------------------------------------------------------
  199. CMTWinsHandler::UpdateStandardVerbs
  200. Tells the IComponent to update the verbs for this node
  201. Author: EricDav
  202. ---------------------------------------------------------------------------*/
  203. void
  204. CMTWinsHandler::UpdateStandardVerbs
  205. (
  206. ITFSNode * pNode,
  207. LONG_PTR dwNodeType
  208. )
  209. {
  210. HRESULT hr = hrOK;
  211. SPIComponentData spCompData;
  212. SPIConsole spConsole;
  213. IDataObject* pDataObject;
  214. m_spNodeMgr->GetComponentData(&spCompData);
  215. CORg ( spCompData->QueryDataObject(NULL, CCT_RESULT, &pDataObject) );
  216. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  217. CORg ( spConsole->UpdateAllViews(pDataObject,
  218. dwNodeType,
  219. RESULT_PANE_UPDATE_VERBS) );
  220. pDataObject->Release();
  221. Error:
  222. return;
  223. }
  224. /*---------------------------------------------------------------------------
  225. CMTWinsHandler::OnResultDelete
  226. Description
  227. Author: EricDav
  228. ---------------------------------------------------------------------------*/
  229. HRESULT
  230. CMTWinsHandler::OnResultDelete
  231. (
  232. ITFSComponent * pComponent,
  233. LPDATAOBJECT pDataObject,
  234. MMC_COOKIE cookie,
  235. LPARAM arg,
  236. LPARAM lParam
  237. )
  238. {
  239. HRESULT hr = hrOK;
  240. Trace0("CMTWinsHandler::OnResultDelete received\n");
  241. // translate this call to the parent and let it handle deletion
  242. // of result pane items
  243. SPITFSNode spNode, spParent;
  244. SPITFSResultHandler spParentRH;
  245. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  246. CORg (spNode->GetParent(&spParent));
  247. if (spParent == NULL)
  248. return hr;
  249. CORg (spParent->GetResultHandler(&spParentRH));
  250. CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_DELETE, arg, lParam));
  251. Error:
  252. return hr;
  253. }
  254. /*!--------------------------------------------------------------------------
  255. CMTWinsHandler::UpdateConsoleVerbs
  256. Updates the standard verbs depending upon the state of the node
  257. Author: EricDav
  258. ---------------------------------------------------------------------------*/
  259. void
  260. CMTWinsHandler::UpdateConsoleVerbs
  261. (
  262. IConsoleVerb * pConsoleVerb,
  263. LONG_PTR dwNodeType,
  264. BOOL bMultiSelect
  265. )
  266. {
  267. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  268. MMC_BUTTON_STATE * ButtonState;
  269. int i;
  270. if (bMultiSelect)
  271. {
  272. ButtonState = g_ConsoleVerbStatesMultiSel[dwNodeType];
  273. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  274. }
  275. else
  276. {
  277. ButtonState = g_ConsoleVerbStates[dwNodeType];
  278. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  279. switch (m_nState)
  280. {
  281. case loaded:
  282. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  283. break;
  284. case notLoaded:
  285. case loading:
  286. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  287. break;
  288. case unableToLoad:
  289. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  290. bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
  291. bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
  292. break;
  293. }
  294. }
  295. EnableVerbs(pConsoleVerb, ButtonState, bStates);
  296. }
  297. /*!--------------------------------------------------------------------------
  298. CMTWinsHandler::EnableVerbs
  299. Enables the toolbar buttons
  300. Author: EricDav
  301. ---------------------------------------------------------------------------*/
  302. void
  303. CMTWinsHandler::EnableVerbs
  304. (
  305. IConsoleVerb * pConsoleVerb,
  306. MMC_BUTTON_STATE ButtonState[],
  307. BOOL bState[]
  308. )
  309. {
  310. if (pConsoleVerb == NULL)
  311. {
  312. Assert(FALSE);
  313. return;
  314. }
  315. for (int i=0; i < ARRAYLEN(g_ConsoleVerbs); ++i)
  316. {
  317. if (ButtonState[i] == ENABLED)
  318. {
  319. // unhide this button before enabling
  320. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  321. HIDDEN,
  322. FALSE);
  323. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  324. ButtonState[i],
  325. bState[i]);
  326. }
  327. else
  328. {
  329. // hide this button
  330. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  331. HIDDEN,
  332. TRUE);
  333. }
  334. }
  335. pConsoleVerb->SetDefaultVerb(m_verbDefault);
  336. }
  337. /*!--------------------------------------------------------------------------
  338. CMTWinsHandler::ExpandNode
  339. Expands/compresses this node
  340. Author: EricDav
  341. ---------------------------------------------------------------------------*/
  342. void
  343. CMTWinsHandler::ExpandNode
  344. (
  345. ITFSNode * pNode,
  346. BOOL fExpand
  347. )
  348. {
  349. SPIComponentData spCompData;
  350. SPIDataObject spDataObject;
  351. LPDATAOBJECT pDataObject;
  352. SPIConsole spConsole;
  353. HRESULT hr = hrOK;
  354. // don't expand the node if we are handling the EXPAND_SYNC message,
  355. // this screws up the insertion of item, getting duplicates.
  356. if (!m_fExpandSync)
  357. {
  358. m_spNodeMgr->GetComponentData(&spCompData);
  359. CORg ( spCompData->QueryDataObject((MMC_COOKIE) pNode, CCT_SCOPE, &pDataObject) );
  360. spDataObject = pDataObject;
  361. CORg ( m_spNodeMgr->GetConsole(&spConsole) );
  362. CORg ( spConsole->UpdateAllViews(pDataObject, TRUE, RESULT_PANE_EXPAND) );
  363. }
  364. Error:
  365. return;
  366. }
  367. /*!--------------------------------------------------------------------------
  368. CMTWinsHandler::OnExpandSync
  369. Handles the MMCN_EXPANDSYNC notifcation
  370. We need to do syncronous enumeration. We'll fire off the background
  371. thread like before, but we'll wait for it to exit before we return.
  372. Author: EricDav
  373. ---------------------------------------------------------------------------*/
  374. HRESULT
  375. CMTWinsHandler::OnExpandSync
  376. (
  377. ITFSNode * pNode,
  378. LPDATAOBJECT pDataObject,
  379. LPARAM arg,
  380. LPARAM lParam
  381. )
  382. {
  383. HRESULT hr = hrOK;
  384. MSG msg;
  385. m_fExpandSync = TRUE;
  386. hr = OnExpand(pNode, pDataObject, CCT_SCOPE, arg, lParam);
  387. // wait for the background thread to exit
  388. if (m_hThread != NULL)
  389. WaitForSingleObject(m_hThread, INFINITE);
  390. // The background thread posts messages to a hidden window to
  391. // pass data back to the main thread. The messages won't go through since we are
  392. // blocking the main thread. The data goes on a queue in the query object
  393. // which the handler has a pointer to so we can just fake the notification.
  394. if (m_spQuery.p)
  395. OnNotifyHaveData((LPARAM) m_spQuery.p);
  396. // Tell MMC we handled this message
  397. MMC_EXPANDSYNC_STRUCT * pES = reinterpret_cast<MMC_EXPANDSYNC_STRUCT *>(lParam);
  398. if (pES)
  399. pES->bHandled = TRUE;
  400. m_fExpandSync = FALSE;
  401. return hr;
  402. }
  403. /*!--------------------------------------------------------------------------
  404. CMTWinsHandler::OnResultSelect
  405. Handles the MMCN_SELECT notifcation
  406. Author: EricDav
  407. ---------------------------------------------------------------------------*/
  408. HRESULT
  409. CMTWinsHandler::OnResultSelect
  410. (
  411. ITFSComponent * pComponent,
  412. LPDATAOBJECT pDataObject,
  413. MMC_COOKIE cookie,
  414. LPARAM arg,
  415. LPARAM lParam
  416. )
  417. {
  418. HRESULT hr = hrOK;
  419. SPIConsoleVerb spConsoleVerb;
  420. SPITFSNode spNode;
  421. SPINTERNAL spInternal;
  422. BOOL bMultiSelect = FALSE;
  423. BOOL bScope = (BOOL) LOWORD(arg);
  424. BOOL bSelect = (BOOL) HIWORD(arg);
  425. m_bSelected = bSelect;
  426. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  427. spInternal = ::ExtractInternalFormat(pDataObject);
  428. if (spInternal &&
  429. spInternal->m_cookie == MMC_MULTI_SELECT_COOKIE)
  430. {
  431. CORg (pComponent->GetSelectedNode(&spNode));
  432. bMultiSelect = TRUE;
  433. }
  434. else
  435. {
  436. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  437. }
  438. UpdateConsoleVerbs(spConsoleVerb, spNode->GetData(TFS_DATA_TYPE), bMultiSelect);
  439. Error:
  440. return hr;
  441. }
  442. /*!--------------------------------------------------------------------------
  443. CMTWinsHandler::OnCreateDataObject
  444. -
  445. Author: EricDav
  446. ---------------------------------------------------------------------------*/
  447. STDMETHODIMP
  448. CMTWinsHandler::OnCreateDataObject
  449. (
  450. ITFSComponent * pComponent,
  451. MMC_COOKIE cookie,
  452. DATA_OBJECT_TYPES type,
  453. IDataObject ** ppDataObject
  454. )
  455. {
  456. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  457. Assert(ppDataObject != NULL);
  458. CDataObject * pObject = NULL;
  459. SPIDataObject spDataObject;
  460. long lViewOptions;
  461. LPOLESTR pViewType;
  462. BOOL bVirtual;
  463. pObject = new CDataObject;
  464. spDataObject = pObject; // do this so that it gets released correctly
  465. Assert(pObject != NULL);
  466. if (cookie == MMC_MULTI_SELECT_COOKIE)
  467. {
  468. OnGetResultViewType(pComponent, cookie, &pViewType, &lViewOptions);
  469. bVirtual = (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ? TRUE : FALSE;
  470. CreateMultiSelectData(pComponent, pObject, bVirtual);
  471. }
  472. // Save cookie and type for delayed rendering
  473. pObject->SetType(type);
  474. pObject->SetCookie(cookie);
  475. // Store the coclass with the data object
  476. pObject->SetClsid(*(m_spTFSComponentData->GetCoClassID()));
  477. pObject->SetTFSComponentData(m_spTFSComponentData);
  478. return pObject->QueryInterface(IID_IDataObject,
  479. reinterpret_cast<void**>(ppDataObject));
  480. }
  481. /*!--------------------------------------------------------------------------
  482. CMTWinsHandler::CreateMultiSelectData
  483. -
  484. Author: EricDav
  485. ---------------------------------------------------------------------------*/
  486. HRESULT
  487. CMTWinsHandler::CreateMultiSelectData
  488. (
  489. ITFSComponent * pComponent,
  490. CDataObject * pObject,
  491. BOOL bVirtual
  492. )
  493. {
  494. HRESULT hr = hrOK;
  495. // build the list of selected nodes
  496. CTFSNodeList listSelectedNodes;
  497. CVirtualIndexArray arraySelectedIndicies;
  498. CGUIDArray rgGuids;
  499. UINT cb;
  500. GUID* pGuid;
  501. const GUID * pcGuid;
  502. int i;
  503. COM_PROTECT_TRY
  504. {
  505. if (bVirtual)
  506. {
  507. // build a list of the selected indicies in the virtual listbox
  508. CORg (BuildVirtualSelectedItemList(pComponent, &arraySelectedIndicies));
  509. // now call and get the GUIDs for each one
  510. for (i = 0; i < arraySelectedIndicies.GetSize(); i++)
  511. {
  512. pcGuid = GetVirtualGuid(arraySelectedIndicies[i]);
  513. if (pcGuid)
  514. rgGuids.AddUnique(*pcGuid);
  515. }
  516. }
  517. else
  518. {
  519. CORg (BuildSelectedItemList(pComponent, &listSelectedNodes));
  520. // collect all of the unique guids
  521. while (listSelectedNodes.GetCount() > 0)
  522. {
  523. SPITFSNode spCurNode;
  524. spCurNode = listSelectedNodes.RemoveHead();
  525. pcGuid = spCurNode->GetNodeType();
  526. rgGuids.AddUnique(*pcGuid);
  527. }
  528. }
  529. // now put the information in the data object
  530. cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
  531. if (cb > 0)
  532. {
  533. pObject->SetMultiSelDobj();
  534. pGuid = new GUID[(size_t)rgGuids.GetSize()];
  535. CopyMemory(pGuid, rgGuids.GetData(), cb);
  536. pObject->SetMultiSelData((BYTE*)pGuid, cb);
  537. }
  538. COM_PROTECT_ERROR_LABEL;
  539. }
  540. COM_PROTECT_CATCH
  541. return hr;
  542. }
  543. /*!--------------------------------------------------------------------------
  544. CMTWinsHandler::OnResultUpdateView
  545. Implementation of ITFSResultHandler::OnResultUpdateView
  546. Author: EricDav
  547. ---------------------------------------------------------------------------*/
  548. HRESULT CMTWinsHandler::OnResultUpdateView
  549. (
  550. ITFSComponent *pComponent,
  551. LPDATAOBJECT pDataObject,
  552. LPARAM data,
  553. LPARAM hint
  554. )
  555. {
  556. HRESULT hr = hrOK;
  557. if (hint == RESULT_PANE_UPDATE_VERBS)
  558. {
  559. SPIConsoleVerb spConsoleVerb;
  560. SPITFSNode spNode;
  561. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  562. UpdateConsoleVerbs(spConsoleVerb, data);
  563. }
  564. else
  565. {
  566. return CBaseResultHandler::OnResultUpdateView(pComponent, pDataObject, data, hint);
  567. }
  568. Error:
  569. return hr;
  570. }
  571. /*!--------------------------------------------------------------------------
  572. CMTWinsHandler::OnResultContextHelp
  573. Implementation of ITFSResultHandler::OnResultContextHelp
  574. Author: v-shubk
  575. ---------------------------------------------------------------------------*/
  576. HRESULT
  577. CMTWinsHandler::OnResultContextHelp
  578. (
  579. ITFSComponent * pComponent,
  580. LPDATAOBJECT pDataObject,
  581. MMC_COOKIE cookie,
  582. LPARAM arg,
  583. LPARAM lParam
  584. )
  585. {
  586. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  587. HRESULT hr = hrOK;
  588. SPIDisplayHelp spDisplayHelp;
  589. SPIConsole spConsole;
  590. pComponent->GetConsole(&spConsole);
  591. hr = spConsole->QueryInterface (IID_IDisplayHelp, (LPVOID*) &spDisplayHelp);
  592. ASSERT (SUCCEEDED (hr));
  593. if ( SUCCEEDED (hr) )
  594. {
  595. LPCTSTR pszHelpFile = m_spTFSCompData->GetHTMLHelpFileName();
  596. if (pszHelpFile == NULL)
  597. goto Error;
  598. CString szHelpFilePath;
  599. UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  600. if (nLen == 0)
  601. {
  602. hr = E_FAIL;
  603. goto Error;
  604. }
  605. szHelpFilePath.ReleaseBuffer();
  606. szHelpFilePath += g_szDefaultHelpTopic;
  607. hr = spDisplayHelp->ShowTopic (T2OLE ((LPTSTR)(LPCTSTR) szHelpFilePath));
  608. ASSERT (SUCCEEDED (hr));
  609. }
  610. Error:
  611. return hr;
  612. }
  613. /*!--------------------------------------------------------------------------
  614. CMTWinsHandler::SaveColumns
  615. -
  616. ---------------------------------------------------------------------------*/
  617. HRESULT
  618. CMTWinsHandler::SaveColumns
  619. (
  620. ITFSComponent * pComponent,
  621. MMC_COOKIE cookie,
  622. LPARAM arg,
  623. LPARAM lParam
  624. )
  625. {
  626. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  627. HRESULT hr = hrOK;
  628. LONG_PTR dwNodeType;
  629. int nCol = 0;
  630. int nColWidth;
  631. SPITFSNode spNode, spRootNode;
  632. SPIHeaderCtrl spHeaderCtrl;
  633. BOOL bDirty = FALSE;
  634. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  635. CORg (pComponent->GetHeaderCtrl(&spHeaderCtrl));
  636. dwNodeType = spNode->GetData(TFS_DATA_TYPE);
  637. while (aColumns[dwNodeType][nCol] != 0)
  638. {
  639. if (SUCCEEDED(spHeaderCtrl->GetColumnWidth(nCol, &nColWidth)) &&
  640. (aColumnWidths[dwNodeType][nCol] != nColWidth))
  641. {
  642. aColumnWidths[dwNodeType][nCol] = nColWidth;
  643. bDirty = TRUE;
  644. }
  645. nCol++;
  646. }
  647. if (bDirty)
  648. {
  649. CORg (m_spNodeMgr->GetRootNode(&spRootNode));
  650. spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
  651. }
  652. Error:
  653. return hr;
  654. }
  655. /*---------------------------------------------------------------------------
  656. Class: CWinsHandler
  657. ---------------------------------------------------------------------------*/
  658. //
  659. // Called by the result handler when a command comes in that isn't handled
  660. // by the result handler. If appropriate it passes it to the scope pane hander.
  661. //
  662. HRESULT
  663. CWinsHandler::HandleScopeCommand
  664. (
  665. MMC_COOKIE cookie,
  666. int nCommandID,
  667. LPDATAOBJECT pDataObject
  668. )
  669. {
  670. HRESULT hr = hrOK;
  671. SPITFSNode spNode;
  672. DATA_OBJECT_TYPES dwType = CCT_RESULT;
  673. if (IS_SPECIAL_DATAOBJECT(pDataObject))
  674. {
  675. dwType = CCT_SCOPE;
  676. }
  677. else
  678. {
  679. if (pDataObject)
  680. {
  681. SPINTERNAL spInternal;
  682. spInternal = ::ExtractInternalFormat(pDataObject);
  683. if (spInternal)
  684. dwType = spInternal->m_type;
  685. }
  686. }
  687. if (dwType == CCT_SCOPE)
  688. {
  689. // call the handler to take care of this
  690. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  691. hr = OnCommand(spNode, nCommandID, dwType, pDataObject, (ULONG) spNode->GetData(TFS_DATA_TYPE));
  692. }
  693. Error:
  694. return hr;
  695. }
  696. //
  697. // Called by the result handler to add the scope pane menu items to the menu
  698. // where appropriate. Puts scope pane menu items in when action menu is clicked
  699. // and the message view has focus as well as when a right click happens in the white
  700. // space of the result pane.
  701. //
  702. HRESULT
  703. CWinsHandler::HandleScopeMenus
  704. (
  705. MMC_COOKIE cookie,
  706. LPDATAOBJECT pDataObject,
  707. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  708. long * pInsertionAllowed
  709. )
  710. {
  711. HRESULT hr = hrOK;
  712. SPITFSNode spNode;
  713. DATA_OBJECT_TYPES dwType = CCT_RESULT;
  714. if (IS_SPECIAL_DATAOBJECT(pDataObject))
  715. {
  716. dwType = CCT_SCOPE;
  717. }
  718. else
  719. {
  720. if (pDataObject)
  721. {
  722. SPINTERNAL spInternal;
  723. spInternal = ::ExtractInternalFormat(pDataObject);
  724. if (spInternal)
  725. dwType = spInternal->m_type;
  726. }
  727. }
  728. if (dwType == CCT_SCOPE)
  729. {
  730. // call the normal handler to put up the menu items
  731. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  732. hr = OnAddMenuItems(spNode, pContextMenuCallback, pDataObject, CCT_SCOPE, (ULONG) spNode->GetData(TFS_DATA_TYPE), pInsertionAllowed);
  733. }
  734. Error:
  735. return hr;
  736. }
  737. /*---------------------------------------------------------------------------
  738. CWinsHandler::Command
  739. Description
  740. Author: EricDav
  741. ---------------------------------------------------------------------------*/
  742. STDMETHODIMP
  743. CWinsHandler::Command
  744. (
  745. ITFSComponent * pComponent,
  746. MMC_COOKIE cookie,
  747. int nCommandID,
  748. LPDATAOBJECT pDataObject
  749. )
  750. {
  751. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  752. HRESULT hr = S_OK;
  753. // this may have come from the scope pane handler, so pass it up
  754. hr = HandleScopeCommand(cookie, nCommandID, pDataObject);
  755. return hr;
  756. }
  757. /*!--------------------------------------------------------------------------
  758. CWinsHandler::AddMenuItems
  759. Over-ride this to add our view menu item
  760. Author: EricDav
  761. ---------------------------------------------------------------------------*/
  762. STDMETHODIMP
  763. CWinsHandler::AddMenuItems
  764. (
  765. ITFSComponent * pComponent,
  766. MMC_COOKIE cookie,
  767. LPDATAOBJECT pDataObject,
  768. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  769. long * pInsertionAllowed
  770. )
  771. {
  772. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  773. HRESULT hr = S_OK;
  774. // figure out if we need to pass this to the scope pane menu handler
  775. hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed);
  776. return hr;
  777. }
  778. /*---------------------------------------------------------------------------
  779. CWinsHandler::OnResultDelete
  780. Description
  781. Author: EricDav
  782. ---------------------------------------------------------------------------*/
  783. HRESULT
  784. CWinsHandler::OnResultDelete
  785. (
  786. ITFSComponent * pComponent,
  787. LPDATAOBJECT pDataObject,
  788. MMC_COOKIE cookie,
  789. LPARAM arg,
  790. LPARAM lParam
  791. )
  792. {
  793. HRESULT hr = hrOK;
  794. Trace0("CWinsHandler::OnResultDelete received\n");
  795. // translate this call to the parent and let it handle deletion
  796. // of result pane items
  797. SPITFSNode spNode, spParent;
  798. SPITFSResultHandler spParentRH;
  799. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  800. CORg (spNode->GetParent(&spParent));
  801. if (spParent == NULL)
  802. return hr;
  803. CORg (spParent->GetResultHandler(&spParentRH));
  804. CORg (spParentRH->Notify(pComponent, spParent->GetData(TFS_DATA_COOKIE), pDataObject, MMCN_DELETE, arg, lParam));
  805. Error:
  806. return hr;
  807. }
  808. /*!--------------------------------------------------------------------------
  809. CWinsHandler::UpdateConsoleVerbs
  810. Updates the standard verbs depending upon the state of the node
  811. Author: EricDav
  812. ---------------------------------------------------------------------------*/
  813. void
  814. CWinsHandler::UpdateConsoleVerbs
  815. (
  816. IConsoleVerb * pConsoleVerb,
  817. LONG_PTR dwNodeType,
  818. BOOL bMultiSelect
  819. )
  820. {
  821. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  822. MMC_BUTTON_STATE * ButtonState;
  823. int i;
  824. if (bMultiSelect)
  825. {
  826. ButtonState = g_ConsoleVerbStatesMultiSel[dwNodeType];
  827. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  828. }
  829. else
  830. {
  831. /*
  832. ButtonState = g_ConsoleVerbStates[dwNodeType];
  833. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  834. */
  835. ButtonState = g_ConsoleVerbStates[dwNodeType];
  836. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  837. switch (m_nState)
  838. {
  839. case loaded:
  840. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  841. break;
  842. case notLoaded:
  843. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  844. bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
  845. bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
  846. break;
  847. case loading:
  848. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  849. break;
  850. case unableToLoad:
  851. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  852. bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
  853. bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
  854. break;
  855. }
  856. }
  857. EnableVerbs(pConsoleVerb, ButtonState, bStates);
  858. }
  859. /*!--------------------------------------------------------------------------
  860. CWinsHandler::EnableVerbs
  861. Enables the toolbar buttons
  862. Author: EricDav
  863. ---------------------------------------------------------------------------*/
  864. void
  865. CWinsHandler::EnableVerbs
  866. (
  867. IConsoleVerb * pConsoleVerb,
  868. MMC_BUTTON_STATE ButtonState[],
  869. BOOL bState[]
  870. )
  871. {
  872. if (pConsoleVerb == NULL)
  873. {
  874. Assert(FALSE);
  875. return;
  876. }
  877. for (int i=0; i < ARRAYLEN(g_ConsoleVerbs); ++i)
  878. {
  879. if (ButtonState[i] == ENABLED)
  880. {
  881. // unhide this button before enabling
  882. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  883. HIDDEN,
  884. FALSE);
  885. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  886. ButtonState[i],
  887. bState[i]);
  888. }
  889. else
  890. {
  891. // hide this button
  892. pConsoleVerb->SetVerbState(g_ConsoleVerbs[i],
  893. HIDDEN,
  894. TRUE);
  895. }
  896. }
  897. pConsoleVerb->SetDefaultVerb(m_verbDefault);
  898. }
  899. /*!--------------------------------------------------------------------------
  900. CWinsHandler::OnResultSelect
  901. Handles the MMCN_SELECT notifcation
  902. Author: EricDav
  903. ---------------------------------------------------------------------------*/
  904. HRESULT
  905. CWinsHandler::OnResultSelect
  906. (
  907. ITFSComponent * pComponent,
  908. LPDATAOBJECT pDataObject,
  909. MMC_COOKIE cookie,
  910. LPARAM arg,
  911. LPARAM lParam
  912. )
  913. {
  914. HRESULT hr = hrOK;
  915. SPIConsoleVerb spConsoleVerb;
  916. SPITFSNode spNode;
  917. SPINTERNAL spInternal;
  918. BOOL bMultiSelect;
  919. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  920. spInternal = ::ExtractInternalFormat(pDataObject);
  921. if (spInternal &&
  922. spInternal->m_cookie == MMC_MULTI_SELECT_COOKIE)
  923. {
  924. CORg (pComponent->GetSelectedNode(&spNode));
  925. bMultiSelect = TRUE;
  926. }
  927. else
  928. {
  929. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  930. bMultiSelect = FALSE;
  931. }
  932. UpdateConsoleVerbs(spConsoleVerb, spNode->GetData(TFS_DATA_TYPE), bMultiSelect);
  933. Error:
  934. return hr;
  935. }
  936. /*!--------------------------------------------------------------------------
  937. CWinsHandler::OnCreateDataObject
  938. -
  939. Author: EricDav
  940. ---------------------------------------------------------------------------*/
  941. STDMETHODIMP
  942. CWinsHandler::OnCreateDataObject
  943. (
  944. ITFSComponent * pComponent,
  945. MMC_COOKIE cookie,
  946. DATA_OBJECT_TYPES type,
  947. IDataObject ** ppDataObject
  948. )
  949. {
  950. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  951. Assert(ppDataObject != NULL);
  952. CDataObject * pObject = NULL;
  953. SPIDataObject spDataObject;
  954. long lViewOptions;
  955. LPOLESTR pViewType;
  956. BOOL bVirtual;
  957. pObject = new CDataObject;
  958. spDataObject = pObject; // do this so that it gets released correctly
  959. Assert(pObject != NULL);
  960. if (cookie == MMC_MULTI_SELECT_COOKIE)
  961. {
  962. OnGetResultViewType(pComponent, cookie, &pViewType, &lViewOptions);
  963. bVirtual = (lViewOptions & MMC_VIEW_OPTIONS_OWNERDATALIST) ? TRUE : FALSE;
  964. CreateMultiSelectData(pComponent, pObject, bVirtual);
  965. }
  966. // Save cookie and type for delayed rendering
  967. pObject->SetType(type);
  968. pObject->SetCookie(cookie);
  969. // Store the coclass with the data object
  970. pObject->SetClsid(*(m_spTFSComponentData->GetCoClassID()));
  971. pObject->SetTFSComponentData(m_spTFSComponentData);
  972. return pObject->QueryInterface(IID_IDataObject,
  973. reinterpret_cast<void**>(ppDataObject));
  974. }
  975. /*!--------------------------------------------------------------------------
  976. CWinsHandler::CreateMultiSelectData
  977. -
  978. Author: EricDav
  979. ---------------------------------------------------------------------------*/
  980. HRESULT
  981. CWinsHandler::CreateMultiSelectData
  982. (
  983. ITFSComponent * pComponent,
  984. CDataObject * pObject,
  985. BOOL bVirtual
  986. )
  987. {
  988. HRESULT hr = hrOK;
  989. // build the list of selected nodes
  990. CTFSNodeList listSelectedNodes;
  991. CVirtualIndexArray arraySelectedIndicies;
  992. CGUIDArray rgGuids;
  993. UINT cb;
  994. GUID* pGuid;
  995. const GUID * pcGuid;
  996. int i;
  997. COM_PROTECT_TRY
  998. {
  999. if (bVirtual)
  1000. {
  1001. // build a list of the selected indicies in the virtual listbox
  1002. CORg (BuildVirtualSelectedItemList(pComponent, &arraySelectedIndicies));
  1003. // now call and get the GUIDs for each one
  1004. for (i = 0; i < arraySelectedIndicies.GetSize(); i++)
  1005. {
  1006. pcGuid = GetVirtualGuid(arraySelectedIndicies[i]);
  1007. if (pcGuid)
  1008. rgGuids.AddUnique(*pcGuid);
  1009. }
  1010. }
  1011. else
  1012. {
  1013. CORg (BuildSelectedItemList(pComponent, &listSelectedNodes));
  1014. // collect all of the unique guids
  1015. while (listSelectedNodes.GetCount() > 0)
  1016. {
  1017. SPITFSNode spCurNode;
  1018. spCurNode = listSelectedNodes.RemoveHead();
  1019. pcGuid = spCurNode->GetNodeType();
  1020. rgGuids.AddUnique(*pcGuid);
  1021. }
  1022. }
  1023. // now put the information in the data object
  1024. cb = (UINT)(rgGuids.GetSize() * sizeof(GUID));
  1025. if (cb > 0)
  1026. {
  1027. pObject->SetMultiSelDobj();
  1028. pGuid = new GUID[(size_t)rgGuids.GetSize()];
  1029. CopyMemory(pGuid, rgGuids.GetData(), cb);
  1030. pObject->SetMultiSelData((BYTE*)pGuid, cb);
  1031. }
  1032. COM_PROTECT_ERROR_LABEL;
  1033. }
  1034. COM_PROTECT_CATCH
  1035. return hr;
  1036. }
  1037. /*!--------------------------------------------------------------------------
  1038. CWinsHandler::OnResultContextHelp
  1039. Implementation of ITFSResultHandler::OnResultContextHelp
  1040. Author: v-shubk
  1041. ---------------------------------------------------------------------------*/
  1042. HRESULT
  1043. CWinsHandler::OnResultContextHelp
  1044. (
  1045. ITFSComponent * pComponent,
  1046. LPDATAOBJECT pDataObject,
  1047. MMC_COOKIE cookie,
  1048. LPARAM arg,
  1049. LPARAM lParam
  1050. )
  1051. {
  1052. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1053. HRESULT hr = hrOK;
  1054. SPIDisplayHelp spDisplayHelp;
  1055. SPIConsole spConsole;
  1056. pComponent->GetConsole(&spConsole);
  1057. hr = spConsole->QueryInterface (IID_IDisplayHelp, (LPVOID*) &spDisplayHelp);
  1058. ASSERT (SUCCEEDED (hr));
  1059. if ( SUCCEEDED (hr) )
  1060. {
  1061. LPCTSTR pszHelpFile = m_spTFSCompData->GetHTMLHelpFileName();
  1062. if (pszHelpFile == NULL)
  1063. goto Error;
  1064. CString szHelpFilePath;
  1065. UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  1066. if (nLen == 0)
  1067. {
  1068. hr = E_FAIL;
  1069. goto Error;
  1070. }
  1071. szHelpFilePath.ReleaseBuffer();
  1072. szHelpFilePath += g_szDefaultHelpTopic;
  1073. hr = spDisplayHelp->ShowTopic (T2OLE ((LPTSTR)(LPCTSTR) szHelpFilePath));
  1074. ASSERT (SUCCEEDED (hr));
  1075. }
  1076. Error:
  1077. return hr;
  1078. }
  1079. /*!--------------------------------------------------------------------------
  1080. CWinsHandler::SaveColumns
  1081. -
  1082. ---------------------------------------------------------------------------*/
  1083. HRESULT
  1084. CWinsHandler::SaveColumns
  1085. (
  1086. ITFSComponent * pComponent,
  1087. MMC_COOKIE cookie,
  1088. LPARAM arg,
  1089. LPARAM lParam
  1090. )
  1091. {
  1092. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1093. HRESULT hr = hrOK;
  1094. LONG_PTR dwNodeType;
  1095. int nCol = 0;
  1096. int nColWidth;
  1097. SPITFSNode spNode, spRootNode;
  1098. SPIHeaderCtrl spHeaderCtrl;
  1099. BOOL bDirty = FALSE;
  1100. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  1101. CORg (pComponent->GetHeaderCtrl(&spHeaderCtrl));
  1102. dwNodeType = spNode->GetData(TFS_DATA_TYPE);
  1103. while (aColumns[dwNodeType][nCol] != 0)
  1104. {
  1105. if (SUCCEEDED(spHeaderCtrl->GetColumnWidth(nCol, &nColWidth)) &&
  1106. (aColumnWidths[dwNodeType][nCol] != nColWidth))
  1107. {
  1108. aColumnWidths[dwNodeType][nCol] = nColWidth;
  1109. bDirty = TRUE;
  1110. }
  1111. nCol++;
  1112. }
  1113. if (bDirty)
  1114. {
  1115. CORg (m_spNodeMgr->GetRootNode(&spRootNode));
  1116. spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
  1117. }
  1118. Error:
  1119. return hr;
  1120. }