C++ MFC功能区-从命令获取单击的基本元素
我在MFC应用程序的功能区上有一个CMFCRibbonEndo按钮。我有一个处理程序,用于在其ID被单击时(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
在\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()
,因此它应该创建正确类的对象。啊-我一定错过了什么-我会再试一次。