|
|
Title | Add an About dialog to the system menu and create menus at run time |
Keywords | About dialog, menu, custom menu, system menu |
Categories | Controls, 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)
Next
' 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 _
Long
Const WM_NCDESTROY = &H82
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, _
OldWindowProc
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 _
Then
MsgBox "Show About dialog here"
Exit Function
End If
NewWindowProc = CallWindowProc( _
OldWindowProc, hwnd, msg, wParam, _
lParam)
End Function
|
|
My book Custom Controls Library uses subclassing to create several
advanced ActiveX controls.
|
|
|
|
|
|