2

MFC アプリケーションのリボンに CMFCRibbonUndoButton があります。ID がクリックされたときのハンドラーがあります ( ON_COMMAND(ID_EDIT_UNDO, ...))。ただし、ボタンがクイック アクセス ツールバー (QAT) にもある場合、明らかに 2 つの 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ました。このコードが行うことは、ボタンの 1 つがクリックされるか、ポップアップ メニューがアクティブになるたびに、最後にアクティブ化された [元に戻す] ボタンへのポインターを格納することです。

// 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 に答える