Hi,
Is there anyway to traverse VB6 menu items one by one and add them e.g
to a tree object or listbox?

Re: Traversing VB6 menu items by Ralph

Ralph
Sun May 25 11:16:36 CDT 2008


"General Surena" <GeneralSurena@gmail.com> wrote in message
news:uo%23AtDovIHA.3968@TK2MSFTNGP04.phx.gbl...
> Hi,
> Is there anyway to traverse VB6 menu items one by one and add them e.g
> to a tree object or listbox?
>

Well they already provide a collection and can be enumerated by a
For...Each.

What do you mean by "VB6 menu items"? The Menus in the IDE or Menus created
by your program.

And it might help to know why you want to do this. If it is just for
documentation there are tools that can help with this. Or do you want to
invoke these items from a ListBox or ListView?

-ralph





Re: Traversing VB6 menu items by General

General
Sun May 25 14:08:32 CDT 2008

Thanks Ralph,
I Mean the menus created by the programmer at design-time.
I want to add them to a tree or listview to let the user invoke them from a
tree and also let the admins of the application to assign access-controls to
menu (enable-disable them for users of the application).


"Ralph" <nt_consulting64@yahoo.com> wrote in message
news:el9TfLovIHA.576@TK2MSFTNGP05.phx.gbl...
>
> "General Surena" <GeneralSurena@gmail.com> wrote in message
> news:uo%23AtDovIHA.3968@TK2MSFTNGP04.phx.gbl...
>> Hi,
>> Is there anyway to traverse VB6 menu items one by one and add them
>> e.g
>> to a tree object or listbox?
>>
>
> Well they already provide a collection and can be enumerated by a
> For...Each.
>
> What do you mean by "VB6 menu items"? The Menus in the IDE or Menus
> created
> by your program.
>
> And it might help to know why you want to do this. If it is just for
> documentation there are tools that can help with this. Or do you want to
> invoke these items from a ListBox or ListView?
>
> -ralph
>
>
>
>



Re: Traversing VB6 menu items by Larry

Larry
Sun May 25 14:26:22 CDT 2008


"General Surena" <GeneralSurena@gmail.com> wrote

> Thanks Ralph,
> I Mean the menus created by the programmer at design-time.
> I want to add them to a tree or listview to let the user invoke them from a
> tree and also let the admins of the application to assign access-controls to
> menu (enable-disable them for users of the application).

> > Well they already provide a collection and can be enumerated by a
> > For...Each.

As Ralph indicated...

For Each obj In Controls
If TypeOf obj Is Menu Then
Debug.Print obj.Caption, obj.Name
End If
Next

Menus are included in the Controls collection.

LFS



Re: Traversing VB6 menu items by General

General
Sun May 25 22:17:58 CDT 2008

Does this preserve the hierarchy of the menu I have created?
Can I make a tree with the same hierarchy of the menu items?

"Larry Serflaten" <serflaten@usinternet.com> wrote in message
news:e4td3zpvIHA.4736@TK2MSFTNGP04.phx.gbl...
>
> "General Surena" <GeneralSurena@gmail.com> wrote
>
>> Thanks Ralph,
>> I Mean the menus created by the programmer at design-time.
>> I want to add them to a tree or listview to let the user invoke them from
>> a
>> tree and also let the admins of the application to assign access-controls
>> to
>> menu (enable-disable them for users of the application).
>
>> > Well they already provide a collection and can be enumerated by a
>> > For...Each.
>
> As Ralph indicated...
>
> For Each obj In Controls
> If TypeOf obj Is Menu Then
> Debug.Print obj.Caption, obj.Name
> End If
> Next
>
> Menus are included in the Controls collection.
>
> LFS
>
>



Re: Traversing VB6 menu items by Ralph

Ralph
Sun May 25 22:03:33 CDT 2008


"General Surena" <GeneralSurena@gmail.com> wrote in message
news:%23eyyzctvIHA.3968@TK2MSFTNGP04.phx.gbl...
> Does this preserve the hierarchy of the menu I have created?
> Can I make a tree with the same hierarchy of the menu items?
>

You'll have to play with it. AFAIK (or perhaps more my guess? <g>) the order
returned by a "For...Each" is usually the order in which the items were
created. Also Menu/Control collections are infamous for having 'holes', ie,
strict indexing often presents surprises.




Re: Traversing VB6 menu items by Larry

Larry
Mon May 26 03:02:01 CDT 2008


"General Surena" <GeneralSurena@gmail.com> wrote

> Does this preserve the hierarchy of the menu I have created?

No, but it will preserve the order as shown in the menu editor.

> Can I make a tree with the same hierarchy of the menu items?

Of course you can, but it will take a bit of creative coding to
preserve the hiearchy. For example, you might use each menu's
Tag property to denote its position in the tree/list.

For example, you might use letters to identify a menu item's
position such that single letters denote top level menus, and
double letters denote second level menus, and triple letters
denote third level menus, and so on. Looking at just the Tags
the structure may look like the following:

A
AA
AB
B
BA
BB
BBA
BBB
BBC
BC
...

After adding a bit of decyphering code, you could then build
a list with all the items in their proper position. Do note, however,
that the Tag property is not available in the Menu Editor, you
would have to adjust those from the Property window....

LFS




Re: Traversing VB6 menu items by General

General
Mon May 26 09:42:40 CDT 2008

Many thanks for the suggestions.
I have come from the Delphi world, there we had a separate menu object
added from the toolbar on a form and you could traverse it just like a tree.
Is there any third-party menu object available in the VB6 world to use
for this purpose?



"Larry Serflaten" <serflaten@usinternet.com> wrote in message
news:ugI4HawvIHA.3384@TK2MSFTNGP03.phx.gbl...
>
> "General Surena" <GeneralSurena@gmail.com> wrote
>
>> Does this preserve the hierarchy of the menu I have created?
>
> No, but it will preserve the order as shown in the menu editor.
>
>> Can I make a tree with the same hierarchy of the menu items?
>
> Of course you can, but it will take a bit of creative coding to
> preserve the hiearchy. For example, you might use each menu's
> Tag property to denote its position in the tree/list.
>
> For example, you might use letters to identify a menu item's
> position such that single letters denote top level menus, and
> double letters denote second level menus, and triple letters
> denote third level menus, and so on. Looking at just the Tags
> the structure may look like the following:
>
> A
> AA
> AB
> B
> BA
> BB
> BBA
> BBB
> BBC
> BC
> ...
>
> After adding a bit of decyphering code, you could then build
> a list with all the items in their proper position. Do note, however,
> that the Tag property is not available in the Menu Editor, you
> would have to adjust those from the Property window....
>
> LFS
>
>
>



Re: Traversing VB6 menu items by General

General
Mon May 26 09:47:09 CDT 2008

I guess there maybe other third-party menu objects available that preserves
the hierarchy of the menu items unlike VB6's built-in one.


"Ralph" <nt_consulting64@yahoo.com> wrote in message
news:euj4A1tvIHA.1240@TK2MSFTNGP02.phx.gbl...
>
> "General Surena" <GeneralSurena@gmail.com> wrote in message
> news:%23eyyzctvIHA.3968@TK2MSFTNGP04.phx.gbl...
>> Does this preserve the hierarchy of the menu I have created?
>> Can I make a tree with the same hierarchy of the menu items?
>>
>
> You'll have to play with it. AFAIK (or perhaps more my guess? <g>) the
> order
> returned by a "For...Each" is usually the order in which the items were
> created. Also Menu/Control collections are infamous for having 'holes',
> ie,
> strict indexing often presents surprises.
>
>
>



Re: Traversing VB6 menu items by expvb

expvb
Mon May 26 09:25:51 CDT 2008

First, could you explain why you want to do this? Sometimes the way you are
trying to solve the problem is not the best way, and others can have
suggestions on how to better solve the underlying problem.

Second, as Larry suggested, you can use the Tag property, however, the Menu
Editor doesn't let you set it at design time, so you have to assign it in
code, in Form_Load event for example. Besides what Larry suggested, some use
the Tag property with easy to divide numbers like "1|3|0", and use
Split(mnu.Tag, "|") to get all three part separately. Example:

Private Sub Form_Load()
Dim ctl As Control
Dim i As Long
Dim L(1 To 3) As Long
Dim s() As String ' 0 Based

mnuFile.Tag = "1|0|0"
mnuNew.Tag = "1|1|0"
mnuOpen.Tag = "1|2|0"

