Dynamic menus. Create menus at runtime...

Posted on 2002-05-02
Last Modified: 2010-05-02
I am trying to create dynamic menus at runtime i.e. I want to generate menu items at runtime  by  picking the menu items from a database, but I am unable to find the options to implement that. I have tried using menuitems and giving the menuitems an index value, thus creating a control array for it - but with this the problem is that I cannot create submenuitems for the dropdown menus I am creating. Also I am trying to generate the top level menu items dynamically which with this approach is giving a problem. I have also tried using commandbar control but that always gives wrong number of arguments error or runtime error 5. I would be glad if anyone of you experts could help me out with this problem or could suggest an alternate solution.
Question by:joyriderank
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +2
LVL 43

Expert Comment

ID: 6985655
If you use the standard menu editor to create a control array of menu items with one item having index 0 in each menu could be shown then you can use the load command to instantiate subsequent menu items.

Author Comment

ID: 6985754

Thanks for the prompt response. I have tried that but I have to create a multi level menu and all the heads have to come dynamically. This much I have been able to acomplish but I need to get more functionality added to the menu on runtime.
LVL 13

Expert Comment

ID: 6985764
VbAccelerator has many excellent menu solutions.
Online Training Solution

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action. Forget about retraining and skyrocket knowledge retention rates.

LVL 43

Expert Comment

ID: 6985831
Thinking of alternatives, I use a TreeView control to populate a menu hierarchy from a database. It provides an excellent interface and is extremely flexible.
LVL 18

Expert Comment

ID: 6985982
This example will show you how to dynamically add some menu items to the System menu of a form.  Simply pass the hwnd of the form to the SubClass function.  Keep in mind that it's one thing to add the menu items, but then it's another to be able to respond when the user clicks those menu items.  So, it's necessary to "hook" the "window proc" of the window with the menu.  This will force all window commands through your custom window proc (in the example below that is the SysMenuHandler routine) which will check to see if the message was generated by clicking on one of your dynamic menus, and if so, it will execute some code.  In all cases, it then sends the message along to the original window proc.

There are also APIs for appending sub-menus, and for getting handles to other menus besides the SystemMenu, but I'm not that familiar with that.  But, this should get you looking in the right direction.

Option Explicit
Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As String) As Long
Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function IsWindow Lib "user32" (ByVal hwnd As Long) As Long

Public Const WM_SYSCOMMAND = &H112
Public Const MF_SEPARATOR = &H800&
Public Const MF_STRING = &H0&
Public Const GWL_WNDPROC = (-4)
Public Const IDM_CUSTOM As Long = 1010
Public Const IDM_CUSTOM2 As Long = 1011
Public lProcOld As Long
Public ghWnd As Long

Public Function SysMenuHandler(ByVal hwnd As Long, ByVal iMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If iMsg = WM_SYSCOMMAND Then
        If wParam = IDM_CUSTOM Then
            MsgBox "About...", vbInformation, "About"
            Exit Function
        End If
        If wParam = IDM_CUSTOM2 Then
            MsgBox "Unhooking...", vbInformation, "Unhook"
            SetWindowLong ghWnd, GWL_WNDPROC, lProcOld
            Exit Function
        End If
    End If
    SysMenuHandler = CallWindowProc(lProcOld, hwnd, iMsg, wParam, lParam)
End Function

Public Function SubClass(hwnd As Long)
    Dim lhSysMenu As Long, lRet As Long
    lhSysMenu = GetSystemMenu(hwnd, 0&)
    'Add seperator
    lRet = AppendMenu(lhSysMenu, MF_SEPARATOR, 0&, vbNullString)
    'Add new menu item
    lRet = AppendMenu(lhSysMenu, MF_STRING, IDM_CUSTOM, "About...")
    lRet = AppendMenu(lhSysMenu, MF_STRING, IDM_CUSTOM2, "Unhook")
    lProcOld = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf SysMenuHandler)
End Function
LVL 12

Accepted Solution

jgv earned 200 total points
ID: 6986772
This sample should provide what you are looking for.
LVL 12

Expert Comment

ID: 6986775
This sample should provide what you are looking for.

Author Comment

ID: 6989476
Thanks for all your comments and suggestion. I have been kept a little buy lately. I will go through your suggestions in the weekend and get back to you guys on Monday. Thanks for your help guys. TAKE CARE.


Author Comment

ID: 7020771
Hi Experts,

Sorry for the delay in getting back to you. First I would like to thank for your suggestions.

MDOUGAN thanks for the code but I am sorry to say I could not make out much from it.

IGV your code was really helpful as it got me to getting the menus created via database connectivity through modifications of course, but I am not able to trap the events for each click. What I mean to say is that now that i have the structure of the menus ready, but what good are they if I can't trap the events of the menus and call the respective form.... So I guess I will raise that question in a new question and am going to post another query regarding the same pretty soon.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In a recent article ( for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

690 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question