首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

自訂編輯框右鍵選單:CEitMenuHandler 類別完整解決方案

     編輯:VC 教學

問題背景

編輯框控制項右鍵彈出的標準內容選單,若要加入自訂選單項,常面臨 WM_INITMENUPOPUP 訊息無法觸發的困擾。編輯控制項似乎以空 HWND 或 TPM_NONOTIFY 呼叫 TrackPopupMenu,導致選單不發送通知訊息,MFC 的 CCmdUI 更新機制因而失效。

解決方案:CEitMenuHandler 類別

本文提供 CEitMenuHandler 小類別完整解決此問題,三步驟即可整合:

1. 實例化處理器

class CMyEdit : public CEdit {
protected:
    CEditMenuHandler m_editMenuHandler;
    virtual void PreSubclassWindow();
};

2. 安裝處理器並指定選單資源 ID

void CMyEdit::PreSubclassWindow() {
    // IDR_EDITMENU 為自訂內容選單資源 ID
    m_editMenuHandler.Install(this, IDR_EDITMENU);
}

3. 轉發命令更新與執行訊息

// 訊息對應
ON_COMMAND_RANGE(ID_EDIT_FIRST, ID_EDIT_LAST, OnEditCommand)
ON_UPDATE_COMMAND_UI_RANGE(ID_EDIT_FIRST, ID_EDIT_LAST, OnUpdateEditCommand)

void CMyEdit::OnUpdateEditCommand(CCmdUI* pCmdUI) {
    m_editMenuHandler.OnUpdateEditCommand(pCmdUI);
}
void CMyEdit::OnEditCommand(UINT nID) {
    m_editMenuHandler.OnEditCommand(nID);
}

CEitMenuHandler 內建處理剪下、複製、貼上等標準編輯命令,依選取狀態與剪貼簿內容自動啟用/停用選單項。若命令已處理回傳 TRUE,否則 FALSE 讓衍生類別自行處理其他命令(如檔案類型選單)。

核心運作原理

CEitMenuHandler 巧妙重用 CPopupMenuInitHandler(詳見作者另一文章)與 CSubclassWnd 類別:

  • CPopupMenuInitHandler:代表視窗攔截 WM_INITMENUPOPUP,完成 MFC 選單更新機制,讓非框架視窗也能使用 ON_UPDATE_COMMAND_UI
  • CSubclassWnd:可子類化任意 CWnd 物件

選單項啟用邏輯範例

// 在 CEditMenuHandler::OnUpdateEditCommand 中
switch (nID) {
    case ID_EDIT_PASTE:
        pCmdUI->Enable(::IsClipboardFormatAvailable(CF_TEXT));
        break;
    // ... 其他標準編輯命令同理
}

期望標準 MFC 選單 ID(ID_EDIT_CUT、ID_EDIT_COPY 等)。命令執行時發送 WM_CUT、WM_COPY 等訊息至編輯控制項,或呼叫 CEdit::Cut、CEdit::Copy 等方法。

完整原始碼與範例請見文末下載。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved