Hack 62 Keep Custom Menus Under Control This hack reveals how to make sure macros that create custom menu items clean up after themselves.This hack shows you how to automatically add a menu item for the RevertToSaved macro [Hack #5] in a global template named MacrosTemplate.dot. It adds the menu item underneath the Save As command on the File menu. The hack also shows how to use VBA to remove the menu item.
7.7.1 The Code The code uses two procedures: AddMenuItem and RemoveMenuItem. The AddMenuItem macro first calls the RemoveMenuItem procedure to delete the custom menu item if it already exists. It then creates a new menu item just below the Save As command on the File menu. If, for some reason, the macro can't find the Save As command on the File menu, it places the custom item at the bottom of the menu.Sub AddMenuItem( ) Dim lPos As Long Dim oFileMenu As CommandBar Dim oSaveAsMenuItem As CommandBarControl Dim oCustomMenuItem As CommandBarControl Dim sMenuItemTag As String ' Define a tag for the custom menu item ' so you can find it later to delete sMenuItemTag = "Custom_RevertToSaved" CustomizationContext = NormalTemplate ' Delete the custom menu item if it already exists Call RemoveMenuItem Set oFileMenu = Application.CommandBars("File") Set oSaveAsMenuItem = oFileMenu.Controls("Save As...") If oSaveAsMenuItem Is Nothing Then lPos = oFileMenu.Controls.Count Else lPos = oSaveAsMenuItem.Index End If Set oCustomMenuItem = oFileMenu.Controls.Add(msoControlButton, _ 1, , lPos + 1, True) oCustomMenuItem.Caption = "Revert To Saved" oCustomMenuItem.Tag = sMenuItemTag oCustomMenuItem.OnAction = "MacrosTemplate.RevertToSaved" End Sub As stated above, the RemoveMenuItem macro checks for the custom item on the File menu. If the macro finds the item, it deletes it. To make sure the custom menu item won't be left behind when the macro it runs isn't available, run this procedure when the global template exits:Sub RemoveMenuItem( ) Dim lPos As Long Dim oFileMenu As CommandBar Dim oCustomMenuItem As CommandBarControl Dim sMenuItemTag As String ' Define a tag for the custom menu item ' so you can find it later to delete sMenuItemTag = "Custom_RevertToSaved" CustomizationContext = NormalTemplate Set oFileMenu = Application.CommandBars("File") Set oCustomMenuItem = oFileMenu.FindControl(Tag:=sMenuItemTag) If Not oCustomMenuItem Is Nothing Then oCustomMenuItem.Delete End If End Sub To ensure that these procedures run when the global template is loaded and unloaded, you should call them from AutoMacros [Hack #60] . Put the following code in the same MacrosTemplate.dot template:Sub AutoExec( ) Call AddMenuItem End Sub Sub AutoExit( ) Call RemoveMenuItem End Sub |