Extending Context Menus for Snap-Ins

[This is preliminary documentation and subject to change.]

MMC will generate default context menus for the items in the scope and result panes, and snap-ins may extend these default context menus. The default context menus contain items for the Create New and Task menus. These default menus are integral to the usability of the console, because they provide lists of the methods (or tasks) that can be invoked on a given node or a list of the objects that can be created within a given container.

Snap-ins extend these context menus by implementing IExtendContextMenu, where the snap-in's implementation of IExtendContextMenu will call methods in IContextMenuCallback which is implemented by MMC. Some snap-ins will also call methods in IContextMenuProvider (also implemented by MMC) when they need to build a context menu from scratch.

IContextMenuCallback is a callback mechanism that has one method, AddItem, for adding single items to a context menu. MMC will provide the snap-in with an instance of IContextMenuCallback when one is needed. Snap-ins should not call QueryInterface for an instance of IContextMenuCallback, nor should they keep the instance of IContextMenuCallback beyond the scope in which it is provided.

IExtendContextMenu is implemented by the snap-in and allows items to be added using the callback mechanism just mentioned. MMC will call AddMenuItems to give the extension an opportunity to add menu items; the snap-in will typically call IContextMenuCallback::AddItem zero or more times to add items to the context menu. MMC will call Command if an when one of the items added by AddMenuItems is chosen.

Most snap-ins will not need to use IContextMenuProvider. This interface allows snap-ins to add extensible context menus to result pane views other than the default list view. For example, if the view is an OCX, the snap-in could always create the context menu itself using the Win32 API. The problem is that using Win32 does not allow other snap-ins to extend this context menu as they could on other nodes. Instead, the OCX should call QueryInterface for a pointer to IContextMenuProvider, and generate the context menu using its COM methods. This context menu can then be extended by other snap-ins. Incidentally, IContextMenuProvider derives from IContextMenuCallback, so it implicitly contains the AddItem method.

IContextMenuProvider methods include EmptyMenuList, which clears the context menu and ShowContextMenu, which displays the menu. Its two remaining methods, AddPrimaryExtensionItems and AddThirdPartyExtensionItems, give other snap-ins the opportunity to extend the context menu.

The snap-in that has added an item to the scope or result pane is always considered to "extend" the context menu. MMC will always call its implementation of IExtendContextMenu::AddMenuItems if that snap-in implements IExtendContextMenu. Snap-ins that wish to extend context menus for items which they did not add themselves must explicitly register themselves as being context menu extensions for nodes of that particular node type.

When a snap-in adds a menu item, it must specify an insertion point in the context menu where that item should be located. The default context menus created by MMC contain a set of insertion points where extension snap-ins may add items. To maintain consistency, snap-ins may not add items other than at those predefined insertion points. Snap-ins creating context menus from scratch using IContextMenuProvider must add these insertion points themselves in order to allow other extensions to add items to those context menus.

The CONTEXTMENUITEM structure provides a variety of flags that can be set to manage MMC context menus, even when they are nested deeply and items are to be inserted in specific positions on the menu. The node manager enforces menu integrity.