?
Solved

run time nested menu items?

Posted on 2003-02-20
5
Medium Priority
?
304 Views
Last Modified: 2011-09-20
Hi all...

I am in a big dilemma and i would need some of your suggestions.

I have an app where one of the menu items will have dynamically generated sub-menu items (collected from an array, etc.).

I figured how to make a control array in the menu editor, and I just set the captions and make those sub-menus visible or not.


The problem comes if I want to add a nested sub-menu to those dynamically generated sub-menus.

Here is a diagram to explain myself:


Tools(main menu item on the menu-bar)
|
|_Dynamic Sub01
|           |_Item A
|           |_Item B
|           |_Item C
|
|_Dynamic Sub02
|           |_Item A
|           |_Item B
|           |_Item C
|
|_Dynamic Sub03
            |_Item A
            |_Item B
            |_Item C



1. As you see, "Dynamic Sub01 - Dynamic Sub03" are my dynamically generated submenu items. Their caption (and how many of them) is set at runtime.

2. The nested sub-menus (Item A-Item C) of the "Submenu 01 - Submenu 03" have always the same captions for all Dynamic Submenus same order, etc. The only thing is they will point to different subs.

So I don't know what's the best strategy for this, where to start, etc.

As I said. I have the first part down already and running - that's the first level of "Dynamic Sub01 - Dynamic Sub03"... The problem are my nested sub-menus (Item A-Item C).

Examples are MORE than welcome!

Thanks a lot,
Gabi.
0
Comment
Question by:gabibucataru
[X]
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
  • 2
  • 2
5 Comments
 
LVL 2

Expert Comment

by:JoaTex
ID: 7989758
Hi
Try this litle Program:

on Menu Editor Make this Menu:
Menu
Caption=Menu
Name = MenuTeste
Visible=false [Increase one Level]

...SubMenu1
Caption=1
Name=Menu1
index=1
Visible=True

...SubMenu2
Caption=2
Name=Menu1
index=2
Visible=True

...SubMenu3
Caption=3
Name=Menu1
index=3
Visible=True
OK

Code:

Option Explicit
Dim M As String
Dim N As Byte
Dim Subm(3)

Private Sub Form_Click()
   MenuTeste.Caption = M
   MenuTeste.Visible = True
   For N = 1 To 3
      Menu1(N).Caption = Subm(N)
      Menu1(N).Visible = True
   Next N
End Sub

Private Sub Form_Load()
   M = "Teste"
   Subm(1) = "Teste1"
   Subm(2) = "Teste2"
   Subm(3) = "Teste3"
End Sub

Hope this suite you
Jo
0
 
LVL 2

Accepted Solution

by:
Sweat earned 200 total points
ID: 7990124
gabibucataru,

I searched on the newsgroups and found the following.  With it, you can dynamically create any number of first level menus and then any number of second level menus below those.  It's a bit complex and you should step through it all to be sure you understand it.

First.  On a new project, create a First level menu item.

Second.  Paste the following code inside the form:

Private Sub Form_Load()
    Call SubClassWnd(Form1.hwnd)
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Call UnSubClass(Form1.hwnd)
End Sub

Third.   Add a new module to the project, just a standard module and paste this code into it:

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private 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
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function CreatePopupMenu Lib "user32" () As Long
Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Private Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long

Dim OldProc As Long
Dim NewMenu As Long

Private Type typProcInf
    piHandle As Long
    piProc As Long
End Type

Private Const GWL_WNDPROC = (-4)
Private Const WM_COMMAND = &H111

' A bunch of menu styles for you
Private Const MF_ENABLED = &H0&
Private Const MF_GRAYED = &H1&
Private Const MF_DISABLED = &H2&
Private Const MF_CHECKED = &H8&
Private Const MF_SEPARATOR = &H800&
Private Const MF_POPUP = &H10&

Private Const BaseMenu = &H100

Public Function SubClassWnd(inWnd As Long) As Boolean
    Dim hMenu As Long

    'Get the existing menu handle
    hMenu = GetMenu(inWnd)

    ' Get the first menu (Try commenting this line to see why it's here)
'    hMenu = GetSubMenu(hMenu, 0)

    ' Create a new menu
    NewMenu = CreatePopupMenu()

<<<<<>>>>>
This will create the first level menu next to the menu
you created originally.  With each appendmenu, you are
creating the sub items within the new first level menu.
<<<<<>>>>>
    ' Add some items to our new menu
    AppendMenu NewMenu, MF_ENABLED, BaseMenu, "One"
    AppendMenu NewMenu, MF_ENABLED, BaseMenu + 1, "Two"
    AppendMenu NewMenu, MF_SEPARATOR, BaseMenu + 2, "-"
    AppendMenu NewMenu, MF_CHECKED, BaseMenu + 3, "Three"

    ' Add the menu to the existing one
    AppendMenu hMenu, MF_POPUP, ByVal NewMenu, "New menu"

<<<<<>>>>>
This creates another instance of the first level menu
next to the one above which was dynamically created.
Continue in your loop or however many menus you need until
you are done
<<<<<>>>>>
    ' Create a new menu
    NewMenu = CreatePopupMenu()

    ' Add some items to our new menu
    AppendMenu NewMenu, MF_ENABLED, BaseMenu, "One-One"
    AppendMenu NewMenu, MF_ENABLED, BaseMenu + 1, "Two-Two"
    AppendMenu NewMenu, MF_SEPARATOR, BaseMenu + 2, "-"
    AppendMenu NewMenu, MF_CHECKED, BaseMenu + 3, "Three-Three"

    ' Add the menu to the existing one
    AppendMenu hMenu, MF_POPUP, ByVal NewMenu, "Another New menu"

    ' Sub-class the window
    OldProc = SetWindowLong(inWnd, GWL_WNDPROC, AddressOf WndProc)
End Function

Public Function UnSubClass(inWnd As Long) As Long
    ' Destroy the custom menu
    Call DestroyMenu(NewMenu)

    ' Un-sub-class the window
    SetWindowLong inWnd, GWL_WNDPROC, OldProc
End Function

Public Function WndProc(ByVal hwnd As Long, ByVal uMsg As Long, _
    ByVal wParam As Long, ByVal lParam As Long) As Long
    If (uMsg = WM_COMMAND) Then ' Command item was selected from the menu
        Select Case ((wParam And &HFFFF) - BaseMenu) ' Item index
            Case 0: MsgBox "Clicked ""One"""
            Case 1: MsgBox "Clicked ""Two"""
            Case 2: MsgBox "Clicked seperator" ' Shouldn't ever fire
            Case 3: MsgBox "Clicked ""Three"""
        End Select
    End If

    ' Send everything past default WndProc() too
    WndProc = CallWindowProc(OldProc, hwnd, uMsg, wParam, lParam)
End Function


Credit for this solution goes to:
    Mike
 - Microsoft Visual Basic MVP -
WWW: Http://EDais.earlsoft.co.uk/
Work E-Mail: EDais@btclick.com
Other E-Mail: Mike.Sutton@btclick.com

from the:
microsoft.public.vb.general.discussion
newsgroup

Sweat


0
 

Author Comment

by:gabibucataru
ID: 8011751
Great example!!!! outstanding!
0
 

Author Comment

by:gabibucataru
ID: 8011768
Awsome!!! Outstanding answer!!!!
0
 
LVL 2

Expert Comment

by:Sweat
ID: 8012121
Gabi,

Thank you.  Just trying to help.

Sweat

0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
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…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month9 days, 12 hours left to enroll

762 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