2010-07-28 1 views
2

У меня есть CMFCRibbonUndoButton на ленте приложения MFC. У меня есть обработчик, когда его ID щелкнул (ON_COMMAND(ID_EDIT_UNDO, ...)). Однако, когда кнопка также находится в панели быстрого доступа (QAT), есть, по-видимому, два CMFCRubbonUndoButtons, каждый из которых сохраняет свое собственное состояние. В обработчике команд я не знаю, как сказать, на что был сделан щелчок, и если вы вызываете GetActionNumber() на неправильном, вы получаете неправильное количество отмененных действий.MFC Ribbon - получить базовый элемент, нажав команду

Есть ли способ в моем ON_COMMAND обработчике, чтобы получить CMFCRibbonBaseElement*, который уволил событие?

Редактировать: ответ важен для меня, вопрос немного неясен, но я кладу щедрость вверх!

Edit: вот как он добавляется к ИАК:

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

Не могли бы вы привести пример того, как вы добавляете кнопку «Отменить» в QAT? Я не работал с MFC через некоторое время, но, похоже, очень странно, что он не будет поддерживать согласованное состояние между кнопками. –

+0

Добавлен код, который я использую, кнопки добавляются в QAT по ID. Он основан на образце кода. – AshleysBrain

+0

Вы хотите, чтобы обе кнопки отмены отображали тот же список элементов отмены?В моем тестовом приложении я могу вызвать AddUndoAction, чтобы добавлять элементы к кнопке отмены на ленте, но эти элементы не отображаются в кнопке отмены на панели быстрого доступа. Я просмотрел исходный код MFC, и кажется, что решение вашей проблемы не будет простым. – ChrisN

ответ

1

Есть ли способ в моем ON_COMMAND обработчика, чтобы получить CMFCRibbonBaseElement*, что уволил событие?

Не напрямую, нет. Сообщение WM_COMMAND отправляется с CMFCRibbonBaseElement::NotifyCommand, и это сообщение не содержит указатель в его параметрах.

Для того, чтобы узнать, какая кнопка Undo была нажата из обработчика 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. 
    } 
} 

Это немного рубить, конечно, но это было почти единственным способом я мог найти, чтобы решить эту проблему.

Во всяком случае, я надеюсь, что это помогает,

Крис

+0

Спасибо, но когда MFC клонирует кнопку отмены, она создает обычный CMFCRibbonUndoButton - не производный класс, поэтому он никогда не обновляет 's_pLastActivated' из кнопки QAT! – AshleysBrain

+0

Интересно, этот код хорошо работает в моем тестовом приложении, и когда MFC клонирует кнопку, он создает объект «CMyMFCRibbonUndoButton». MFC называет 'GetRuntimeClass() -> CreateObject()' на кнопке, поэтому он должен создать объект нужного класса. – ChrisN

+0

А - Я, должно быть, что-то пропустил - попробую еще раз. – AshleysBrain

0

Посмотрите на MSOffice2007Demo в Visual C++ 2008 Feature Pack examples

Они используют другую технику, где они ловушка зарегистрированное сообщение (AFX_WM_ON_BEFORE_SHOW_RIBBON_ITEM_MENU) в этом обработчике они восстанавливают список отмены динамически (аналогично обработке старого SDK WM_INITMENUPOPUP).

CMFCRibbonUndoButton, который вызвал сообщение, передается в LPARAM сообщения.

Используя этот метод, вы сохраните свой список отмены независимо от элементов управления лентой и используйте элемент управления в качестве представления в своем списке.

Смежные вопросы