What's New
Q & A
Tip Jar
C# Helper...
Follow VBHelper on Twitter
MSDN Visual Basic Community
TitleAdd an About dialog to the system menu and create menus at run time
KeywordsAbout dialog, menu, custom menu, system menu
CategoriesControls, API
Use menu API functions to create the menus. Subclass to receive the menus' activation messages.

Warning: Subclassing is dangerous. The debugger does not work well when a new WindowProc is installed. If you halt the program instead of unloading its forms, it will crash and so will the Visual Basic IDE. Save your work often! Don't say you weren't warned.

When the form loads, it calls the CreateMenus subroutine. That routine gets the form's menu's handle. It creates a popup menu to hold new menu items. It then changes the main menu item's caption to "New Menu Item."

Next the routine gets the handle for menu's first item and adds a series of menu entries. Finally, the routine gets a handle to the form's system menu and adds a seperator and an About item.

Private Sub CreateMenus()
Dim hFormMenu As Long
Dim hSubMenu2 As Long
Dim hSubMenu2List As Long
Dim iCounter As Integer
Dim hSystemMenu As Long

    ' Get the handle to the Menu on the
    ' current form
    hFormMenu = GetMenu(Me.hwnd)

    ' Create a new popup menu to be used to
    ' place the required menu items in
    hSubMenu2List = CreatePopupMenu()

    ' Modify the second menu option on the Form
    ' Menu (denoted by the position 1 -
    ' menu positions start with 0 for the first
    ' item, so 1 specifies the second item).
    ' Specify that the Submenu option will
    ' activate the new popup menu just created
    ' (given the new popup menu handle). Note:
    ' The last string parameter in the function
    ' call specifies the new menu option caption
    ' so if it is to stay the same, make this
    ' string the same as the original caption
    ModifyMenu hFormMenu, 0, MF_BYPOSITION + MF_POPUP, _
        hSubMenu2List, "New Menu Item"

    ' Get the handle of the first menu
    ' option on the Form Menu (denoted by the
    ' position 0)
    hSubMenu2 = GetSubMenu(hFormMenu, 0)

    ' Add new items to the second menu option
    ' list ("Document List")
    For iCounter = 1 To 10
        AppendMenu hSubMenu2, MF_STRING + MF_ENABLED, 1000 _
            + iCounter, "Document " & CStr(iCounter)

    ' Add "About" to the system menu.
    hSystemMenu = GetSystemMenu(hwnd, False)
    AppendMenu hSystemMenu, MF_SEPARATOR, 0, ""
    AppendMenu hSystemMenu, MF_STRING + MF_ENABLED, _
        IDM_ABOUT, "About..."
End Sub
When the new WindowProc sees the WM_NCDESTROY message, it restores the original WindowProc. When it sees the WM_COMMAND message, one of the menu items has been selected. When it sees the WM_SYSCOMMAND message with parameter IDM_ABOUT, the system menu's About entry has been selected.
Public Function NewWindowProc(ByVal hwnd As Long, ByVal msg _
    As Long, ByVal wParam As Long, ByVal lParam As Long) As _
Const MIN_MENU = 1001
Const MAX_MENU = 1010

    ' If we're being destroyed,
    ' restore the original WindowProc.
    If msg = WM_NCDESTROY Then
        SetWindowLong _
            hwnd, GWL_WNDPROC, _
    End If

    If msg = WM_COMMAND Then
        MsgBox "Command ID" & Str$(wParam)
        If wParam >= MIN_MENU And _
            wParam <= MAX_MENU _
                Then Exit Function
    End If

    If msg = WM_SYSCOMMAND And _
        wParam = IDM_ABOUT _
        MsgBox "Show About dialog here"
        Exit Function
    End If

    NewWindowProc = CallWindowProc( _
        OldWindowProc, hwnd, msg, wParam, _
End Function
My book Custom Controls Library uses subclassing to create several advanced ActiveX controls.
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.