Click to See Complete Forum and Search --> : URGENT : with pop-up menu, HOW do you get the element just clicked ??


StéphaneDebono
April 7th, 1999, 07:47 AM
Hi,

In my project I use list control and pop-up menus on th items (icons). I would like to know which item was selected by the user.

You have to know that the items of thes pop-up menus change with the items. I don't use ID for these items.

So, how can I get the item just selected when the pop-up menu is closing.

Thanks for your help.

Best regards

Stéphane.

Dave Lorde
April 7th, 1999, 08:24 AM
Use an ON_COMMAND_RANGE message map entry with a handler that takes a UINT. The ID of the selected menu item will be passed to the handler in this UINT argument.

You do need to give your menu items IDs, even if they are added dynamically.

Dave

StéphaneDebono
April 7th, 1999, 09:12 AM
I read that ON_COMMAND_RANGE(id1, id2, memberFxn)

How can I use that ? Do I have to put id1 = IDR_MENU1 ? And what about id2 ?

Could you detail your idea ?

Thanks a lot,

Stéphane.

Dave Lorde
April 7th, 1999, 09:33 AM
It's all in the online documentation, with an example (see "ON_COMMAND_RANGE" and "Handlers for Message-Map Ranges").

Since I have five minutes spare, I'll save you the trouble of looking it up.

id1 and id2 are respectively the beginning and end of a contiguous range of command IDs. In your case, id1 will be the value of the first menu item, and id2 will be the value of the last menu item.

In the .CPP file, add your message-map entry, as shown in the following example:

...
BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
//{{AFX_MSG_MAP(CMyApp)
...
//}}AFX_MSG_MAP
ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, OnDoSomething)
END_MESSAGE_MAP( )
...

Declaring the Handler Function:
In the .H file, add your handler function declaration outside the //{{AFX_MSG comment brackets. The following code shows how this might look, as shown in the next-to-last line below:

// Generated message-map functions
protected:
//{{AFX_MSG(CMyApp)
...
//}}AFX_MSG
afx_msg void OnDoSomething( UINT nID );
DECLARE_MESSAGE_MAP()

Handler functions for single commands normally take no parameters. With the exception of update handler functions, handler functions for message-map ranges require an extra parameter, nID, of type UINT. This parameter is the first parameter. The extra parameter accommodates the extra command ID needed to specify which command the user actually chose.

StéphaneDebono
April 7th, 1999, 09:51 AM
thanks for these details. But, and it will be my last question, my problem is that I don't know ID_MYCMD_ONE and ID_MYCMD_TEN, because I don't know how many items I will have for my pop-up.
I use AppendMenu to add items to my pop-up enu which is empty at the beginning. So how can I know the range of the possible IDs ?

Hoping you fill find a solution for me.

Best regards

Stéphane.

Karl
April 7th, 1999, 09:58 AM
Have a look to this article:

http://www.codeguru.com/menu/track_popup.shtml

With this, you got the index (first, second, etc...) of the selected item in the popup.

an other way may be to reserve, for example, 100 ID starting from ID_MYCMD_ONE. I think that a popup with more than 100 items won't be really useful.

HTH.

K.

Ash to ash and clay to clay, if the enemy doesn't get you, your own folk may.

Dave Lorde
April 7th, 1999, 10:03 AM
You have to set aside a range of resource IDs that can be used.

I do it by editing my resource.h file:

...
#define ID_FOO 345

// Reserve 20 menu IDs
#define ID_VIEW_POPUP_MIN 346
#define ID_VIEW_POPUP_MAX 366

#define ID_BAR 367

If you have a sensible specification for your program, you will be able to decide the reasonable maximum number of possible entries.

Before you start modifying the menu, initialise a counter to the id1 value (start of the reserved resource ID range). When you append the menu items, use this counter for the ID value. Increment it after each menu item is added. If the counter exceeds the id2 value (end of reserved resource range), display an error message or throw an exception.

If you reserve a large enough range, the screen will be filled with menu options before they run out.

It's really quite simple.

Dave

April 7th, 1999, 10:04 AM
You can also use the menu in immediate mode. This way you don't need message maps.

CMenu menu;
int pMenuID = 0;
DWORD SelectionMade;
VERIFY(menu.LoadMenu(IDR_MENU1));
CMenu* pPopup = menu.GetSubMenu(pMenuID);
ASSERT(pPopup != NULL);
POINT pp;
GetCursorPos(&pp);
SelectionMade = pPopup->TrackPopupMenu(
TPM_LEFTALIGN | TPM_LEFTBUTTON |
TPM_NONOTIFY | TPM_RETURNCMD, //**NOTE** Undocumented flags
pp.x,pp.y,this);
pPopup->DestroyMenu();

//The value of SelectionMade is
//the id of the command selected
//or 0 if no selection was made
switch(SelectionMade)
{
// ..... do some

StéphaneDebono
April 7th, 1999, 10:27 AM
I tried the code of the link you told me. It is cool. However there is a problem. Indeed, if an item of the pop-up menu is a pop-up menu and if you select an item in the new pop-up menu, that is to say at the level 2, then the id return is always 0. It's ok for the level 1 but not for the level 2.

Do you have a solution for this ?

Please help.

Stéphane.

Karl
April 7th, 1999, 10:45 AM
I don't know, Sorry.

K.

Ash to ash and clay to clay, if the enemy doesn't get you, your own folk may.