0

How can I set a CMenu item prompt at runtime? I know that it can be done in resource editor in VS, but I don't have such resource and create menu and it's items dynamically.

brightside90
  • 243
  • 3
  • 13
  • See `CMenu::CreateMenu` in the MSDN documentation: https://msdn.microsoft.com/en-us/library/d0s49351.aspx#cmenu__createmenu – Richard Critten Mar 22 '17 at 12:28
  • So, are you trying to create a popup menu on some control / dialog? There is no context to your question. We don't even know what type of MFC project it is. – Andrew Truckle Mar 22 '17 at 19:00
  • @RichardCritten so, and what should I see here? Simple function that creates menu and doesn't have any params... – brightside90 Mar 23 '17 at 07:29
  • @AndrewTruckle I am trying to create menu for dialog toolbar button – brightside90 Mar 23 '17 at 07:31
  • @brightside90 Dialog applications don't by default support doing what you want. You have to add more messages to deal with it. – Andrew Truckle Mar 23 '17 at 07:53
  • @AndrewTruckle what messages do you mean? – brightside90 Mar 23 '17 at 08:24
  • @brightside90 I will be able to reply later this afternoon when I can check my old project. But have you considered doing a single document interface instead which supports this natively ? – Andrew Truckle Mar 23 '17 at 08:30
  • @AndrewTruckle no I can't use SDI, because it's my work project. You know, I have already solve this problem, but in very hard way. When I've asked this question I was wondered - why I can create CMenu from existing resource with items prompt in it, and why I can't do it from scratch. CMenu class looks very poor. Or I'm just do something wrong :) – brightside90 Mar 23 '17 at 08:47
  • 1
    Single and multiple document use the mainframe architecture. Dialog projects don't, so you have to add it. But to be fair your question is confusing and lacks explanation and details if you have already solved it then why ask the question? And you could have shown screen shots of what you are expecting and examples of code of what you did so far. Otherwise we could be simply talking about different things or offering what you already know. – Andrew Truckle Mar 23 '17 at 08:55

2 Answers2

1

If you are using MFC Feature Pack, you will need to override the OnMenuButtonToolHitTest of your MainFrame class:

BOOL CMainFrame::OnMenuButtonToolHitTest(CMFCToolBarButton* pButton, TOOLINFO* pTI)
{
    if(!pButton)
        return FALSE;
    if(!pTI)
        return FALSE;

    if (pButton->m_nID == UINT(-1)) //not a menu-item, but an opener menu for a sub-menu
        return FALSE;

    // Stolen from CMFCToolBar::OnToolHitTest on file afxtoolbar.cpp

    // It is not needed to do the GetMessageString part, because it already done
    // on function CMFCPopupMenuBar::OnToolHitTest of afxpopupmenubar.cpp file, which
    // supplies the two parts to the Tooltip Manager

    CString strTipText;
    TCHAR szFullText[256];

    AfxLoadString(pButton->m_nID, szFullText);
    AfxExtractSubString(strTipText, szFullText, 1, '\n');

    pTI->lpszText = _tcsdup(strTipText);

    return TRUE;
}

You will have to define in your resource file strings with the EXACT same ID as your menus; and their format is Prompt text\nPrompt title. I am not sure but I think the only new line you can have is the one that separates title from text.

You may also want to do things beyond simply displaying prompts when hovering menus using the mouse. You can do it by overriding OnMenuSelect of your MainFrame class:

void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
    if (nItemID == ID_MENU_I_WANT_TO_PROCESS)
    {
        DoThings(); 
    }

    __super::OnMenuSelect(nItemID, nFlags, hSysMenu);
}

I recommend you to make an override to GetMessageString function on your MainFrame class and put a breakpoint there for you see how the flow goes.

sergiol
  • 4,122
  • 4
  • 47
  • 81
0

You can use ModifyMenu (https://msdn.microsoft.com/fr-fr/library/4tbfebs6.aspx). The call can be something like:

 pParentMenu->ModifyMenu(ID_MY_ITEM, MF_STRING, ID_MY_ITEM, "My new text");

pParentMenu is a CMenu object pointing to the parent menu. ID_MY_ITEM is the sub-menu id. It is also possible to select the menu to change using its index.

Ionel POP
  • 743
  • 7
  • 12
  • @lonelPOP using this way we can change item text, not it's prompt, that should be displayed in dialog status line, for example – brightside90 Mar 23 '17 at 07:33
  • 1
    Dialog applications don't by default support doing what you want. You have to add more messages to deal with it. – Andrew Truckle Mar 23 '17 at 07:48