Пример кода для CMFCMenuButton?

Извините за вопрос новичка, но может ли кто-нибудь указать мне на пример кода, который иллюстрирует использование CMFCMenuButton? Справка Microsoft ссылается на "Образцы новых элементов управления", но эти образцы, похоже, находятся в Visual Studio 2008 "Feature Pack", и это отказывается устанавливать на мою систему, так как я использую VS 2013 и не имею VS 2008. Я не смог найти примеры в качестве отдельного кода. Если быть точным, у меня есть диалоговое окно, в котором я хочу кнопку с надписью Сохранить с раскрывающимися опциями Сохранить все и Сохранить видимым (с Сохранить все по умолчанию). Но любой рабочий код, по крайней мере, поможет мне начать.

1 ответ

Решение

Объявите данные членов:

CMFCMenuButton m_button_menu;
CMenu m_menu;

Также добавьте идентификатор кнопки на карту сообщений и обмен данными:

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);
} 

Определение:

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

    return TRUE;  
}

куда IDR_MENU1 обычная строка меню, и мы получаем ее первое подменю. Например:

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

Если щелкнуть стрелку раскрывающегося меню кнопки, появится всплывающее меню, результат меню будет передан OnButtonMenu, Если нажата левая сторона кнопки, то OnButtonMenu вызывается напрямую, без отображения всплывающего меню.

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);
}

** При работе с элементами управления стыковкой, диалоговыми панелями и т. Д. MFC может запускать свой собственный подкласс, я не думаю, DoDataExchange вызывается. m_button_menu может быть недействительным. GetDlgItem может быть использован для поиска правильного указателя:

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

Везде, где мы используем GetButtonMenu() вместо m_button_menu, Например:

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)
    ...
}
Другие вопросы по тегам