Punti di connessione
Questo articolo illustra come implementare i punti di connessione (precedentemente noto come punti di connessione OLE) utilizzando le classi CCmdTarget e CConnectionPointMFC.
In passato, Component Object (COM) Model definito un meccanismo generale (IUnknown::QueryInterface) che oggetti consentiti per distribuire ed esporre le funzionalità nelle interfacce.Tuttavia, un meccanismo corrispondente che gli oggetti consentiti per esporre le proprie funzionalità chiamare le interfacce specifiche non sono definiti.Ovvero COM definito come puntatori in ingresso agli oggetti (puntatori alle interfacce di tale oggetto) sono stati gestiti, ma non include un modello esplicito per le interfacce in uscita (puntatori l'oggetto utilizza ad altri oggetti interfacce).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, chiamare il database di origine e l'oggetto che implementa l'interfaccia, chiamare il sink.Un punto di connessione è l'interfaccia esposta dal database di origine.Esponendo un punto di connessione, un database di origine consente ai sink stabiliscano le connessioni se stessa (l'origine).Tramite il meccanismo dei punti di connessione (l'interfaccia di IConnectionPoint ), un puntatore all'interfaccia del sink viene passato all'oggetto origine.Questo puntatore viene fornito il database di origine con 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 seguente figura viene illustrato il punto di connessione appena descritta.
Punto di connessione implementato
MFC implementa questo modello nelle classi di CCmdTarget e di CConnectionPoint .Le classi derivate da CConnectionPoint implementano l'interfaccia di IConnectionPoint , utilizzata per esporre i punti di connessione ad altri oggetti.Le classi derivate da CCmdTarget implementano l'interfaccia di IConnectionPointContainer , che può enumerare tutti i punti di connessione disponibili di un oggetto o trova uno specifico punto di connessione.
Per ogni punto di connessione implementato nella classe, è necessario dichiarare una parte della connessione che implementa il punto di connessione.Se si implementa uno o più punti di connessione, è inoltre necessario dichiarare una singola mappa delle connessioni nella classe.Una mappa delle connessioni è una tabella dei punti di connessione supportati dal controllo ActiveX.
Negli esempi seguenti viene illustrata una mappa delle connessioni semplice e un punto di connessione.Il primo esempio viene dichiarata la mappa delle connessioni e il punto; il secondo esempio viene implementato il mapping e il punto.Si noti che CMyClassdeve essere CCmdTargetclasse derivata da.Nel primo esempio, il codice viene inserito nella dichiarazione di classe, sotto la sezione di 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 e le macro di END_CONNECTION_PART dichiarare una classe incorporata, XSampleConnPt (derivato da CConnectionPoint), che implementa questo punto di connessione specifica.Se si desidera eseguire l'override delle funzioni membro di CConnectionPoint o per aggiungere funzioni membro personalizzati, dichiararle tra queste due macro.Ad esempio, la macro di CONNECTION_IID esegue l'override della funzione membro di CConnectionPoint::GetIID quando inserito tra queste due macro.
Nel secondo esempio, il codice viene inserito nel file di implementazione del controllo (file CPP).Questo codice implementa la mappa delle connessioni, inclusi il punto di connessione, SampleConnPt:
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
Se la classe dispone di più punti di connessione, inserire le macro aggiuntive di CONNECTION_PART tra BEGIN_CONNECTION_MAP e le macro di END_CONNECTION_MAP .
Infine, aggiungere una chiamata a EnableConnections nel costruttore della classe.Di seguito è riportato un esempio:
CMyClass::CMyClass()
{
EnableConnections();
}
Una volta che il codice è stato inserito, il CCmdTargetnella classe derivata espone un punto di connessione per l'interfaccia di ISampleSink .La figura che segue viene illustrato questo esempio.
Un punto di connessione distribuito con MFC
In genere, i punti di connessione supportano il “multicasting„ — la possibilità di trasmettere per comunicare ai sink più collegati agli stessi interfaccia.Nel codice riportato di seguito viene illustrato come a multicast scorrendo ogni sink su 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 vengono recuperati l'impostazione corrente delle connessioni sul punto di connessione di SampleConnPt con una chiamata a CConnectionPoint::GetConnections.Quindi scorre le connessioni e chiama ISampleSink::SinkFunc su ogni connessione attiva.