VC++ 5.0 提供 MFC 與 ATL 兩種開發路徑。MFC 封裝 COleControl,免去介面細節,開發快,但生成檔案較大且客戶端需對應版本 MFC DLL;ATL 輕量、無 MFC 依賴,但需深諳 COM/OLE 細節。本文採 MFC 路徑示範。
Test。| 派生類別 | 基底類別 | 功能 |
|---|---|---|
| CTestApp | COleControlModule | 控制項模組初始化/終結 |
| CTestCtrl | COleControl | 視窗建立、繪製、訊息處理 |
| CTestPropPage | COlePropertyPage | 屬性頁管理 |
Test.ocx,開發環境自動註冊。他機使用需執行 regsvr32 Test.ocx。template <class T>
class CToolbar {
public:
CToolbar();
void CreateToolbar(HWND hParent);
void AddButtons();
void DestroyToolbar();
LRESULT OnToolbarNeedText(WPARAM, LPNMHDR, BOOL&);
protected:
HWND m_hwndToolbar;
};
在 TestCtl.h 包含標頭,讓控制項類別多重繼承:
class CTestCtrl : public COleControl, public CToolbar<CTestCtrl> { ... };
並加入工具列按鈕對應巨集映射表 (BEGIN_TOOLBAR_MAP...END_TOOLBAR_MAP) 以響應按鈕訊息。
在控制項類別中直接新增 CEdit m_TestEdit 成員。重載 COleControl::CreateControlWindow:先呼叫基底實作,再依序建立工具列與編輯視窗,移除預設 OnDraw 中的矩形/橢圓繪製。CreateTestEdit 計算客戶區扣除工具列後的剩餘區域,調用 m_TestEdit.Create 填滿。
重載 COleControl::OnSetObjectRects:
void CTestCtrl::OnSetObjectRects(LPCRECT lpRectPos, LPCRECT lpRectClip) {
::SendMessage(m_hwndToolbar, TB_AUTOSIZE, 0, 0); // 工具列自適應
CRect rcClient(lpRectPos);
CRect rcToolbar; m_wndToolbar.GetWindowRect(&rcToolbar); ScreenToClient(&rcToolbar);
rcClient.top = rcToolbar.bottom; // 子視窗填滿剩餘區域
m_TestEdit.SetWindowPos(NULL, rcClient.left, rcClient.top,
rcClient.Width(), rcClient.Height(), SWP_NOZORDER);
COleControl::OnSetObjectRects(lpRectPos, lpRectClip);
}
OnSetFocus 中呼叫 m_TestEdit.SetFocus() 將焦點交給編輯視窗。m_TestEdit 方法 (如 Cut, Copy)。OnNotify 中處理 TTN_NEEDTEXT 顯示工具列按鈕提示。OnDestroy 中依序呼叫 DestroyToolbar() 與 m_TestEdit.DestroyWindow() 釋放資源。
遵循四步驟(建立工具列/子視窗、動態佈局、命令轉發、資源清理)即可打造功能完整的 ActiveX 控制項。子視窗可自訂實現任意複雜功能,工具列提供直觀操作介面。