ActiveX 控件作為 COM 技術的經典應用,雖已非主流,但在工業控制、老舊系統維護、瀏覽器插件等場景仍不可替代。本文以圖文並茂形式,完整演示從 VC++ 創建 ActiveX 控件項目、添加屬性/方法/事件、到 C# WinForms 專案引用測試的全流程。
ActiveXDemo,確定進入向導。向導自動生成核心類:CActiveXDemoCtrl (控件邏輯)、CActiveXDemoPropPage (屬性頁)、IDL 定義、註冊腳本等。
ActiveXDemo.ocx。ActiveXDemo Control 插入。OutStrCActiveXDemoCtrl → Add Property。BSTR (COM 字符串),名稱:OutStr,實現類型:Member Variable,變量名:m_strOutStr。.h/.cpp 生成 Get/Set、DISP_PROPERTY、IDL propget/propput。OnDraw 繪製文本:void CActiveXDemoCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid) {
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
pdc->TextOut(10, 10, m_strOutStr); // 繪製屬性字符串
}
TestContainer。ActiveXDemo Control。OutStr = "Hello from VC++"。DblClickCActiveXDemoCtrl → Add Event。DblClick,確定。[id(DISPID_DBLCLICK)],在 .cpp 添加 EVENT_STOCK_DBLCLICK() 映射。DblClick 觸發。ActiveXDemo Control → 確定。axActiveXDemo1。AxActiveXDemoLib.dll (RCW) 與 ActiveXDemoLib.dll (Interop)。public Form1() {
InitializeComponent();
axActiveXDemo1.OutStr = "ActiveX Demo from C#"; // 設置屬性
}
private void axActiveXDemo1_DblClick(object sender, EventArgs e) {
MessageBox.Show("VC++ 編寫 ActiveX 控件,C# 測試成功!");
}
| 環節 | 核心機制 | 注意事項 |
|---|---|---|
| IDL 定義 | 接口契約,定義屬性/方法/事件 DISPID | 修改後需重新編譯 OCX 並重新註冊 (regsvr32) |
| 屬性實現 | Member Variable 自動生成 Get/Set + 通知綁定 | 複雜類型用 VARIANT/BSTR/SAFEARRAY |
| 事件觸發 | Fire_Click() 等股票事件 / Fire_CustomEvent() 自定義事件 | 連接點機制,容器實現 _IActiveXDemoEvents 接口 |
| C# 互操作 | RCW (Runtime Callable Wrapper) 封裝 COM 指針 | 引用計數由 CLR 管理,注意 Marshal.ReleaseComObject 釋放時機 |
| 部署 | 目標機需註冊 OCX (regsvr32 ActiveXDemo.ocx) | 64 位系統註冊到 SysWOW64,C# 專案勾選 Prefer 32-bit 或編譯 x64 OCX |
regsvr32,檢查 OCX 依賴 (Dependency Walker)。propget/propput 屬性標志,OnDraw 是否調用 InvalidateControl() 觸發重繪。EVENT_SINK_MAP 正確,容器是否實現了事件接口 (C# 自動生成)。完整項目源碼下載:activexdemo.rar (含 VC++ 控件、VC++ 測試容器、C# 測試專案)。
掌握 ActiveX 開發流程,不僅能維護存量系統,更能深入理解 COM 雙介面、連接點、封送處理等 Windows 核心互操作機制,為學習 .NET Interop、WinRT、WebView2 等現代技術打下堅實基礎。