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

ATL 開發複合控件實戰:含連接點事件的完整範例

     編輯:關於VC++

複合控件將多個子控件封裝於單一 ActiveX 介面,適合建立可重用的 UI 模組。本文以 ATL 7.0/8.0 為例,逐步示範建立含「列表檢視 + 進度條」的複合控件,並實作連接點事件回呼給容器(如 VB、C#、網頁)。

專案建立與控件插入

  1. ATL DLL 專案(命名 AtlSample),預設選項完成。
  2. 加入 ATL Object → 類別:**Full Control** → 簡稱 AtlComp。
    勾選 Support Error Info、Support Connection Points。

對話框模板與資源

  • 資源編輯器打開 IDD_ATLCOMP,拖入 List Control (IDC_LIST1) 與 Progress Control (IDC_PROGRESS1)。
  • AtlComp.h 引入 #include <CommCtrl.h>。
  • 類別加入私有成員:HIMAGELIST m_hImlIcons; HWND m_hListCtrl;

訊息對應與初始化 (WM_INITDIALOG)

LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&)
{
    // 進度條顏色
    SendDlgItemMessage(IDC_PROGRESS1, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0,128,0));
    SendDlgItemMessage(IDC_PROGRESS1, PBM_SETPOS, 0, 0);

    // 列表檢視初始化
    m_hListCtrl = GetDlgItem(IDC_LIST1);
    m_hImlIcons = ImageList_Create(16, 16, ILC_MASK | ILC_COLOR32, 2, 0);
    HICON hIcon = LoadIcon(_Module.m_hInstResource, MAKEINTRESOURCE(IDI_ICON_LIST));
    ImageList_AddIcon(m_hImlIcons, hIcon);
    ListView_SetImageList(m_hListCtrl, m_hImlIcons, LVSIL_SMALL);
    ListView_SetExtendedListViewStyle(m_hListCtrl, LVS_EX_FULLROWSELECT);

    // 欄位
    LV_COLUMN lvCol = { LVCF_TEXT | LVCF_WIDTH, LVCFMT_LEFT };
    lvCol.cx = 200; lvCol.pszText = "檔案名稱"; ListView_InsertColumn(m_hListCtrl, 0, &lvCol);
    lvCol.cx = 80;  lvCol.pszText = "檔案大小"; ListView_InsertColumn(m_hListCtrl, 1, &lvCol);
    return 0;
}

資源釋放 (WM_DESTROY)

LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&)
{
    ImageList_Destroy(m_hImlIcons);
    return 0;
}

自訂方法:Atl()

清空列表、插入示範項目、更新進度條 50%。

STDMETHODIMP AtlComp::Atl()
{
    ListView_DeleteAllItems(m_hListCtrl);
    LVITEM lvItem = { LVIF_TEXT | LVIF_IMAGE, 0, 0, 0, 0, L"我愛VC.C++", 0 };
    ListView_InsertItem(m_hListCtrl, &lvItem);
    ListView_SetItemText(m_hListCtrl, 0, 1, L"1024");
    SendDlgItemMessage(IDC_PROGRESS1, PBM_SETPOS, 50, 0);
    return S_OK;
}

連接點事件:AtlEven

  1. 類別檢視 → 介面右鍵 → Add Connection Point,名稱 AtlEven,參數 [in] long lState, [in] char* lpszInfo。
  2. 編譯 IDL(專案右鍵 → Compile IDL)。
  3. 在 Atl() 方法首尾觸發事件:
    Fire_AtlEven(0, "方法開始"); … Fire_AtlEven(1, "方法結束");

測試容器 (MFC 對話框專案 TestAtlDlg)

  • 對話框插入 AtlComp 控件(ID: IDC_ATLCOMP1)。
  • 標頭檔加入 DECLARE_EVENTSINK_MAP()。
  • 實作檔對應事件:
BEGIN_EVENTSINK_MAP(CTestAtlDlg, CDialog)
    ON_EVENT(CTestAtlDlg, IDC_ATLCOMP1, 1, OnAtlEvent, VTS_I4 VTS_BSTR)
END_EVENTSINK_MAP()

void CTestAtlDlg::OnAtlEvent(long state, LPCTSTR buf)
{
    // state: 0=開始, 1=結束; buf: 文字描述
    TRACE("AtlEven: %d - %s\n", state, buf);
}

關鍵點總結

項目說明
複合控件基類CComControl<T> + IPersistStreamInitImpl + IOleControlImpl 等
子視窗建立時機OnCreate 或 WM_INITDIALOG,勿用 WS_VISIBLE,由容器控制顯示
連接點觸發Fire_<EventName> 由 ATL 產生,自動遍歷所有訂閱端
測試容器事件接收MFC 使用 EVENTSINK_MAP,.NET 直接 += 事件處理器

此範例展示 ATL 複合控件的完整生命週期,可直接擴充為生產級 UI 元件庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved