304 lines
11 KiB
C++
304 lines
11 KiB
C++
//____________________________________________________________________________
|
|
//
|
|
// 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 <pshpack8.h> // 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<ContextMenu>
|
|
{
|
|
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 <poppack.h> // 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_
|