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

VC++ 編輯框右鍵選單自訂:CEitMenuHandler 類封裝實戰

     編輯:VC 教學

痛點

MFC 編輯框 (`CEdit`) 右鍵預設選單不發送 `WM_INITMENUPOPUP`,導致無法用標準 `ON_UPDATE_COMMAND_UI` 機制啟用/禁用項目,也難以插入自訂功能 (如「插入日期」、「轉大寫」)。

解決方案:CEitMenuHandler

封裝 `CPopupMenuInitHandler` (攔截 `WM_INITMENUPOPUP` 並驅動 MFC 選單更新) + `CSubclassWnd` (子類化任意 `CWnd`),提供即插即用的編輯框選單擴充。

三步整合

1. 宣告與安裝


class CMyEdit : public CEdit {
    CEditMenuHandler m_handler;
    virtual void PreSubclassWindow();
    afx_msg void OnUpdateEditCmd(CCmdUI* pCmdUI);
    afx_msg void OnEditCmd(UINT nID);
    DECLARE_MESSAGE_MAP()
};

void CMyEdit::PreSubclassWindow() {
    CEdit::PreSubclassWindow();
    m_handler.Install(this, IDR_MY_EDIT_MENU); // 資源編輯器建立選單 IDR_MY_EDIT_MENU
}

2. 訊息映射


BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
    ON_UPDATE_COMMAND_UI_RANGE(ID_EDIT_FIRST, ID_EDIT_LAST, OnUpdateEditCmd)
    ON_COMMAND_RANGE(ID_EDIT_FIRST, ID_EDIT_LAST, OnEditCmd)
    // 自訂項目
    ON_COMMAND(ID_FMT_UPPER, OnFmtUpper)
    ON_UPDATE_COMMAND_UI(ID_FMT_UPPER, OnUpdateFmtUpper)
END_MESSAGE_MAP()

3. 轉發給 Handler


void CMyEdit::OnUpdateEditCmd(CCmdUI* pCmdUI) {
    m_handler.OnUpdateEditCommand(pCmdUI);
}
void CMyEdit::OnEditCmd(UINT nID) {
    if (!m_handler.OnEditCommand(nID)) {
        // Handler 未處理 (如自訂項目) → 交給預設或自行處理
    }
}

Handler 內建功能

  • 標準編輯命令:剪下/複製/貼上/刪除/全選/撤銷,自動依選取範圍與剪貼簿內容啟用/禁用。
  • 右鍵彈出時自動定位選單座標。
  • 若命令未處理返回 `FALSE`,由衍生類繼續處理。

自訂項目範例:插入當前日期


void CMyEdit::OnFmtUpper() {
    CString sel; GetSelText(sel); sel.MakeUpper(); ReplaceSel(sel);
}
void CMyEdit::OnUpdateFmtUpper(CCmdUI* pCmdUI) {
    CString sel; GetSelText(sel); pCmdUI->Enable(!sel.IsEmpty());
}

原理速覽

  1. `CSubclassWnd` 子類化編輯框,攔截 `WM_CONTEXTMENU`。
  2. `CPopupMenuInitHandler` 在彈出選單前發送 `WM_INITMENUPOPUP` 給自身,觸發 MFC `ON_UPDATE_COMMAND_UI` 流程。
  3. `CEditMenuHandler` 繼承上述兩者,預設處理標準編輯命令 (發送 `WM_CUT/COPY/PASTE` 等)。

原始碼獲取

完整類別碼較長,建議參考原文附件或 CodeGuru 同類文章《Adding Custom Items to the Edit Control Context Menu》。

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