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

//____________________________________________________________________________
//
// 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_