how subclassing menus?

how can i subclassing the menus?
i have 1 code code for build the menus:
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
#define ID_NEW_RECORD_ITEM        1001
#define ID_SAVE_RECORD_ITEM        1002
#define ID_QUIT_ITEM            1003
#define ID_SHOW_ALL_ITEM        1004
#define ID_SELECT_REPORT_ITEM    1005


void CreateAMenu(HWND hWnd)
{
    HMENU hMenu = CreateMenu();
    HMENU hSubMenu = CreatePopupMenu();

    AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&File");
    AppendMenu(hSubMenu, MF_STRING, ID_NEW_RECORD_ITEM, "&New Record");
    AppendMenu(hSubMenu, MF_STRING, ID_SAVE_RECORD_ITEM, "&Save Record");
    AppendMenu(hSubMenu, MF_STRING, ID_QUIT_ITEM, "&Quit");


    hSubMenu = CreatePopupMenu();
    AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, "&Reports");
    AppendMenu(hSubMenu, MF_STRING, ID_SHOW_ALL_ITEM, "Show &All Data");
    AppendMenu(hSubMenu, MF_STRING, ID_SELECT_REPORT_ITEM, "S&eelect report");


    SetMenu(hWnd, hMenu);
}

the menus are showed and i read some of AppendMenu: http://msdn.microsoft.com/en-us/library/windows/desktop/ms647616(v=vs.85).aspx
but i don't see 1 way for subclass the menus :(
can anyone advice me?
i'm creating the class:

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
class Menu
{
private:
    static int intID;
    int ID=0;
    HMENU hMenu=NULL;
    public:
    Menu(string caption="&Menu",HMENU subtmenu=NULL, HWND MainHWND=WindowMain)
    {
        intID=intID+1;
        ID=intID;
        caption=(string)caption + " " + to_string(ID);

        if(GetMenu(MainHWND)==NULL) //problem here :(
            hMenu = CreateMenu();
        HMENU hSubMenu = CreatePopupMenu();
        if (subtmenu==NULL)

            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, caption.c_str());
        else
            AppendMenu(hSubMenu, MF_STRING, ID, caption.c_str());
        SetMenu(MainHWND, hMenu);
    }
    operator int()
    {
        return ID;
    }

    operator HMENU()
    {
        return hMenu;
    }
    void Destroy()
    {
        DestroyMenu(hMenu);
    }
};
int Menu::intID=0;

i'm testing if the menu was created or not. but i'm not getting the correct results :(
can anyone tell me what i'm doing wrong?
now was fixed:
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
Menu(string caption="&Menu",HMENU subtmenu=NULL, HWND MainHWND=WindowMain)
    {
        intID=intID+1;
        ID=intID;
        caption=(string)caption + " " + to_string(ID);

        if(GetMenu(MainHWND)==NULL)
            hMenu = CreateMenu();
        else
            hMenu =GetMenu(MainHWND);

        HMENU hSubMenu = CreatePopupMenu();

        if (subtmenu==NULL)
        {
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, caption.c_str());
            MenuHandle=hMenu;
        }
        else//problem
        {
            AppendMenu(subtmenu, MF_STRING, ID, caption.c_str());
            MenuHandle=subtmenu;
        }

        SetMenu(MainHWND, hMenu);
    }

or i'm doing wrong with HMENU or something :(
the menu is created but now in right place :(
heres the entire class:
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
40
41
42
43
44
45
46
47
48
49
class Menu
{
private:
    static int intID;
    int ID=0;
    HMENU MenuHandle=NULL;
    HMENU hMenu=NULL;
    public:
    Menu(string caption="&Menu",HMENU subtmenu=NULL, HWND MainHWND=WindowMain) //the subtmenu is where to put the sub menu item
    {
        intID=intID+1;
        ID=intID;
        caption=(string)caption + " " + to_string(ID);

        if(GetMenu(MainHWND)==NULL)
            hMenu = CreateMenu();
        else
            hMenu =GetMenu(MainHWND);

        HMENU hSubMenu = CreatePopupMenu();

        if (subtmenu==NULL)
        {
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, caption.c_str());
            MenuHandle=hMenu;
        }
        else
        {
            AppendMenu(subtmenu, MF_STRING, ID, caption.c_str());
            MenuHandle=subtmenu;
        }

        SetMenu(MainHWND, hMenu);
    }
    operator int()
    {
        return ID;
    }

    operator HMENU()
    {
        return MenuHandle;
    }
    void Destroy()
    {
        DestroyMenu(MenuHandle);
    }
};
int Menu::intID=0;

