編輯框(CEdit)預設右鍵選單由系統內建處理,不發送 WM_INITMENUPOPUP,導致無法透過 MFC 命令更新機制(ON_UPDATE_COMMAND_UI)動態啟用/停用項目。本文提供 CEditMenuHandler 類別,封裝子類化、選單建立、命令路由與更新邏輯,僅需三步驟即可為編輯框加入自訂右鍵選單項目(如檔案類型切換)。
WM_INITMENUPOPUP,模擬 CFrameWnd 的命令更新流程,讓任意視窗支援 ON_UPDATE_COMMAND_UI。CPopupMenuInitHandler,內建剪下/複製/貼上/刪除/全選等標準編輯命令處理,自動依選取狀態與剪貼簿內容啟用/停用項目。class CMyEdit : public CEdit {
CEditMenuHandler m_editMenuHandler;
virtual void PreSubclassWindow();
};
PreSubclassWindow,非對話框可在 OnCreate):
void CMyEdit::PreSubclassWindow() {
m_editMenuHandler.Install(this, IDR_EDITMENU); // IDR_EDITMENU 為自訂選單資源 ID
}
// 訊息映射
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);
}
標準編輯命令(ID_EDIT_CUT 等)由處理器內部透過 WM_CUT/WM_COPY 等訊息轉發給編輯框。自訂項目(如「TXT 格式」、「BMP 格式」)直接在 CMyEdit 加入對應 ON_COMMAND 處理:
ON_COMMAND(ID_FILETYPE_TXT, OnFiletypeTXT)
void CMyEdit::OnFiletypeTXT() {
SetWindowText(_T("txt")); SetSel(0, -1);
}
更新邏輯同樣在 OnUpdateEditCommand 中由處理器代理,自訂項目可自行加入 ON_UPDATE_COMMAND_UI 處理。
CEditMenuHandler::OnUpdateEditCommand 內部對 ID_EDIT_PASTE 呼叫 ::IsClipboardFormatAvailable(CF_TEXT) 判斷是否啟用。WM_CUT/WM_COPY/WM_PASTE/WM_CLEAR 等訊息,CEdit 內建處理。TRUE 表示已處理,FALSE 讓後續處理器繼續。範例程式展示編輯框右鍵選單含標準編輯項目與三種檔案類型切換項目,完整演示從安裝到自訂擴充的完整流程。原始碼附帶 CPopupMenuInitHandler、CSubclassWnd 實作,可直接移植專案。