Link to home
Start Free TrialLog in
Avatar of ElishaKlein
ElishaKlein

asked on

How to have a menu item that can be clicked but also has a submenu

Hi,
I need to be able to have items in a menu that can be clicked on but also have a submenu of items. (TrackPopUpMenu...)
The way I understand right now in the windows menus an item is either an item and can be clicked or a submenu and then only its items can be clicked.
What I need is something like in the Internet explorer favorites where if you double click on a folder it opens the folder (the folder of course has subitems) only I would rather it happened when you click and not double click.
Is there any way to detect a click or doubleclick (not OnSelect which happens when it is highlighted) on the menu item that has a submenu ?
I will accept any type of solution that will solve this problem meaning any technology or even custom compontents that give this functionality.
I already have a menu like this in DHTML but I would like to have the functionality in an active-x or something because I want the menu in an internet explorer toolbar that I have created.
Also I would much prefer if the menu behaved as the windows menus meaning I would not have to click on an arrow to open each level of the menu unless there is no other choice.
I am giving a lot of points for this so I expect a serious answer please that will help to solve my problem.
Thanks very much in advance.
Avatar of migel
migel

Hi!
IMHO You need to write your own control that behave like menu but wit your own customization with submenus.
Try this link

http://www.codeproject.com/docking/sizablerebar.asp - A set of classes to create the IE-style GUI

Good Luck
Avatar of ElishaKlein

ASKER

Hi,
roshmon can you show me the part of this project that is relevant to what I want to do please ? Some sampe code ?
migel thanks for your response, sounds like a good direction for a start. Can you show more details of how I would do this ? Like sample code please ?
Thanks a lot.
Avatar of AndyAinscow
I must be missing something important in the question.
I have an app with a list box.  I right click the list box to get a context menu.  That has various items one of which when the mouse goes onto it opens a sub menu (no click required).
All built in the resource editor - no coding to get the sub menu displayed.
I personally find this easier to use than a menu where one would have to click an item to get at further choices.
Is it the permanent display of the sub menu that is important for you?
Hi Andy,
Thanks for your reply. I guess I didn't say this but the contents of the menu are built dynamically and needs to be refreshable at runtime while the menu is open. Also it is a hierarchial structure that can have many levels meaning a menu with a sub menu with submenus with items... but each submenu is also an item in itself.
Also if I am already going into the details - beyond each item and subitems each item (or submenu) will also need to be able to open a seperate menu (context menu) when it is right clicked so the user will be able to configure the actual structure for the main menu (like deleting an item for example) but i figured this is a seperate question and I plan to reward points for that seperately.
ASKER CERTIFIED SOLUTION
Avatar of Roshan Davis
Roshan Davis
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a lot Rosh.
I think I understand what you require.

How about
when launching your menu you create a list box (long enought to hold your items), maybe ownerdraw for displaying the menu items with sub menu's.  This list box is a sparate child window.
When the user selects a sub menu item then a further child list box is created and displayed.
ie. Just one class is required for this control.

When the 'menu' experiences a right mouse click then you can customise/resize appropriately.
when an item is selected work you way up the ownership chain (GetParent) until it meets the window that started everything off, send it a message saying what was selected and then delete these 'menu' windows.
Andy,
If I understand correctly what you are saying each level of the menu would actually be a seperate list box window ?
How would the submenu open (second list box) when you highlighted an item with subitems ?
This solution sounds very complex because there are a lot of details I would need to work out including making the list box look like a menu and coordinating beteween all the levels of the menu.


Also how would the cursor pass from one listbox to another?
How would all this look ?
Yes - that allows a permanence in the display.
You can set the foreground/text colours by overriding the OnCtlColor function (that makes it look like a menu).  Using owner draw you can display the items containing a sub menu differently from the other items (favorites in IE).
One list box is a child of the other (and inversely a parent of the other).
You put the itmes into the list therefore you 'know' if the correct response to the mouse click / enter key is to perform an action or to display/hide the sub menu.  Equally well you can respond to the left/right arrow key to pass focus down to the child list box or back up to the parent list box.  The normal up/down arrow keys are handled by the default behaviour.

The items you put into the list would require something for the text to display, the event to perform (if an event driver) or an ID to allow you to generate the child menu and a CMenuListbox pointer for your child menu.  (You did say you create/modify the menus dynamically).

There is certainly some coding required but you would have to understand the code written by someone else should you find something somewhere that purports to do the job (and may well require bits recoding for your specific instance).
Can You post some sample code of a watered down version to illustrate how it would work and what it  would look like ?
"You put the itmes into the list therefore you 'know' if the correct response to the mouse click / enter key is to perform an action or to display/hide the sub menu."

Just to be clear on the main issue of the question. The sub menu should appear when I highlight the parent item. But something else will happen when I click the parent item.
I had a further thought.  This is overly complex.
Use a tree control instead.  That only requires the one window and a lot of the functionality is already coded into it.
I just got called away briefly before I could type more.
A tree control.  You can add/modify/remove items on the fly.  You can populate the branch only when it is to be opened.  Keyboard support for arrow keys are built in.  Only one child window required so should be easier for you to control everything.

