Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MFC功能区-从命令获取单击的基本元素_C++_Mfc_Ribbon_Mfc Feature Pack - Fatal编程技术网

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

C++ MFC功能区-从命令获取单击的基本元素,c++,mfc,ribbon,mfc-feature-pack,C++,Mfc,Ribbon,Mfc Feature Pack,我在MFC应用程序的功能区上有一个CMFCRibbonEndo按钮。我有一个处理程序,用于在其ID被单击时(在\u命令上(ID\u EDIT\u UNDO,…))。但是,当按钮也位于快速访问工具栏(QAT)中时,显然有两个CMFCRubbonUndoButton按钮,每个按钮都保持自己的状态。在命令处理程序中,我不知道如何判断单击了哪个,如果对错误的操作调用GetActionNumber(),则返回的撤消操作数是错误的 在我的ON_命令处理程序中是否有方法获取触发事件的CMFCRibbonBas

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

在我的
ON_命令
处理程序中是否有方法获取触发事件的
CMFCRibbonBaseElement*

编辑:答案对我来说很重要,这个问题有点晦涩难懂,但我正在悬赏

编辑:以下是如何将其添加到QAT:

CList<UINT, UINT> lstQATCmds;
lstQATCmds.AddTail(ID_EDIT_UNDO);
m_RibbonBar.SetQuickAccessCommands(lstQATCmds);
CList-lstQATCmds;
lstQATCmds.AddTail(ID\u EDIT\u UNDO);
m_RibbonBar.SetQuickAccessCommands(lstQATCmds);
在我的
ON_命令
处理程序中是否有方法获取触发事件的
CMFCRibbonBaseElement*

不是直接发送,否。
WM_命令
消息是从
CMFCRibbonBaseElement::NotifyCommand
发送的,该消息的参数中不包含指针

为了能够从\u命令上的
处理程序中判断单击了哪个撤消按钮,我编写了这个类,它继承了
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.
    }
}
这当然有点像黑客,但这是我能找到的解决问题的唯一方法

不管怎样,我希望这有帮助


Chris

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

引发消息的CMFCribbonEndo按钮在消息的LPRAM中传递


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

能否举例说明如何将撤消按钮添加到QAT中?我已经有一段时间没有使用MFC了,但看起来很奇怪,它无法保持按钮之间的状态一致。添加了我使用的代码,按钮按ID添加到QAT。它基于示例代码。是否希望两个撤消按钮都显示相同的撤消项列表?在我的测试应用程序中,我可以调用AddUndoAction向功能区中的“撤消”按钮添加项目,但这些项目不会显示在快速访问工具栏的“撤消”按钮中。我浏览了MFC源代码,似乎您的问题的解决方案并不简单。chris-这正是我得到的,QAT按钮仍然是空的-但您可以使用
CRibbonBar::GetElementsByID()
并传递
ID\u EDIT\u UNDO
-返回两个控件,这允许您将相同的操作列表添加到这两个操作中。这让我得出结论,MFC在某个地方克隆了它-但是你如何判断在处理程序中单击了哪个?另一个提示:CRibbonBar有一个
m_Pressed
成员,当左键单击主按钮时,该成员可以正确识别按钮,但它不适用于下拉菜单或通过键盘快捷键触发。谢谢,但是当MFC在幕后克隆undo按钮时,它会创建一个普通的CMFCRibbonUndoButton,而不是派生类,因此它永远不会从QAT按钮更新
s\u
!有趣的是,这段代码在我的测试应用程序中运行良好,当MFC克隆按钮时,它会创建一个
cmymfcribbonEndobutton
对象。MFC调用按钮上的
GetRuntimeClass()->CreateObject()
,因此它应该创建正确类的对象。啊-我一定错过了什么-我会再试一次。