2010-07-28 47 views
2

我在MFC應用程序的功能區上有一個CMFCRibbonUndoButton。當我點擊它的ID時,我有一個處理程序(ON_COMMAND(ID_EDIT_UNDO, ...))。但是,當按鈕也位於快速訪問工具欄(QAT)中時,顯然有兩個CMFCRubbonUndoButton,它們各自保持自己的狀態。在命令處理程序中,我不知道如何分辨被點擊的內容,如果您撥錯了GetActionNumber(),則會返回錯誤的撤消操作數。MFC功能區 - 從命令中獲取基本元素

在我的ON_COMMAND處理程序中有沒有辦法讓CMFCRibbonBaseElement*發起事件?

編輯:答案對我很重要,這個問題有點模糊,但是我給了一個賞金!

編輯:這裏是它是如何加入到QAT:

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

您能舉一個例子說明如何將撤消按鈕添加到QAT?我有一段時間沒有用過MFC,但似乎很奇怪它不會保持按鈕之間的狀態一致。 – 2010-08-01 02:21:44

+0

添加了我使用的代碼,按鈕通過ID添加到QAT。它基於示例代碼。 – AshleysBrain 2010-08-01 14:44:23

+0

你是否希望兩個撤銷按鈕都顯示相同的撤消項目列表?在我的測試應用程序中,我可以調用AddUndoAction將項目添加到功能區中的撤消按鈕,但這些項目不會顯示在快速訪問工具欄的撤消按鈕中。我瀏覽了MFC源代碼,看來問題的解決方案並不簡單。 – ChrisN 2010-08-01 21:44:51

回答

1

有沒有在我的ON_COMMAND處理的方式來獲取觸發事件的CMFCRibbonBaseElement*

不直接,沒有。 WM_COMMAND消息從CMFCRibbonBaseElement::NotifyCommand發送,並且此消息不包含其參數中的指針。

爲了能夠確定從ON_COMMAND處理程序中點擊了哪個Undo按鈕,我編寫了這個類,它繼承了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 - 而不是派生類,所以它永遠不會從QAT按鈕更新's_pLastActivated'! – AshleysBrain 2010-08-03 23:11:53

+0

有趣的是,這段代碼在我的測試應用程序中很好地工作,當MFC克隆按鈕時,它會創建一個'CMyMFCRibbonUndoButton'對象。 MFC在按鈕上調用'GetRuntimeClass() - > CreateObject()',所以它應該創建一個正確類的對象。 – ChrisN 2010-08-04 08:26:07

+0

啊 - 我一定錯過了什麼 - 我會再試一次。 – AshleysBrain 2010-08-04 14:30:18

0

已經在Visual C++ 2008 Feature Pack examples

他們使用不同的技術來看看MSOffice2007Demo他們的陷阱在此處理程序的註冊信息(AFX_WM_ON_BEFORE_SHOW_RIBBON_ITEM_MENU)他們動態地重建撤消列表(類似於舊的SDK WM_INITMENUPOPUP處理)。

激發消息的CMFCRibbonUndoButton在消息的LPARAM中傳遞。

使用這種技術,您可以獨立於功能區控件維護您的撤消列表,並使用該控件作爲列表視圖。