本文系統剖析 MFC 中工具列(Toolbar)與狀態列(Status Bar)的核心運作機制,涵蓋訊息路由、飛越提示、工具提示、命令啟用/禁用、顯示隱藏控制、停靠與浮動等進階主題,並輔以原始碼級別的詳細說明。
MFC 透過兩個自訂訊息管理狀態列文字:
WM_SETMESSAGESTRING:設定狀態列文字,對應處理函數 OnSetMessageString。WM_POPMESSAGESTRING:恢復預設狀態文字(如 "Ready"),對應 OnPopMessageString。OnSetMessageString 支援兩種文字來源:直接傳入字串指標(lParam),或透過資源 ID(wParam)從字串表載入。字串資源採用「狀態列文字\\n工具提示文字」格式,以 \n 分隔。函數最終呼叫狀態列的 SetWindowText,觸發 WM_SETTEXT 訊息,由 CStatusBar::OnSetText 轉為 SetPaneText(0, ...) 顯示於第 0 格。
當使用者選取選單項目時,CFrameWnd::OnMenuSelect 記錄目前追蹤的命令 ID 至 m_nIDTracking。隨後系統送出 WM_ENTERIDLE,OnEnterIdle 偵測到選單模式且 ID 改變時,呼叫 SetMessageText 更新狀態列。此機制確保提示文字在選單展開期間即時顯示。
CControlBar::WindowProc 重寫訊息分發路徑:對 WM_COMMAND、WM_NOTIFY 等特定訊息,優先讓控制列自身處理(OnWndMsg),未處理則轉發給擁有者視窗(框架視窗),最後才交給預設視窗程序。此設計確保工具列按鈕點擊產生的 WM_COMMAND 能正確路由至框架視窗的命令處理函數。
PreTranslateMessage 主要實現 CBRS_FLYBY(飛越提示)與 CBRS_TOOLTIPS(工具提示)功能:
OnToolHitTest 判斷所在按鈕。TTN_NEEDTEXT 通知取得工具提示文字,由 CFrameWnd::OnToolTipText 處理,從字串資源第二段擷取提示內容。MFC 提供自動啟用/禁用、勾選/取消勾選功能。核心流程:
WM_IDLEUPDATECMDUI 給所有控制列。CControlBar::OnIdleUpdateCmdUI 建立 CCmdUI 物件,呼叫虛擬函數 OnUpdateCmdUI。CToolBar、CStatusBar、CDialogBar)實作各自的 OnUpdateCmdUI,逐項建立 CToolCmdUI 或 CStatusCmdUI 並呼叫 DoUpdate 送出 CN_UPDATE_COMMAND_UI 通知。ON_UPDATE_COMMAND_UI 對應處理函數被調用,設定啟用狀態、文字、勾選等。選單項目同樣支援此機制:WM_INITMENUPOPUP 觸發 OnInitMenuPopup,逐項建立 CCmdUI 並呼叫 DoUpdate,實現選單動態啟用/禁用。
標準命令 ID_VIEW_TOOLBAR、ID_VIEW_STATUS_BAR 對應 ON_COMMAND_EX 映射至 OnBarCheck,切換 WS_VISIBLE 風格並呼叫 ShowControlBar。對應的更新處理函數 OnUpdateControlBarMenu 依控制列可見狀態設定選單勾選狀態。
EnableDocking 指定可停靠邊緣,建立 CDockBar(停靠列)子視窗;工具列呼叫 EnableDocking 宣告自身可停靠;最後框架視窗呼叫 DockControlBar 完成停靠。層級關係:框架視窗 → 停靠列 → 工具列。FloatControlBar 建立 CMiniDockFrameWnd(微型停靠框架視窗),內含一個 CDockBar,工具列停靠於其中。浮動視窗可自由拖曳。MFC 透過訊息映射、命令路由、CCmdUI 架構、控制列虛擬函數重寫等機制,構建了完整且可擴充的工具列/狀態列框架。深入理解這些底層運作,有助於開發者實現自訂控制列行為、解決訊息路由問題、優化 UI 回應效能。