mnuTools.Tag = "2|0|0"
mnuOptions.Tag = "2|1|0"

mnuHelp.Tag = "3|0|0"
mnuAbout.Tag = "3|1|0"

s = Split(mnuOpen.Tag, "|")
For i = 0 To UBound(s)
L(i + 1) = Val(s(i))
Debug.Print L(i + 1)
Next

For Each ctl In Controls
If TypeOf ctl Is Menu Then
Debug.Print ctl.Name, ctl.Tag
End If
Next
End Sub


Finally, it's possible to loop through the Menu using the API, however, you
cannot automatically tell which menu is related to the control name in VB6
because the menu control does not expose any handles. However, the API gives
their relative position starting from 0, and for each submenu, or another
menu, it starts from 0 again, so you can do some simple mapping. Search the
newsgroups for "vb GetMenu" for samples.



Re: Traversing VB6 menu items by expvb

expvb
Mon May 26 09:56:39 CDT 2008

Here is a sample for an API method that loops through up to 3 levels:

Option Explicit

Private Const MF_BYCOMMAND = &H0&
Private Const MF_BYPOSITION = &H400&
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long)
As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal
nPos As Long) As Long
Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA"
(ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal
nMaxCount As Long, ByVal wFlag As Long) As Long

Private Sub Form_Load()
Dim hMenu(1 To 10) As Long
Dim MenuItemsCount(1 To 10) As Long
Dim i As Long
Dim j As Long
Dim k As Long

' Level 1 Menu(Main Menu)
hMenu(1) = GetMenu(Me.hwnd)

If hMenu(1) <> 0 Then
MenuItemsCount(1) = GetMenuItemCount(hMenu(1))
' Level 1 loop
For i = 0 To MenuItemsCount(1) - 1
' Print the menu text
Debug.Print "Level 1:"; i; j; k; GetMenuText(hMenu(1), i)
' Level 2 Menu
hMenu(2) = GetSubMenu(hMenu(1), i)
If hMenu(2) <> 0 Then
MenuItemsCount(2) = GetMenuItemCount(hMenu(2))
' Level 2 loop
For j = 0 To MenuItemsCount(2) - 1
' Print the menu text
Debug.Print "Level 2:"; i; j; k; GetMenuText(hMenu(2),
j)
' Level 3 Menu
hMenu(3) = GetSubMenu(hMenu(2), i)
If hMenu(3) <> 0 Then
MenuItemsCount(3) = GetMenuItemCount(hMenu(3))
' Level 3 loop
For k = 0 To MenuItemsCount(3) - 1
' Print the menu text
Debug.Print "Level 3:"; i; j; k;
GetMenuText(hMenu(3), k)
Next
End If
Next
End If
Next
End If
End Sub

Private Function GetMenuText(ByVal hMenu As Long, ByVal wIDItem As Long) As
String
Dim c As Long
Dim s As String

' Get the text size
c = GetMenuString(hMenu, wIDItem, vbNullString, 0, MF_BYPOSITION)

' Allocate the string
s = String(c + 1, 0)

' Get the text
c = GetMenuString(hMenu, wIDItem, s, c + 1, MF_BYPOSITION)

GetMenuText = s

End Function



Re: Traversing VB6 menu items by General

General
Mon May 26 10:55:41 CDT 2008

Thanks for ur lengthy explanation.
I want to add the menu items to a tree and then let the admins assign
access levels to each menu item for each user of the system )enable-disable
them) and then add this access levels to a database table.

"expvb" <nobody@cox.net> wrote in message
news:%238YMixzvIHA.524@TK2MSFTNGP05.phx.gbl...
> First, could you explain why you want to do this? Sometimes the way you
> are trying to solve the problem is not the best way, and others can have
> suggestions on how to better solve the underlying problem.
>
> Second, as Larry suggested, you can use the Tag property, however, the
> Menu Editor doesn't let you set it at design time, so you have to assign
> it in code, in Form_Load event for example. Besides what Larry suggested,
> some use the Tag property with easy to divide numbers like "1|3|0", and
> use Split(mnu.Tag, "|") to get all three part separately. Example:
>
> Private Sub Form_Load()
> Dim ctl As Control
> Dim i As Long
> Dim L(1 To 3) As Long
> Dim s() As String ' 0 Based
>
> mnuFile.Tag = "1|0|0"
> mnuNew.Tag = "1|1|0"
> mnuOpen.Tag = "1|2|0"
>
> mnuTools.Tag = "2|0|0"
> mnuOptions.Tag = "2|1|0"
>
> mnuHelp.Tag = "3|0|0"
> mnuAbout.Tag = "3|1|0"
>
> s = Split(mnuOpen.Tag, "|")
> For i = 0 To UBound(s)
> L(i + 1) = Val(s(i))
> Debug.Print L(i + 1)
> Next
>
> For Each ctl In Controls
> If TypeOf ctl Is Menu Then
> Debug.Print ctl.Name, ctl.Tag
> End If
> Next
> End Sub
>
>
> Finally, it's possible to loop through the Menu using the API, however,
> you cannot automatically tell which menu is related to the control name in
> VB6 because the menu control does not expose any handles. However, the API
> gives their relative position starting from 0, and for each submenu, or
> another menu, it starts from 0 again, so you can do some simple mapping.
> Search the newsgroups for "vb GetMenu" for samples.
>
>



Re: Traversing VB6 menu items by expvb

expvb
Mon May 26 09:59:59 CDT 2008

There was a one letter typo in the previous code, here is the correct one:

Option Explicit

Private Const MF_BYCOMMAND = &H0&
Private Const MF_BYPOSITION = &H400&
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long)
As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal
nPos As Long) As Long
Private Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA"
(ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal
nMaxCount As Long, ByVal wFlag As Long) As Long

Private Sub Form_Load()
Dim hMenu(1 To 10) As Long
Dim MenuItemsCount(1 To 10) As Long
Dim i As Long
Dim j As Long
Dim k As Long

' Level 1 Menu(Main Menu)
hMenu(1) = GetMenu(Me.hwnd)

If hMenu(1) <> 0 Then
MenuItemsCount(1) = GetMenuItemCount(hMenu(1))
' Level 1 loop
For i = 0 To MenuItemsCount(1) - 1
' Print the menu text
Debug.Print "Level 1:"; i; j; k; GetMenuText(hMenu(1), i)
' Level 2 Menu
hMenu(2) = GetSubMenu(hMenu(1), i)
If hMenu(2) <> 0 Then
MenuItemsCount(2) = GetMenuItemCount(hMenu(2))
' Level 2 loop
For j = 0 To MenuItemsCount(2) - 1
' Print the menu text
Debug.Print "Level 2:"; i; j; k; GetMenuText(hMenu(2),
j)
' Level 3 Menu
hMenu(3) = GetSubMenu(hMenu(2), j)
If hMenu(3) <> 0 Then
MenuItemsCount(3) = GetMenuItemCount(hMenu(3))
' Level 3 loop
For k = 0 To MenuItemsCount(3) - 1
' Print the menu text
Debug.Print "Level 3:"; i; j; k;
GetMenuText(hMenu(3), k)
Next
End If
Next
End If
Next
End If

End Sub

Private Function GetMenuText(ByVal hMenu As Long, ByVal wIDItem As Long) As
String
Dim c As Long
Dim s As String

' Get the text size
c = GetMenuString(hMenu, wIDItem, vbNullString, 0, MF_BYPOSITION)

' Allocate the string
s = String(c + 1, 0)

' Get the text
c = GetMenuString(hMenu, wIDItem, s, c + 1, MF_BYPOSITION)

GetMenuText = s

End Function



Re: Traversing VB6 menu items by Bill

Bill
Mon May 26 10:14:26 CDT 2008

"General Surena" <GeneralSurena@gmail.com> wrote in message
news:eSqL8dzvIHA.3384@TK2MSFTNGP03.phx.gbl...
>I guess there maybe other third-party menu objects available that preserves
>the hierarchy of the menu items unlike VB6's built-in one.

I get the impression that what you are attempting to describe, and what most
others in here are thinking are two completely different things.

When I read your original message, I was not thinking along the line of the
standard menuing system built-into VB, but rather you are looking for a
treeview. VB has a built-in treeview control which would accomplish what I
think you're looking for. We took it one step further for our accounting
package and bought a third-party control, whose name eludes me for some
reason, which is a presentation layer control that combines treeview with
listview and window panes.

