Condividi tramite


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.

Diagram showing an implemented connection point.
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 CCmdTargetclasse 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 CCmdTargetclasse derivata da -espone un punto di connessione per l'interfaccia ISampleSink . Questo esempio viene illustrato nell'immagine seguente.

Diagram showing a Connection point implemented by using MFC.
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.

Vedi anche

MFC COM