2

我在 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);
4

2 回答 2

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.
    }
}

当然,这有点骇人听闻,但这是我能找到解决问题的唯一方法。

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

克里斯

于 2010-08-03T21:05:37.837 回答
0

查看Visual C++ 2008 Feature Pack 示例中的 MSOffice2007Demo

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

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

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

于 2010-12-13T02:47:59.033 回答