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.

303 lines
11 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: oncmenu.h
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History:
  15. //____________________________________________________________________________
  16. //
  17. #ifndef _MMC_ONCMENU_H_
  18. #define _MMC_ONCMENU_H_
  19. #pragma once
  20. class CNode;
  21. class CNodeCallback;
  22. class CConsoleTree;
  23. class CResultItem;
  24. #include <pshpack8.h> // Sundown
  25. #include "cmenuinfo.h"
  26. #include "menuitem.h"
  27. //############################################################################
  28. //############################################################################
  29. //
  30. // DEADLOCK PREVENTION:
  31. // A thread holding m_CritsecSnapinList may try to take m_CritsecMenuList
  32. // A thread holding m_CritsecMenuList may NOT try to take m_CritsecSnapinList
  33. //
  34. //############################################################################
  35. //############################################################################
  36. #define START_CRITSEC(critsec) \
  37. CSingleLock lock_##critsec( &critsec ); \
  38. try { \
  39. lock_##critsec.Lock();
  40. #define END_CRITSEC(critsec) \
  41. } catch ( std::exception e) { \
  42. lock_##critsec.Unlock(); }
  43. #define START_CRITSEC_MENU START_CRITSEC(m_CritsecMenuList)
  44. #define END_CRITSEC_MENU END_CRITSEC(m_CritsecMenuList)
  45. #define START_CRITSEC_SNAPIN START_CRITSEC(m_CritsecSnapinList)
  46. #define END_CRITSEC_SNAPIN END_CRITSEC(m_CritsecSnapinList)
  47. #define START_CRITSEC_BOTH \
  48. CSingleLock lock_snapin( &m_CritsecSnapinList ); \
  49. CSingleLock lock_menu( &m_CritsecMenuList ); \
  50. try { \
  51. lock_snapin.Lock(); \
  52. lock_menu.Lock();
  53. #define END_CRITSEC_BOTH \
  54. } catch ( std::exception e) { \
  55. lock_menu.Unlock(); \
  56. lock_snapin.Unlock(); }
  57. /*+-------------------------------------------------------------------------*
  58. * class CContextMenu.
  59. *
  60. *
  61. * PURPOSE: Holds a context menu structure, which is a tree of menu items.
  62. *
  63. *+-------------------------------------------------------------------------*/
  64. class CContextMenu :
  65. public CTiedObject,
  66. public IContextMenuCallback,
  67. public IContextMenuCallback2,
  68. public CMMCIDispatchImpl<ContextMenu>
  69. {
  70. protected:
  71. typedef CContextMenu ThisClass;
  72. // CMMCNewEnumImpl tmplate needs following type to be defined.
  73. // see template class comments for more info
  74. typedef void CMyTiedObject;
  75. public:
  76. CContextMenu();
  77. ~CContextMenu();
  78. static ::SC ScCreateInstance(ContextMenu **ppContextMenu, CContextMenu **ppCContextMenu = NULL); // creates a new instance of a context menu.
  79. ::SC ScInitialize(CNode* pNode, CNodeCallback* pNodeCallback,
  80. CScopeTree* pCScopeTree, const CContextMenuInfo& contextInfo); // initializes a context menu
  81. static ::SC ScCreateContextMenu( PNODE pNode, HNODE hNode, PPCONTEXTMENU ppContextMenu,
  82. CNodeCallback *pNodeCallback, CScopeTree *pScopeTree); // creates and returns a ContextMenu interface for the given node.
  83. static ::SC ScCreateContextMenuForScopeNode(CNode *pNode,
  84. CNodeCallback *pNodeCallback, CScopeTree *pScopeTree,
  85. PPCONTEXTMENU ppContextMenu, CContextMenu * &pContextMenu);
  86. static ::SC ScCreateSelectionContextMenu( HNODE hNodeScope, const CContextMenuInfo *pContextInfo, PPCONTEXTMENU ppContextMenu,
  87. CNodeCallback *pNodeCallback, CScopeTree *pScopeTree);
  88. // com entry points
  89. BEGIN_MMC_COM_MAP(ThisClass)
  90. COM_INTERFACE_ENTRY(IContextMenuCallback) // the IContextMenuProvider and IContextMenu
  91. COM_INTERFACE_ENTRY(IContextMenuCallback2)
  92. END_MMC_COM_MAP()
  93. DECLARE_POLY_AGGREGATABLE(ThisClass)
  94. // ContextMenu Methods
  95. STDMETHOD(get_Item)(VARIANT varIndexOrName, PPMENUITEM ppMenuItem);
  96. STDMETHOD(get_Count)(PLONG pCount);
  97. // ContextMenu collection methods
  98. typedef UINT Position; // just uses the index of the menu item.
  99. // these enumerator methods only enumerate "real" menu items - not submenu items or separators
  100. ::SC ScEnumNext(Position &pos, PDISPATCH & pDispatch);
  101. ::SC ScEnumSkip(unsigned long celt, unsigned long& celtSkipped, Position &pos);
  102. ::SC ScEnumReset(Position &pos);
  103. // used by the collection methods
  104. typedef ThisClass * PMMCCONTEXTMENU;
  105. // IExtendContexMenu methods
  106. ::SC ScAddMenuItems( LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pCallback, long * pInsertionAllowed); // does nothing.
  107. ::SC ScCommand ( long lCommandID, LPDATAOBJECT pDataObject);
  108. CNodeCallback * GetNodeCallback() {return m_pNodeCallback;}
  109. HRESULT Display(BOOL b);
  110. ::SC ScDisplaySnapinPropertySheet();
  111. ::SC ScBuildContextMenu();
  112. ::SC ScGetItem(int iItem, CMenuItem** ppMenuItem); // get the i'th item - easy accessor
  113. HRESULT CreateContextMenuProvider();
  114. HRESULT CreateTempVerbSet(bool bForScopeItem);
  115. HRESULT CreateTempVerbSetForMultiSel(void);
  116. private:
  117. ::SC ScAddMenuItem(UINT nResourceID, // contains text and status text separated by '\n'
  118. LPCTSTR szLanguageIndependentName,
  119. long lCommandID, long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU,
  120. long fFlags = 0);
  121. ::SC ScAddInsertionPoint(long lCommandID, long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU );
  122. ::SC ScAddSeparator(long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU);
  123. ::SC ScAddSubmenu_Task();
  124. ::SC ScAddSubmenu_CreateNew(BOOL fStaticFolder);
  125. ::SC ScChangeListViewMode(int nNewMode); // changes the list view mode to the specified mode.
  126. ::SC ScGetItem(MenuItemList *pMenuItemList, int &iItem, CMenuItem** ppMenuItem); // get the i'th item.
  127. ::SC ScGetItemCount(UINT &count);
  128. private:
  129. typedef enum _MENU_LEVEL
  130. {
  131. MENU_LEVEL_TOP = 0,
  132. MENU_LEVEL_SUB = 1
  133. } MENU_LEVEL;
  134. ::SC ScAddMenuItemsForTreeItem();
  135. ::SC ScAddMenuItemsForViewMenu(MENU_LEVEL menuLevel);
  136. ::SC ScAddMenuItemsForVerbSets();
  137. ::SC ScAddMenuItemsforFavorites();
  138. ::SC ScAddMenuItemsForLVBackgnd();
  139. ::SC ScAddMenuItemsForMultiSelect();
  140. ::SC ScAddMenuItemsForLV();
  141. ::SC ScAddMenuItemsForOCX();
  142. HRESULT AddMenuItems();
  143. static void RemoveTempSelection(CConsoleTree* lConsoleTree);
  144. CResultItem* GetResultItem() const;
  145. public:
  146. CContextMenuInfo *PContextInfo() {return &m_ContextInfo;}
  147. const CContextMenuInfo *PContextInfo() const {return &m_ContextInfo;}
  148. void SetStatusBar(CConsoleStatusBar *pStatusBar);
  149. ::SC ScAddItem ( CONTEXTMENUITEM* pItem, bool bPassCommandBackToSnapin = false );
  150. private:
  151. CConsoleStatusBar * GetStatusBar();
  152. BOOL IsVerbEnabled(MMC_CONSOLE_VERB verb);
  153. CNode* m_pNode;
  154. CNodeCallback* m_pNodeCallback;
  155. CScopeTree* m_pCScopeTree;
  156. CContextMenuInfo m_ContextInfo;
  157. IDataObjectPtr m_spIDataObject;
  158. IConsoleVerbPtr m_spVerbSet;
  159. MMC_CONSOLE_VERB m_eDefaultVerb;
  160. long m_lCommandIDMax;
  161. CConsoleStatusBar * m_pStatusBar;
  162. ///////////////////////////////////////////////////////////////////////////////
  163. // IContextMenuCallback interface
  164. public:
  165. STDMETHOD(AddItem) ( CONTEXTMENUITEM* pItem );
  166. ///////////////////////////////////////////////////////////////////////////////
  167. // IContextMenuCallback interface
  168. public:
  169. STDMETHOD(AddItem) ( CONTEXTMENUITEM2* pItem );
  170. ///////////////////////////////////////////////////////////////////////////////
  171. // IContextMenuProvider interface
  172. public:
  173. STDMETHOD(EmptyMenuList) ();
  174. STDMETHOD(AddThirdPartyExtensionItems) (
  175. IDataObject* piDataObject );
  176. STDMETHOD(AddPrimaryExtensionItems) (
  177. IUnknown* piCallback,
  178. IDataObject* piDataObject );
  179. STDMETHOD(ShowContextMenu) (HWND hwndParent,
  180. LONG xPos,
  181. LONG yPos,
  182. LONG* plSelected);
  183. // this isn't part of IContextMenuProvider, but ShowContextMenu calls it
  184. STDMETHOD(ShowContextMenuEx) (HWND hwndParent,
  185. LONG xPos,
  186. LONG yPos,
  187. LPCRECT prcExclude,
  188. bool bAllowDefaultMenuItem,
  189. LONG* plSelected);
  190. // IContextMenuProviderPrivate
  191. STDMETHOD(AddMultiSelectExtensionItems) (LONG_PTR lMultiSelection );
  192. private:
  193. CMenuItem* m_pmenuitemRoot;
  194. SnapinStructList* m_SnapinList;
  195. MENU_OWNER_ID m_MaxPrimaryOwnerID;
  196. MENU_OWNER_ID m_MaxThirdPartyOwnerID;
  197. MENU_OWNER_ID m_CurrentExtensionOwnerID;
  198. long m_nNextMenuItemID;
  199. long m_fPrimaryInsertionFlags;
  200. long m_fThirdPartyInsertionFlags;
  201. bool m_fAddingPrimaryExtensionItems;
  202. bool m_fAddedThirdPartyExtensions;
  203. CStr m_strObjectGUID;
  204. CCriticalSection m_CritsecMenuList;
  205. CCriticalSection m_CritsecSnapinList;
  206. STDMETHOD(DoAddMenuItem) ( LPCTSTR lpszName,
  207. LPCTSTR lpszStatusBarText,
  208. LPCTSTR lpszLanguageIndependentName,
  209. LONG lCommandID,
  210. LONG lInsertionPointID,
  211. LONG fFlags,
  212. LONG fSpecialFlags,
  213. MENU_OWNER_ID lOwnerID,
  214. CMenuItem** ppMenuItem = NULL,
  215. bool bPassCommandBackToSnapin = false );
  216. ::SC ScAddSnapinToList_GUID(
  217. const CLSID& clsid,
  218. IDataObject* piDataObject,
  219. MENU_OWNER_ID ownerid );
  220. ::SC ScAddSnapinToList_IUnknown(
  221. IUnknown* piUnknown,
  222. IDataObject* piDataObject,
  223. MENU_OWNER_ID ownerid );
  224. ::SC ScAddSnapinToList_IExtendContextMenu(
  225. IExtendContextMenu* pIExtendContextMenu,
  226. IDataObject* piDataObject,
  227. MENU_OWNER_ID ownerid );
  228. SnapinStruct* FindSnapin( MENU_OWNER_ID nOwnerID );
  229. public:
  230. MenuItemList* GetMenuItemList();
  231. HRESULT ExecuteMenuItem(CMenuItem *pItem);
  232. private:
  233. void ReleaseSnapinList();
  234. public:
  235. HRESULT BuildContextMenu(WTL::CMenu &menu);
  236. CMenuItem* FindMenuItem( LONG_PTR nMenuItemID, BOOL fFindSubmenu = FALSE );
  237. CMenuItem* ReverseFindMenuItem( long nCommandID, MENU_OWNER_ID nOwnerID, CStr &strPath, CStr &strLanguageIndependentPath);
  238. CMenuItem* FindNthItemInSubmenu( HMENU hmenuParent, UINT iPosition, LPTSTR lpszMenuName);
  239. };
  240. #include <poppack.h> // Sundown
  241. void OnCustomizeView(CViewData* pViewData);
  242. SC ScDisplaySnapinNodePropertySheet(CNode* pNode);
  243. SC ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam);
  244. SC ScDisplayMultiSelPropertySheet(CNode* pNode);
  245. SC ScDisplayScopeNodePropertySheet(CMTNode *pMTNode);
  246. #endif // _MMC_ONCMENU_H_