MFC 面向獨立 Windows 應用開發,提供完整應用框架;ATL 專注 COM 元件開發,提供輕量樣板代碼。兩者在 ActiveX 控制項開發上「會師」,本文以「訊息流量監控控制項」為例,深度剖析兩者異同。
一個完整 ActiveX 控制項需實現三大類介面:
IOleObject, IPersistStorage, IDataObject, IOleInPlaceActiveObject, IOleInPlaceObject, IViewObject2, IRunnableObjectCCmdTarget 內建 IUnknown、參考計數、聚合支援BEGIN_INTERFACE_PART, INTERFACE_MAP) 實現介面QueryInterface,類似訊息映射機制COleControl 內建 22 個標準介面,**一次繼承全拿,無法裁剪**COleDispatchImpl 實現 IDispatch,ClassWizard 視覺化添加屬性/方法COleObjectFactory + 巨集實現CComObjectRootEx<ThreadModel> 處理參考計數(單/多執行緒模型切換只需換模板參數)CComObjectRootBase + COM_MAP 實現 QueryInterface,提供 17 種介面映射方式(含 tear-off、聚合)IOleObjectImpl),**可精確裁剪體積**CComCoClass/CComClassFactory/CComCreator 模板家族IDispatchImpl 基於型別庫實現標準 IDispatch,支援雙介面DECLARE_NOT_AGGREGATABLE, DECLARE_ONLY_AGGREGATABLE, DECLARE_POLY_AGGREGATABLE 巨集精確控制| 面向 | MFC 實作 | ATL 實作 |
|---|---|---|
| 專案建立 | MFC ActiveX Control Wizard,一次設定所有選項 | ATL COM AppWizard 建 DLL,再 Insert ATL Object 添加控制項 |
| 執行緒模型 | 固定單執行緒 | 可選 Single-threaded / Apartment-threaded,Wizard 禁止 Free-threaded |
繪圖 (OnDraw) | CDC* 封裝,自動處理繪圖/列印/設計時 | 需手動處理 HDC、ATL_DRAWINFO 結構,靈活但繁瑣 |
| 輸入介面 | ClassWizard 添加屬性/方法 → 自動更新 Dispatch Map | 類別檢視添加 → 自動同步 IDL、.h、.cpp |
| 自定義 COM 介面 | 需手寫嵌套類 + 介面映射巨集,**極其繁瑣** | 直接加入介面繼承鏈 + COM_MAP 條目,**極其簡單** |
| 屬性持久化 | DoPropExchange + PX_* 巨集,封裝 IPersistStorage/Stream/PropertyBag | 繼承 IPersistStorageImpl 等 + PROP_MAP 表,手動掃描序列化 |
| 屬性頁 | Wizard 產生對話框模板 + COlePropertyPage,DDX 自動綁定外部名稱 | 需手寫 Apply/Show,手動 QueryInterface 設定屬性 |
| 視窗訊息 | 標準 MFC 訊息映射 + ClassWizard | CWindowImpl + MESSAGE_HANDLER 巨集 + 類別檢視 |
| 連接點/事件 | ClassWizard Events 頁 → 自動產生 .ODL、觸發函式 | 先寫 IDL 定義事件 → 編譯型別庫 → 類別檢視 Implement Connection Point 產生 Proxy |
QueryInterface 除錯)MFC 像「豪華套裝房」——入住快、設施全,但牆壁難拆;ATL 像「積木組件」——需自行組裝,但每塊磚都可替換。隨著 ATL 成熟(Wizard 增強、屬性頁視覺化),易用性差距正在縮小。建議:UI 重、工期緊用 MFC;COM 純度高、體積敏感、長期維護用 ATL。