支援 IDispEventImpl
模板類別識別碼ispEventImpl 可用於在 ATL 類中提供連接點接收器支援。連接點接收器使類得以處理從外部 COM 物件引發的事件。這些連接點接收器是用事件接收映射(由類提供)來映射的。
若要正確地實作類別的連接點接收器,必須完成以下步驟:
- 為每個外部對象匯入類型庫
- 聲明 IDispEventImpl 介面
- 聲明事件接收映射
- 通知和取消通知連接點
實現連接點接收器所涉及的步驟都是只通過修改類的標頭檔 (.h) 來完成的。
匯入類型庫
對於每一個希望處理其事件的外部對象,都必須匯入類型庫。此步驟定義可以處理的事件,並提供在聲明事件接收映射時使用的資訊。可以使用 #import 指令來完成此任務。在類的標頭檔 (.h) 中,為每個要支援的調度介面添加必需的 #import 指令行。
下面的樣本匯入外部 COM 伺服器 (MyServer) 的類型庫:
#import "D://MyServer.dll" raw_interfaces_only, no_namespace, named_guids
注意 對每個要支援的外部類型庫必須有一個單獨的 #import 語句。
聲明 IDispEventImpl 介面
您已匯入了每個調度介面的類型庫,現在需要為每個外部調度介面分別聲明 IDispEventImpl 介面。修改類的聲明,為每個外部對象添加一個 IDispEventImpl 介面聲明。有關參數的更多資訊,請參見 IDispEventImpl。
下面的代碼聲明兩個連接點接收器,一個用於自訂 IExtEvents1 和 IExtEvents2 介面,一個用於 CMyObj 類實現的 COM 物件:
public IDispEventImpl<0, CMyObj, &DIID__IExtEvents1,
&LIBID_EXTEVENTS1Lib, 1, 0>,
public IDispEventImpl<1, CMyObj, &DIID__IExtEvents2,
&LIBID_EXTEVENTS2Lib, 1, 0>
聲明事件接收映射
為使事件通知能夠由正確的函數處理,類必須將每個事件路由到它的正確處理常式。這一點通過聲明一個事件接收映射來實現。
ATL 提供了若干個使此映射更容易的宏:BEGIN_SINK_MAP、END_SINK_MAP 和 SINK_ENTRY。標準格式如下所示:
BEGIN_SINK_MAP(comClass)
SINK_ENTRY(id, dispid, func)
. . . //additional external event entries
END_SINK_MAP()
下面的樣本用兩個事件處理常式聲明一個事件接收映射:
BEGIN_SINK_MAP(CMyObj)
SINK_ENTRY(0, Events1, OnClick1)
SINK_ENTRY(0, Events2, OnClick2)
END_SINK_MAP()
實現已接近完成。最後一步涉及通知和取消通知外部介面。
通知和取消通知 IDispEventImpl 介面
最後一步是實現一個在適當的時間通知(或取消通知)所有連接點的方法。必須先完成這種通知,外部客戶端與對象之間的通訊才能發生。在對象變得可見之前,會向對象支援的每個外部調度介面查詢輸出介面。建立一個串連,並使用對輸出介面的引用來處理來自對象的事件。此過程稱為“通知”。
在對象使用完外部介面之後,應通知輸出介面它們不再由類使用。此過程稱為“取消通知”。
由於 COM 物件的獨特特性,此過程的具體細節和執行因實現而異。這些細節超出了本主題的範圍,不予討論。