I'm guessing that you're not talking about pull-down menus at all, am I
correct?

This would be a window with a treeview visible at all times that the user
can navigate.



Re: Traversing VB6 menu items by Bill

Bill
Mon May 26 10:17:30 CDT 2008

"General Surena" <GeneralSurena@gmail.com> wrote in message
news:O6RYNE0vIHA.3792@TK2MSFTNGP02.phx.gbl...
> Thanks for ur lengthy explanation.
> I want to add the menu items to a tree and then let the admins assign
> access levels to each menu item for each user of the
> system )enable-disable them) and then add this access levels to a database
> table.

Okay, I had to load up my project (on a holiday no less) just to figure out
the name of the one I use. It's made by Infragistics, however I don't know
that they still make available or support an ActiveX version or not, I think
they've moved into the dot not community like most every other control
developer.

try http://www.infragistics.com to see for yourself

I use their outlook bar control and their explorer control.



Re: Traversing VB6 menu items by expvb

expvb
Mon May 26 10:40:16 CDT 2008

"General Surena" <GeneralSurena@gmail.com> wrote in message
news:O6RYNE0vIHA.3792@TK2MSFTNGP02.phx.gbl...
> Thanks for ur lengthy explanation.
> I want to add the menu items to a tree and then let the admins assign
> access levels to each menu item for each user of the
> system )enable-disable them) and then add this access levels to a database
> table.

A Treeview can display Checkboxes, beyond that you have to use multiple
ListBoxes or a 3rd party control.




Re: Traversing VB6 menu items by General

General
Mon May 26 13:05:45 CDT 2008

No, they are right.
I am trying to traverse the standard menuing system built into VB6 and
add the items one by one to a treeview control like the one you mentioned.


"Bill Hileman" <discgolfdad@gEEmail.com> wrote in message
news:eg3ZqM0vIHA.1936@TK2MSFTNGP04.phx.gbl...
> "General Surena" <GeneralSurena@gmail.com> wrote in message
> news:eSqL8dzvIHA.3384@TK2MSFTNGP03.phx.gbl...
>>I guess there maybe other third-party menu objects available that
>>preserves the hierarchy of the menu items unlike VB6's built-in one.
>
> I get the impression that what you are attempting to describe, and what
> most others in here are thinking are two completely different things.
>
> When I read your original message, I was not thinking along the line of
> the standard menuing system built-into VB, but rather you are looking for
> a treeview. VB has a built-in treeview control which would accomplish
> what I think you're looking for. We took it one step further for our
> accounting package and bought a third-party control, whose name eludes me
> for some reason, which is a presentation layer control that combines
> treeview with listview and window panes.
>
> I'm guessing that you're not talking about pull-down menus at all, am I
> correct?
>
> This would be a window with a treeview visible at all times that the user
> can navigate.
>
>



Re: Traversing VB6 menu items by General

General
Mon May 26 13:12:06 CDT 2008

I just need the items to be loaded into a tree (name of each item in the
menu object + hierarchical structure).
I can use checkboxes outside the treeview control. The admin must click on
each node representing a menu item and just enable-disable it for the user.


"expvb" <nobody@cox.net> wrote in message
news:euozHb0vIHA.5580@TK2MSFTNGP04.phx.gbl...
> "General Surena" <GeneralSurena@gmail.com> wrote in message
> news:O6RYNE0vIHA.3792@TK2MSFTNGP02.phx.gbl...
>> Thanks for ur lengthy explanation.
>> I want to add the menu items to a tree and then let the admins assign
>> access levels to each menu item for each user of the
>> system )enable-disable them) and then add this access levels to a
>> database table.
>
> A Treeview can display Checkboxes, beyond that you have to use multiple
> ListBoxes or a 3rd party control.
>
>
>



Re: Traversing VB6 menu items by Bob

Bob
Mon May 26 15:43:22 CDT 2008

General Surena wrote:
> Many thanks for the suggestions.
> I have come from the Delphi world, there we had a separate menu object
> added from the toolbar on a form and you could traverse it just like a tree.
> Is there any third-party menu object available in the VB6 world to use
> for this purpose?



I don't know if it's still available anywhere, but
Sheridan's "WinAPI Oblets" could probably do it.




Bob
--