Example code for CMFCMenuButton?

橙三吉。 提交于 2019-12-10 19:57:54

问题


Sorry for the newbie question, but can anyone point me at sample code that illustrates the use of the CMFCMenuButton? The Microsoft help refers to "New Controls samples", but these samples seem to be in the Visual Studio 2008 "Feature Pack", and this refuses to install on my system since I'm running VS 2013 and don't have VS 2008. I haven't been able to find the samples as stand-alone code. To be specific, I have a dialog bar in which I want a button labelled Save with drop-down options of Save All and Save Visible (with Save All the default). But any working code would at least get me started.


回答1:


Declare data members:

CMFCMenuButton m_button_menu;
CMenu m_menu;

Also add the button's id to message map and data exchange:

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_BN_CLICKED(IDC_MFCMENUBUTTON1, OnButtonMenu)
    ...
END_MESSAGE_MAP

void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_MFCMENUBUTTON1, m_button_menu);
} 

Define:

BOOL CMyDialog::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    //...
    m_menu.LoadMenu(IDR_MENU1);
    m_button_menu.m_hMenu = m_menu.GetSubMenu(0)->GetSafeHmenu();

    return TRUE;  
}

Where IDR_MENU1 is a regular menu bar and we get its first submenu. For example:

IDR_MENU1 MENU
BEGIN
    POPUP "Dummy"
    BEGIN
        MENUITEM "&Item1", ID_FILE_ITEM1
        MENUITEM "&Item2", ID_FILE_ITEM2
    END
END

If button's drop-down arrow is clicked, a popup menu appears, menu result is passed to OnButtonMenu. If left side of button is clicked, then OnButtonMenu is called directly, without showing a popup menu.

void CMyDialog::OnButtonMenu()
{
    CString str;
    switch (m_button_menu.m_nMenuResult)
    {
    case ID_FILE_ITEM1:
        str = L"first menu item clicked";
        break;
    case ID_FILE_ITEM2:
        str = L"second menu item clicked";
        break;
    default:
        str = L"Button click (popup menu did not appear, or menu ID is not handled)";
        break;
    }
    MessageBox(str);
}

** When working with docking controls, dialog bars, etc. MFC may run its own subclass, I don't think DoDataExchange gets called. m_button_menu could be invalid. GetDlgItem can be used to find the correct pointer:

CMFCMenuButton* CMyDlgBar::GetButtonMenu()
{
    CMFCMenuButton* pButton = &m_button_menu;
    if (!IsWindow(pButton->m_hWnd))
        pButton = (CMFCMenuButton*)GetDlgItem(IDC_MFCMENUBUTTON1);
    return pButton;
}

Everywhere else we use GetButtonMenu() instead of m_button_menu. For example:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    //...
    m_dlgbar.Create(...);
    m_dlgbar.m_menu.LoadMenu(IDR_MENU1);
    m_dlgbar.GetButtonMenu()->m_hMenu = m_dlgbar.m_menu.GetSubMenu(0)->GetSafeHmenu();

    return 0;
}

void CMainFrame::OnButtonMenu()
{
    CString str;
    switch (GetButtonMenu()->m_nMenuResult)
    ...
}

What if the Drop-Down Arrow does not show?

Then read the answer here that explains the changes needed to your RC file.



来源:https://stackoverflow.com/questions/31997495/example-code-for-cmfcmenubutton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!