Points de connexion
Cet article explique comment implémenter des points de connexion (anciennement appelés points de connexion OLE) à l'aide des classes CCmdTarget
et CConnectionPoint
de MFC.
Dans le passé, le modèle objet de composant (COM) a défini un mécanisme général (IUnknown::QueryInterface
*) qui permettait aux objets d’implémenter et d’exposer des fonctionnalités dans les interfaces. Toutefois, un mécanisme de correspondance qui permettait aux objets de montrer leur capacité à appeler des interfaces spécifiques n'était pas défini. Autrement dit, le modèle COM définissait comment les pointeurs entrants aux objets (pointeurs aux interfaces de l'objet) étaient traités, mais il n'y avait pas de modèle explicite pour les interfaces sortantes (les pointeurs que l'objet conserve dans d'autres interfaces d'objets). COM a maintenant un modèle, appelé points de connexion, qui prend en charge cette fonctionnalité.
Une connexion est composée de deux parties : l'objet qui appelle l'interface, appelé la source, et l'objet implémentant l'interface, appelé le récepteur. Un point de connexion est l'interface exposée par la source. En exposant un point de connexion, une source permet à des récepteurs d'établir des connexions à elle-même (source). Par le biais du mécanisme de point de connexion (l’interface IConnectionPoint
), un pointeur vers l’interface récepteur est transmis à l’objet source. Ce pointeur assure à la source l'accès à l'implémentation du récepteur d'un ensemble de fonctions membres. Par exemple, pour déclencher un événement implémenté par le récepteur, la source peut appeler la méthode appropriée de l'implémentation du récepteur. L'illustration suivante montre le point de connexion qui vient d'être décrit.
Point de Connecter ion implémenté
MFC implémente ce modèle dans les classes C Connecter ionPoint et CCmdTarget. Les classes dérivées de l’implémentation de CConnectionPoint
l’interface IConnectionPoint
, utilisées pour exposer des points de connexion à d’autres objets. Les classes dérivées de l’implémentation de CCmdTarget
l’interface IConnectionPointContainer
, qui peuvent énumérer tous les points de connexion disponibles d’un objet ou rechercher un point de connexion spécifique.
Pour chaque point de connexion implémenté dans votre classe, vous devez déclarer une partie de la connexion qui implémente le point de connexion. Si vous implémentez un ou plusieurs points de connexion, vous devez également déclarer un seul mappage de connexions dans votre classe. Un mappage de connexions est une table de points de connexion prise en charge par le contrôle ActiveX.
Les exemples suivants illustrent un mappage de connexions simple et un point de connexion. Le premier exemple déclare le mappage de connexions et le point ; le deuxième exemple implémente le mappage et le point. Notez qu’il doit s’agir CMyClass
d’une CCmdTarget
classe dérivée. Dans le premier exemple, le code est inséré dans la déclaration de classe, sous la protected
section :
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()
Les macros BEGIN_CONNECTION_PART et END_CONNECTION_PART déclarent une classe XSampleConnPt
incorporée (dérivée de CConnectionPoint
), qui implémente ce point de connexion particulier. Si vous souhaitez remplacer toutes les fonctions membres de CConnectionPoint
ou ajouter vos propres fonctions membres, déclarez-les entre ces deux macros. Par exemple, la macro CONNECTION_IID
remplace la fonction membre CConnectionPoint::GetIID
lorsqu'elle est placée entre ces deux macros.
Dans le deuxième exemple, le code est inséré dans le fichier d'implémentation du contrôle (fichier .cpp). Ce code implémente le mappage de connexions, notamment le point de connexion, SampleConnPt
:
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
Si votre classe a plusieurs points de connexion, insérez des macros CONNECTION_PART supplémentaires entre les macros BEGIN_CONNECTION_MAP et END_CONNECTION_MAP.
Enfin, ajoutez un appel à la méthode EnableConnections
dans le constructeur de la classe. Par exemple :
CMyClass::CMyClass()
{
EnableConnections();
}
Une fois ce code inséré, votre CCmdTarget
classe dérivée expose un point de connexion pour l’interface ISampleSink
. La figure suivante illustre cet exemple:
Un point de connexion implémenté avec MFC
Généralement, les points de connexion prennent en charge la "multidiffusion" : la capacité de distribution à plusieurs récepteurs connectés à la même interface. Le fragment de l'exemple suivant montre comment utiliser la multidiffusion en parcourant chaque destinataire sur un point de connexion :
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
Cet exemple récupère l'ensemble actuel de connexions sur le point de connexion SampleConnPt
par un appel à CConnectionPoint::GetConnections
. Il effectue ensuite une itération via les connexions et appelle ISampleSink::SinkFunc
chaque connexion active.