Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3370 lines
91 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: oncmenu.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 1/9/1997 RaviR Created
  15. //____________________________________________________________________________
  16. //
  17. #include "stdafx.h"
  18. #include "tasks.h"
  19. #include "oncmenu.h"
  20. #include <comcat.h> // COM Component Categories Manager
  21. #include "compcat.h"
  22. #include "guids.h"
  23. #include "newnode.h"
  24. #include "..\inc\amcmsgid.h"
  25. #include "multisel.h"
  26. #include "scopndcb.h"
  27. #include "cmenuinfo.h"
  28. #include "contree.h"
  29. #include "conview.h"
  30. #include "conframe.h"
  31. #include "rsltitem.h"
  32. #include "variant.h" // ConvertByRefVariantToByValue
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. // forward reference
  38. class CConsoleStatusBar;
  39. //############################################################################
  40. //############################################################################
  41. //
  42. // Language-independent menu names. DO NOT CHANGE THESE!!
  43. //
  44. // the macro expands out to something like
  45. // const LPCTSTR szCONTEXTHELP = TEXT("_CONTEXTHELP")
  46. //
  47. //############################################################################
  48. //############################################################################
  49. #define DECLARE_MENU_ITEM(_item) const LPCTSTR sz##_item = TEXT("_")TEXT(#_item);
  50. DECLARE_MENU_ITEM(CONTEXTHELP)
  51. DECLARE_MENU_ITEM(VIEW)
  52. DECLARE_MENU_ITEM(CUSTOMIZE)
  53. DECLARE_MENU_ITEM(COLUMNS)
  54. DECLARE_MENU_ITEM(VIEW_LARGE)
  55. DECLARE_MENU_ITEM(VIEW_SMALL)
  56. DECLARE_MENU_ITEM(VIEW_LIST)
  57. DECLARE_MENU_ITEM(VIEW_DETAIL)
  58. DECLARE_MENU_ITEM(VIEW_FILTERED)
  59. DECLARE_MENU_ITEM(ORGANIZE_FAVORITES)
  60. DECLARE_MENU_ITEM(CUT)
  61. DECLARE_MENU_ITEM(COPY)
  62. DECLARE_MENU_ITEM(PASTE)
  63. DECLARE_MENU_ITEM(DELETE)
  64. DECLARE_MENU_ITEM(PRINT)
  65. DECLARE_MENU_ITEM(RENAME)
  66. DECLARE_MENU_ITEM(REFRESH)
  67. DECLARE_MENU_ITEM(SAVE_LIST)
  68. DECLARE_MENU_ITEM(PROPERTIES)
  69. DECLARE_MENU_ITEM(OPEN)
  70. DECLARE_MENU_ITEM(EXPLORE)
  71. DECLARE_MENU_ITEM(NEW_TASKPAD_FROM_HERE)
  72. DECLARE_MENU_ITEM(EDIT_TASKPAD)
  73. DECLARE_MENU_ITEM(DELETE_TASKPAD)
  74. DECLARE_MENU_ITEM(ARRANGE_ICONS)
  75. DECLARE_MENU_ITEM(ARRANGE_AUTO)
  76. DECLARE_MENU_ITEM(LINE_UP_ICONS)
  77. DECLARE_MENU_ITEM(TASK)
  78. DECLARE_MENU_ITEM(CREATE_NEW)
  79. //############################################################################
  80. //############################################################################
  81. //
  82. // Trace Tags
  83. //
  84. //############################################################################
  85. //############################################################################
  86. #ifdef DBG
  87. CTraceTag tagOnCMenu(TEXT("OnCMenu"), TEXT("OnCMenu"));
  88. #endif
  89. //############################################################################
  90. //############################################################################
  91. //
  92. // Implementation of class CCustomizeViewDialog
  93. //
  94. //############################################################################
  95. //############################################################################
  96. class CCustomizeViewDialog : public CDialogImpl<CCustomizeViewDialog>
  97. {
  98. typedef CCustomizeViewDialog ThisClass;
  99. typedef CDialogImpl<CCustomizeViewDialog> BaseClass;
  100. public:
  101. // Operators
  102. enum { IDD = IDD_CUSTOMIZE_VIEW };
  103. CCustomizeViewDialog(CViewData *pViewData);
  104. protected:
  105. BEGIN_MSG_MAP(ThisClass)
  106. MESSAGE_HANDLER (WM_INITDIALOG, OnInitDialog)
  107. CONTEXT_HELP_HANDLER()
  108. COMMAND_ID_HANDLER (IDOK, OnOK)
  109. COMMAND_HANDLER (IDC_CUST_STD_MENUS, BN_CLICKED, OnClick)
  110. COMMAND_HANDLER (IDC_CUST_SNAPIN_MENUS, BN_CLICKED, OnClick)
  111. COMMAND_HANDLER (IDC_CUST_STD_BUTTONS, BN_CLICKED, OnClick)
  112. COMMAND_HANDLER (IDC_CUST_SNAPIN_BUTTONS, BN_CLICKED, OnClick)
  113. COMMAND_HANDLER (IDC_CUST_STATUS_BAR, BN_CLICKED, OnClick)
  114. COMMAND_HANDLER (IDC_CUST_DESC_BAR, BN_CLICKED, OnClick)
  115. COMMAND_HANDLER (IDC_CUST_CONSOLE_TREE, BN_CLICKED, OnClick)
  116. COMMAND_HANDLER (IDC_CUST_TASKPAD_TABS, BN_CLICKED, OnClick)
  117. END_MSG_MAP();
  118. IMPLEMENT_CONTEXT_HELP(g_aHelpIDs_IDD_CUSTOMIZE_VIEW);
  119. LRESULT OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  120. LRESULT OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  121. LRESULT OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  122. LRESULT OnClick (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
  123. bool PureIsDlgButtonChecked (int nIDButton) const
  124. { return (IsDlgButtonChecked(nIDButton) == BST_CHECKED); }
  125. private:
  126. CViewData * m_pViewData;
  127. bool m_bStdMenus : 1;
  128. bool m_bSnapinMenus : 1;
  129. bool m_bStdButtons : 1;
  130. bool m_bSnapinButtons : 1;
  131. bool m_bStatusBar : 1;
  132. bool m_bDescBar : 1;
  133. bool m_bConsoleTree : 1;
  134. bool m_bTaskpadTabs : 1;
  135. };
  136. CCustomizeViewDialog::CCustomizeViewDialog(CViewData *pViewData)
  137. : m_pViewData(pViewData)
  138. {
  139. DWORD dwToolbarsDisplayed = pViewData->GetToolbarsDisplayed();
  140. m_bStdMenus = dwToolbarsDisplayed & STD_MENUS;
  141. m_bSnapinMenus = dwToolbarsDisplayed & SNAPIN_MENUS;
  142. m_bStdButtons = dwToolbarsDisplayed & STD_BUTTONS;
  143. m_bSnapinButtons = dwToolbarsDisplayed & SNAPIN_BUTTONS;
  144. m_bStatusBar = pViewData->IsStatusBarVisible();
  145. m_bDescBar = pViewData->IsDescBarVisible();
  146. m_bConsoleTree = pViewData->IsScopePaneVisible();
  147. m_bTaskpadTabs = pViewData->AreTaskpadTabsAllowed();
  148. }
  149. LRESULT
  150. CCustomizeViewDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  151. {
  152. /*
  153. * Since these two values correspond to the possible values of a bool,
  154. * we don't have to have an ugly conditional operator below, i.e.:
  155. *
  156. * CheckDlgButton (..., (m_bStdMenus) ? BST_CHECKED : BST_UNCHECKED);
  157. */
  158. ASSERT (BST_CHECKED == true);
  159. ASSERT (BST_UNCHECKED == false);
  160. CheckDlgButton (IDC_CUST_SNAPIN_MENUS, m_bSnapinMenus);
  161. CheckDlgButton (IDC_CUST_SNAPIN_BUTTONS, m_bSnapinButtons);
  162. CheckDlgButton (IDC_CUST_STATUS_BAR, m_bStatusBar);
  163. CheckDlgButton (IDC_CUST_DESC_BAR, m_bDescBar);
  164. CheckDlgButton (IDC_CUST_TASKPAD_TABS, m_bTaskpadTabs);
  165. // if snap-in has disabled standard menus and toolbars, don't
  166. // allow user to enable them.
  167. // (Note: NOTOOLBARS disables both menus and toolbars)
  168. if (m_pViewData->GetWindowOptions() & MMC_NW_OPTION_NOTOOLBARS)
  169. {
  170. CheckDlgButton (IDC_CUST_STD_MENUS, false);
  171. CheckDlgButton (IDC_CUST_STD_BUTTONS, false);
  172. ::EnableWindow (GetDlgItem(IDC_CUST_STD_MENUS), false);
  173. ::EnableWindow (GetDlgItem(IDC_CUST_STD_BUTTONS), false);
  174. }
  175. else
  176. {
  177. CheckDlgButton (IDC_CUST_STD_MENUS, m_bStdMenus);
  178. CheckDlgButton (IDC_CUST_STD_BUTTONS, m_bStdButtons);
  179. }
  180. // if snap-in has disable the scope pane, then don't let user
  181. // try to enable/disable scope tree access.
  182. if (m_pViewData->GetWindowOptions() & MMC_NW_OPTION_NOSCOPEPANE)
  183. {
  184. CheckDlgButton (IDC_CUST_CONSOLE_TREE, false);
  185. ::EnableWindow (GetDlgItem(IDC_CUST_CONSOLE_TREE), false);
  186. }
  187. else
  188. {
  189. CheckDlgButton (IDC_CUST_CONSOLE_TREE, m_bConsoleTree);
  190. }
  191. // Disable/Remove the "Close"/"ALT+F4" from the dialog.
  192. HMENU hSysMenu = GetSystemMenu(FALSE);
  193. if (hSysMenu)
  194. VERIFY(RemoveMenu(hSysMenu, SC_CLOSE, MF_BYCOMMAND));
  195. return 0;
  196. }
  197. LRESULT
  198. CCustomizeViewDialog::OnClick (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  199. {
  200. CConsoleView* pConsoleView = m_pViewData->GetConsoleView();
  201. ASSERT (pConsoleView != NULL);
  202. switch (wID)
  203. {
  204. case IDC_CUST_STD_MENUS:
  205. m_pViewData->ToggleToolbar(MID_STD_MENUS);
  206. break;
  207. case IDC_CUST_SNAPIN_MENUS:
  208. m_pViewData->ToggleToolbar(MID_SNAPIN_MENUS);
  209. break;
  210. case IDC_CUST_STD_BUTTONS:
  211. m_pViewData->ToggleToolbar(MID_STD_BUTTONS);
  212. break;
  213. case IDC_CUST_SNAPIN_BUTTONS:
  214. m_pViewData->ToggleToolbar(MID_SNAPIN_BUTTONS);
  215. break;
  216. case IDC_CUST_STATUS_BAR:
  217. if (pConsoleView != NULL)
  218. pConsoleView->ScToggleStatusBar();
  219. break;
  220. case IDC_CUST_DESC_BAR:
  221. if (pConsoleView != NULL)
  222. pConsoleView->ScToggleDescriptionBar();
  223. break;
  224. case IDC_CUST_CONSOLE_TREE:
  225. if (pConsoleView != NULL)
  226. pConsoleView->ScToggleScopePane();
  227. break;
  228. case IDC_CUST_TASKPAD_TABS:
  229. if (pConsoleView != NULL)
  230. pConsoleView->ScToggleTaskpadTabs();
  231. break;
  232. }
  233. return (0);
  234. }
  235. LRESULT
  236. CCustomizeViewDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  237. {
  238. EndDialog(IDOK);
  239. return 0;
  240. }
  241. //############################################################################
  242. //############################################################################
  243. //
  244. // Implementation of class CContextMenu
  245. //
  246. //############################################################################
  247. //############################################################################
  248. DEBUG_DECLARE_INSTANCE_COUNTER(CContextMenu);
  249. CContextMenu::CContextMenu() :
  250. m_pNode(NULL),
  251. m_pNodeCallback(NULL),
  252. m_pCScopeTree(NULL),
  253. m_eDefaultVerb((MMC_CONSOLE_VERB)0),
  254. m_lCommandIDMax(0),
  255. m_pStatusBar(NULL),
  256. m_pmenuitemRoot(NULL),
  257. m_MaxPrimaryOwnerID(OWNERID_PRIMARY_MIN),
  258. m_MaxThirdPartyOwnerID(OWNERID_THIRD_PARTY_MIN),
  259. m_CurrentExtensionOwnerID(OWNERID_NATIVE),
  260. m_nNextMenuItemID(MENUITEM_BASE_ID),
  261. m_fPrimaryInsertionFlags(0),
  262. m_fThirdPartyInsertionFlags(0),
  263. m_fAddingPrimaryExtensionItems(false),
  264. m_fAddedThirdPartyExtensions(false),
  265. m_SnapinList(NULL)
  266. {
  267. DEBUG_INCREMENT_INSTANCE_COUNTER(CContextMenu);
  268. // Fix!!
  269. m_SnapinList = new SnapinStructList;
  270. ASSERT(m_SnapinList);
  271. }
  272. SC
  273. CContextMenu::ScInitialize(
  274. CNode* pNode,
  275. CNodeCallback* pNodeCallback,
  276. CScopeTree* pCScopeTree,
  277. const CContextMenuInfo& contextInfo)
  278. {
  279. DECLARE_SC(sc, TEXT("CContextMenu::ScInitialize"));
  280. m_pNode = pNode;
  281. m_pNodeCallback = pNodeCallback;
  282. m_pCScopeTree = pCScopeTree;
  283. m_ContextInfo = contextInfo;
  284. return sc;
  285. }
  286. CContextMenu::~CContextMenu()
  287. {
  288. EmptyMenuList();
  289. ASSERT(m_SnapinList != NULL);
  290. if (m_SnapinList != NULL)
  291. {
  292. #ifdef DBG
  293. int const count = m_SnapinList->GetCount();
  294. ASSERT( count == 0);
  295. #endif
  296. delete m_SnapinList;
  297. }
  298. DEBUG_DECREMENT_INSTANCE_COUNTER(CContextMenu);
  299. }
  300. /*+-------------------------------------------------------------------------*
  301. *
  302. * CContextMenu::SetStatusBar
  303. *
  304. * PURPOSE: Sets the status bar pointer.
  305. *
  306. * PARAMETERS:
  307. * CConsoleStatusBar * pStatusBar :
  308. *
  309. * RETURNS:
  310. * void
  311. *
  312. *+-------------------------------------------------------------------------*/
  313. void
  314. CContextMenu::SetStatusBar(CConsoleStatusBar *pStatusBar)
  315. {
  316. if(NULL != pStatusBar)
  317. m_pStatusBar = pStatusBar;
  318. }
  319. /*+-------------------------------------------------------------------------*
  320. *
  321. * CContextMenu::GetStatusBar
  322. *
  323. * PURPOSE: Returns a pointer to the status bar to use when displaying the menu.
  324. *
  325. * RETURNS:
  326. * CConsoleStatusBar *
  327. *
  328. *+-------------------------------------------------------------------------*/
  329. CConsoleStatusBar *
  330. CContextMenu::GetStatusBar()
  331. {
  332. DECLARE_SC(sc, TEXT("CContextMenu::GetStatusBar"));
  333. if(m_pStatusBar)
  334. return m_pStatusBar;
  335. if(m_pNode && m_pNode->GetViewData())
  336. {
  337. m_pStatusBar = m_pNode->GetViewData()->GetStatusBar();
  338. return m_pStatusBar;
  339. }
  340. // last try, use the console view
  341. if(m_ContextInfo.m_pConsoleView)
  342. {
  343. sc = m_ContextInfo.m_pConsoleView->ScGetStatusBar(&m_pStatusBar);
  344. if(sc)
  345. return NULL;
  346. }
  347. return m_pStatusBar;
  348. }
  349. /*+-------------------------------------------------------------------------*
  350. *
  351. * CContextMenu::ScCreateInstance
  352. *
  353. * PURPOSE: Creates a new context menu instance.
  354. *
  355. * PARAMETERS:
  356. * ContextMenu ** ppContextMenu : pointer to the ContextMenu interface on
  357. * the instance. This maintains the lifetime.
  358. *
  359. * CContextMenu **ppCContextMenu : If non-null, returns the derived object pointer.
  360. *
  361. * RETURNS:
  362. * SC
  363. *
  364. *+-------------------------------------------------------------------------*/
  365. SC
  366. CContextMenu::ScCreateInstance(ContextMenu **ppContextMenu, CContextMenu **ppCContextMenu)
  367. {
  368. DECLARE_SC(sc, TEXT("CContextMenu::ScCreateInstance"));
  369. sc = ScCheckPointers(ppContextMenu, E_UNEXPECTED);
  370. if(sc)
  371. return sc;
  372. CComObject<CMMCNewEnumImpl<CContextMenu, CContextMenu::Position, CContextMenu> > *pContextMenu = NULL;
  373. sc = pContextMenu->CreateInstance(&pContextMenu);
  374. if(sc.IsError() || !pContextMenu)
  375. return (sc = E_UNEXPECTED).ToHr();
  376. *ppContextMenu = pContextMenu; // handles the lifetime.
  377. (*ppContextMenu)->AddRef(); // addref for client.
  378. if(ppCContextMenu != NULL)
  379. *ppCContextMenu = pContextMenu;
  380. return sc;
  381. }
  382. /*+-------------------------------------------------------------------------*
  383. *
  384. * CContextMenu::ScCreateContextMenu
  385. *
  386. * PURPOSE: Creates a context menu for the specified node.
  387. *
  388. * PARAMETERS:
  389. * PNODE pNode :
  390. * PPCONTEXTMENU ppContextMenu :
  391. *
  392. * RETURNS:
  393. * SC
  394. *
  395. *+-------------------------------------------------------------------------*/
  396. SC
  397. CContextMenu::ScCreateContextMenu( PNODE pNode, HNODE hNode, PPCONTEXTMENU ppContextMenu,
  398. CNodeCallback *pNodeCallback, CScopeTree *pScopeTree)
  399. {
  400. DECLARE_SC(sc, TEXT("CContextMenu::ScCreateContextMenu"));
  401. CNode *pNodeTarget = CNode::FromHandle(hNode);
  402. // validate parameters
  403. sc = ScCheckPointers(pNode, pNodeTarget, ppContextMenu);
  404. if(sc)
  405. return sc;
  406. // init out parameter
  407. *ppContextMenu = NULL;
  408. BOOL bIsScopeNode = false;
  409. sc = pNode->IsScopeNode(&bIsScopeNode);
  410. if(sc)
  411. return sc;
  412. if(!bIsScopeNode)
  413. return (sc = E_NOTIMPL); // TODO: result items and multiselect items.
  414. // create a context menu object initialized to the specified node.
  415. CContextMenu *pContextMenu = NULL;
  416. // not using upt parameter directly to avoid returning the object
  417. // with an error result code. See bug 139528
  418. // will assign at the end when we now that everything succeeded
  419. ContextMenuPtr spContextMenu;
  420. sc = CContextMenu::ScCreateContextMenuForScopeNode(pNodeTarget, pNodeCallback, pScopeTree,
  421. &spContextMenu, pContextMenu);
  422. if(sc)
  423. return sc;
  424. sc = pContextMenu->ScBuildContextMenu();
  425. if(sc)
  426. return sc;
  427. // return the object
  428. *ppContextMenu = spContextMenu.Detach();
  429. return sc;
  430. }
  431. /***************************************************************************\
  432. *
  433. * METHOD: CContextMenu::ScCreateContextMenuForScopeNode
  434. *
  435. * PURPOSE:
  436. *
  437. * PARAMETERS:
  438. * CNode *pNode - [in] node on which the context menu will be created
  439. * CNodeCallback *pNodeCallback - [in] node callback
  440. * CScopeTree *pScopeTree - [in] scope tree
  441. * PPCONTEXTMENU ppContextMenu - [out] context menu interface
  442. * CContextMenu * &pContextMenu - [out] context menu raw pointer
  443. *
  444. * RETURNS:
  445. * SC - result code
  446. *
  447. \***************************************************************************/
  448. SC
  449. CContextMenu::ScCreateContextMenuForScopeNode(CNode *pNode, CNodeCallback *pNodeCallback,
  450. CScopeTree *pScopeTree,
  451. PPCONTEXTMENU ppContextMenu,
  452. CContextMenu * &pContextMenu)
  453. {
  454. DECLARE_SC(sc, TEXT("CContextMenu::ScCreateContextMenuForScopeNode"));
  455. // validate parameters
  456. sc = ScCheckPointers(ppContextMenu);
  457. if(sc)
  458. return sc;
  459. CContextMenuInfo contextInfo;
  460. // always use the temp verbs - cannot depend on what the active pane is
  461. contextInfo.m_dwFlags = CMINFO_USE_TEMP_VERB;
  462. bool fScopeItem = true;
  463. // initialize the context info structure.
  464. {
  465. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  466. contextInfo.m_eDataObjectType = fScopeItem ? CCT_SCOPE: CCT_RESULT;
  467. contextInfo.m_bBackground = FALSE;
  468. contextInfo.m_hSelectedScopeNode = NULL; //assigned below
  469. contextInfo.m_resultItemParam = NULL; //resultItemParam;
  470. contextInfo.m_bMultiSelect = FALSE; //(resultItemParam == LVDATA_MULTISELECT);
  471. contextInfo.m_bScopeAllowed = fScopeItem;
  472. contextInfo.m_dwFlags |= CMINFO_SHOW_SCOPEITEM_OPEN; // when called through the object model, always add the open item so that this can be accessed.
  473. if ( pNode!= NULL )
  474. {
  475. CViewData *pViewData = pNode->GetViewData();
  476. CConsoleView *pView = NULL;
  477. if (NULL != pViewData && NULL != (pView = pViewData->GetConsoleView()))
  478. {
  479. // set the owner of the view
  480. contextInfo.m_hSelectedScopeNode = pView->GetSelectedNode();
  481. //if the scope node is also the owner of the view ,
  482. // add more menu items
  483. if (contextInfo.m_hSelectedScopeNode == CNode::ToHandle(pNode))
  484. {
  485. contextInfo.m_dwFlags |= CMINFO_SHOW_VIEWOWNER_ITEMS;
  486. // show view items as well
  487. contextInfo.m_dwFlags |= CMINFO_SHOW_VIEW_ITEMS;
  488. //.. and if there is a list it can be saved
  489. if ( NULL != pViewData->GetListCtrl() )
  490. contextInfo.m_dwFlags |= CMINFO_SHOW_SAVE_LIST;
  491. }
  492. }
  493. contextInfo.m_hWnd = pNode->GetViewData()->GetView();
  494. contextInfo.m_pConsoleView = pNode->GetViewData()->GetConsoleView();
  495. }
  496. }
  497. // create a context menu object initialized to the specified node.
  498. sc = CContextMenu::ScCreateInstance(ppContextMenu, &pContextMenu);
  499. if (sc)
  500. return sc;
  501. // recheck the pointer
  502. sc = ScCheckPointers(pContextMenu, E_UNEXPECTED);
  503. if (sc)
  504. return sc;
  505. sc = pContextMenu->ScInitialize(pNode, pNodeCallback, pScopeTree, contextInfo);
  506. if(sc)
  507. return sc;
  508. return sc;
  509. }
  510. /*+-------------------------------------------------------------------------*
  511. *
  512. * CContextMenu::ScCreateSelectionContextMenu
  513. *
  514. * PURPOSE: Creates a context menu object for the selection in the list view.
  515. *
  516. * PARAMETERS:
  517. * HNODE hNodeScope :
  518. * CContextMenuInfo * pContextInfo :
  519. * PPCONTEXTMENU ppContextMenu :
  520. * CNodeCallback * pNodeCallback :
  521. * CScopeTree * pScopeTree :
  522. *
  523. * RETURNS:
  524. * SC
  525. *
  526. *+-------------------------------------------------------------------------*/
  527. SC
  528. CContextMenu::ScCreateSelectionContextMenu( HNODE hNodeScope, const CContextMenuInfo *pContextInfo, PPCONTEXTMENU ppContextMenu,
  529. CNodeCallback *pNodeCallback, CScopeTree *pScopeTree)
  530. {
  531. DECLARE_SC(sc, TEXT("CContextMenu::ScCreateSelectionContextMenu"));
  532. CNode *pNodeSel = CNode::FromHandle(hNodeScope);
  533. // validate parameters
  534. sc = ScCheckPointers(pNodeSel, ppContextMenu);
  535. if(sc)
  536. return sc;
  537. // create a context menu object initialized to the specified node.
  538. CContextMenu *pContextMenu = NULL;
  539. sc = CContextMenu::ScCreateInstance(ppContextMenu, &pContextMenu);
  540. if(sc.IsError() || !pContextMenu)
  541. {
  542. return (sc = E_OUTOFMEMORY);
  543. }
  544. sc = pContextMenu->ScInitialize(pNodeSel, pNodeCallback, pScopeTree, *pContextInfo);
  545. if(sc)
  546. return sc;
  547. sc = pContextMenu->ScBuildContextMenu();
  548. if(sc)
  549. return sc;
  550. return sc;
  551. }
  552. /*+-------------------------------------------------------------------------*
  553. *
  554. * CContextMenu::ScGetItem
  555. *
  556. * PURPOSE: Returns the iItem'th menu item.
  557. *
  558. * PARAMETERS:
  559. * int iItem : The zero-based item index.
  560. * CMenuItem** ppMenuItem :
  561. *
  562. * RETURNS:
  563. * SC
  564. *
  565. *+-------------------------------------------------------------------------*/
  566. SC
  567. CContextMenu::ScGetItem(int iItem, CMenuItem** ppMenuItem)
  568. {
  569. DECLARE_SC(sc, TEXT("CContextMenu::ScGetItem"));
  570. sc = ScCheckPointers(ppMenuItem, E_UNEXPECTED);
  571. if(sc)
  572. return sc;
  573. // init out param
  574. *ppMenuItem = NULL;
  575. sc = ScGetItem(GetMenuItemList(), iItem, ppMenuItem);
  576. return sc;
  577. }
  578. /*+-------------------------------------------------------------------------*
  579. *
  580. * CContextMenu::ScGetItem
  581. *
  582. * PURPOSE: Returns the nth item in the list of menu items, or NULL if
  583. * there are insufficient items.
  584. * Also returns the total count of items in the list.
  585. *
  586. * NOTE: This method allows the context menu to be traversed. Just call it
  587. * with increasing iItem, for 0 <= iItem < count.
  588. *
  589. * NOTE: ScGetItemCount benefits from knowledge about implementation details
  590. * of this function.
  591. *
  592. * PARAMETERS:
  593. * MenuItemList * pMenuItemList : [in] The context menu to traverse.
  594. * int & iItem : [in, destroyed on exit]: the (zero-based) item index
  595. * CMenuItem** ppMenuItem : [out]: The iItem'th menu item.
  596. *
  597. * RETURNS:
  598. * SC : S_OK for success, an error code for error.
  599. *
  600. *+-------------------------------------------------------------------------*/
  601. SC
  602. CContextMenu::ScGetItem(MenuItemList *pMenuItemList, int &iItem, CMenuItem** ppMenuItem)
  603. {
  604. DECLARE_SC(sc, TEXT("CContextMenu::ScGetItem"));
  605. sc = ScCheckPointers(pMenuItemList, ppMenuItem, E_UNEXPECTED);
  606. if(sc)
  607. return sc;
  608. *ppMenuItem = NULL;
  609. POSITION position = pMenuItemList->GetHeadPosition(); // presumably we're already at the head position.
  610. while(position!=NULL && *ppMenuItem == NULL)
  611. {
  612. CMenuItem* pMenuItem = pMenuItemList->GetNext(position);
  613. if( (pMenuItem->IsSpecialSubmenu() || pMenuItem->IsPopupMenu() )
  614. && pMenuItem->HasChildList())
  615. {
  616. // recurse through the submenus
  617. sc = ScGetItem( &pMenuItem->GetMenuItemSubmenu(), iItem, ppMenuItem );
  618. if(sc)
  619. return sc; // errors get reported right away.
  620. }
  621. else if( !pMenuItem->IsSpecialSeparator() && !pMenuItem->IsSpecialInsertionPoint()
  622. && !(pMenuItem->GetMenuItemFlags() & MF_SEPARATOR))
  623. {
  624. if(iItem-- == 0) // found the i'th item, but keep going to find the count of items.
  625. *ppMenuItem = pMenuItem;
  626. }
  627. }
  628. // either found one or iterated to the end ...
  629. return sc;
  630. }
  631. /***************************************************************************\
  632. *
  633. * METHOD: CContextMenu::ScGetItemCount
  634. *
  635. * PURPOSE: Counts menu items by iterating thu them
  636. *
  637. * NOTE: benefits from knowledge about implementation details of ScGetItem
  638. *
  639. * PARAMETERS:
  640. * UINT &count
  641. *
  642. * RETURNS:
  643. * SC - result code
  644. *
  645. \***************************************************************************/
  646. SC
  647. CContextMenu::ScGetItemCount(UINT &count)
  648. {
  649. DECLARE_SC(sc, TEXT("CContextMenu::ScGetItemCount"));
  650. count = 0;
  651. // set iItem to invalid index - so ScGetItem will iterate to the end
  652. const int iInvalidIndexToSearch = -1;
  653. int iItem = iInvalidIndexToSearch;
  654. CMenuItem * pMenuItem = NULL;
  655. sc = ScGetItem(GetMenuItemList(), iItem, &pMenuItem);
  656. if(sc)
  657. return sc;
  658. ASSERT( pMenuItem == NULL); // we do not expect it to be found!
  659. // since iItem was decremented for each element - we can easily
  660. // calculate how many items we've got
  661. count = -(iItem - iInvalidIndexToSearch);
  662. return sc;
  663. }
  664. /*+-------------------------------------------------------------------------*
  665. *
  666. * CContextMenu::ScEnumNext
  667. *
  668. * PURPOSE: Returns a pointer to the next menu item
  669. *
  670. * PARAMETERS:
  671. * Position & pos :
  672. * PDISPATCH & pDispatch :
  673. *
  674. * RETURNS:
  675. * ::SC
  676. *
  677. *+-------------------------------------------------------------------------*/
  678. ::SC
  679. CContextMenu::ScEnumNext(Position &pos, PDISPATCH & pDispatch)
  680. {
  681. DECLARE_SC(sc, TEXT("CContextMenu::ScEnumNext"));
  682. // initialize out parameter
  683. pDispatch = NULL;
  684. long cnt = 0;
  685. sc = get_Count(&cnt);
  686. if (sc)
  687. return sc;
  688. // false if no more items
  689. if (cnt <= pos)
  690. return sc = S_FALSE;
  691. MenuItem *pMenuItem = NULL; // deliberately not a smart pointer.
  692. sc = get_Item(CComVariant((int)pos+1) /*convert from zero-based to one-based*/, &pMenuItem);
  693. if(sc.IsError() || sc == ::SC(S_FALSE))
  694. return sc; // failed of no with such an index items (S_FALSE)
  695. // increment position
  696. pos++;
  697. pDispatch = pMenuItem; //retains the refcount.
  698. return sc;
  699. }
  700. /*+-------------------------------------------------------------------------*
  701. *
  702. * CContextMenu::ScEnumSkip
  703. *
  704. * PURPOSE: Skips the specified number of menu items.
  705. *
  706. * PARAMETERS:
  707. * unsigned long :
  708. * unsigned long :
  709. * Position & pos :
  710. *
  711. * RETURNS:
  712. * ::SC
  713. *
  714. *+-------------------------------------------------------------------------*/
  715. ::SC
  716. CContextMenu::ScEnumSkip(unsigned long celt, unsigned long& celtSkipped, Position &pos)
  717. {
  718. DECLARE_SC(sc, TEXT("CContextMenu::ScEnumSkip"));
  719. long count = 0;
  720. sc = get_Count(&count);
  721. if(sc)
  722. return sc;
  723. if(count <= pos + celt) // could not skip as many as needed
  724. {
  725. celtSkipped = count - celt - 1;
  726. pos = count; // one past the end.
  727. return (sc = S_FALSE);
  728. }
  729. else // could skip as many as needed.
  730. {
  731. celtSkipped = celt;
  732. pos += celt;
  733. return sc;
  734. }
  735. }
  736. ::SC
  737. CContextMenu::ScEnumReset(Position &pos)
  738. {
  739. DECLARE_SC(sc, TEXT("CContextMenu::ScEnumReset"));
  740. pos = 0;
  741. return sc;
  742. }
  743. /*+-------------------------------------------------------------------------*
  744. *
  745. * CContextMenu::get_Count
  746. *
  747. * PURPOSE:
  748. *
  749. * PARAMETERS:
  750. * PLONG pCount :
  751. *
  752. * RETURNS:
  753. * STDMETHODIMP
  754. *
  755. *+-------------------------------------------------------------------------*/
  756. STDMETHODIMP
  757. CContextMenu::get_Count(PLONG pCount)
  758. {
  759. DECLARE_SC(sc, TEXT("CMMCContextMenu::get_Count"));
  760. sc = ScCheckPointers(pCount);
  761. if(sc)
  762. return sc.ToHr();
  763. // init out param
  764. *pCount = 0;
  765. UINT count = 0;
  766. sc = ScGetItemCount(count);
  767. if(sc)
  768. return sc.ToHr();
  769. *pCount = count;
  770. return sc.ToHr();
  771. }
  772. /*+-------------------------------------------------------------------------*
  773. *
  774. * CContextMenu::get_Item
  775. *
  776. * PURPOSE: Returns the menu item specified by the index.
  777. *
  778. * PARAMETERS:
  779. * long Index : The one-based index of the menu item to return.
  780. * PPMENUITEM ppMenuItem :
  781. *
  782. * RETURNS:
  783. * STDMETHODIMP
  784. *
  785. *+-------------------------------------------------------------------------*/
  786. STDMETHODIMP
  787. CContextMenu::get_Item(VARIANT IndexOrName, PPMENUITEM ppMenuItem)
  788. {
  789. DECLARE_SC(sc, TEXT("CMMCContextMenu::get_Item"));
  790. sc = ScCheckPointers(ppMenuItem);
  791. if(sc)
  792. return sc.ToHr();
  793. // init out param
  794. *ppMenuItem = NULL;
  795. VARIANT* pvarTemp = ConvertByRefVariantToByValue(&IndexOrName);
  796. sc = ScCheckPointers( pvarTemp, E_UNEXPECTED );
  797. if(sc)
  798. return sc.ToHr();
  799. bool bByReference = ( 0 != (V_VT(pvarTemp) & VT_BYREF) ); // value passed by reference
  800. UINT uiVarType = (V_VT(pvarTemp) & VT_TYPEMASK); // get variable type (strip flags)
  801. CMenuItem * pMenuItem = NULL;
  802. // compute the one-based index of the item
  803. if (uiVarType == VT_I4) // int type in C++; Long type in VB
  804. {
  805. // index: get I4 properly ( see if it's a reference )
  806. UINT uiIndex = bByReference ? *(pvarTemp->plVal) : pvarTemp->lVal;
  807. // find menu item by index
  808. sc = ScGetItem(uiIndex -1 /* convert from one-based to zero-based */, &pMenuItem);
  809. if(sc)
  810. return sc.ToHr();
  811. }
  812. else if (uiVarType == VT_I2) // short type in C++; Integer type in VB
  813. {
  814. // index: get I2 properly ( see if it's a reference )
  815. UINT uiIndex = bByReference ? *(pvarTemp->piVal) : pvarTemp->iVal;
  816. // find menu item by index
  817. sc = ScGetItem(uiIndex -1 /* convert from one-based to zero-based */, &pMenuItem);
  818. if(sc)
  819. return sc.ToHr();
  820. }
  821. else if (uiVarType == VT_BSTR) // BSTR type in C++; String type in VB
  822. {
  823. // Name: get string properly ( see if it's a reference )
  824. LPOLESTR lpstrPath = bByReference ? *(pvarTemp->pbstrVal) : pvarTemp->bstrVal;
  825. // look for subitem of root menu item
  826. if (m_pmenuitemRoot)
  827. {
  828. USES_CONVERSION;
  829. // convert to string. Avoid NULL pointer (change to empty string)
  830. LPCTSTR lpctstrPath = lpstrPath ? OLE2CT(lpstrPath) : _T("");
  831. // find menu item by path
  832. pMenuItem = m_pmenuitemRoot->FindItemByPath( lpctstrPath );
  833. }
  834. }
  835. else // something we did not expect
  836. {
  837. // we expect either index (VT_I2 , VT_I4) or path (VT_BSTR) only
  838. // anything else is treatead as invalid agument
  839. return (sc = E_INVALIDARG).ToHr();
  840. }
  841. if(!pMenuItem) // did not find it - return null
  842. {
  843. *ppMenuItem = NULL;
  844. return (sc = S_FALSE).ToHr();
  845. }
  846. // construct com object
  847. sc = pMenuItem->ScGetMenuItem(ppMenuItem);
  848. return sc.ToHr();
  849. }
  850. HRESULT CContextMenu::CreateContextMenuProvider()
  851. {
  852. if (PContextInfo()->m_bBackground == TRUE &&
  853. PContextInfo()->m_eDataObjectType == CCT_SCOPE)
  854. return S_OK;
  855. ASSERT(m_pNode != NULL);
  856. if (m_pNode == NULL)
  857. return E_FAIL;
  858. HRESULT hr = S_OK;
  859. do // not a loop
  860. {
  861. //
  862. // Use the standard verb present for this view.
  863. //
  864. if (!(PContextInfo()->m_dwFlags & CMINFO_USE_TEMP_VERB))
  865. {
  866. m_spVerbSet = m_pNode->GetViewData()->GetVerbSet();
  867. break;
  868. }
  869. //
  870. // Create a temporary Standard verb ..
  871. //
  872. // .. for a scope item
  873. if (PContextInfo()->m_eDataObjectType == CCT_SCOPE)
  874. {
  875. hr = CreateTempVerbSet(true);
  876. break;
  877. }
  878. // .. for a list item
  879. if (!IS_SPECIAL_LVDATA(PContextInfo()->m_resultItemParam))
  880. {
  881. hr = CreateTempVerbSet(false);
  882. break;
  883. }
  884. // .. for a multi-sel in list view
  885. if (PContextInfo()->m_resultItemParam == LVDATA_MULTISELECT)
  886. {
  887. hr = CreateTempVerbSetForMultiSel();
  888. break;
  889. }
  890. else
  891. {
  892. ASSERT(0);
  893. hr = E_FAIL;
  894. break;
  895. }
  896. } while (0);
  897. if (FAILED(hr))
  898. return hr;
  899. m_spVerbSet->GetDefaultVerb(&m_eDefaultVerb);
  900. return S_OK;
  901. }
  902. /*+-------------------------------------------------------------------------*
  903. *
  904. * CContextMenu::ScAddInsertionPoint
  905. *
  906. * PURPOSE:
  907. *
  908. * PARAMETERS:
  909. * long lCommandID :
  910. * long lInsertionPointID :
  911. *
  912. * RETURNS:
  913. * SC
  914. *
  915. *+-------------------------------------------------------------------------*/
  916. SC
  917. CContextMenu::ScAddInsertionPoint(long lCommandID, long lInsertionPointID /*= CCM_INSERTIONPOINTID_ROOT_MENU*/)
  918. {
  919. SC sc;
  920. CONTEXTMENUITEM contextmenuitem;
  921. ::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
  922. contextmenuitem.strName = NULL;
  923. contextmenuitem.strStatusBarText = NULL;
  924. contextmenuitem.lCommandID = lCommandID;
  925. contextmenuitem.lInsertionPointID = lInsertionPointID;
  926. contextmenuitem.fFlags = 0;
  927. contextmenuitem.fSpecialFlags = CCM_SPECIAL_INSERTION_POINT;
  928. sc = AddItem(&contextmenuitem);
  929. if(sc)
  930. goto Error;
  931. Cleanup:
  932. return sc;
  933. Error:
  934. TraceError(TEXT("CContextMenu::ScAddInsertionPoint"), sc);
  935. goto Cleanup;
  936. }
  937. /*+-------------------------------------------------------------------------*
  938. *
  939. * CContextMenu::ScAddSeparator
  940. *
  941. * PURPOSE: Adds a separator to the context menu
  942. *
  943. * PARAMETERS:
  944. * long lInsertionPointID :
  945. *
  946. * RETURNS:
  947. * SC
  948. *
  949. *+-------------------------------------------------------------------------*/
  950. SC
  951. CContextMenu::ScAddSeparator(long lInsertionPointID /* = CCM_INSERTIONPOINTID_ROOT_MENU */)
  952. {
  953. SC sc;
  954. CONTEXTMENUITEM contextmenuitem;
  955. ::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
  956. contextmenuitem.strName = NULL;
  957. contextmenuitem.strStatusBarText = NULL;
  958. contextmenuitem.lCommandID = 0;
  959. contextmenuitem.lInsertionPointID = lInsertionPointID;
  960. contextmenuitem.fFlags = MF_SEPARATOR;
  961. contextmenuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
  962. sc = AddItem( &contextmenuitem);
  963. if(sc)
  964. goto Error;
  965. Cleanup:
  966. return sc;
  967. Error:
  968. TraceError(TEXT("CContextMenu::ScAddSeparator"), sc);
  969. goto Cleanup;
  970. }
  971. /*+-------------------------------------------------------------------------*
  972. *
  973. * CContextMenu::ScAddMenuItem
  974. *
  975. * PURPOSE: Adds a menu item to the context menu.
  976. *
  977. * PARAMETERS:
  978. * UINT nResourceID : contains text and status text separated by '\n'
  979. * long lCommandID : the ID used to notify the IExtendContextMenu when an item is selected
  980. * long lInsertionPointID : the location to insert the item
  981. * long fFlags :
  982. *
  983. * RETURNS:
  984. * SC
  985. *
  986. *+-------------------------------------------------------------------------*/
  987. SC
  988. CContextMenu::ScAddMenuItem(
  989. UINT nResourceID, // contains text and status text separated by '\n'
  990. LPCTSTR szLanguageIndependentName,
  991. long lCommandID,
  992. long lInsertionPointID /* = CCM_INSERTIONPOINTID_ROOT_MENU */,
  993. long fFlags /* = 0 */)
  994. {
  995. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItem"));
  996. sc = ScCheckPointers(szLanguageIndependentName, E_UNEXPECTED);
  997. if(sc)
  998. return sc;
  999. USES_CONVERSION;
  1000. HINSTANCE hInst = GetStringModule();
  1001. CONTEXTMENUITEM2 contextmenuitem2;
  1002. // load the resource
  1003. CStr strText;
  1004. strText.LoadString(hInst, nResourceID );
  1005. ASSERT( !strText.IsEmpty() );
  1006. // split the resource into the menu text and status text
  1007. CStr strStatusText;
  1008. int iSeparator = strText.Find(_T('\n'));
  1009. if (0 > iSeparator)
  1010. {
  1011. ASSERT( FALSE );
  1012. strStatusText = strText;
  1013. }
  1014. else
  1015. {
  1016. strStatusText = strText.Right( strText.GetLength()-(iSeparator+1) );
  1017. strText = strText.Left( iSeparator );
  1018. }
  1019. // add the menu item
  1020. ::ZeroMemory( &contextmenuitem2, sizeof(contextmenuitem2) );
  1021. contextmenuitem2.strName = T2OLE(const_cast<LPTSTR>((LPCTSTR)strText));
  1022. contextmenuitem2.strLanguageIndependentName = T2OLE(const_cast<LPTSTR>(szLanguageIndependentName));
  1023. contextmenuitem2.strStatusBarText = T2OLE(const_cast<LPTSTR>((LPCTSTR)strStatusText));
  1024. contextmenuitem2.lCommandID = lCommandID;
  1025. contextmenuitem2.lInsertionPointID = lInsertionPointID;
  1026. contextmenuitem2.fFlags = fFlags;
  1027. contextmenuitem2.fSpecialFlags = ((fFlags & MF_POPUP) ? CCM_SPECIAL_SUBMENU : 0L) |
  1028. ((fFlags & MF_DEFAULT) ? CCM_SPECIAL_DEFAULT_ITEM : 0L);
  1029. sc = AddItem(&contextmenuitem2);
  1030. if(sc)
  1031. return sc;
  1032. return sc;
  1033. }
  1034. HRESULT
  1035. CContextMenu::CreateTempVerbSetForMultiSel(void)
  1036. {
  1037. DECLARE_SC(sc, TEXT("CContextMenu::CreateTempVerbSetForMultiSel"));
  1038. sc = ScCheckPointers(m_pNode, m_pNodeCallback, E_UNEXPECTED);
  1039. if (sc)
  1040. return sc.ToHr();
  1041. // set standard bars
  1042. CComObject<CTemporaryVerbSet>* pVerbSet;
  1043. sc = CComObject<CTemporaryVerbSet>::CreateInstance(&pVerbSet);
  1044. if (sc)
  1045. return sc.ToHr();
  1046. sc = ScCheckPointers(pVerbSet, E_OUTOFMEMORY);
  1047. if (sc)
  1048. return sc.ToHr();
  1049. m_spVerbSet = pVerbSet;
  1050. sc = m_pNodeCallback->ScInitializeTempVerbSetForMultiSel(m_pNode, *pVerbSet);
  1051. if (sc)
  1052. return sc.ToHr();
  1053. return sc.ToHr();
  1054. }
  1055. /* CContextMenu::CreateTempVerbSet
  1056. *
  1057. * PURPOSE: Used to create a temporary CVerbSet
  1058. *
  1059. * PARAMETERS:
  1060. * bool bForScopeItem:
  1061. *
  1062. * RETURNS:
  1063. * HRESULT
  1064. */
  1065. HRESULT CContextMenu::CreateTempVerbSet(bool bForScopeItem)
  1066. {
  1067. DECLARE_SC(sc, TEXT("CContextMenu::CreateTempVerbSet"));
  1068. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1069. if (sc)
  1070. return sc.ToHr();
  1071. // ensure component is initialized !!!
  1072. // for instance task wizard will call this for static nodes which aren't expanded yet
  1073. // Does not hurt to check anyway - better safe than sorry
  1074. sc = m_pNode->InitComponents ();
  1075. if(sc)
  1076. return sc.ToHr();
  1077. CComponent* pCC = m_pNode->GetPrimaryComponent();
  1078. sc = ScCheckPointers(pCC, E_FAIL);
  1079. if (sc)
  1080. return sc.ToHr();
  1081. sc = pCC->ScResetConsoleVerbStates();
  1082. if (sc)
  1083. return sc.ToHr();
  1084. CComObject<CTemporaryVerbSet>* pVerb;
  1085. sc = CComObject<CTemporaryVerbSet>::CreateInstance(&pVerb);
  1086. if (sc)
  1087. return sc.ToHr();
  1088. sc = ScCheckPointers(pVerb, E_OUTOFMEMORY);
  1089. if (sc)
  1090. return sc.ToHr();
  1091. sc = pVerb->ScInitialize(m_pNode, PContextInfo()->m_resultItemParam, bForScopeItem);
  1092. if (sc)
  1093. {
  1094. delete pVerb;
  1095. return sc.ToHr();
  1096. }
  1097. m_spVerbSet = pVerb;
  1098. return sc.ToHr();
  1099. }
  1100. /*+-------------------------------------------------------------------------*
  1101. *
  1102. * CContextMenu::AddMenuItems
  1103. *
  1104. * PURPOSE: Adds all menu items into the menu.
  1105. *
  1106. * RETURNS:
  1107. * HRESULT
  1108. *
  1109. *+-------------------------------------------------------------------------*/
  1110. HRESULT
  1111. CContextMenu::AddMenuItems()
  1112. {
  1113. DECLARE_SC(sc, TEXT("CContextMenu::AddMenuItems"));
  1114. sc = EmptyMenuList();
  1115. if(sc)
  1116. return sc.ToHr();
  1117. // Add menu items
  1118. if (PContextInfo()->m_eContextMenuType == MMC_CONTEXT_MENU_VIEW)
  1119. {
  1120. sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_TOP);
  1121. if(sc)
  1122. return sc.ToHr();
  1123. }
  1124. else if (PContextInfo()->m_dwFlags & CMINFO_FAVORITES_MENU)
  1125. {
  1126. sc = ScAddMenuItemsforFavorites();
  1127. if(sc)
  1128. return sc.ToHr();
  1129. }
  1130. else if (PContextInfo()->m_bBackground == TRUE)
  1131. {
  1132. if (PContextInfo()->m_eDataObjectType != CCT_SCOPE)
  1133. {
  1134. sc = ScAddMenuItemsForLVBackgnd();
  1135. if(sc)
  1136. return sc.ToHr();
  1137. }
  1138. }
  1139. else
  1140. {
  1141. if (PContextInfo()->m_eDataObjectType == CCT_SCOPE)
  1142. {
  1143. sc = ScAddMenuItemsForTreeItem();
  1144. if(sc)
  1145. return sc.ToHr();
  1146. }
  1147. else if ( m_pNode && (PContextInfo()->m_eDataObjectType == CCT_RESULT) &&
  1148. (m_pNode->GetViewData()->HasOCX()) )
  1149. {
  1150. // Selection is an OCX
  1151. sc = ScAddMenuItemsForOCX();
  1152. if(sc)
  1153. return sc.ToHr();
  1154. }
  1155. else if ( m_pNode && (PContextInfo()->m_eDataObjectType == CCT_RESULT) &&
  1156. (m_pNode->GetViewData()->HasWebBrowser()) )
  1157. {
  1158. // do nothing for web pages.
  1159. }
  1160. else if (PContextInfo()->m_bMultiSelect == FALSE)
  1161. {
  1162. sc = ScAddMenuItemsForLV();
  1163. if(sc)
  1164. return sc.ToHr();
  1165. }
  1166. else
  1167. {
  1168. sc = ScAddMenuItemsForMultiSelect();
  1169. if(sc)
  1170. return sc.ToHr();
  1171. }
  1172. }
  1173. // Add "Help" to every context menu except the view menu
  1174. if (PContextInfo()->m_eContextMenuType != MMC_CONTEXT_MENU_VIEW)
  1175. {
  1176. sc = ScAddSeparator(); // make sure there is a separator.
  1177. if(sc)
  1178. return sc.ToHr();
  1179. sc = ScAddMenuItem (IDS_MMC_CONTEXTHELP, szCONTEXTHELP, MID_CONTEXTHELP);
  1180. if(sc)
  1181. return sc.ToHr();
  1182. }
  1183. return sc.ToHr();
  1184. }
  1185. void
  1186. CContextMenu::RemoveTempSelection (CConsoleTree* pConsoleTree)
  1187. {
  1188. if (pConsoleTree != NULL)
  1189. pConsoleTree->ScRemoveTempSelection ();
  1190. }
  1191. /*+-------------------------------------------------------------------------*
  1192. * CContextMenu::Display
  1193. *
  1194. * PURPOSE: Creates the context menu tree, and shows it, if needed.
  1195. *
  1196. * PARAMETERS:
  1197. * BOOL b: FALSE: (Normal): Display the context menu
  1198. * TRUE: Don't show the context menu
  1199. *
  1200. * RETURNS:
  1201. * HRESULT
  1202. /*+-------------------------------------------------------------------------*/
  1203. HRESULT
  1204. CContextMenu::Display(BOOL b)
  1205. {
  1206. TRACE_METHOD(CContextMenu, Display);
  1207. HRESULT hr = S_OK;
  1208. // b == 0 => normal
  1209. // b == TRUE => don't show context menu
  1210. // Validate menu type
  1211. if (PContextInfo()->m_eContextMenuType >= MMC_CONTEXT_MENU_LAST)
  1212. {
  1213. ASSERT(FALSE);
  1214. return S_FALSE;
  1215. }
  1216. // Display a context menu for the scope or result side
  1217. if (PContextInfo()->m_eDataObjectType != CCT_SCOPE &&
  1218. PContextInfo()->m_eDataObjectType != CCT_RESULT)
  1219. {
  1220. ASSERT(FALSE);
  1221. return S_FALSE;
  1222. }
  1223. hr = CreateContextMenuProvider();
  1224. if (FAILED(hr))
  1225. return hr;
  1226. hr = AddMenuItems();
  1227. if(FAILED(hr))
  1228. return hr;
  1229. // Display the context menu
  1230. long lSelected = 0; // 0 means no selection
  1231. hr = ShowContextMenuEx(PContextInfo()->m_hWnd,
  1232. PContextInfo()->m_displayPoint.x,
  1233. PContextInfo()->m_displayPoint.y,
  1234. &PContextInfo()->m_rectExclude,
  1235. PContextInfo()->m_bAllowDefaultItem,
  1236. &lSelected);
  1237. TRACE(_T("hr = %X, Command %ld\n"), hr, lSelected);
  1238. RemoveTempSelection (PContextInfo()->m_pConsoleTree); // remove the temporary selection, if any.
  1239. return hr;
  1240. }
  1241. /*+-------------------------------------------------------------------------*
  1242. *
  1243. * CContextMenu::ScBuildContextMenu
  1244. *
  1245. * PURPOSE: Builds the context menu.
  1246. *
  1247. * RETURNS:
  1248. * SC
  1249. *
  1250. *+-------------------------------------------------------------------------*/
  1251. SC
  1252. CContextMenu::ScBuildContextMenu()
  1253. {
  1254. DECLARE_SC(sc, TEXT("CContextMenu::ScBuildContextMenu"));
  1255. sc = EmptyMenuList();
  1256. if(sc)
  1257. return sc;
  1258. // Validate menu type
  1259. if (PContextInfo()->m_eContextMenuType >= MMC_CONTEXT_MENU_LAST)
  1260. return (sc = S_FALSE);
  1261. // Display a context menu for the scope or result side
  1262. if (PContextInfo()->m_eDataObjectType != CCT_SCOPE &&
  1263. PContextInfo()->m_eDataObjectType != CCT_RESULT)
  1264. return (sc = S_FALSE);
  1265. sc = CreateContextMenuProvider();
  1266. if(sc)
  1267. return sc;
  1268. sc = AddMenuItems();
  1269. if(sc)
  1270. return sc;
  1271. CConsoleTree* pConsoleTree = PContextInfo()->m_pConsoleTree; // get this value BEFORE calling BuildAndTraverseCOntextMenu.
  1272. WTL::CMenu menu;
  1273. VERIFY( menu.CreatePopupMenu() );
  1274. START_CRITSEC_BOTH;
  1275. if (NULL == m_pmenuitemRoot)
  1276. return S_OK;
  1277. sc = BuildContextMenu(menu); // build the context menu
  1278. if(sc)
  1279. return sc;
  1280. END_CRITSEC_BOTH;
  1281. /* NOTE: Do NOT use the "this" object or any of its members after this point
  1282. * because it might have been deleted. This happens, for instance, when a selection
  1283. * change occurs.
  1284. */
  1285. // remove the temporary selection, if any.
  1286. RemoveTempSelection (pConsoleTree);
  1287. return sc;
  1288. }
  1289. inline BOOL CContextMenu::IsVerbEnabled(MMC_CONSOLE_VERB verb)
  1290. {
  1291. DECLARE_SC(sc, TEXT("CContextMenu::IsVerbEnabled"));
  1292. if (verb == MMC_VERB_PASTE)
  1293. {
  1294. ASSERT(m_pNode);
  1295. ASSERT(m_pNodeCallback);
  1296. if (m_pNode == NULL || m_pNodeCallback == NULL)
  1297. return false;
  1298. bool bPasteAllowed = false;
  1299. // From given context determine whether scope pane or result pane item is selected.
  1300. bool bScope = ( m_ContextInfo.m_bBackground || (m_ContextInfo.m_eDataObjectType == CCT_SCOPE));
  1301. LPARAM lvData = bScope ? NULL : m_ContextInfo.m_resultItemParam;
  1302. sc = m_pNodeCallback->QueryPasteFromClipboard(CNode::ToHandle(m_pNode), bScope, lvData, bPasteAllowed);
  1303. if (sc)
  1304. return (bPasteAllowed = false);
  1305. return bPasteAllowed;
  1306. }
  1307. else
  1308. {
  1309. ASSERT(m_spVerbSet != NULL);
  1310. if (m_spVerbSet == NULL)
  1311. return FALSE;
  1312. BOOL bFlag = FALSE;
  1313. m_spVerbSet->GetVerbState(verb, HIDDEN, &bFlag);
  1314. if (bFlag == TRUE)
  1315. return FALSE;
  1316. m_spVerbSet->GetVerbState(verb, ENABLED, &bFlag);
  1317. return bFlag;
  1318. }
  1319. }
  1320. /*+-------------------------------------------------------------------------*
  1321. *
  1322. * CContextMenu::ScAddMenuItemsForViewMenu
  1323. *
  1324. * PURPOSE: Adds the menu items for the View menu
  1325. *
  1326. * PARAMETERS:
  1327. * MENU_LEVEL menuLevel :
  1328. *
  1329. * RETURNS:
  1330. * SC
  1331. *
  1332. *+-------------------------------------------------------------------------*/
  1333. SC
  1334. CContextMenu::ScAddMenuItemsForViewMenu(MENU_LEVEL menuLevel)
  1335. {
  1336. DECLARE_SC(sc, TEXT("CContextMenu::AddMenuItemsForViewMenu"));
  1337. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1338. if(sc)
  1339. return sc;
  1340. CViewData* pViewData = m_pNode->GetViewData();
  1341. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  1342. if(sc)
  1343. return sc;
  1344. ASSERT(pViewData != NULL);
  1345. LONG lInsertID = 0;
  1346. int nViewMode = -1;
  1347. if (PContextInfo()->m_spListView)
  1348. nViewMode = PContextInfo()->m_spListView->GetViewMode();
  1349. // If no a top level menu, insert the view submenu item
  1350. // and insert view items under it
  1351. if (menuLevel == MENU_LEVEL_SUB)
  1352. {
  1353. sc = ScAddMenuItem(IDS_VIEW, szVIEW, MID_VIEW, 0, MF_POPUP);
  1354. if(sc)
  1355. return sc;
  1356. lInsertID = MID_VIEW;
  1357. }
  1358. // Add cols only if it is List View in report or filtered mode.
  1359. if ((m_pNode->GetViewData() ) &&
  1360. (m_pNode->GetViewData()->GetListCtrl() ) &&
  1361. ( (nViewMode == MMCLV_VIEWSTYLE_REPORT) ||
  1362. (nViewMode == MMCLV_VIEWSTYLE_FILTERED) ) )
  1363. {
  1364. sc = ScAddMenuItem(IDS_COLUMNS, szCOLUMNS, MID_COLUMNS, lInsertID);
  1365. if(sc)
  1366. return sc;
  1367. }
  1368. sc = ScAddSeparator( lInsertID);
  1369. if(sc)
  1370. return sc;
  1371. DWORD dwListOptions = pViewData->GetListOptions();
  1372. DWORD dwMiscOptions = pViewData->GetMiscOptions();
  1373. // If allowed, insert the standard listview choices
  1374. if (!(dwMiscOptions & RVTI_MISC_OPTIONS_NOLISTVIEWS))
  1375. {
  1376. #define STYLECHECK(Mode) ((Mode == nViewMode) ? MF_CHECKED|MFT_RADIOCHECK : 0)
  1377. sc = ScAddMenuItem(IDS_VIEW_LARGE, szVIEW_LARGE, MID_VIEW_LARGE, lInsertID, STYLECHECK(LVS_ICON));
  1378. if(sc)
  1379. return sc;
  1380. sc = ScAddMenuItem(IDS_VIEW_SMALL, szVIEW_SMALL, MID_VIEW_SMALL, lInsertID, STYLECHECK(LVS_SMALLICON));
  1381. if(sc)
  1382. return sc;
  1383. sc = ScAddMenuItem(IDS_VIEW_LIST, szVIEW_LIST, MID_VIEW_LIST, lInsertID, STYLECHECK(LVS_LIST));
  1384. if(sc)
  1385. return sc;
  1386. sc = ScAddMenuItem(IDS_VIEW_DETAIL, szVIEW_DETAIL, MID_VIEW_DETAIL, lInsertID, STYLECHECK(LVS_REPORT));
  1387. if(sc)
  1388. return sc;
  1389. if (dwListOptions & RVTI_LIST_OPTIONS_FILTERED)
  1390. {
  1391. sc = ScAddMenuItem(IDS_VIEW_FILTERED, szVIEW_FILTERED, MID_VIEW_FILTERED, lInsertID, STYLECHECK(MMCLV_VIEWSTYLE_FILTERED));
  1392. if(sc)
  1393. return sc;
  1394. }
  1395. sc = ScAddSeparator( lInsertID);
  1396. if(sc)
  1397. return sc;
  1398. }
  1399. // Ask IComponent to insert view items
  1400. if (m_spIDataObject == NULL)
  1401. {
  1402. sc = ScCheckPointers (m_pNode->GetMTNode(), E_UNEXPECTED);
  1403. if (sc)
  1404. return sc;
  1405. sc = m_pNode->GetMTNode()->QueryDataObject(CCT_SCOPE, &m_spIDataObject);
  1406. if(sc)
  1407. return sc;
  1408. }
  1409. sc = ScCheckPointers(m_spIDataObject, E_UNEXPECTED);
  1410. if(sc)
  1411. return sc;
  1412. CComponent* pCC = m_pNode->GetPrimaryComponent();
  1413. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  1414. if(sc)
  1415. return sc;
  1416. IUnknownPtr spUnknown = pCC->GetIComponent();
  1417. sc = ScCheckPointers(spUnknown);
  1418. if(sc)
  1419. return sc;
  1420. // Add insertion point for primary custom views
  1421. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_VIEW, lInsertID);
  1422. if(sc)
  1423. return sc;
  1424. sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
  1425. if(sc)
  1426. return sc;
  1427. if (pViewData->AllowViewCustomization())
  1428. {
  1429. // "Customize" menu item
  1430. sc = ScAddSeparator( lInsertID);
  1431. if(sc)
  1432. return sc;
  1433. sc = ScAddMenuItem( IDS_CUSTOMIZE, szCUSTOMIZE, MID_CUSTOMIZE, lInsertID);
  1434. if(sc)
  1435. return sc;
  1436. }
  1437. return sc;
  1438. }
  1439. /*+-------------------------------------------------------------------------*
  1440. *
  1441. * CContextMenu::ScAddMenuItemsforFavorites
  1442. *
  1443. * PURPOSE: Adds items for the Favorites menu
  1444. *
  1445. * RETURNS:
  1446. * SC
  1447. *
  1448. *+-------------------------------------------------------------------------*/
  1449. SC
  1450. CContextMenu::ScAddMenuItemsforFavorites()
  1451. {
  1452. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsforFavorites"));
  1453. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1454. if(sc)
  1455. return sc;
  1456. CViewData* pViewData = m_pNode->GetViewData();
  1457. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  1458. if(sc)
  1459. return sc;
  1460. if (pViewData->IsAuthorMode())
  1461. {
  1462. sc = ScAddMenuItem( IDS_ORGANIZEFAVORITES, szORGANIZE_FAVORITES, MID_ORGANIZE_FAVORITES);
  1463. if(sc)
  1464. return sc;
  1465. sc = ScAddSeparator();
  1466. if(sc)
  1467. return sc;
  1468. }
  1469. return sc;
  1470. }
  1471. /*+-------------------------------------------------------------------------*
  1472. *
  1473. * CContextMenu::ScAddMenuItemsForVerbSets
  1474. *
  1475. * PURPOSE: Adds the built-in menu items for the verbs
  1476. *
  1477. * RETURNS:
  1478. * SC
  1479. *
  1480. *+-------------------------------------------------------------------------*/
  1481. SC
  1482. CContextMenu::ScAddMenuItemsForVerbSets()
  1483. {
  1484. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForVerbSets"));
  1485. // Add print menu item
  1486. sc = ScAddSeparator();
  1487. if(sc)
  1488. return sc;
  1489. if (IsVerbEnabled(MMC_VERB_CUT) == TRUE)
  1490. {
  1491. sc = ScAddMenuItem( IDS_CUT, szCUT, MID_CUT);
  1492. if(sc)
  1493. return sc;
  1494. }
  1495. if (IsVerbEnabled(MMC_VERB_COPY) == TRUE)
  1496. {
  1497. sc = ScAddMenuItem( IDS_COPY, szCOPY, MID_COPY);
  1498. if(sc)
  1499. return sc;
  1500. }
  1501. if (IsVerbEnabled(MMC_VERB_PASTE) == TRUE)
  1502. {
  1503. sc = ScAddMenuItem( IDS_PASTE, szPASTE, MID_PASTE);
  1504. if(sc)
  1505. return sc;
  1506. }
  1507. if (IsVerbEnabled(MMC_VERB_DELETE) == TRUE)
  1508. {
  1509. sc = ScAddMenuItem( IDS_DELETE, szDELETE, MID_DELETE);
  1510. if(sc)
  1511. return sc;
  1512. }
  1513. if (IsVerbEnabled(MMC_VERB_PRINT) == TRUE)
  1514. {
  1515. sc = ScAddMenuItem( IDS_PRINT, szPRINT, MID_PRINT);
  1516. if(sc)
  1517. return sc;
  1518. }
  1519. if (IsVerbEnabled(MMC_VERB_RENAME) == TRUE)
  1520. {
  1521. sc = ScAddMenuItem( IDS_RENAME, szRENAME, MID_RENAME);
  1522. if(sc)
  1523. return sc;
  1524. }
  1525. if (IsVerbEnabled(MMC_VERB_REFRESH) == TRUE)
  1526. {
  1527. sc = ScAddMenuItem( IDS_REFRESH, szREFRESH, MID_REFRESH);
  1528. if(sc)
  1529. return sc;
  1530. }
  1531. // NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB
  1532. // In the verb add command because it is diaplayed next to the verbs
  1533. // Send a message to the list asking if it has anything on it.
  1534. // If so, display the 'save list' item
  1535. if (PContextInfo()->m_dwFlags & CMINFO_SHOW_SAVE_LIST)
  1536. {
  1537. sc = ScAddMenuItem( IDS_SAVE_LIST, szSAVE_LIST, MID_LISTSAVE);
  1538. if(sc)
  1539. return sc;
  1540. }
  1541. // NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB
  1542. sc = ScAddSeparator();
  1543. if(sc)
  1544. return sc;
  1545. // Ask the node whether it will put up property pages. If so add the
  1546. // "Properties" menu item
  1547. if (IsVerbEnabled(MMC_VERB_PROPERTIES) == TRUE)
  1548. {
  1549. // Do not make properties bold for scope items.
  1550. bool bScopeItemInScopePane = (CMINFO_DO_SCOPEPANE_MENU & m_ContextInfo.m_dwFlags);
  1551. bool bEnablePropertiesAsDefaultMenu = ( (m_eDefaultVerb == MMC_VERB_PROPERTIES) && (! bScopeItemInScopePane) );
  1552. sc = ScAddMenuItem( IDS_PROPERTIES, szPROPERTIES, MID_PROPERTIES, 0,
  1553. bEnablePropertiesAsDefaultMenu ? MF_DEFAULT : 0);
  1554. if(sc)
  1555. return sc;
  1556. sc = ScAddSeparator();
  1557. if(sc)
  1558. return sc;
  1559. }
  1560. return sc;
  1561. }
  1562. /*+-------------------------------------------------------------------------*
  1563. *
  1564. * CContextMenu::ScAddMenuItemsForTreeItem
  1565. *
  1566. * PURPOSE: Adds menu items for a scope node in the tree
  1567. *
  1568. * RETURNS:
  1569. * SC
  1570. *
  1571. *+-------------------------------------------------------------------------*/
  1572. SC
  1573. CContextMenu::ScAddMenuItemsForTreeItem()
  1574. {
  1575. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForTreeItem"));
  1576. sc = ScCheckPointers(m_pNode);
  1577. if(sc)
  1578. return sc;
  1579. CMTNode* pMTNode = m_pNode->GetMTNode();
  1580. CViewData* pViewData = m_pNode->GetViewData();
  1581. sc = ScCheckPointers(pMTNode, pViewData);
  1582. if(sc)
  1583. return sc;
  1584. // Show Open item if enabled or forced by caller
  1585. if ( IsVerbEnabled(MMC_VERB_OPEN) == TRUE ||
  1586. PContextInfo()->m_dwFlags & CMINFO_SHOW_SCOPEITEM_OPEN )
  1587. {
  1588. sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0,
  1589. (m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
  1590. if(sc)
  1591. return sc;
  1592. }
  1593. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
  1594. if(sc)
  1595. return sc;
  1596. sc = ScAddSeparator();
  1597. if(sc)
  1598. return sc;
  1599. // Add "Create New" menu item
  1600. sc = ScAddSubmenu_CreateNew(m_pNode->IsStaticNode());
  1601. if(sc)
  1602. return sc;
  1603. // Add "Task" menu item
  1604. sc = ScAddSubmenu_Task();
  1605. if(sc)
  1606. return sc;
  1607. sc = ScAddSeparator();
  1608. if(sc)
  1609. return sc;
  1610. // Show the view menu
  1611. if (PContextInfo()->m_dwFlags & CMINFO_SHOW_VIEW_ITEMS)
  1612. {
  1613. sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_SUB);
  1614. if(sc)
  1615. return sc;
  1616. }
  1617. // New window is allowed only if the view allows customization and
  1618. // it is not SDI user mode.
  1619. if (m_pNode->AllowNewWindowFromHere() && !pViewData->IsUser_SDIMode())
  1620. ScAddMenuItem( IDS_EXPLORE, szEXPLORE, MID_EXPLORE);
  1621. // Taskpad editing only allowed in author mode and for node that owns the view
  1622. if (pViewData->IsAuthorMode() && (PContextInfo()->m_dwFlags & CMINFO_SHOW_VIEWOWNER_ITEMS))
  1623. {
  1624. // add the "New Taskpad..." menu item
  1625. sc = ScAddSeparator();
  1626. if(sc)
  1627. return sc;
  1628. sc = ScAddMenuItem( IDS_NEW_TASKPAD_FROM_HERE, szNEW_TASKPAD_FROM_HERE,
  1629. MID_NEW_TASKPAD_FROM_HERE);
  1630. if(sc)
  1631. return sc;
  1632. // add the "Edit Taskpad" and "Delete Taskpad" menus item if the callback pointer is non-null.
  1633. if ((pViewData->m_spTaskCallback != NULL) &&
  1634. (pViewData->m_spTaskCallback->IsEditable() == S_OK))
  1635. {
  1636. sc = ScAddMenuItem( IDS_EDIT_TASKPAD, szEDIT_TASKPAD, MID_EDIT_TASKPAD);
  1637. if(sc)
  1638. return sc;
  1639. sc = ScAddMenuItem( IDS_DELETE_TASKPAD, szDELETE_TASKPAD, MID_DELETE_TASKPAD);
  1640. if(sc)
  1641. return sc;
  1642. }
  1643. }
  1644. sc = ScAddMenuItemsForVerbSets();
  1645. if(sc)
  1646. return sc;
  1647. // Ask the snap-ins to add there menu items.
  1648. CComponentData* pCCD = pMTNode->GetPrimaryComponentData();
  1649. if (m_spIDataObject == NULL)
  1650. {
  1651. sc = pMTNode->QueryDataObject(CCT_SCOPE, &m_spIDataObject);
  1652. if(sc)
  1653. return sc;
  1654. }
  1655. //ASSERT(m_pNode->GetPrimaryComponent() != NULL);
  1656. //IUnknownPtr spUnknown = m_pNode->GetPrimaryComponent()->GetIComponent();
  1657. // TODO: This is temporary. All context menu notifications should
  1658. // go to IComponent's in the future.
  1659. IUnknownPtr spUnknown = pCCD->GetIComponentData();
  1660. ASSERT(spUnknown != NULL);
  1661. sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
  1662. if(sc)
  1663. return sc;
  1664. sc = AddThirdPartyExtensionItems(m_spIDataObject);
  1665. if(sc)
  1666. return sc;
  1667. return sc;
  1668. }
  1669. /*+-------------------------------------------------------------------------*
  1670. *
  1671. * CContextMenu::ScAddMenuItemsForMultiSelect
  1672. *
  1673. * PURPOSE: Menu for use when multiple items are selected and the right mouse button is pressed
  1674. *
  1675. * RETURNS:
  1676. * SC
  1677. *
  1678. *+-------------------------------------------------------------------------*/
  1679. SC
  1680. CContextMenu::ScAddMenuItemsForMultiSelect()
  1681. {
  1682. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForMultiSelect"));
  1683. sc = EmptyMenuList();
  1684. if(sc)
  1685. return sc;
  1686. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
  1687. if(sc)
  1688. return sc;
  1689. sc = ScAddSeparator();
  1690. if(sc)
  1691. return sc;
  1692. // no Create New menu for result items
  1693. sc = ScAddSubmenu_Task();
  1694. if(sc)
  1695. return sc;
  1696. sc = ScAddMenuItemsForVerbSets();
  1697. if(sc)
  1698. return sc;
  1699. {
  1700. ASSERT(m_pNode != NULL);
  1701. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1702. if(sc)
  1703. return sc;
  1704. sc = ScCheckPointers(m_pNode->GetViewData(), E_UNEXPECTED);
  1705. if(sc)
  1706. return sc;
  1707. CMultiSelection* pMS = m_pNode->GetViewData()->GetMultiSelection();
  1708. if (pMS != NULL)
  1709. {
  1710. IDataObjectPtr spIDataObject;
  1711. sc = pMS->GetMultiSelDataObject(&spIDataObject);
  1712. if(sc)
  1713. return sc;
  1714. CSnapIn* pSI = m_pNode->GetPrimarySnapIn();
  1715. if (pSI != NULL &&
  1716. pMS->IsAnExtensionSnapIn(pSI->GetSnapInCLSID()) == TRUE)
  1717. {
  1718. sc = ScCheckPointers(m_pNode->GetPrimaryComponent(), E_UNEXPECTED);
  1719. if(sc)
  1720. return sc;
  1721. IComponent* pIComponent = m_pNode->GetPrimaryComponent()->GetIComponent();
  1722. sc = AddPrimaryExtensionItems(pIComponent, spIDataObject);
  1723. if(sc)
  1724. return sc;
  1725. }
  1726. sc = AddMultiSelectExtensionItems(reinterpret_cast<LONG_PTR>(pMS));
  1727. if(sc)
  1728. return sc;
  1729. }
  1730. }
  1731. return sc;
  1732. }
  1733. /*+-------------------------------------------------------------------------*
  1734. *
  1735. * CContextMenu::ScAddMenuItemsForOCX
  1736. *
  1737. * PURPOSE: This method will be called if there is an OCX in
  1738. * Result pane and some thing is selected in OCX and
  1739. * the user clicked "Action" menu.
  1740. *
  1741. * RETURNS:
  1742. * SC
  1743. *
  1744. *+-------------------------------------------------------------------------*/
  1745. SC
  1746. CContextMenu::ScAddMenuItemsForOCX()
  1747. {
  1748. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForOCX"));
  1749. LPCOMPONENT pIComponent = NULL; // IComponent interface to the snap-in
  1750. CComponent* pComponent = NULL; // Internal component structure
  1751. MMC_COOKIE cookie;
  1752. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1753. if(sc)
  1754. return sc;
  1755. sc = EmptyMenuList();
  1756. if(sc)
  1757. return sc;
  1758. if (IsVerbEnabled(MMC_VERB_OPEN) == TRUE)
  1759. {
  1760. sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0,
  1761. (m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
  1762. if(sc)
  1763. return sc;
  1764. }
  1765. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
  1766. if(sc)
  1767. return sc;
  1768. sc = ScAddSeparator();
  1769. if(sc)
  1770. return sc;
  1771. // no Create New menu for result items
  1772. sc = ScAddSubmenu_Task();
  1773. if(sc)
  1774. return sc;
  1775. sc = ScAddMenuItemsForVerbSets();
  1776. if(sc)
  1777. return sc;
  1778. sc = ScAddSeparator();
  1779. if(sc)
  1780. return sc;
  1781. LPDATAOBJECT lpDataObj = (m_pNode->GetViewData()->HasOCX()) ?
  1782. DOBJ_CUSTOMOCX : DOBJ_CUSTOMWEB;
  1783. // Item must be from primary component
  1784. pComponent = m_pNode->GetPrimaryComponent();
  1785. sc = ScCheckPointers(pComponent, E_UNEXPECTED);
  1786. if(sc)
  1787. return sc;
  1788. pIComponent = pComponent->GetIComponent();
  1789. sc = ScCheckPointers(pIComponent, E_UNEXPECTED);
  1790. if(sc)
  1791. return sc;
  1792. sc = AddPrimaryExtensionItems(pIComponent, lpDataObj);
  1793. if(sc)
  1794. return sc;
  1795. return TRUE;
  1796. }
  1797. /*+-------------------------------------------------------------------------*
  1798. *
  1799. * CContextMenu::ScAddMenuItemsForLV
  1800. *
  1801. * PURPOSE: Add menu items for a list view item
  1802. *
  1803. * RETURNS:
  1804. * SC
  1805. *
  1806. *+-------------------------------------------------------------------------*/
  1807. SC
  1808. CContextMenu::ScAddMenuItemsForLV()
  1809. {
  1810. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForLV"));
  1811. LPCOMPONENT pIComponent; // IComponet interface to the snap-in
  1812. CComponent* pComponent; // Internal component structure
  1813. MMC_COOKIE cookie;
  1814. ASSERT(m_pNode != NULL);
  1815. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1816. if (sc)
  1817. return sc;
  1818. // if virtual list
  1819. if (m_pNode->GetViewData()->IsVirtualList())
  1820. {
  1821. // ItemParam is the item index, use it as the cookie
  1822. cookie = PContextInfo()->m_resultItemParam;
  1823. // Item must be from primary component
  1824. pComponent = m_pNode->GetPrimaryComponent();
  1825. }
  1826. else
  1827. {
  1828. // ItemParam is list item data, get cookie and component ID from it
  1829. ASSERT(PContextInfo()->m_resultItemParam != 0);
  1830. CResultItem* pri = GetResultItem();
  1831. if (pri != NULL)
  1832. {
  1833. ASSERT(!pri->IsScopeItem());
  1834. cookie = pri->GetSnapinData();
  1835. pComponent = m_pNode->GetComponent(pri->GetOwnerID());
  1836. }
  1837. }
  1838. sc = ScCheckPointers(pComponent, E_UNEXPECTED);
  1839. if(sc)
  1840. return sc;
  1841. pIComponent = pComponent->GetIComponent();
  1842. sc = ScCheckPointers(pIComponent);
  1843. if(sc)
  1844. return sc;
  1845. // Load the IDataObject for the snap-in's cookie
  1846. if (m_spIDataObject == NULL)
  1847. {
  1848. sc = pIComponent->QueryDataObject(cookie, CCT_RESULT, &m_spIDataObject);
  1849. if(sc)
  1850. return sc;
  1851. }
  1852. sc = EmptyMenuList();
  1853. if(sc)
  1854. return sc;
  1855. if (IsVerbEnabled(MMC_VERB_OPEN) == TRUE)
  1856. {
  1857. sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0, (m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
  1858. if(sc)
  1859. return sc;
  1860. }
  1861. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
  1862. if(sc)
  1863. return sc;
  1864. sc = ScAddSeparator();
  1865. if(sc)
  1866. return sc;
  1867. // no Create New menu for result items
  1868. sc = ScAddSubmenu_Task();
  1869. if(sc)
  1870. return sc;
  1871. sc = ScAddMenuItemsForVerbSets();
  1872. if(sc)
  1873. return sc;
  1874. sc = ScAddSeparator();
  1875. if(sc)
  1876. return sc;
  1877. sc = AddPrimaryExtensionItems(pIComponent, m_spIDataObject);
  1878. if(sc)
  1879. return sc;
  1880. sc = AddThirdPartyExtensionItems(m_spIDataObject);
  1881. if(sc)
  1882. return sc;
  1883. return sc;
  1884. }
  1885. /*+-------------------------------------------------------------------------*
  1886. *
  1887. * CContextMenu::ScAddMenuItemsForLVBackgnd
  1888. *
  1889. * PURPOSE: This handles a right mouse click on the result pane side (Assuming our listview)
  1890. * It displays also adds the currently selected folders context menu items
  1891. *
  1892. * RETURNS:
  1893. * SC
  1894. *
  1895. *+-------------------------------------------------------------------------*/
  1896. SC
  1897. CContextMenu::ScAddMenuItemsForLVBackgnd()
  1898. {
  1899. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForLVBackgnd"));
  1900. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  1901. if(sc)
  1902. return sc;
  1903. sc = EmptyMenuList();
  1904. if(sc)
  1905. return sc;
  1906. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
  1907. if(sc)
  1908. return sc;
  1909. sc = ScAddSeparator();
  1910. if(sc)
  1911. return sc;
  1912. sc = ScAddSubmenu_CreateNew(m_pNode->IsStaticNode());
  1913. if(sc)
  1914. return sc;
  1915. sc = ScAddSubmenu_Task();
  1916. if(sc)
  1917. return sc;
  1918. sc = ScAddSeparator();
  1919. if(sc)
  1920. return sc;
  1921. // Add relevant standard verbs.
  1922. if (IsVerbEnabled(MMC_VERB_PASTE) == TRUE)
  1923. {
  1924. sc = ScAddMenuItem( IDS_PASTE, szPASTE, MID_PASTE);
  1925. if(sc)
  1926. return sc;
  1927. }
  1928. if (IsVerbEnabled(MMC_VERB_REFRESH) == TRUE)
  1929. {
  1930. sc = ScAddMenuItem( IDS_REFRESH, szREFRESH, MID_REFRESH);
  1931. if(sc)
  1932. return sc;
  1933. }
  1934. // Displays the save list icon if necessary
  1935. if ((PContextInfo()->m_pConsoleView != NULL) &&
  1936. (PContextInfo()->m_pConsoleView->GetListSize() > 0))
  1937. {
  1938. sc = ScAddMenuItem( IDS_SAVE_LIST, szSAVE_LIST, MID_LISTSAVE);
  1939. if(sc)
  1940. return sc;
  1941. }
  1942. sc = ScAddSeparator();
  1943. if(sc)
  1944. return sc;
  1945. // Add view submenu
  1946. sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_SUB);
  1947. if(sc)
  1948. return sc;
  1949. // Add Arrange Icons
  1950. sc = ScAddSeparator();
  1951. if(sc)
  1952. return sc;
  1953. sc = ScAddMenuItem( IDS_ARRANGE_ICONS, szARRANGE_ICONS, MID_ARRANGE_ICONS, 0, MF_POPUP);
  1954. if(sc)
  1955. return sc;
  1956. long lStyle = 0;
  1957. if (PContextInfo()->m_spListView)
  1958. {
  1959. lStyle = PContextInfo()->m_spListView->GetListStyle();
  1960. ASSERT(lStyle != 0);
  1961. }
  1962. // auto arrange
  1963. sc = ScAddMenuItem( IDS_ARRANGE_AUTO, szARRANGE_AUTO, MID_ARRANGE_AUTO, MID_ARRANGE_ICONS,
  1964. ((lStyle & LVS_AUTOARRANGE) ? MF_CHECKED : MF_UNCHECKED));
  1965. if(sc)
  1966. return sc;
  1967. sc = ScAddMenuItem( IDS_LINE_UP_ICONS, szLINE_UP_ICONS, MID_LINE_UP_ICONS);
  1968. if(sc)
  1969. return sc;
  1970. // Ask the node whether it will put up property pages. If so add the
  1971. // "Properties" menu item
  1972. if (IsVerbEnabled(MMC_VERB_PROPERTIES) == TRUE)
  1973. {
  1974. sc = ScAddMenuItem( IDS_PROPERTIES, szPROPERTIES, MID_PROPERTIES);
  1975. if(sc)
  1976. return sc;
  1977. sc = ScAddSeparator();
  1978. if(sc)
  1979. return sc;
  1980. }
  1981. // if there is a valid data object we would have gotten it when adding the
  1982. // view menu itmes, so we don't need to duplicate the code to get it here
  1983. if (m_spIDataObject != NULL)
  1984. {
  1985. CComponent* pCC = m_pNode->GetPrimaryComponent();
  1986. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  1987. if(sc)
  1988. return sc;
  1989. IUnknownPtr spUnknown = pCC->GetIComponent();
  1990. sc = ScCheckPointers(spUnknown);
  1991. if(sc)
  1992. return sc;
  1993. sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
  1994. if(sc)
  1995. return sc;
  1996. sc = AddThirdPartyExtensionItems(m_spIDataObject);
  1997. if(sc)
  1998. return sc;
  1999. }
  2000. return sc;
  2001. }
  2002. void OnCustomizeView(CViewData* pViewData)
  2003. {
  2004. CCustomizeViewDialog dlg(pViewData);
  2005. dlg.DoModal();
  2006. }
  2007. /*+-------------------------------------------------------------------------*
  2008. *
  2009. * CContextMenu::AddMenuItems
  2010. *
  2011. * PURPOSE: Unimplemented, but needed because this class implements
  2012. * IExtendContextMenu
  2013. *
  2014. * PARAMETERS:
  2015. * LPDATAOBJECT pDataObject :
  2016. * LPCONTEXTMENUCALLBACK pCallback :
  2017. * long * pInsertionAllowed :
  2018. *
  2019. * RETURNS:
  2020. * SC
  2021. *
  2022. *+-------------------------------------------------------------------------*/
  2023. SC
  2024. CContextMenu::ScAddMenuItems( LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pCallback, long * pInsertionAllowed)
  2025. {
  2026. DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItems"));
  2027. ASSERT(0 && "Should not come here!");
  2028. return sc = E_UNEXPECTED;
  2029. }
  2030. /*+-------------------------------------------------------------------------*
  2031. *
  2032. * CContextMenu::Command
  2033. *
  2034. * PURPOSE: Handles the built- in menu item execution.
  2035. *
  2036. * PARAMETERS:
  2037. * long lCommandID :
  2038. * LPDATAOBJECT pDataObject :
  2039. *
  2040. * RETURNS:
  2041. * SC
  2042. *
  2043. *+-------------------------------------------------------------------------*/
  2044. SC
  2045. CContextMenu::ScCommand(long lCommandID, LPDATAOBJECT pDataObject)
  2046. {
  2047. DECLARE_SC(sc, TEXT("CContextMenu::Command"));
  2048. CNodeCallback * pNodeCallback=GetNodeCallback();
  2049. sc = ScCheckPointers(pNodeCallback, E_UNEXPECTED);
  2050. if(sc)
  2051. return sc;
  2052. /*+-------------------------------------------------------------------------*/
  2053. // special case: MID_CONTEXTHELP: m_pNode can be NULL when help clicked on scope node background,
  2054. // so we handle this first.
  2055. if(MID_CONTEXTHELP == lCommandID)
  2056. {
  2057. sc = ScCheckPointers(PContextInfo());
  2058. if(sc)
  2059. return sc;
  2060. CConsoleView* pConsoleView = PContextInfo()->m_pConsoleView;
  2061. sc = ScCheckPointers(pConsoleView);
  2062. if(sc)
  2063. return sc;
  2064. if (PContextInfo()->m_bMultiSelect)
  2065. {
  2066. sc = pConsoleView->ScContextHelp ();
  2067. if(sc)
  2068. return sc;
  2069. }
  2070. else
  2071. {
  2072. sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_CONTEXTHELP,
  2073. ((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
  2074. (PContextInfo()->m_bBackground == TRUE)),
  2075. PContextInfo()->m_resultItemParam);
  2076. // if snap-in did not handle the help request, show mmc topics
  2077. if (sc.ToHr() != S_OK)
  2078. sc = PContextInfo()->m_pConsoleView->ScHelpTopics ();
  2079. return sc;
  2080. }
  2081. return sc;
  2082. }
  2083. /*+-------------------------------------------------------------------------*/
  2084. // must have a non-null m_pNode.
  2085. sc = ScCheckPointers(m_pNode);
  2086. if(sc)
  2087. return sc;
  2088. HNODE hNode = CNode::ToHandle(m_pNode);
  2089. BOOL bModeChange = FALSE;
  2090. int nNewMode;
  2091. // some widely used objects
  2092. CViewData * pViewData = m_pNode->GetViewData();
  2093. sc = ScCheckPointers(pViewData);
  2094. if(sc)
  2095. return sc;
  2096. CConsoleFrame* pFrame = pViewData->GetConsoleFrame();
  2097. CMTNode* pMTNode = m_pNode->GetMTNode();
  2098. CConsoleView* pConsoleView= pViewData->GetConsoleView();
  2099. sc = ScCheckPointers(pFrame, pMTNode, pConsoleView, E_UNEXPECTED);
  2100. if(sc)
  2101. return sc;
  2102. // handle the correct item
  2103. switch (lCommandID)
  2104. {
  2105. case MID_RENAME:
  2106. sc = pConsoleView->ScOnRename(PContextInfo());
  2107. if(sc)
  2108. return sc;
  2109. break;
  2110. case MID_REFRESH:
  2111. {
  2112. BOOL bScope = ( (PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
  2113. (PContextInfo()->m_bBackground == TRUE) );
  2114. sc = pConsoleView->ScOnRefresh(hNode, bScope, PContextInfo()->m_resultItemParam);
  2115. if(sc)
  2116. return sc;
  2117. }
  2118. break;
  2119. case MID_LINE_UP_ICONS:
  2120. sc = pConsoleView->ScLineUpIcons();
  2121. if(sc)
  2122. return sc;
  2123. break;
  2124. case MID_ARRANGE_AUTO:
  2125. sc = pConsoleView->ScAutoArrangeIcons();
  2126. if(sc)
  2127. return sc;
  2128. break;
  2129. case MID_ORGANIZE_FAVORITES:
  2130. sc = pConsoleView->ScOrganizeFavorites();
  2131. if(sc)
  2132. return sc;
  2133. break;
  2134. case MID_DELETE:
  2135. {
  2136. bool bScope = (CCT_SCOPE == PContextInfo()->m_eDataObjectType);
  2137. bool bScopeItemInResultPane = PContextInfo()->m_dwFlags & CMINFO_SCOPEITEM_IN_RES_PANE;
  2138. bool bScopeItemInScopePaneOrResultPane = bScope || bScopeItemInResultPane;
  2139. LPARAM lvData = PContextInfo()->m_resultItemParam;
  2140. if (PContextInfo()->m_bBackground)
  2141. lvData = LVDATA_BACKGROUND;
  2142. else if (PContextInfo()->m_bMultiSelect)
  2143. lvData = LVDATA_MULTISELECT;
  2144. sc = pNodeCallback->Notify(hNode, NCLBK_DELETE,
  2145. bScopeItemInScopePaneOrResultPane ,
  2146. lvData);
  2147. if(sc)
  2148. return sc;
  2149. break;
  2150. }
  2151. case MID_NEW_TASKPAD_FROM_HERE:
  2152. sc = pNodeCallback->Notify(hNode, NCLBK_NEW_TASKPAD_FROM_HERE, 0, 0);
  2153. if(sc)
  2154. return sc;
  2155. break;
  2156. case MID_EDIT_TASKPAD:
  2157. sc = pNodeCallback->Notify(hNode, NCLBK_EDIT_TASKPAD, 0, 0);
  2158. if(sc)
  2159. return sc;
  2160. break;
  2161. case MID_DELETE_TASKPAD:
  2162. sc = pNodeCallback->Notify(hNode, NCLBK_DELETE_TASKPAD, 0, 0);
  2163. if(sc)
  2164. return sc;
  2165. break;
  2166. case MID_EXPLORE: // New window from here
  2167. {
  2168. try
  2169. {
  2170. CreateNewViewStruct cnvs;
  2171. cnvs.idRootNode = pMTNode->GetID();
  2172. cnvs.lWindowOptions = MMC_NW_OPTION_NONE;
  2173. cnvs.fVisible = true;
  2174. sc = pFrame->ScCreateNewView(&cnvs);
  2175. if(sc)
  2176. return sc;
  2177. }
  2178. catch (...)
  2179. {
  2180. sc = E_FAIL;
  2181. ASSERT(0 && "NewWindow invalid scope item");
  2182. return sc;
  2183. }
  2184. }
  2185. break;
  2186. case MID_OPEN:
  2187. {
  2188. sc = pConsoleView->ScSelectNode (pMTNode->GetID());
  2189. if(sc)
  2190. return sc;
  2191. }
  2192. break;
  2193. case MID_PROPERTIES:
  2194. if (NULL == m_pNode)
  2195. return (sc = E_UNEXPECTED);
  2196. sc = ScDisplaySnapinPropertySheet();
  2197. if(sc)
  2198. return sc;
  2199. break;
  2200. case MID_VIEW_LARGE:
  2201. bModeChange = TRUE;
  2202. nNewMode = LVS_ICON;
  2203. break;
  2204. case MID_VIEW_SMALL:
  2205. bModeChange = TRUE;
  2206. nNewMode = LVS_SMALLICON;
  2207. break;
  2208. case MID_VIEW_LIST:
  2209. bModeChange = TRUE;
  2210. nNewMode = LVS_LIST;
  2211. break;
  2212. case MID_VIEW_DETAIL:
  2213. bModeChange = TRUE;
  2214. nNewMode = LVS_REPORT;
  2215. break;
  2216. case MID_VIEW_FILTERED:
  2217. bModeChange = TRUE;
  2218. nNewMode = MMCLV_VIEWSTYLE_FILTERED;
  2219. break;
  2220. case MID_CUT:
  2221. sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_CUT,
  2222. (PContextInfo()->m_eDataObjectType == CCT_SCOPE),
  2223. PContextInfo()->m_resultItemParam);
  2224. if(sc)
  2225. return sc;
  2226. sc = pConsoleView->ScCut (PContextInfo()->m_htiRClicked);
  2227. if(sc)
  2228. return sc;
  2229. break;
  2230. case MID_COPY:
  2231. sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_COPY,
  2232. (PContextInfo()->m_eDataObjectType == CCT_SCOPE),
  2233. PContextInfo()->m_resultItemParam);
  2234. if(sc)
  2235. return sc;
  2236. break;
  2237. case MID_PASTE:
  2238. sc = pNodeCallback->Paste(CNode::ToHandle(m_pNode),
  2239. ((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
  2240. (PContextInfo()->m_bBackground == TRUE)),
  2241. PContextInfo()->m_resultItemParam);
  2242. if(sc)
  2243. return sc;
  2244. sc = pConsoleView->ScPaste ();
  2245. if(sc)
  2246. return sc;
  2247. break;
  2248. case MID_COLUMNS:
  2249. ASSERT(m_pNode);
  2250. if (m_pNode)
  2251. m_pNode->OnColumns();
  2252. break;
  2253. case MID_LISTSAVE:
  2254. // If the listsave menu item has been activated, then tell the view to
  2255. // save the active list
  2256. sc = pConsoleView->ScSaveList();
  2257. if(sc)
  2258. return sc;
  2259. break;
  2260. case MID_PRINT:
  2261. sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_PRINT,
  2262. ((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
  2263. (PContextInfo()->m_bBackground == TRUE)),
  2264. PContextInfo()->m_resultItemParam);
  2265. if(sc)
  2266. return sc;
  2267. break;
  2268. case MID_CUSTOMIZE:
  2269. if (pViewData)
  2270. OnCustomizeView(pViewData);
  2271. break;
  2272. default:
  2273. ASSERT(0 && "Should not come here");
  2274. break;
  2275. }
  2276. if (bModeChange)
  2277. {
  2278. sc = ScChangeListViewMode(nNewMode);
  2279. if(sc)
  2280. return sc;
  2281. }
  2282. return sc;
  2283. }
  2284. /*+-------------------------------------------------------------------------*
  2285. *
  2286. * CContextMenu::ScChangeListViewMode
  2287. *
  2288. * PURPOSE: Changes the list view mode to the specified mode.
  2289. *
  2290. * PARAMETERS:
  2291. * int nNewMode : The mode to change to.
  2292. *
  2293. * RETURNS:
  2294. * SC
  2295. *
  2296. *+-------------------------------------------------------------------------*/
  2297. SC
  2298. CContextMenu::ScChangeListViewMode(int nNewMode)
  2299. {
  2300. DECLARE_SC(sc, TEXT("CContextMenu::ScChangeListViewMode"));
  2301. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  2302. if(sc)
  2303. return sc;
  2304. // If switching from a snapin custom to a standard listview
  2305. // send snapin a notification command
  2306. if ((PContextInfo()->m_spListView == NULL))
  2307. {
  2308. sc = ScCheckPointers(m_spIDataObject.GetInterfacePtr(), E_UNEXPECTED);
  2309. if(sc)
  2310. return sc;
  2311. CComponent* pCC = m_pNode->GetPrimaryComponent();
  2312. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  2313. if(sc)
  2314. return sc;
  2315. IExtendContextMenuPtr spIExtendContextMenu = pCC->GetIComponent();
  2316. if(spIExtendContextMenu)
  2317. {
  2318. try
  2319. {
  2320. sc = spIExtendContextMenu->Command(MMCC_STANDARD_VIEW_SELECT, m_spIDataObject);
  2321. if(sc)
  2322. return sc;
  2323. }
  2324. catch ( std::bad_alloc )
  2325. {
  2326. return (sc = E_OUTOFMEMORY);
  2327. }
  2328. catch ( std::exception )
  2329. {
  2330. return (sc = E_UNEXPECTED);
  2331. }
  2332. }
  2333. }
  2334. CViewData *pViewData = m_pNode->GetViewData();
  2335. sc = ScCheckPointers(pViewData, E_UNEXPECTED);
  2336. if (sc)
  2337. return sc;
  2338. // Persist the new mode.
  2339. sc = m_pNode->ScSetViewMode(nNewMode);
  2340. if (sc)
  2341. return sc;
  2342. // tell conui to change the list mode.
  2343. CConsoleView* pConsoleView = pViewData->GetConsoleView();
  2344. sc = ScCheckPointers(pConsoleView, E_UNEXPECTED);
  2345. if (sc)
  2346. return sc;
  2347. sc = pConsoleView->ScChangeViewMode (nNewMode);
  2348. if (sc)
  2349. return sc;
  2350. return sc;
  2351. }
  2352. /*+-------------------------------------------------------------------------*
  2353. *
  2354. * CContextMenu::ScAddSubmenu_Task
  2355. *
  2356. * PURPOSE: Adds the Task submenu
  2357. *
  2358. * RETURNS:
  2359. * SC
  2360. *
  2361. *+-------------------------------------------------------------------------*/
  2362. SC
  2363. CContextMenu::ScAddSubmenu_Task()
  2364. {
  2365. DECLARE_SC(sc, TEXT("CContextMenu::ScAddSubmenu_Task"));
  2366. sc = ScAddMenuItem(IDS_TASK, szTASK, MID_TASK, 0, MF_POPUP);
  2367. if(sc)
  2368. return sc;
  2369. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TASK, MID_TASK);
  2370. if(sc)
  2371. return sc;
  2372. sc = ScAddSeparator( MID_TASK );
  2373. if(sc)
  2374. return sc;
  2375. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_3RDPARTY_TASK, MID_TASK);
  2376. if(sc)
  2377. return sc;
  2378. sc = ScAddSeparator( MID_TASK);
  2379. if(sc)
  2380. return sc;
  2381. return sc;
  2382. }
  2383. /*+-------------------------------------------------------------------------*
  2384. *
  2385. * CContextMenu::ScAddSubmenu_CreateNew
  2386. *
  2387. * PURPOSE: Adds the New submenu
  2388. *
  2389. * PARAMETERS:
  2390. * BOOL fStaticFolder :
  2391. *
  2392. * RETURNS:
  2393. * SC
  2394. *
  2395. *+-------------------------------------------------------------------------*/
  2396. SC
  2397. CContextMenu::ScAddSubmenu_CreateNew(BOOL fStaticFolder)
  2398. {
  2399. DECLARE_SC(sc, TEXT("CContextMenu::ScAddSubmenu_CreateNew"));
  2400. sc = ScAddMenuItem(IDS_CREATE_NEW, szCREATE_NEW, MID_CREATE_NEW, 0, MF_POPUP);
  2401. if(sc)
  2402. return sc;
  2403. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_NEW, MID_CREATE_NEW);
  2404. if(sc)
  2405. return sc;
  2406. sc = ScAddSeparator( MID_CREATE_NEW);
  2407. if(sc)
  2408. return sc;
  2409. sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_3RDPARTY_NEW, MID_CREATE_NEW);
  2410. if(sc)
  2411. return sc;
  2412. sc = ScAddSeparator( MID_CREATE_NEW);
  2413. if(sc)
  2414. return sc;
  2415. return sc;
  2416. }
  2417. /*+-------------------------------------------------------------------------*
  2418. *
  2419. * CContextMenu::ScDisplaySnapinPropertySheet
  2420. *
  2421. * PURPOSE:
  2422. *
  2423. * RETURNS:
  2424. * void
  2425. *
  2426. *+-------------------------------------------------------------------------*/
  2427. SC
  2428. CContextMenu::ScDisplaySnapinPropertySheet()
  2429. {
  2430. DECLARE_SC(sc, TEXT("CContextMenu::ScDisplaySnapinPropertySheet"));
  2431. sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
  2432. if (sc)
  2433. return sc;
  2434. if (CCT_SCOPE == PContextInfo()->m_eDataObjectType ||
  2435. PContextInfo()->m_bBackground == TRUE)
  2436. {
  2437. sc = ScDisplaySnapinNodePropertySheet(m_pNode);
  2438. if(sc)
  2439. return sc;
  2440. }
  2441. else
  2442. {
  2443. // Get the view type.
  2444. ASSERT(m_pNode->GetViewData());
  2445. CViewData *pViewData = m_pNode->GetViewData();
  2446. if (PContextInfo()->m_bMultiSelect)
  2447. {
  2448. // Must be in the result pane.
  2449. sc = ScDisplayMultiSelPropertySheet(m_pNode);
  2450. if(sc)
  2451. return sc;
  2452. }
  2453. else if (m_pNode->GetViewData()->IsVirtualList())
  2454. {
  2455. // if virtual list, must be leaf item and resultItemParam is the cookie
  2456. sc = ScDisplaySnapinLeafPropertySheet(m_pNode, PContextInfo()->m_resultItemParam);
  2457. if(sc)
  2458. return sc;
  2459. }
  2460. else if( (pViewData->HasOCX()) || (pViewData->HasWebBrowser()) )
  2461. {
  2462. LPDATAOBJECT pdobj = (pViewData->HasOCX()) ? DOBJ_CUSTOMOCX
  2463. : DOBJ_CUSTOMWEB;
  2464. CComponent* pCC = m_pNode->GetPrimaryComponent();
  2465. ASSERT(pCC != NULL);
  2466. // The custom view was selected and "properties" was selected from "Action Menu".
  2467. // We dont know anything about the view, so we fake "Properties" button click.
  2468. pCC->Notify(pdobj, MMCN_BTN_CLICK, 0, MMC_VERB_PROPERTIES);
  2469. }
  2470. else
  2471. {
  2472. CResultItem* pri = GetResultItem();
  2473. if (pri != NULL)
  2474. {
  2475. if (pri->IsScopeItem())
  2476. {
  2477. sc = ScDisplaySnapinNodePropertySheet(m_pNode);
  2478. if(sc)
  2479. return sc;
  2480. }
  2481. else
  2482. {
  2483. sc = ScDisplaySnapinLeafPropertySheet(m_pNode, pri->GetSnapinData());
  2484. if(sc)
  2485. return sc;
  2486. }
  2487. }
  2488. }
  2489. }
  2490. return sc;
  2491. }
  2492. /************************************************************************
  2493. * -----------------------------------------
  2494. * Order: Calling function
  2495. * Called function 1
  2496. * Called function 2
  2497. * -----------------------------------------
  2498. *
  2499. *
  2500. * CContextMenu::ProcessSelection()
  2501. * CContextMenu::ScDisplaySnapinPropertySheet()
  2502. * ScDisplaySnapinNodePropertySheet(CNode* pNode)
  2503. * ScDisplaySnapinPropertySheet
  2504. * FindPropertySheet
  2505. * ScDisplayMultiSelPropertySheet(CNode* pNode)
  2506. * ScDisplaySnapinPropertySheet
  2507. * FindPropertySheet
  2508. * ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
  2509. * ScDisplaySnapinPropertySheet
  2510. * FindPropertySheet
  2511. *
  2512. * CNodeCallback::OnProperties(CNode* pNode, BOOL bScope, LPARAM lvData)
  2513. * ScDisplaySnapinNodePropertySheet(CNode* pNode)
  2514. * ScDisplaySnapinPropertySheet
  2515. * FindPropertySheet
  2516. * ScDisplayMultiSelPropertySheet(CNode* pNode)
  2517. * ScDisplaySnapinPropertySheet
  2518. * FindPropertySheet
  2519. * ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
  2520. * ScDisplaySnapinPropertySheet
  2521. * FindPropertySheet
  2522. ************************************************************************/
  2523. SC ScDisplaySnapinPropertySheet(IComponent* pComponent,
  2524. IComponentData* pComponentData,
  2525. IDataObject* pDataObject,
  2526. EPropertySheetType type,
  2527. LPCWSTR pName,
  2528. LPARAM lUniqueID,
  2529. CMTNode* pMTNode);
  2530. //--------------------------------------------------------------------------
  2531. SC ScDisplaySnapinNodePropertySheet(CNode* pNode)
  2532. {
  2533. DECLARE_SC(sc, TEXT("ScDisplaySnapinNodePropertySheet"));
  2534. sc = ScCheckPointers(pNode, E_UNEXPECTED);
  2535. if(sc)
  2536. return sc;
  2537. sc = ScDisplayScopeNodePropertySheet(pNode->GetMTNode());
  2538. if(sc)
  2539. return sc;
  2540. return sc;
  2541. }
  2542. /*+-------------------------------------------------------------------------*
  2543. *
  2544. * ScDisplayScopeNodePropertySheet
  2545. *
  2546. * PURPOSE: Displays a property sheet for a scope node.
  2547. *
  2548. * PARAMETERS:
  2549. * CMTNode * pMTNode : The scope node.
  2550. *
  2551. * RETURNS:
  2552. * SC
  2553. *
  2554. *+-------------------------------------------------------------------------*/
  2555. SC
  2556. ScDisplayScopeNodePropertySheet(CMTNode *pMTNode)
  2557. {
  2558. DECLARE_SC(sc, TEXT("ScDisplayScopeNodePropertySheet"));
  2559. IDataObjectPtr spIDataObject;
  2560. sc = pMTNode->QueryDataObject(CCT_SCOPE, &spIDataObject);
  2561. if(sc)
  2562. return sc;
  2563. CComponentData* pCCD = pMTNode->GetPrimaryComponentData();
  2564. sc = ScCheckPointers(pCCD);
  2565. if(sc)
  2566. return sc;
  2567. LPARAM lUniqueID = CMTNode::ToScopeItem(pMTNode);
  2568. tstring strName = pMTNode->GetDisplayName();
  2569. if (strName.empty())
  2570. strName = _T("");
  2571. USES_CONVERSION;
  2572. sc = ScDisplaySnapinPropertySheet(NULL, pCCD->GetIComponentData(),
  2573. spIDataObject,
  2574. epstScopeItem,
  2575. T2CW (strName.data()),
  2576. lUniqueID,
  2577. pMTNode);
  2578. return sc;
  2579. }
  2580. /*+-------------------------------------------------------------------------*
  2581. *
  2582. * ScDisplayMultiSelPropertySheet
  2583. *
  2584. * PURPOSE:
  2585. *
  2586. * PARAMETERS:
  2587. * CNode* pNode :
  2588. *
  2589. * RETURNS:
  2590. * SC
  2591. *
  2592. *+-------------------------------------------------------------------------*/
  2593. SC ScDisplayMultiSelPropertySheet(CNode* pNode)
  2594. {
  2595. DECLARE_SC(sc, TEXT("ScDisplayMultiSelPropertySheet"));
  2596. USES_CONVERSION;
  2597. // check inputs
  2598. sc = ScCheckPointers(pNode);
  2599. if(sc)
  2600. return sc;
  2601. sc = ScCheckPointers(pNode->GetViewData(), E_UNEXPECTED);
  2602. if(sc)
  2603. return sc;
  2604. CMultiSelection* pMS = pNode->GetViewData()->GetMultiSelection();
  2605. sc = ScCheckPointers(pMS, E_UNEXPECTED);
  2606. if(sc)
  2607. return sc;
  2608. ASSERT(pMS->IsSingleSnapinSelection());
  2609. if (pMS->IsSingleSnapinSelection() == false)
  2610. return (sc = E_UNEXPECTED);
  2611. IDataObjectPtr spIDataObject = pMS->GetSingleSnapinSelDataObject();
  2612. sc = ScCheckPointers(spIDataObject, E_UNEXPECTED);
  2613. if(sc)
  2614. return sc;
  2615. CComponent* pCC = pMS->GetPrimarySnapinComponent();
  2616. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  2617. if(sc)
  2618. return sc;
  2619. LPARAM lUniqueID = reinterpret_cast<LPARAM>(pMS);
  2620. CStr strName;
  2621. strName.LoadString(GetStringModule(), IDS_PROP_ON_MULTIOBJ);
  2622. LPWSTR pwszDispName = T2W((LPTSTR)(LPCTSTR)strName);
  2623. sc = ScDisplaySnapinPropertySheet(pCC->GetIComponent(), NULL,
  2624. spIDataObject,
  2625. epstMultipleItems,
  2626. pwszDispName,
  2627. lUniqueID,
  2628. pNode->GetMTNode());
  2629. if(sc)
  2630. return sc;
  2631. return sc;
  2632. }
  2633. /*+-------------------------------------------------------------------------*
  2634. *
  2635. * ScDisplaySnapinLeafPropertySheet
  2636. *
  2637. * PURPOSE:
  2638. *
  2639. * PARAMETERS:
  2640. * CNode* pNode :
  2641. * LPARAM lParam :
  2642. *
  2643. * RETURNS:
  2644. * SC
  2645. *
  2646. *+-------------------------------------------------------------------------*/
  2647. SC
  2648. ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
  2649. {
  2650. DECLARE_SC(sc, TEXT("ScDisplaySnapinLeafPropertySheet"));
  2651. ASSERT(!(IS_SPECIAL_COOKIE(lParam)));
  2652. sc = ScCheckPointers(pNode);
  2653. if(sc)
  2654. return sc;
  2655. sc = ScCheckPointers(pNode->GetViewData(), E_UNEXPECTED);
  2656. if(sc)
  2657. return sc;
  2658. ASSERT(lParam != 0 || pNode->GetViewData()->IsVirtualList());
  2659. CComponent* pCC = pNode->GetPrimaryComponent();
  2660. sc = ScCheckPointers(pCC, E_UNEXPECTED);
  2661. if(sc)
  2662. return sc;
  2663. IComponent* pIComponent = pCC->GetIComponent();
  2664. sc = ScCheckPointers(pIComponent, E_UNEXPECTED);
  2665. if(sc)
  2666. return sc;
  2667. // Get the IDataObject for the snap-in's cookie
  2668. IDataObjectPtr spIDataObject;
  2669. sc = pIComponent->QueryDataObject(lParam, CCT_RESULT, &spIDataObject);
  2670. if(sc)
  2671. return sc;
  2672. RESULTDATAITEM rdi;
  2673. ZeroMemory(&rdi, sizeof(rdi));
  2674. if (pNode->GetViewData()->IsVirtualList())
  2675. rdi.nIndex = lParam;
  2676. else
  2677. rdi.lParam = lParam;
  2678. rdi.mask = RDI_STR;
  2679. LPWSTR pName = L"";
  2680. sc = pIComponent->GetDisplayInfo(&rdi);
  2681. if (!sc.IsError() && rdi.str != NULL)
  2682. pName = rdi.str;
  2683. sc = ScDisplaySnapinPropertySheet(pIComponent, NULL,
  2684. spIDataObject,
  2685. epstResultItem,
  2686. pName,
  2687. 0,
  2688. pNode->GetMTNode());
  2689. return sc;
  2690. }
  2691. /*+-------------------------------------------------------------------------*
  2692. * ScDisplaySnapinPropertySheet
  2693. *
  2694. *
  2695. * PURPOSE:
  2696. *
  2697. *+-------------------------------------------------------------------------*/
  2698. SC ScDisplaySnapinPropertySheet(IComponent* pComponent,
  2699. IComponentData* pComponentData,
  2700. IDataObject* pDataObject,
  2701. EPropertySheetType type,
  2702. LPCWSTR pName,
  2703. LPARAM lUniqueID,
  2704. CMTNode* pMTNode)
  2705. {
  2706. DECLARE_SC(sc, TEXT("ScDisplaySnapinPropertySheet"));
  2707. // one of pComponent and pComponentData must be non-null
  2708. if(pComponentData == NULL && pComponent == NULL)
  2709. return (sc = E_INVALIDARG);
  2710. // check other parameters
  2711. sc = ScCheckPointers(pDataObject, pName, pMTNode);
  2712. if(sc)
  2713. return sc;
  2714. IUnknown *pUnknown = (pComponent != NULL) ? (IUnknown *)pComponent : (IUnknown *)pComponentData;
  2715. IPropertySheetProviderPrivatePtr spPropSheetProviderPrivate;
  2716. do
  2717. {
  2718. ASSERT(pDataObject != NULL);
  2719. ASSERT(pUnknown != NULL);
  2720. sc = spPropSheetProviderPrivate.CreateInstance(CLSID_NodeInit, NULL, MMC_CLSCTX_INPROC);
  2721. if(sc)
  2722. break;
  2723. sc = ScCheckPointers(spPropSheetProviderPrivate, E_UNEXPECTED);
  2724. if(sc)
  2725. break;
  2726. // See if the prop page for this is already up
  2727. sc = spPropSheetProviderPrivate->FindPropertySheetEx(lUniqueID, pComponent, pComponentData, pDataObject);
  2728. if (sc == S_OK)
  2729. break;
  2730. // No it is not present. So create a property sheet.
  2731. DWORD dwOptions = (type == epstMultipleItems) ? MMC_PSO_NO_PROPTITLE : 0;
  2732. sc = spPropSheetProviderPrivate->CreatePropertySheet(pName, TRUE, lUniqueID, pDataObject, dwOptions);
  2733. if(sc)
  2734. break;
  2735. // This data is used to get path to property sheet owner for tooltips
  2736. spPropSheetProviderPrivate->SetPropertySheetData(type, CMTNode::ToHandle(pMTNode));
  2737. sc = spPropSheetProviderPrivate->AddPrimaryPages(pUnknown, TRUE, NULL,
  2738. (type == epstScopeItem));
  2739. //#ifdef EXTENSIONS_CANNOT_ADD_PAGES_IF_PRIMARY_DOESNT
  2740. // note that only S_OK continues execution, S_FALSE breaks out
  2741. if (!(sc == S_OK) ) // ie if sc != S_OK
  2742. break;
  2743. //#endif
  2744. // Enable adding extensions
  2745. if (type == epstMultipleItems)
  2746. {
  2747. IPropertySheetProviderPrivatePtr spPSPPrivate = spPropSheetProviderPrivate;
  2748. sc = spPSPPrivate->AddMultiSelectionExtensionPages(lUniqueID);
  2749. }
  2750. else
  2751. {
  2752. sc = spPropSheetProviderPrivate->AddExtensionPages();
  2753. }
  2754. // any errors from extensions are thrown away.
  2755. CWindow w(CScopeTree::GetScopeTree()->GetMainWindow());
  2756. sc = spPropSheetProviderPrivate->Show((LONG_PTR)w.m_hWnd, 0);
  2757. } while (0);
  2758. // Clean up the 'Created' property sheet if there was an error
  2759. if (spPropSheetProviderPrivate != NULL && sc.IsError())
  2760. spPropSheetProviderPrivate->Show(-1, 0);
  2761. return sc;
  2762. }
  2763. /*+-------------------------------------------------------------------------*
  2764. * CContextMenu::GetResultItem
  2765. *
  2766. * Returns the CResultItem pointer for the result item represented by the
  2767. * context info.
  2768. *
  2769. * This function is out-of-line to eliminate coupling between oncmenu.h and
  2770. * rsltitem.h.
  2771. *--------------------------------------------------------------------------*/
  2772. CResultItem* CContextMenu::GetResultItem () const
  2773. {
  2774. return (CResultItem::FromHandle (PContextInfo()->m_resultItemParam));
  2775. }