動態修改選單文字易(CCmdUI::SetText),但同步更新狀態列提示與工具提示需特殊處理。本文分析 MFC 內部機制並提供解決方案。
動態選單易讓使用者困惑,建議優先考慮核取記號(SetCheck)或固定提示文字。若確有必要,再採用下列技術。
MFC 在 CFrameWnd::OnMenuSelect 中發送 WM_SETMESSAGESTRING 至自身,WPARAM 為命令 ID 或 0(配合 LPARAM 字串)。重寫 OnMenuSelect 即可注入動態提示:
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) {
if (nItemID 需動態提示) {
CString sPrompt = 產生提示字串();
SendMessage(WM_SETMESSAGESTRING, 0, (LPARAM)(LPCTSTR)sPrompt);
m_nIDTracking = nItemID;
} else {
CFrameWnd::OnMenuSelect(nItemID, nFlags, hSysMenu);
}
}
CFrameWnd::OnToolTipText 處理 TTN_NEEDTEXT 通知,標準實作從資源字串讀取 \n 後的文字。重寫此函數並填入 TOOLTIPTEXT 結構的 lpszText 即可實現動態工具提示。
將單一功能拆為多個命令 ID(如 ID_HIDE_TOOLBAR/ID_SHOW_TOOLBAR),命令處理器切換選單項 ID。適用於狀態固定的情境,不適用 MRU 等動態清單。
文中附 DynPrompt 範例程式展示完整實作。