what i'm doing wrong?
finally i fix that too:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
class Menu
{
private:
    static int intID;
    int ID=0;
    HMENU MenuHandle=NULL;
    HMENU hMenu=NULL;
    string strCaption="";
    public:
    Menu(string caption="&Menu",HMENU subtmenu=NULL, HWND MainHWND=WindowMain)
    {
        intID=intID+1;
        ID=intID;
        if(caption!="-")
            caption=(string)caption + " " + to_string(ID);
        strCaption=caption;
        if(GetMenu(MainHWND)==NULL)
            hMenu = CreateMenu();
        else
            hMenu =GetMenu(MainHWND);

        HMENU hSubMenu = CreatePopupMenu();

        if (subtmenu==NULL)
        {
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, caption.c_str());
            MenuHandle=hSubMenu;//my error was here
            SetMenu(MainHWND, hMenu);
        }
        else
        {
            if(caption=="-")
                AppendMenu(subtmenu, MF_SEPARATOR, ID, caption.c_str());
            else
                AppendMenu(subtmenu, MF_STRING, ID, caption.c_str());
            MenuHandle=subtmenu;
            SetMenu(MainHWND, subtmenu);
        }
    }

    property<string> Caption{
    Get(string)
    {
        return strCaption;

    },
    Set(string text)
    {


    }};

    operator int()
    {
        return ID;
    }

    operator HMENU()
    {
        return MenuHandle;
    }
    void Destroy()
    {
        DestroyMenu(MenuHandle);
    }
};
int Menu::intID=0;

now i need change some options in items menus. but for that i need the menu positions :(
can i get the menu position or i must 'calculate' it, when i create it?
ok. i fix that and now i'm trying subclass the menu:
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class Menu
{
private:
    static int intID;
    int ID=0;
    bool primeiromenu=false;
    HMENU MenuHandle=NULL;
    HMENU hMenu=NULL;
    int menuposition=0;

    string strCaption="";

    static LRESULT CALLBACK MenuSubclassProc( HWND hwnd, UINT uMsg, WPARAM wParam,  LPARAM lParam)
    {
       Menu *wnd = 0;

        // retrieve associated Window instance
        wnd = reinterpret_cast<Menu *>(GetWindowLong(hwnd, GWL_USERDATA));
        if(uMsg==WM_MENUCOMMAND)
            wnd->MenuClick();

        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
    public:

    event(MenuClick) = []() {;};

    Menu(string caption="&Menu",HMENU subtmenu=NULL, HWND MainHWND=WindowMain)
    {
        intID=intID+1;
        ID=intID;
        if(caption!="-")
            caption=(string)caption + " " + to_string(ID);
        strCaption=caption;
        if(GetMenu(MainHWND)==NULL)
            hMenu = CreateMenu();
        else
            hMenu =GetMenu(MainHWND);
        if (subtmenu==NULL)
        {
            HMENU hSubMenu=CreatePopupMenu() ;
            AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, caption.c_str());
            MenuHandle=hSubMenu;//my error was here
            SetMenu(MainHWND, hMenu);
            menuposition=GetMenuItemCount(hMenu)-1;
            primeiromenu=true;
        }
        else
        {
            if(caption=="-")
                AppendMenu(subtmenu, MF_SEPARATOR, ID, caption.c_str());
            else
                AppendMenu(subtmenu, MF_STRING, ID, caption.c_str());
            MenuHandle=subtmenu;
            menuposition=GetMenuItemCount(subtmenu)-1;
            SetMenu(MainHWND, hMenu);
        }

            MENUINFO  mi;
            mi.cbSize=sizeof(MENUINFO );
            if(primeiromenu==true)
                SetMenuInfo(GetMenu(WindowMain),&mi);
            else
                GetMenuInfo(MenuHandle,&mi);
            mi.fMask=MIM_STYLE;
            mi.dwStyle =MNS_NOTIFYBYPOS;
            if(primeiromenu==true)
                SetMenuInfo(GetMenu(WindowMain),&mi);
            else
                SetMenuInfo(MenuHandle,&mi);

        SetWindowLong(MainHWND,GWL_WNDPROC,(LONG)MenuSubclassProc);
        SetWindowLong(MainHWND,GWL_USERDATA,(LONG)this);
        
    }

    void Show(HWND mainshowed)
    {
        LPPOINT x;
        GetCursorPos(x);
        SetForegroundWindow(mainshowed);
        TrackPopupMenu(MenuHandle,NULL,x->x,x->y,0,mainshowed,NULL);
        PostMessage(mainshowed, WM_NULL, 0, 0);
    }

    int getmenuposition()
    {
        return menuposition;
    }

    property<string> Caption
    {
        Get(string)
        {
            return strCaption;

        },
        Set(string text)
        {
            MENUITEMINFO mi;
            mi.cbSize=sizeof(MENUITEMINFO);
            if(primeiromenu==true)
                GetMenuItemInfo(GetMenu(WindowMain),menuposition,true,&mi);
            else
                GetMenuItemInfo(MenuHandle,menuposition,true,&mi);
            mi.fMask=MIIM_STRING;
            mi.dwTypeData =(LPTSTR)text.c_str();
            if(primeiromenu==true)
                SetMenuItemInfo(GetMenu(WindowMain),menuposition,true,&mi);
            else
                SetMenuItemInfo(MenuHandle,menuposition,true,&mi);

        }
    };

    operator int()
    {
        return ID;
    }

    operator HMENU()
    {
        return MenuHandle;
    }
    void Destroy()
    {
        DestroyMenu(MenuHandle);
    }
};
int Menu::intID=0;

i see some problems :(
the MenuClick lambda is called, but the form loses the window procedure :(
1
2
SetWindowLong(MainHWND,GWL_WNDPROC,(LONG)MenuSubclassProc);
        SetWindowLong(MainHWND,GWL_USERDATA,(LONG)this);

MainHWND is the form/winow handle. so how can i fix the problem?
Last edited on
Topic archived. No new replies allowed.