logic:
create as child control, populate with items. Display some symbol (or other visual hint) for the items to have a sub menu.
When a branch is to be displayed add the items to that branch. Resize window width.  (Sub Menu behaviour)
Message handler for the click event - if it has children display/hide branch.  If no children then it is an event to be passed onto the parent window for handling.
USe SetCapture/GetCapture/Release capture to destroy the child when the user clicks off the control with the mouse.
Andy thanks for your suggestions.
Actually I thought about using a tree control but I stopped because I don't think it is possible to have it come out of an internet explorer toolbar is it ?
Also I don't like it so much becuase you have to click once for each level of the menu. I want just one click at the end when you find the item you need. highlighting opens the submenus. Can this be done with a tree control ?
Your dll/ActiveX control would have to encapsulate the tree and its functionality.
Exactly what options/actions you have/perform and how it communicates with the browser are up to you but that is another matter.  I think the tree is a possible way to go (it should provide an undestandable interface for the user).  After all your extension will have to contain at least one window.
I realize I may have mentioned a lot of details in the question, however I tried to keep the basic question focused and well defined. I want to create a menu that has submenus and they can also have submenus, so that each each submenu opens when it's parent is highlighted and each item (or parent item also) is selcted when it is clicked. As I said I already have this menu in DHTML (so the user interface is well defined and easy to understand).
The fact that I could (somehow, maybe) modify the behavior of either a menu, or a list, or a tree to achieve this behaviour is I feel obvious.
The question is how I am going to do that.
I need at least a viable plan, if not some sample code so I can decide what to do.

Thanks.
Just fill the tree and all it's branches when you launch it.  There is a function in a tree that will open all branches automatically.
You code however have some code that checks if the mouse is hovering over an item (for say 0.4 secs) and then it automatically opens that branch for you (if it is a sub menu type of item that is).
go to www.msnbc.com .
Look at the menu on the left side of the page.
Highlight travel for example.
This is what I want my menu to behave like, except in one way.
In my alternative menu if you click say "latest travel news" it will also take me to a web page.
OK.
I'll look at the msnbc page re menu.
I'll not have chance to post anything else today.  
I do have time for a quick comment.  It looks like a more or less standard context menu.  Possibly owner drawn.
To be clearer.
Main menu - list box based.  Check for mouse hovering over an item, display context menu if it is hovering and if there is a context menu available.
For the hover follow the mouse move messages and see if it is over an item in the list box for more than a predetermined interval.

That way mouse click on listbox - do event
Mouse hover, popup menu appears and that will fire an event is something is selected
But that brings us back to all the problems with the list box.
I started looking at hooking the click on the menu. looks simpler and more promising.
I had a look at the msnbc site and the menu there.  The main menu part looks very different to the rest.  The rest looks like a normal context menu.
Hence the suggestion of the main menu part as a list box.
The top entries don't have any context menu possibilites the lower ones do.

I suggest the following three stages of coding.
So have a list box with 2 items.  Click on the first and your 'app' fires an event to go to www.x.com, click the second and it shows a dialog with some info.
<easy coding>

Now
Modify the click on the second item and instead of the dialog start a context menu (as if a right click had occurred)  This is too test the functionality of the context menu and its code.
<still pretty easy>

Finally.
Reset the click event for the second item.
When the list box is visible start a timer at say 0.1 second intervals.
Set a member var to hold the current item's number in the list (or some other unique ID)
have a handler for the mouse move message.
in the handler do the following.
check if the mouse is captured by the app and if not capture the mouse. (we want all mouse movements)
check is the mouse over the list (maybe it has moved off) and if not release the mouse, set to null the var noting which item the mouse is over.
In the OnTimer do the following
is the item the mouse is over the same as the last one the timer fired at.  Yes - increment a counter, no - set counter to zero.
Is the counter at a preset value (eg. 4 == 0.4 secs) yes - display context menu.

There are other things to handle but that gives you an idea of a possible logic.
Andy,
Thanks for your help.
I think we also had another misunderstanding here. I do not need the top level to look diferent like it does on msnbc. It was just an example to say that I want it to look like (the rest of it after the top). My fault for not explaining that.
In  any case I have decided to use a context menu and hook the click events. Thats what I found in the link that Rosh gave me, so I awarded him the points.
I feel like you should also get some points since you spent so much time, even though it didn't help in the end.
Right now I am getting the click events from the menu from the hook, but the only problem now is I can't recognize if the click was inside the menu or not. I tried using MenuItemFromPoint but that didn't work (I think because I don't have the HWND from the menu I have the hwnd from my window that holds the menu and gets the hook notifications) so right now I am assuming that the click is on the last item that was highlighted but this is a probelem when the user actually clicks outside the menu.
Can I open a private question for you and if you help me with this give you another 500 points ?
OK - misunderstandings occurr and it's your question to award how you see fit.
I'll have a think about the latest problem.  If I can help then we can generate another question specifically for the points as you suggest.
I'll post something later.
Ok thanks.
Please could you send me the code invovlved in launching the context menu and your click event you get (or the complete file).
info@ainscow.ch
Got it to work !!
Do you still want to see the code ?
In case anyone else wants to see the answer:
I saved the window that was highlighted in OnMenuSelect
POINT pt;
GetCursorPos(&pt);
MenuWnd = WindowFromPoint(pt);

And then in the MouseProc (from the hook) I checked if it was the same window before deciding that an item had been selected.
I had an idea on the same lines myself but I didn't know enough of what you were doing to suggest it.
So does it all work?
Yeah it does.
I'll remember your name if I have any trouble in the future.