The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
1 VB 5 Custom Controls &nbsp

NOTE: this code has been superceded by the version at the new site.


Icons In Menus 2 - Create Unlimited Popup Menus

Popup Menu DLL Demonstration

Download the cNewMenu ActiveX DLL (55kb)

Download the cNewMenu demonstration project (46kb)

Download the cNewMenu demonstration project and component source code (175kb)

&nbsp UpdatedUpdated! 30 May 1999 &nbsp
&nbsp This DLL (version 2.00.0011) now supports CoolMenu applications in conjunction with the vbAccelerator CoolMenu Toolbar and Rebar control. &nbsp
&nbsp Accelerators now work. When you add a menu item, if you specify an Accelerator in the caption, for example, "&Home" & vbTab & "Alt+Home", then the control will intercept it and raise a Click event. &nbsp
&nbsp New eye candy - a bitmap can be tiled into the background of the menu and there is a new GradientHighlight property (as demonstrated in the picture above). &nbsp
&nbsp Check box images can now be automatically drawn using the system standard check marks rather than an ImageList icons. In addition, Options Box style check marks are now also supported. &nbsp
&nbsp Bug fix - now the Click event fires whenever a menu item is clicked. &nbsp
&nbsp UpdatedUpdated! 27 January 1999 &nbsp
&nbsp A horrible bug has been fixed. This caused menus to get corrupted when using quite a few sub-menus - sub-menus would move to new positions, items would swap into the wrong menu... Thanks to David Isham for pointing out this bug and helping me with code to test it out. &nbsp
&nbsp Now Menu Items can be set to Owner-Draw style. This raises an event to the client and allows the client to draw part or all of the menu item. &nbsp
&nbsp Menu breaks are now supported in the same way as the Icon Menu control (i.e. prefixing the caption with a pipe ("|") will cause a menu break with a column divider at that menu item, prefixing it with a hat ("^") will cause a menu break without a column divider.) &nbsp
&nbsp New Header property causes a menu item to be drawn as an ICQ-style separator with text. The Header style can also draw like a caption for a more modern effect. &nbsp
&nbsp Setting the Default property for a menu item causes it to be drawn in bold font. &nbsp
&nbsp Source Code Note &nbsp
&nbsp This DLL is a binary compatible component which works with all other samples. If you compile your own copy of this DLL yourself please make sure you change the name. See disclaimer and license for more details. &nbsp
&nbsp Before you Begin &nbsp
&nbsp These projects require the SSubTmr.DLL component. Make sure you have loaded and registered this before trying any project. &nbsp

The cNewMenu ActiveX DLL is a companion to the cPopMenu control. cPopMenu allow you to subclass an existing form's VB menus and add icons and Office 97 style menu drawing. cNewMenu does the same, but instead of subclassing existing menus it allows you to create as many new popup menus as you want. You can store the popup menus within the control so you can swap between them at any point. Even better than that, your popup menus can have an unrestricted number of sub-popup menus (well, at least until you run out of screen space!) and you can dynamically build the sub menus in just the same way as the cPopMenu control.

Click here to view the cNewMenu.DLL method and event documentation

Quick Start - Using the cNewMenu DLL
Here is how to get cNewMenu working in your project quickly:

  • Add a reference to the cNewMenu DLL to your project (it appears as "vbAccelerator Popup Menu DLL - Allows an umlimited number of new pop-up menus to be created without reference to a VB menu" in the References list.) If you don't already have an ImageList, add one with the icons you want.
  • Initialise an instance of the cPopupMenu class in a form you want the popup menus to appear. You can either make the instance visible to the entire form, in which case you can respond to cPopupMenu events such as ItemHighlight and InitPopupMenu, or you can declare it at the point you need it.
    • To declare the instance with event handling:

Private WithEvents m_cPopMenu as cPopMenu

Private Sub Form_Load()

&nbsp &nbsp Set m_cPopMenu = New cPopupMenu
&nbsp &nbsp ' Initialise the Image List (you can change this later):
&nbsp &nbsp m_cPopMenu.ImageList = ilsIcons16
&nbsp &nbsp ' Initialise the hWndOwner (you must do this before showing a menu):
&nbsp &nbsp m_cPopMenu.hWndOwner = Me.hWnd

