//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: oncmenu.h // // Contents: // // Classes: // // Functions: // // History: //____________________________________________________________________________ // #ifndef _MMC_ONCMENU_H_ #define _MMC_ONCMENU_H_ #pragma once class CNode; class CNodeCallback; class CConsoleTree; class CResultItem; #include // Sundown #include "cmenuinfo.h" #include "menuitem.h" //############################################################################ //############################################################################ // // DEADLOCK PREVENTION: // A thread holding m_CritsecSnapinList may try to take m_CritsecMenuList // A thread holding m_CritsecMenuList may NOT try to take m_CritsecSnapinList // //############################################################################ //############################################################################ #define START_CRITSEC(critsec) \ CSingleLock lock_##critsec( &critsec ); \ try { \ lock_##critsec.Lock(); #define END_CRITSEC(critsec) \ } catch ( std::exception e) { \ lock_##critsec.Unlock(); } #define START_CRITSEC_MENU START_CRITSEC(m_CritsecMenuList) #define END_CRITSEC_MENU END_CRITSEC(m_CritsecMenuList) #define START_CRITSEC_SNAPIN START_CRITSEC(m_CritsecSnapinList) #define END_CRITSEC_SNAPIN END_CRITSEC(m_CritsecSnapinList) #define START_CRITSEC_BOTH \ CSingleLock lock_snapin( &m_CritsecSnapinList ); \ CSingleLock lock_menu( &m_CritsecMenuList ); \ try { \ lock_snapin.Lock(); \ lock_menu.Lock(); #define END_CRITSEC_BOTH \ } catch ( std::exception e) { \ lock_menu.Unlock(); \ lock_snapin.Unlock(); } /*+-------------------------------------------------------------------------* * class CContextMenu. * * * PURPOSE: Holds a context menu structure, which is a tree of menu items. * *+-------------------------------------------------------------------------*/ class CContextMenu : public CTiedObject, public IContextMenuCallback, public IContextMenuCallback2, public CMMCIDispatchImpl { protected: typedef CContextMenu ThisClass; // CMMCNewEnumImpl tmplate needs following type to be defined. // see template class comments for more info typedef void CMyTiedObject; public: CContextMenu(); ~CContextMenu(); static ::SC ScCreateInstance(ContextMenu **ppContextMenu, CContextMenu **ppCContextMenu = NULL); // creates a new instance of a context menu. ::SC ScInitialize(CNode* pNode, CNodeCallback* pNodeCallback, CScopeTree* pCScopeTree, const CContextMenuInfo& contextInfo); // initializes a context menu static ::SC ScCreateContextMenu( PNODE pNode, HNODE hNode, PPCONTEXTMENU ppContextMenu, CNodeCallback *pNodeCallback, CScopeTree *pScopeTree); // creates and returns a ContextMenu interface for the given node. static ::SC ScCreateContextMenuForScopeNode(CNode *pNode, CNodeCallback *pNodeCallback, CScopeTree *pScopeTree, PPCONTEXTMENU ppContextMenu, CContextMenu * &pContextMenu); static ::SC ScCreateSelectionContextMenu( HNODE hNodeScope, const CContextMenuInfo *pContextInfo, PPCONTEXTMENU ppContextMenu, CNodeCallback *pNodeCallback, CScopeTree *pScopeTree); // com entry points BEGIN_MMC_COM_MAP(ThisClass) COM_INTERFACE_ENTRY(IContextMenuCallback) // the IContextMenuProvider and IContextMenu COM_INTERFACE_ENTRY(IContextMenuCallback2) END_MMC_COM_MAP() DECLARE_POLY_AGGREGATABLE(ThisClass) // ContextMenu Methods STDMETHOD(get_Item)(VARIANT varIndexOrName, PPMENUITEM ppMenuItem); STDMETHOD(get_Count)(PLONG pCount); // ContextMenu collection methods typedef UINT Position; // just uses the index of the menu item. // these enumerator methods only enumerate "real" menu items - not submenu items or separators ::SC ScEnumNext(Position &pos, PDISPATCH & pDispatch); ::SC ScEnumSkip(unsigned long celt, unsigned long& celtSkipped, Position &pos); ::SC ScEnumReset(Position &pos); // used by the collection methods typedef ThisClass * PMMCCONTEXTMENU; // IExtendContexMenu methods ::SC ScAddMenuItems( LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pCallback, long * pInsertionAllowed); // does nothing. ::SC ScCommand ( long lCommandID, LPDATAOBJECT pDataObject); CNodeCallback * GetNodeCallback() {return m_pNodeCallback;} HRESULT Display(BOOL b); ::SC ScDisplaySnapinPropertySheet(); ::SC ScBuildContextMenu(); ::SC ScGetItem(int iItem, CMenuItem** ppMenuItem); // get the i'th item - easy accessor HRESULT CreateContextMenuProvider(); HRESULT CreateTempVerbSet(bool bForScopeItem); HRESULT CreateTempVerbSetForMultiSel(void); private: ::SC ScAddMenuItem(UINT nResourceID, // contains text and status text separated by '\n' LPCTSTR szLanguageIndependentName, long lCommandID, long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU, long fFlags = 0); ::SC ScAddInsertionPoint(long lCommandID, long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU ); ::SC ScAddSeparator(long lInsertionPointID = CCM_INSERTIONPOINTID_ROOT_MENU); ::SC ScAddSubmenu_Task(); ::SC ScAddSubmenu_CreateNew(BOOL fStaticFolder); ::SC ScChangeListViewMode(int nNewMode); // changes the list view mode to the specified mode. ::SC ScGetItem(MenuItemList *pMenuItemList, int &iItem, CMenuItem** ppMenuItem); // get the i'th item. ::SC ScGetItemCount(UINT &count); private: typedef enum _MENU_LEVEL { MENU_LEVEL_TOP = 0, MENU_LEVEL_SUB = 1 } MENU_LEVEL; ::SC ScAddMenuItemsForTreeItem(); ::SC ScAddMenuItemsForViewMenu(MENU_LEVEL menuLevel); ::SC ScAddMenuItemsForVerbSets(); ::SC ScAddMenuItemsforFavorites(); ::SC ScAddMenuItemsForLVBackgnd(); ::SC ScAddMenuItemsForMultiSelect(); ::SC ScAddMenuItemsForLV(); ::SC ScAddMenuItemsForOCX(); HRESULT AddMenuItems(); static void RemoveTempSelection(CConsoleTree* lConsoleTree); CResultItem* GetResultItem() const; public: CContextMenuInfo *PContextInfo() {return &m_ContextInfo;} const CContextMenuInfo *PContextInfo() const {return &m_ContextInfo;} void SetStatusBar(CConsoleStatusBar *pStatusBar); ::SC ScAddItem ( CONTEXTMENUITEM* pItem, bool bPassCommandBackToSnapin = false ); private: CConsoleStatusBar * GetStatusBar(); BOOL IsVerbEnabled(MMC_CONSOLE_VERB verb); CNode* m_pNode; CNodeCallback* m_pNodeCallback; CScopeTree* m_pCScopeTree; CContextMenuInfo m_ContextInfo; IDataObjectPtr m_spIDataObject; IConsoleVerbPtr m_spVerbSet; MMC_CONSOLE_VERB m_eDefaultVerb; long m_lCommandIDMax; CConsoleStatusBar * m_pStatusBar; /////////////////////////////////////////////////////////////////////////////// // IContextMenuCallback interface public: STDMETHOD(AddItem) ( CONTEXTMENUITEM* pItem ); /////////////////////////////////////////////////////////////////////////////// // IContextMenuCallback interface public: STDMETHOD(AddItem) ( CONTEXTMENUITEM2* pItem ); /////////////////////////////////////////////////////////////////////////////// // IContextMenuProvider interface public: STDMETHOD(EmptyMenuList) (); STDMETHOD(AddThirdPartyExtensionItems) ( IDataObject* piDataObject ); STDMETHOD(AddPrimaryExtensionItems) ( IUnknown* piCallback, IDataObject* piDataObject ); STDMETHOD(ShowContextMenu) (HWND hwndParent, LONG xPos, LONG yPos, LONG* plSelected); // this isn't part of IContextMenuProvider, but ShowContextMenu calls it STDMETHOD(ShowContextMenuEx) (HWND hwndParent, LONG xPos, LONG yPos, LPCRECT prcExclude, bool bAllowDefaultMenuItem, LONG* plSelected); // IContextMenuProviderPrivate STDMETHOD(AddMultiSelectExtensionItems) (LONG_PTR lMultiSelection ); private: CMenuItem* m_pmenuitemRoot; SnapinStructList* m_SnapinList; MENU_OWNER_ID m_MaxPrimaryOwnerID; MENU_OWNER_ID m_MaxThirdPartyOwnerID; MENU_OWNER_ID m_CurrentExtensionOwnerID; long m_nNextMenuItemID; long m_fPrimaryInsertionFlags; long m_fThirdPartyInsertionFlags; bool m_fAddingPrimaryExtensionItems; bool m_fAddedThirdPartyExtensions; CStr m_strObjectGUID; CCriticalSection m_CritsecMenuList; CCriticalSection m_CritsecSnapinList; STDMETHOD(DoAddMenuItem) ( LPCTSTR lpszName, LPCTSTR lpszStatusBarText, LPCTSTR lpszLanguageIndependentName, LONG lCommandID, LONG lInsertionPointID, LONG fFlags, LONG fSpecialFlags, MENU_OWNER_ID lOwnerID, CMenuItem** ppMenuItem = NULL, bool bPassCommandBackToSnapin = false ); ::SC ScAddSnapinToList_GUID( const CLSID& clsid, IDataObject* piDataObject, MENU_OWNER_ID ownerid ); ::SC ScAddSnapinToList_IUnknown( IUnknown* piUnknown, IDataObject* piDataObject, MENU_OWNER_ID ownerid ); ::SC ScAddSnapinToList_IExtendContextMenu( IExtendContextMenu* pIExtendContextMenu, IDataObject* piDataObject, MENU_OWNER_ID ownerid ); SnapinStruct* FindSnapin( MENU_OWNER_ID nOwnerID ); public: MenuItemList* GetMenuItemList(); HRESULT ExecuteMenuItem(CMenuItem *pItem); private: void ReleaseSnapinList(); public: HRESULT BuildContextMenu(WTL::CMenu &menu); CMenuItem* FindMenuItem( LONG_PTR nMenuItemID, BOOL fFindSubmenu = FALSE ); CMenuItem* ReverseFindMenuItem( long nCommandID, MENU_OWNER_ID nOwnerID, CStr &strPath, CStr &strLanguageIndependentPath); CMenuItem* FindNthItemInSubmenu( HMENU hmenuParent, UINT iPosition, LPTSTR lpszMenuName); }; #include // Sundown void OnCustomizeView(CViewData* pViewData); SC ScDisplaySnapinNodePropertySheet(CNode* pNode); SC ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam); SC ScDisplayMultiSelPropertySheet(CNode* pNode); SC ScDisplayScopeNodePropertySheet(CMTNode *pMTNode); #endif // _MMC_ONCMENU_H_