Context menu item order

Please help me on the below code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 case WM_RBUTTONDOWN:
        {
            HMENU hPopupMenu = CreatePopupMenu();
            HMENU hSubMenu=CreatePopupMenu();  // Create submenu
            
            // Add items to submenu
            InsertMenu(hSubMenu, 0, MF_BYPOSITION | MF_STRING,ID_IDX, _T("Start"));
            InsertMenu(hSubMenu, 0, MF_BYPOSITION | MF_STRING, ID_IDY, _T("Stop"));
            
            // Add items to hPopupMenu (ones without submenu)
            InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, 1245, _T("Exit"));

            // fill MENUITEMINFO structure
            MENUITEMINFO mi1,mi2 = { 0};
            mi.cbSize=sizeof(MENUITEMINFO );
            mi.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
            mi.wID = ID_Z;
            mi.hSubMenu=hSubMenu;
            mi.dwTypeData=_T("Play");
            // insert menu item with submenu to hPopupMenu
            InsertMenuItem ( hPopupMenu, 0, false, &mi );
            

            mi2.cbSize=sizeof(MENUITEMINFO );
            mi2.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
            mi2.wID = ID_P;
            mi2.hSubMenu=hSubMenu;
            mi2.dwTypeData=_T("Game");
            // insert menu item with submenu to hPopupMenu
            InsertMenuItem ( hPopupMenu, 0, false, &mi2 );


            SetForegroundWindow(hwndDlg);
            TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, 0, 0, 0, hwndDlg, NULL);
        } 




I want List in the order that
Game->Start/Stop
Exit
Play->start/Stop
The second parameter of functions InsertMenu and InsertMenuItem specifies the position of menu item
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
            HMENU hPopupMenu = CreatePopupMenu();
            HMENU hSubMenu=CreatePopupMenu();  // Create submenu
            
            // Add items to submenu
            InsertMenu(hSubMenu, 0, MF_BYPOSITION | MF_STRING,ID_IDX, _T("Start"));
            InsertMenu(hSubMenu, 0, MF_BYPOSITION | MF_STRING, ID_IDY, _T("Stop"));
            
            // fill MENUITEMINFO structure
            MENUITEMINFO mi1,mi2 = { 0};
            mi1.cbSize=sizeof(MENUITEMINFO );
            mi1.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
            mi1.wID = ID_Z;
            mi1.hSubMenu=hSubMenu;
            mi1.dwTypeData=_T("Play");
            // insert menu item with submenu to hPopupMenu
            InsertMenuItem ( hPopupMenu, 0, false, &mi );
            

            // Add "exit" - notice that the second parameter is '1' - this item will be second in the list
            InsertMenu(hPopupMenu, 1, MF_BYPOSITION | MF_STRING, 1245, _T("Exit"));

            mi2.cbSize=sizeof(MENUITEMINFO );
            mi2.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
            mi2.wID = ID_P;
            mi2.hSubMenu=hSubMenu;
            mi2.dwTypeData=_T("Game");
            // insert menu item with submenu to hPopupMenu
            InsertMenuItem ( hPopupMenu, 2, false, &mi2 ); // Set position to '2'


            SetForegroundWindow(hwndDlg);
            TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, 0, 0, 0, hwndDlg, NULL);




Here's another way to create the menu you need without using MENUITEM struct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  HMENU hPopupMenu = CreatePopupMenu();
            HMENU hSubMenuGame=CreatePopupMenu();  // Create submenu for Game
            HMENU hSubMenuPlay=CreatePopupMenu();  // submenu for 'play'

            // Add items to submenus
            InsertMenu(hSubMenuPlay, 0, MF_BYPOSITION | MF_STRING,ID_IDX, _T("Start"));
            InsertMenu(hSubMenuPlay, 0, MF_BYPOSITION | MF_STRING, ID_IDY, _T("Stop"));
            InsertMenu(hSubMenuGame, 0, MF_BYPOSITION | MF_STRING,ID_GAME_START, _T("Start"));
            InsertMenu(hSubMenuGame, 0, MF_BYPOSITION | MF_STRING, ID_GAME_STOP, _T("Stop"));

            //Append submenu 'play' to popup menu
            AppendMenu(hPopupMenu,MF_POPUP | MF_STRING,(UINT)hSubMenuGame,_T("Game"));
            //Append menu item 'exit'
            AppendMenu(hPopupMenu,  MF_BYPOSITION | MF_STRING, 1245, _T("Exit"));
            // Append submenu 'play'
            AppendMenu(hPopupMenu,MF_POPUP | MF_STRING,(UINT)hSubMenuGame,_T("Play"));


            SetForegroundWindow(hwndDlg);
            TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, 0, 0, 0, hwndDlg, NULL);

This method is simpler but I'm used to the first one.
As you're always passing index 0 to InsertMenu when using MF_BYPOSITION, the submenus will be ordered Stop and then Start. So either swap the order you insert the items (at the front), or step the index.

(I prefer the latter, parrticularly when building more complicated menu structures, as that's the way my brain works: I like to append to my menus.)

And don't forget to pass a sensible position to TrackPopupMenu (usually the one passed as the lParam of the WM_CONTEXTMENU message.)

Andy
Last edited on
Topic archived. No new replies allowed.