End Sub
  • To declare the instance when you need it:

  • Private Sub txtEdit_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

    &nbsp &nbsp Dim cPopMenu As New cPopupMenu
    &nbsp &nbsp ' Initialise the Image List:
    &nbsp &nbsp cPopMenu.ImageList = ilsIcons16
    &nbsp &nbsp ' Initialise the hWndOwner (you must do this before showing a menu):
    &nbsp &nbsp cPopMenu.hWndOwner = Me.hWnd

    End Sub
  • Now you are in a position to create some menus. This sample shows you how to add a (vaguely familiar?) menu which looks like this:

      Toggle >
          tickBreak on All Errors
          Break in Class Module
          Break on Unhandled Errors
      Object Browser

    Dim lIndex As Long
    Dim lIconIndex As Long

    &nbsp &nbsp ' Here I am assuming the Image List is called ilsIcons and
    &nbsp &nbsp ' the PopMenu object is cP:

    &nbsp &nbsp ' Add Cut/Copy/Paste:
    &nbsp &nbsp lIconIndex = ilsIcons.ListImages("CUT").Index - 1
    &nbsp &nbsp cP.AddItem "Cu&t", , , , lIconIndex, , , "Cut"
    &nbsp &nbsp lIconIndex = ilsIcons.ListImages("COPY").Index - 1
    &nbsp &nbsp cP.AddItem "&Copy", , , , lIconIndex, , , "Copy"
    &nbsp &nbsp lIconIndex = ilsIcons.ListImages("PASTE").Index - 1
    &nbsp &nbsp ' The Paste item is disabled here:
    &nbsp &nbsp cP.AddItem "&Paste", , , , lIconIndex, False, , "Paste"
    &nbsp &nbsp cP.AddItem "-"

    &nbsp &nbsp ' Add Toggle and Store the Index so we can add sub items to it:
    &nbsp &nbsp lIndex = cP.AddItem("&Toggle")

    &nbsp &nbsp &nbsp &nbsp ' Add the Sub Items:
    &nbsp &nbsp &nbsp &nbsp lIconIndex = ilsIcons.ListImages("BREAKPOINT").Index - 1
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "Breakpoint", , ,lIndex , lIconIndex, , , "Breakpoint"
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "-", , ,lIndex
    &nbsp &nbsp &nbsp &nbsp ' This item is checked:
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "Break on All Errors", , ,lIndex , , , True, "BreakAll"
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "Break in Class Module", , ,lIndex , , , , "BreakClass"
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "Break on Unhandled Errors", , ,lIndex , , , , "BreakUnhandled"
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "-", , ,lIndex
    &nbsp &nbsp &nbsp &nbsp lIconIndex = ilsIcons.ListImages("BOOKMARK").Index - 1
    &nbsp &nbsp &nbsp &nbsp cP.AddItem "Bookmark", , ,lIndex , , , , "Bookmark"

    &nbsp &nbsp cP.AddItem "-"
    &nbsp &nbsp lIconIndex = ilsIcons.ListImages("OBJECTBROWSER").Index - 1
    &nbsp &nbsp cP.AddItem "&Object Browser", , , , lIconIndex, False, , "ObjBrowser"

  • Having built a menu, you can now show it. Note that if your PopMenu instance is visible for the entire form, you can store this menu for later use under a string key of your choice using cP.Store "YourName". To get it back again, just call cP.Restore "YourName".

    To show the menu, you need to determine the left and right positions to show it, and you can optionally provide the boundaries of a rectangle in which the menu must not appear. This rectangle is useful if you are showing the menu as the result of clicking a button, when you don't want the button to be obscured by the menu:

  • &nbsp &nbsp ' Show the menu and get the index the user chooses (if any):
    &nbsp &nbsp ' For this sample, it is assumed the menu is been shown because
    &nbsp &nbsp ' the button cmdNewMenu has been clicked:

    &nbsp &nbsp lIndex = cP.ShowPopupMenu( _
    &nbsp &nbsp &nbsp &nbsp cmdNewMenu.Left, cmdNewMenu.Top + cmdNewMenu.Height, _
    &nbsp &nbsp &nbsp &nbsp cmdNewMenu.Left, cmdNewMenu.Top, _
    &nbsp &nbsp &nbsp &nbsp cmdNewMenu.Left + cmdNewMenu.Width, cmdNewMenu.Top + cmdNewMenu.Height _
    &nbsp &nbsp &nbsp &nbsp )
    &nbsp &nbsp If (iIndex > 0) Then
    &nbsp &nbsp &nbsp &nbsp ' Display the key of the chosen item:
    &nbsp &nbsp &nbsp &nbsp MsgBox "Selected: " & cP.ItemKey(iIndex)
    &nbsp &nbsp End If

    Note that the coordinates to exclude should be specified relative to the form which owns the instance of the cPopupMenu class (specified through the hWndOwner property when you initialise the class).

    You can do more sophisticated things by responding to the ItemHighlight and MenuExit events to provide status messages. You can also respond to the InitPopupMenuMenu event if you want to dynamically create sub items just as they are about to be shown. Check the cPopMenu control for more details on these methods.

    Text Separators
    The new text separator feature can be used by either setting the Header property to true for the menu item, or by prefixing the item's caption with a minus when it is added:

    &nbsp &nbsp cP.AddItem "-Other Sites", , , , lIconIndex

    There are two styles for text separators, set using the HeaderStyle property:
    1. ecnmHeaderCaptionBar
      This is the default, and renders like a small caption bar:
      Caption style text separators

    2. ecnmHeaderSeparator
      In this style the separator renders in the ICQ style:
      ICQ style text separators
    Although the small caption style headers look a little like the tear off bars you get in Office, there is no way to allow a menu to be torn off like a dialog control. vbAccelerator is working on an Office 97 style tear-off drop-down control, but this will be based on a VB Form rather than a Menu.

    Owner-Draw Menus
    Each menu item added can now be made to raise an event whenever it is about to be measured or drawn by setting the OwnerDraw property to True for that item. Having done this, you can then create completely customised menu items with your own style of caption.

    Check out the supporting samples to see how this works:

    TopBack to top

    Source Code - What We're About!Back to Source Code


    NOTE: this code has been superceded by the version at the new site.

    AboutContributeSend FeedbackPrivacy

    Copyright 1998-1999, Steve McMahon ( All Rights Reserved.
    Last updated: 30 May 1999