Альтернатива CMFCCaptionMenuButton? - PullRequest
0 голосов
/ 04 марта 2011

Мне нужно создать кнопку панели заголовков для CDockablePane, которая будет вызывать меню с различными параметрами. Я попытался использовать CMFCCaptionMenuButton, и кнопка и меню отображаются, но методы отображения сообщений для идентификаторов меню не запускаются. В документации MFC говорится, что CMFCCaptionMenuButton предназначено для внутренней инфраструктуры, а не для вашего кода.

Итак, при условии, что это моя проблема, я должен использовать CMFCCaptionBarButton, а затем создать отдельное всплывающее меню? Кто-нибудь делал подобное меню в MFC на панели заголовков?

Вот некоторые уменьшенные фрагменты кода на случай, если я просто совершил глупую ошибку при подключении событий:

BEGIN_MESSAGE_MAP(CDockPane, CDockablePane)
    ON_COMMAND(ID_MORPH_BROWSER, OnMorphBrowser)
END_MESSAGE_MAP()

void CDockPane::OnPressButtons(UINT nHit)
{
    // only for custom button handling don't call base
    // close, maximize, and pin will be handled by default

    switch (nHit)
    {
        case ID_MORPHTEST:
        {
            CMorphMenuButton* pButton = dynamic_cast<CMorphMenuButton*>(m_arrButtons.GetAt(m_morphIndex));
            pButton->ShowMenu(this);
            break;
        }
    }
}

void CDockPane::SetCaptionButtons()
{
    CDockablePane::SetCaptionButtons(); // for close, pin etc

    m_morphIndex = m_arrButtons.Add(new CMorphMenuButton(ID_MORPHTEST));
}

void CDockPane::OnMorphBrowser()
{
    // do stuff on menu item click
}

Редактировать: удален предыдущий код, который больше не используется

1 Ответ

1 голос
/ 21 марта 2011

Теперь, когда звуки чириканья сверчков на заднем плане уменьшились, я думаю, я опубликую обходной путь, который у меня сейчас есть:

Вместо того, чтобы наследовать и расширять CMFCCaptionMenuButton Я строю свой класс, расширяя CMFCCaptionButton.Затем я создаю меню и предоставляю метод ShowMenu, который будет вызываться явным образом при обработке событий пользовательских кнопок, а также переопределять GetIconID, чтобы возвращать конкретный системный значок для кнопки для каждого меню, добавляемого на панель заголовков, заканчивая чем-то вроде этого дляпример, приведенный в вопросе:

#pragma once

// CMorphMenuButton command target

class CMorphMenuButton : public CMFCCaptionButton
{
public:
    CMorphMenuButton(UINT nHit);
    virtual ~CMorphMenuButton();

    virtual CMenuImages::IMAGES_IDS GetIconID (BOOL bHorz, BOOL bMaximized) const;
    void ShowMenu(CWnd* pWnd);

private:
    CMenu m_dockMenu;
    CMenu* m_subMenu;
};

// MorphMenuButton.cpp : implementation file
//

#include "stdafx.h"
#include "MorphMenuButton.h"


// CMorphMenuButton
CMorphMenuButton::CMorphMenuButton(UINT nHit)
    : CMFCCaptionButton(nHit)
{
    SetMiniFrameButton(); // already defaulted?

    m_dockMenu.LoadMenu(IDR_DOCKPANE); // resource ID for dock pane menus
}

CMorphMenuButton::~CMorphMenuButton()
{
    m_dockMenu.DestroyMenu();
}

CMenuImages::IMAGES_IDS CMorphMenuButton::GetIconID(BOOL bHorz, BOOL bMaximized) const
{
    return CMenuImages::IdArrowForward;
}

void CMorphMenuButton::ShowMenu(CWnd* pWnd)
{
    CRect windowRect, buttonRect;
    pWnd->GetWindowRect(&windowRect);
    buttonRect = GetRect();
    CPoint menuPos(windowRect.left + buttonRect.right, windowRect.top + buttonRect.bottom);

    m_subMenu = m_dockMenu.GetSubMenu(0);
    if (!m_subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, menuPos.x, menuPos.y, pWnd))
    {
        DWORD id = GetLastError();
        wchar_t errMsg[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, id, 0, errMsg, sizeof(errMsg), 0);
        MessageBox(0, errMsg, L"Error", MB_OK);
    }
}

Настройка кнопок панели заголовка и обработка событий нажатия для кнопок и меню такие же, как определено в вопросе, и это работает.

...