locked
Tip for dynamic Popup Menus without UI handers RRS feed

  • General discussion

  • I spent over a day on this and it ended up being so simple.  The docs should make a better note of the TPM_NONOTIFY flag for TrackPopupMenu().  Even though the MSDN does say it will not call handlers,  it is necessary if you want the dynamically added menu items to be enabled (not grayed out).  There are many KLUDGES out there that don't use this flag and either use some resource, UI or use some trick with the IDLE message to emulate a CCmdUI behavior.  MSDN does begin with some discussing what is necessary, including trapping OnCmdMsg(), etc, but it never shows specifically what that is.  What it doesn't mention at all is the simple TPM_NONOTIFY flag which solves this issue.   I finally try it after a day of wasted time and VOILA, it worked. Maybe this tip will save other "Non-Smart" people some time. :)

    Example code:

    void CmyControl::DoPopupMenu()
    {
        CMenu menu;
        menu.CreatePopupMenu();
        int nBaseID  = 0x0E00;  // Your own base id
        menu.AppendMenu(uFlags, nBaseID+1, _T("Item #1"));
        menu.AppendMenu(uFlags, nBaseID+2, _T("Item #2"));
        menu.AppendMenu(uFlags, nBaseID+3, _T("Item #3"));
        ....
        menu.AppendMenu(uFlags, nBaseID+n, _T("Item #n"));
    
        POINT pt;
        GetCursorPos(&pt);
       // TMP_NONOTIFY required for no UI handlers and enabling the menu items
        UINT tpmFlags = TPM_LEFTALIGN|TPM_RETURNCMD|TPM_NONOTIFY;
        int nRes = menu.TrackPopupMenu(tpmFlags,pt.x,pt.y,AfxGetApp()->GetMainWnd());
        //
    // handle nRes
    // int nIndex = nRes-nBaseID; // 1 to N .... return; }

    Hector Santos, http://www.santronics.com
    Via Wildcat! Live Exchange NNTP Gateway http://opensite.winserver.com



    Tuesday, January 24, 2012 1:02 AM

All replies

  • TPM_NONOTIFY
    0x0080L

    The function does not send notification messages when the user clicks a menu item.

    So if you set this how about send messages when user click a menu item.


    NEU_ShieldEdge
    Wednesday, January 25, 2012 6:24 AM
  • TPM_NONOTIFY
    0x0080L

    The function does not send notification messages when the user clicks a menu item.

    So if you set this how about send messages when user click a menu item.


    If you have no ON_COMMAND() or ON_COMMAND_UI() for the Window, then the dispatching will never happening.  In this case, unless you use TPM_NONOTIFY, the menu items are disabled.    You can then use the result (nRes) to do you own call (i.e. switch statement) or issue a command to the specific window message handler.   

    Another way is to create your own menu resource and use something like:

     

       CMenu EditorMenu;
       if (EditorMenu.LoadMenu(IDR_MAINFRAME)) {<br/>       // Get the 2nd Pull down Menu
           CMenu *PopupMenu = EditorMenu.GetSubMenu(1);
           if (PopupMenu) {
               CMenu hdrMenu;
               hdrMenu.Attach(*PopupMenu);
               POINT pt;
               GetCursorPos(&pt);
               UINT tpmFlags = TPM_LEFTALIGN|TPM_LEFTBUTTON;
               int nRes = hdrMenu.TrackPopupMenu(tpmFlags,pt.x,pt.y,AfxGetApp()->GetMainWnd() );
               TRACE("TRACK RESULT: %d\n",nRes);
           }
       }
    
    


     

    ddd

     

     

     

     

     


    Hector Santos, http://www.santronics.com
    Via Wildcat! Live Exchange NNTP Gateway http://opensite.winserver.com
    Thursday, January 26, 2012 1:49 AM