MFC 編輯框 (`CEdit`) 右鍵預設選單不發送 `WM_INITMENUPOPUP`,導致無法用標準 `ON_UPDATE_COMMAND_UI` 機制啟用/禁用項目,也難以插入自訂功能 (如「插入日期」、「轉大寫」)。
封裝 `CPopupMenuInitHandler` (攔截 `WM_INITMENUPOPUP` 並驅動 MFC 選單更新) + `CSubclassWnd` (子類化任意 `CWnd`),提供即插即用的編輯框選單擴充。
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
}
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()
void CMyEdit::OnUpdateEditCmd(CCmdUI* pCmdUI) {
m_handler.OnUpdateEditCommand(pCmdUI);
}
void CMyEdit::OnEditCmd(UINT nID) {
if (!m_handler.OnEditCommand(nID)) {
// Handler 未處理 (如自訂項目) → 交給預設或自行處理
}
}
void CMyEdit::OnFmtUpper() {
CString sel; GetSelText(sel); sel.MakeUpper(); ReplaceSel(sel);
}
void CMyEdit::OnUpdateFmtUpper(CCmdUI* pCmdUI) {
CString sel; GetSelText(sel); pCmdUI->Enable(!sel.IsEmpty());
}
完整類別碼較長,建議參考原文附件或 CodeGuru 同類文章《Adding Custom Items to the Edit Control Context Menu》。