MFC功能区 - 从命令单击获取基本元素

时间:2010-07-28 14:17:59

标签: c++ mfc ribbon mfc-feature-pack

我在MFC应用程序的功能区上有一个CMFCRibbonUndoButton。我有一个处理器,用于何时单击其ID(ON_COMMAND(ID_EDIT_UNDO, ...))。但是,当按钮也在快速访问工具栏(QAT)中时,显然有两个CMFCRubbonUndoButtons,每个都保持自己的状态。在命令处理程序中,我不知道如何判断哪个被单击,如果您在错误的单词上调用GetActionNumber(),则会返回错误的撤消操作数。

我的ON_COMMAND处理程序中是否有办法让CMFCRibbonBaseElement*解雇该事件?

编辑:答案对我来说很重要,这个问题有点模糊,但我正在给予赏金!

编辑:这是它如何添加到QAT:

CList<UINT, UINT> lstQATCmds;
lstQATCmds.AddTail(ID_EDIT_UNDO);
m_RibbonBar.SetQuickAccessCommands(lstQATCmds);

2 个答案:

答案 0 :(得分:1)

  

我的ON_COMMAND处理程序中是否有办法让CMFCRibbonBaseElement*解雇该事件?

不直接,不。 WM_COMMAND消息是从CMFCRibbonBaseElement::NotifyCommand发送的,此消息的参数中不包含指针。

为了能够告诉ON_COMMAND处理程序中单击了哪个撤消按钮,我编写了这个继承CMFCRibbonUndoButton的类。这个代码的作用是在每次单击其中一个按钮或激活弹出菜单时存储指向上次激活的撤消按钮的指针。

// CMyMFCRibbonUndoButton.h

class CMyMFCRibbonUndoButton : public CMFCRibbonUndoButton
{
    DECLARE_DYNCREATE(CMyMFCRibbonUndoButton)

public:
    CMyMFCRibbonUndoButton();
    CMyMFCRibbonUndoButton(UINT nID, LPCTSTR lpszText,
        int nSmallImageIndex = -1, int nLargeImageIndex = -1);

    virtual void OnClick(CPoint point);
    virtual void OnShowPopupMenu();

    static CMyMFCRibbonUndoButton* GetLastActivated();

private:
    static CMyMFCRibbonUndoButton* s_pLastActivated;
};

// CMyMFCRibbonUndoButton.cpp

IMPLEMENT_DYNCREATE(CMyMFCRibbonUndoButton, CMFCRibbonUndoButton)

CMyMFCRibbonUndoButton* CMyMFCRibbonUndoButton::s_pLastActivated = NULL;

CMyMFCRibbonUndoButton::CMyMFCRibbonUndoButton()
{
}

CMyMFCRibbonUndoButton::CMyMFCRibbonUndoButton(UINT nID, LPCTSTR lpszText,
    int nSmallImageIndex, int nLargeImageIndex) :
    CMFCRibbonUndoButton(nID, lpszText, nSmallImageIndex, nLargeImageIndex)
{
}

void CMyMFCRibbonUndoButton::OnClick(CPoint point)
{
    s_pLastActivated = this;
    CMFCRibbonUndoButton::OnClick(point);
}

void CMyMFCRibbonUndoButton::OnShowPopupMenu()
{
    s_pLastActivated = this;
    CMFCRibbonUndoButton::OnShowPopupMenu();
}

CMyMFCRibbonUndoButton* CMyMFCRibbonUndoButton::GetLastActivated()
{
    return s_pLastActivated;
}

初始化功能区栏时,请使用此类代替CMFCRibbonUndoButton。在处理程序函数中,调用GetLastActivated()来检索此指针,例如:

void CMyTestDoc::OnEditUndo()
{
    CMyMFCRibbonUndoButton* pUndoButton =
        CMyMFCRibbonUndoButton::GetLastActivated();

    ASSERT_VALID(pUndoButton);

    if (pUndoButton != NULL)
    {
        int ActionNumber = pUndoButton->GetActionNumber();
        // etc.
    }
}

当然,这有点像黑客攻击,但这是我找到解决问题的唯一方法。

无论如何,我希望这有帮助,

克里斯

答案 1 :(得分:0)

查看Visual C++ 2008 Feature Pack examples

中的MSOffice2007Demo

他们使用不同的技术捕获已注册的消息(AFX_WM_ON_BEFORE_SHOW_RIBBON_ITEM_MENU),并在此处理程序中动态重建撤消列表(类似于旧的SDK WM_INITMENUPOPUP处理)。

激发消息的CMFCRibbonUndoButton在消息的LPARAM中传递。

使用此技术,您可以独立于功能区控件维护撤消列表,并将控件用作列表视图。