連接點
本文說明如何使用 MFC 類別 CCmdTarget
和 CConnectionPoint
來實作連接點(先前稱為 OLE 連接點)。
過去,元件物件模型(COM)定義了一般機制( IUnknown::QueryInterface
*),允許物件在介面中實作和公開功能。 不過,未定義允許物件公開呼叫特定介面之功能的對應機制。 也就是說,COM 定義了物件的傳入指標(該物件的介面指標)的處理方式,但它沒有外送介面的明確模型(物件保留給其他物件的介面指標)。 COM 現在有一個稱為連接點的模型,可支援這項功能。
連接有兩個部分:呼叫 介面的物件,稱為來源,以及實作 介面的物件,稱為接收。 連接點是由來源公開的介面。 藉由公開連接點,來源可讓接收建立本身的連線(來源)。 透過連接點機制( IConnectionPoint
介面),接收介面的指標會傳遞至來源物件。 此指標可讓來源存取接收的一組成員函式實作。 例如,若要引發接收實作的事件,來源可以呼叫接收實作的適當方法。 下圖示范剛才描述的連接點。
實作的連線點
MFC 會在 C連線ionPoint 和 CCmdTarget 類別中 實作此模型。 衍生自 CConnectionPoint
的類別會實 IConnectionPoint
作 介面,用來公開連接點給其他物件。 衍生自 CCmdTarget
的 IConnectionPointContainer
類別會實作 介面,其可以列舉物件的所有可用連接點,或尋找特定的連接點。
針對類別中實作的每個連接點,您必須宣告實作連接點的連接元件。 如果您實作一或多個連接點,您也必須在類別中宣告單一連接對應。 連接對應是 ActiveX 控制項所支援連接點的資料表。
下列範例示範簡單的連接對應和一個連接點。 第一個範例會宣告連接對應和點;第二個範例會實作地圖和點。 請注意, CMyClass
必須是 CCmdTarget
衍生類別。 在第一個範例中,程式碼會插入類別宣告的 區段底下 protected
:
class CMyClass : public CCmdTarget
{
protected:
// Connection point for ISample interface
BEGIN_CONNECTION_PART(CMyClass, SampleConnPt)
CONNECTION_IID(IID_ISampleSink)
END_CONNECTION_PART(SampleConnPt)
DECLARE_CONNECTION_MAP()
BEGIN_CONNECTION_PART 和 END_CONNECTION_PART 宏會宣告實作這個特定連接點的內嵌類別 XSampleConnPt
(衍生自 CConnectionPoint
)。 如果您想要覆寫任何 CConnectionPoint
成員函式或新增您自己的成員函式,請在這兩個宏之間宣告它們。 例如,宏會在 CONNECTION_IID
放在這兩個 CConnectionPoint::GetIID
宏之間時覆寫成員函式。
在第二個範例中,程式碼會插入控制項的實作檔 (.cpp 檔案)。 此程式碼會實作連接對應,其中包含連接點: SampleConnPt
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
如果您的類別有多個連接點,請在BEGIN_CONNECTION_MAP 與 END_CONNECTION_MAP 宏之間 插入其他 CONNECTION_PART 宏。
最後,在 類別的建構函式中新增 對 的呼叫 EnableConnections
。 例如:
CMyClass::CMyClass()
{
EnableConnections();
}
插入此程式碼之後,衍生 CCmdTarget
類別會公開 介面的連接 ISampleSink
點。 下圖說明這個範例。
使用 MFC 實作的連線點
通常,連接點支援「多播」—能夠廣播至連線至相同介面的多個接收。 下列範例片段示範如何逐一查看連接點上的每個接收,以多播:
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
這個範例會擷取連接點上的 SampleConnPt
目前連接集,並呼叫 CConnectionPoint::GetConnections
。 然後它會逐一查看連線,並在每個作用中連線上呼叫 ISampleSink::SinkFunc
。