Body připojení
Tento článek vysvětluje, jak implementovat spojovací body (dříve označované jako spojovací body OLE) pomocí tříd CCmdTarget
MFC a CConnectionPoint
.
V minulosti model COM (Component Object Model) definoval obecný mechanismus (IUnknown::QueryInterface
*), který umožnil objektům implementovat a zveřejnit funkce v rozhraních. Nebyl však definován odpovídající mechanismus, který umožňoval objektům zveřejnit jejich schopnost volat konkrétní rozhraní. To znamená, že objekt COM definoval způsob zpracování příchozích ukazatelů na objekty (ukazatele na rozhraní daného objektu), ale neměl explicitní model pro odchozí rozhraní (ukazatele, které objekt uchovává na rozhraní jiných objektů). Com teď má model označovaný jako spojovací body, který tuto funkci podporuje.
Připojení má dvě části: objekt volající rozhraní, označovaný jako zdroj, a objekt, který implementuje rozhraní, označovaný jako jímka. Spojovací bod je rozhraní vystavené zdrojem. Zveřejněním spojovacího bodu zdroj umožňuje jímce navázat připojení k sobě (zdroj). Prostřednictvím mechanismu spojovacího IConnectionPoint
bodu (rozhraní) se do zdrojového objektu předá ukazatel na rozhraní jímky. Tento ukazatel poskytuje zdroj s přístupem k implementaci sady členských funkcí jímky. Pokud například chcete aktivovat událost implementovanou jímkou, zdroj může volat příslušnou metodu implementace jímky. Následující obrázek znázorňuje právě popsaný spojovací bod.
Implementovaný bod Připojení ionu
MFC implementuje tento model do tříd C Připojení ionPoint a CCmdTarget. Třídy odvozené z CConnectionPoint
implementace IConnectionPoint
rozhraní, které slouží k vystavení spojovacích bodů jiným objektům. Třídy odvozené z CCmdTarget
implementace IConnectionPointContainer
rozhraní, které mohou vytvořit výčet všech dostupných spojovacích bodů objektu nebo najít konkrétní spojovací bod.
Pro každý spojovací bod implementovaný ve vaší třídě musíte deklarovat část připojení, která implementuje spojovací bod. Pokud implementujete jeden nebo více spojovacích bodů, musíte ve své třídě deklarovat také jednu mapu připojení. Mapa připojení je tabulka spojovacích bodů podporovaných ovládacím prvek technologie ActiveX.
Následující příklady ukazují jednoduchou mapu připojení a jeden spojovací bod. První příklad deklaruje mapování připojení a bod; druhý příklad implementuje mapu a bod. Všimněte si, že CMyClass
musí být -odvozená CCmdTarget
třída. V prvním příkladu se kód vloží do deklarace třídy v protected
části:
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()
Makra BEGIN_CONNECTION_PART a END_CONNECTION_PART deklarují vloženou třídu XSampleConnPt
(odvozenou z CConnectionPoint
), která implementuje tento konkrétní spojovací bod. Pokud chcete přepsat všechny CConnectionPoint
členské funkce nebo přidat vlastní členské funkce, deklarujte je mezi těmito dvěma makry. Makro například CONNECTION_IID
přepíše CConnectionPoint::GetIID
členovu funkci při umístění mezi těmito dvěma makry.
V druhém příkladu se kód vloží do souboru implementace ovládacího prvku (soubor .cpp). Tento kód implementuje mapu připojení, která zahrnuje spojovací bod: SampleConnPt
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
Pokud má vaše třída více než jeden spojovací bod, vložte mezi makra BEGIN_CONNECTION_MAP a END_CONNECTION_MAP další CONNECTION_PART makra.
Nakonec do konstruktoru třídy přidejte volání EnableConnections
. Příklad:
CMyClass::CMyClass()
{
EnableConnections();
}
Po vložení tohoto kódu vaše CCmdTarget
-odvozená třída zveřejňuje spojovací bod pro ISampleSink
rozhraní. Následující obrázek znázorňuje tento příklad.
Bod Připojení implementovaný v prostředí MFC
Spojovací body obvykle podporují "vícesměrové vysílání" – schopnost vysílat do více jímek připojených ke stejnému rozhraní. Následující příklad fragmentu ukazuje, jak provést vícesměrové vysílání iterací přes každou jímku v spojovacím bodu:
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
Tento příklad načte aktuální sadu připojení v spojovacím SampleConnPt
bodu s voláním CConnectionPoint::GetConnections
. Pak iteruje prostřednictvím připojení a volá ISampleSink::SinkFunc
každé aktivní připojení.