Click to See Complete Forum and Search --> : Menus and WM_MENUCOMMAND


TSmooth
November 13th, 2003, 11:53 AM
I have a program which has a menu created in the resource editor consisting of the following top level menus: File, Edit, and Rides. The Rides menu initially contains only a separator bar but during the programs initializaion functions, several menu items are added to it. I need to process these menu items when they are clicked, obviously, but since I do not know the exact number or therefore the ID of the menu items ahead of time, I found that I need to force the menu to generate WM_MENUCOMMAND messages instead of WM_COMMAND messages. I did this using the following code after reading related MSDN information:

HMENU hMenu;
MENUINFO MenuInfo;
BOOL fResult;

hMenu = GetMenu(hwnd);
hMenu = GetSubMenu(hMenu, 2); // Handle to the "Rides" menu
MenuInfo.cbSize = sizeof(MENUINFO);
MenuInfo.dwStyle = MNS_NOTIFYBYPOS;
MenuInfo.fMask = MIM_STYLE | MIM_APPLYTOSUBMENUS;
fResult = SetMenuInfo(hMenu, &MenuInfo);

SetMenuInfo returns success however WM_COMMANDs are still being generated for this menu instead of WM_MENUCOMMAND. I tried this without setting the MIM_APPLYTOSUBMENUS flag as well as the entire piece of code after the new menuitems are already added instead of before. Any help/suggestions would be appreciated. Thanks!

P.S. If i comment out the GetSubMenu() line then it works for all menus, they all generate WM_MENUCOMMAND, but i need it to work for the "Rides" menu only.

OriginalDazed
December 2nd, 2003, 08:35 PM
Why not just assign an ID to the menus when your creating them... for example....

#define ID_FILE_OPEN 201
#define ID_FILE_EXIT 202

HMENU hMenu, hSubMenu;
hMenu = CreateMenu();
hSubMenu = CreateMenu();
AppendMenu(hSubMenu, MF_STRING, ID_FILE_OPEN , "Open");
AppendMenu(hSubMenu, MF_SEPARATOR, 0, 0);
AppendMenu(hSubMenu, MF_STRING , ID_FILE_EXIT, "E&xit");
AppendMenu(hMenu, MF_STRING|MF_POPUP, (UINT)hSubMenu, "File");

SetMenu(hwnd, hMenu);

This creates a menu with File being 'top-level' as you call it, and Open, Exit under it...

Then you can process the WM_COMMAND notification as follows...

case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
// Exit Program?
break; ;
case ID_FILE_OPEN:
// Open File?
break ;
}
break;

TSmooth
December 2nd, 2003, 10:10 PM
The problem with that was that I didn't know how many items were going to be added and thus I wouldn't know how many pre-defined ID's to have and what to do for each case statement. However I solved my problem by determining if the WM_COMMAND was generated by a menu item, if it was, I process all my known cases such as IDC_EXIT or whatever then if it's not one of those cases I know it's from my dynamic menu and I get the text of that menu item which is what I needed and do the necessary functionality from that.