針對需動態切換大量控制項的介面場景(如多標籤裝置控制面板、類 Visual Studio 選項對話框),本文提出基於 CWnd 閒置池 的控制項復用架構。透過將隱藏控制項放入池中供下一個標籤復用,實測可將 GDI 物件數量降低 10 倍以上。
以型別字串(如 "Button"、"Slider")為鍵,管理可復用的 CWnd* 指標。提供 GetWnd(type) 取得與 AddWnd(type, pWnd) 歸還介面,析構時自動釋放池中所有視窗。
抽象基類 CWndControl 封裝通用屬性:可見性、啟用狀態、唯讀、位置、大小、字型、事件處理鏈、關聯控制項等。衍生類(CWndButton、CWndSlider 等)實作純虛函數 CreateWnd、UpdateWnd、OnCmdMsg,完成具體 MFC 控制項的建立與同步。
附加至 CDialog,管理 CWndControl 集合。AddControl 時優先從池取得同類型 CWnd,調用 AttachWnd 綁定並套用屬性;RemoveControl 時呼叫 DetachWnd 隱藏並歸還池中。並轉發 OnCmdMsg 至對應控制項的事件處理器。
定義 IWndEventHandler 介面與 CWndEvent 事件物件。控制項觸發命令時,容器分發事件至註冊的處理器(通常是對話框類),由 HandleWndEvent 依發送者名稱分派邏輯。
提供 MDI 示範專案 TestFreePool,每個 MDI 子視窗載入一個 XML 佈局檔,定義控制項群組與屬性。支援標準 MFC 控制項與 ActiveX 控制項(如 WebBrowser2)。內建右鍵選單「Show CWnd Count」統計實際建立的 CWnd 數量驗證資源節省效果。
| XML 檔案 | 說明 | 實際 CWnd 數 | 未用池估算值 |
|---|---|---|---|
| Example1.xml | 所有支援控制項類型展示 | 30 | 41 |
| Example2.xml | 12 群組,各 10 Label + 10 Button | 27 | 259 |
| Example3.xml | VS2005 選項對話框 3 頁模擬 | 30 | 48 |
CTreeWnd / CListWnd:樹狀與列表控制項封裝。CControlDlg:整合容器的實際對話框類別。CControlGroup / CControlXml:XML 解析引擎,建構群組樹與控制項實例。ControlWnd:頂層視窗,包含左側樹狀導航、右側內容區、事件日誌區。本架構證明了閒置池模式在動態 UI 場景下的顯著資源優勢。原始碼採用模組化設計,易於擴充新控制項類型(參考專案目錄下的說明文件)。事件機制雖簡單但足夠彈性,可依需求引入更豐富的事件參數與路由策略。XML 解析器採用輕量級 CMarkup,無額外依賴,適合嵌入式或綠色軟體部署。
