Punkty połączenia
W tym artykule wyjaśniono, jak zaimplementować punkty połączenia (wcześniej znane jako punkty połączenia OLE) przy użyciu klas CCmdTarget
MFC i CConnectionPoint
.
W przeszłości model obiektów składowych (COM) zdefiniował ogólny mechanizm (IUnknown::QueryInterface
*), który pozwolił obiektom implementować i uwidaczniać funkcje w interfejsach. Jednak odpowiedni mechanizm, który pozwolił obiektom uwidocznić ich możliwości wywoływania określonych interfejsów, nie został zdefiniowany. Oznacza to, że com zdefiniował sposób obsługi przychodzących wskaźników do obiektów (wskaźników do interfejsów tego obiektu), ale nie miał jawnego modelu dla interfejsów wychodzących (wskaźniki przechowywane w interfejsach innych obiektów). Model COM ma teraz model nazywany punktami połączenia, który obsługuje tę funkcję.
Połączenie ma dwie części: obiekt wywołujący interfejs, nazywany źródłem i obiekt implementujące interfejs, nazywany ujściem. Punkt połączenia to interfejs udostępniany przez źródło. Uwidaczniając punkt połączenia, źródło umożliwia ujściom nawiązywanie połączeń z samym sobą (źródłem). Za pośrednictwem mechanizmu punktu połączenia ( IConnectionPoint
interfejsu) wskaźnik do interfejsu ujścia jest przekazywany do obiektu źródłowego. Ten wskaźnik zapewnia źródło dostępu do implementacji ujścia zestawu funkcji składowych. Na przykład w celu wyzwolenia zdarzenia zaimplementowanego przez ujście źródło może wywołać odpowiednią metodę implementacji ujścia. Na poniższej ilustracji przedstawiono właśnie opisany punkt połączenia.
Zaimplementowany punkt Połączenie ion
MFC implementuje ten model w klasach C Połączenie ionPoint i CCmdTarget. Klasy pochodzące z CConnectionPoint
implementacji interfejsu IConnectionPoint
używane do uwidaczniania punktów połączenia z innymi obiektami. Klasy pochodzące z CCmdTarget
implementacji interfejsu IConnectionPointContainer
, które mogą wyliczać wszystkie dostępne punkty połączenia obiektu lub znaleźć określony punkt połączenia.
Dla każdego punktu połączenia zaimplementowanego w klasie należy zadeklarować część połączenia, która implementuje punkt połączenia. W przypadku zaimplementowania co najmniej jednego punktu połączenia należy również zadeklarować jedną mapę połączenia w klasie. Mapa połączenia to tabela punktów połączenia obsługiwanych przez kontrolkę ActiveX.
W poniższych przykładach przedstawiono prostą mapę połączenia i jeden punkt połączenia. Pierwszy przykład deklaruje mapę połączenia i punkt; drugi przykład implementuje mapę i punkt. Należy pamiętać, że CMyClass
musi być klasą pochodną CCmdTarget
. W pierwszym przykładzie kod jest wstawiany w deklaracji klasy w protected
sekcji :
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 i END_CONNECTION_PART deklarują klasę XSampleConnPt
osadzoną (pochodzącą z CConnectionPoint
klasy ), która implementuje ten konkretny punkt połączenia. Jeśli chcesz zastąpić dowolne CConnectionPoint
funkcje składowe lub dodać własne funkcje członkowskie, zadeklaruj je między tymi dwoma makrami. Na przykład CONNECTION_IID
makro zastępuje funkcję składową po umieszczeniu CConnectionPoint::GetIID
między tymi dwoma makrami.
W drugim przykładzie kod jest wstawiany w pliku implementacji kontrolki (plik cpp). Ten kod implementuje mapę połączenia, która zawiera punkt połączenia, SampleConnPt
:
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
Jeśli klasa ma więcej niż jeden punkt połączenia, wstaw dodatkowe makra CONNECTION_PART między makrami BEGIN_CONNECTION_MAP i END_CONNECTION_MAP .
Na koniec dodaj wywołanie metody w EnableConnections
konstruktorze klasy. Przykład:
CMyClass::CMyClass()
{
EnableConnections();
}
Po wstawieniu CCmdTarget
tego kodu klasa -derived uwidacznia punkt połączenia dla interfejsu ISampleSink
. Na poniższej ilustracji przedstawiono ten przykład.
Punkt Połączenie ion zaimplementowany za pomocą MFC
Zazwyczaj punkty połączenia obsługują "multiemisję" — możliwość emisji do wielu ujściów połączonych z tym samym interfejsem. Poniższy przykładowy fragment przedstawia sposób multiemisji przez iterowanie po każdym ujściu w punkcie połączenia:
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
W tym przykładzie jest pobierany bieżący zestaw połączeń w SampleConnPt
punkcie połączenia z wywołaniem metody CConnectionPoint::GetConnections
. Następnie wykonuje iterację za pośrednictwem połączeń i wywołuje ISampleSink::SinkFunc
każde aktywne połączenie.