Punti di connessione
Questo articolo illustra come implementare i punti di connessione (in precedenza noti come punti di connessione OLE) usando le classi CCmdTarget
MFC e CConnectionPoint
.
In passato, il Component Object Model (COM) ha definito un meccanismo generale (IUnknown::QueryInterface
*) che ha consentito agli oggetti di implementare ed esporre funzionalità nelle interfacce. Tuttavia, non è stato definito un meccanismo corrispondente che consentiva agli oggetti di esporre la loro capacità di chiamare interfacce specifiche. Com ha quindi definito il modo in cui sono stati gestiti i puntatori in ingresso agli oggetti (puntatori alle interfacce di tale oggetto), ma non ha un modello esplicito per le interfacce in uscita (puntatori all'oggetto con le interfacce di altri oggetti). COM dispone ora di un modello, denominato punti di connessione, che supporta questa funzionalità.
Una connessione ha due parti: l'oggetto che chiama l'interfaccia, denominata origine e l'oggetto che implementa l'interfaccia, denominata sink. Un punto di connessione è l'interfaccia esposta dall'origine. Esponendo un punto di connessione, un'origine consente ai sink di stabilire connessioni a se stesso (origine). Tramite il meccanismo del punto di connessione (interfaccia IConnectionPoint
), un puntatore all'interfaccia sink viene passato all'oggetto di origine. Questo puntatore fornisce all'origine l'accesso all'implementazione del sink di un set di funzioni membro. Ad esempio, per generare un evento implementato dal sink, l'origine può chiamare il metodo appropriato dell'implementazione del sink. La figura seguente illustra il punto di connessione appena descritto.
Punto di connessione implementato
MFC implementa questo modello nelle classi C Connessione ionPoint e CCmdTarget. Le classi derivate dall'implementazione CConnectionPoint
dell'interfaccia IConnectionPoint
, usate per esporre i punti di connessione ad altri oggetti. Le classi derivate dall'implementazione CCmdTarget
dell'interfaccia IConnectionPointContainer
, che può enumerare tutti i punti di connessione disponibili di un oggetto o trovare un punto di connessione specifico.
Per ogni punto di connessione implementato nella classe, è necessario dichiarare una parte di connessione che implementa il punto di connessione. Se si implementano uno o più punti di connessione, è necessario dichiarare anche una singola mappa di connessione nella classe. Una mappa di connessione è una tabella di punti di connessione supportati dal controllo ActiveX.
Gli esempi seguenti illustrano una semplice mappa di connessione e un punto di connessione. Il primo esempio dichiara la mappa di connessione e il punto; il secondo esempio implementa la mappa e il punto. Si noti che CMyClass
deve essere una CCmdTarget
classe derivata da . Nel primo esempio il codice viene inserito nella dichiarazione di classe, nella protected
sezione :
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()
Le macro BEGIN_CONNECTION_PART e END_CONNECTION_PART dichiarano una classe incorporata ( XSampleConnPt
derivata da CConnectionPoint
), che implementa questo particolare punto di connessione. Se si desidera eseguire l'override di qualsiasi CConnectionPoint
funzione membro o aggiungere funzioni membro personalizzate, dichiararle tra queste due macro. Ad esempio, la macro esegue l'override CONNECTION_IID
della CConnectionPoint::GetIID
funzione membro quando viene posizionata tra queste due macro.
Nel secondo esempio il codice viene inserito nel file di implementazione del controllo (file con estensione cpp). Questo codice implementa la mappa di connessione, che include il punto di connessione, SampleConnPt
:
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
Se la classe ha più di un punto di connessione, inserire ulteriori macro CONNECTION_PART tra le macro BEGIN_CONNECTION_MAP e END_CONNECTION_MAP .
Aggiungere infine una chiamata a EnableConnections
nel costruttore della classe. Ad esempio:
CMyClass::CMyClass()
{
EnableConnections();
}
Dopo l'inserimento di questo codice, la CCmdTarget
classe derivata da -espone un punto di connessione per l'interfaccia ISampleSink
. Questo esempio viene illustrato nell'immagine seguente.
Un punto di Connessione ion implementato con MFC
In genere, i punti di connessione supportano il "multicast", ovvero la possibilità di trasmettere a più sink connessi alla stessa interfaccia. Il frammento di esempio seguente illustra come eseguire il multicast eseguendo l'iterazione di ogni sink in un punto di connessione:
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
In questo esempio viene recuperato il set corrente di connessioni nel SampleConnPt
punto di connessione con una chiamata a CConnectionPoint::GetConnections
. Scorre quindi le connessioni e chiama ISampleSink::SinkFunc
su ogni connessione attiva.