首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

VC++ 技術內幕筆記第 8 章:ActiveX 控件開發與容器程式設計

     編輯:VC 教學

ActiveX 控件本質

  • 基於 COM 技術的軟體模組,舊稱 OLE 控件 (.ocx);
  • 可視為特殊子視窗,但**不發送 WM_* 通知**,改為**激發事件 (Event)**;
  • 事件實為控件呼叫容器回呼函數,無返回值,類似 Click、KeyDown;
  • 運行時可能**無視窗** (Windowless),Create 實為載入程式碼 + 就地啟動,再建立自身視窗;
  • 儲存於 .ocx (DLL),容器透過登錄表 + COM 載入。

安裝與專案整合

  1. 複製 .ocx 至目標機;
  2. regsvr32 xxx.ocx 註冊;
  3. VC 專案:Project → Add To Project → Components and Controls → Registered ActiveX Controls 選擇插入;
  4. ClassWizard 自動產生 CWnd 衍生包裝類,含屬性/方法對應函數、建構函數支援動態建立。

包裝類運作機制

所有成員函數內部呼叫 CWnd::InvokeHelper:

void InvokeHelper(
    DISPID dwDispID,      // 方法/屬性的 Dispatch ID (由控件提供者定義)
    WORD wFlags,          // 呼叫目的
    VARTYPE vtRet,        // 返回值型別
    void* pvRet,          // 返回值緩衝區
    const BYTE* pbParamInfo, // 參數型別資訊
    ...                   // 參數列表
);

wFlags 常值:

  • DISPATCH_METHOD:呼叫方法;
  • DISPATCH_PROPERTYGET:讀屬性;
  • DISPATCH_PROPERTYPUT:寫屬性 (by value);
  • DISPATCH_PROPERTYPUTREF:寫屬性 (by reference)。

vtRet 對照:VT_EMPTY(void)、VT_I2(short)、VT_I4(long)、VT_R4(float)、VT_R8(double)、VT_CY(CY)、VT_DATE(DATE)、VT_BSTR(BSTR)、VT_DISPATCH(LPDISPATCH)...

設計時 vs 執行時屬性

  • 設計時屬性:屬性視窗設定,儲存於資源/註冊表,DoModal/Create 前生效;
  • 執行時屬性:全部可讀寫 (除非控件設計為唯讀),透過包裝類 Get/Set 存取。

發佈部署清單

  • 必須隨安裝包附帶對應 .ocx;
  • 提供安裝程式自動執行 regsvr32;
  • 注意版本相容:新版 OCX 應保持介面向後相容。

容器程式設計實戰模式

// 對話框資源放入控件 → ClassWizard 產生 CMyAxCtrl 包裝類
// 成員變數 m_ctrl (CMyAxCtrl)

// 動態建立 (非對話框)
CMyAxCtrl* pCtrl = new CMyAxCtrl;
pCtrl->Create(NULL, WS_VISIBLE|WS_CHILD, rect, this, IDC_MYCTRL);

// 呼叫方法
pCtrl->SomeMethod(param1, param2);

// 存取屬性
long val = pCtrl->GetSomeProperty();
pCtrl->SetSomeProperty(newVal);

// 事件處理:ClassWizard 在包裝類產生事件處理函數
// 如 void OnClickEvent(short button, short shift, long x, long y)

避坑指南

  • 不要直接使用控件的 hWnd,容器與控件間有 MFC 代理層;
  • 事件處理函數**不可**有返回值 (對應 VT_EMPTY);
  • 跨執行緒存取控件需封送 (Marshal),MFC 單執行緒模型下直接用會崩潰;
  • 記憶體洩漏風險:動態建立的控件必須 DestroyWindow + delete。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved