MFC 預設每個命令 ID 僅對應一組固定提示字串(狀態列 + 工具提示)。當選單項目文字動態變更時(如「隱藏工具列」↔「顯示工具列」),如何同步更新提示文字?本文深入分析 MFC 內部機制,提供三種解決策略與完整範例程式 DynPrompt。
動態選單易讓使用者困惑。優先考慮:
CCmdUI::SetCheck())替代文字切換WM_MENUSELECTCFrameWnd::OnMenuSelect() 發送 WM_SETMESSAGESTRING 至自身WM_SETMESSAGESTRING (定義於 afxpriv.h) 以 WPARAM 傳遞字串資源 ID,或 LPARAM 傳遞實際字串指標// 資源字串格式
STRINGTABLE DISCARDABLE
BEGIN
ID_VIEW_TOOLBAR "顯示或隱藏工具列\n切換工具列"
END
// 換行符後文字作為工具提示
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);
}
}
BOOL CMainFrame::OnToolTipText(UINT id, NMHDR* pNMHDR, LRESULT* pResult) {
// 截獲 TOOLTIPTEXT 結構,動態填入 lpszText
// 參考 MFC 原始碼實現邏輯
return TRUE;
}
| 策略 | 適用場景 | 優缺點 |
|---|---|---|
| 通用提示文字 | 布林狀態切換(顯示/隱藏) | 最簡單、使用者不困惑、無需額外程式碼 |
| 雙命令 ID 偽裝 | 固定狀態對(如 MRU 非適用) | 需切換命令 ID、處理命令轉發、增加複雜度 |
| 重載訊息處理 | 真正需要動態內容(如 MRU 檔名) | 最靈活、但需深入 MFC 內部機制、維護成本較高 |
OnMenuSelect 攔截與 WM_SETMESSAGESTRING 發送OnMenuSelect + WM_SETMESSAGESTRING,工具提示重載 OnToolTipTextDynPrompt 範例,但注意維護複雜度