Compartilhar via


Pontos de conexão

Este artigo explica como implementar pontos de conexão (anteriormente conhecidos como pontos de conexão OLE) usando as classes MFC CCmdTarget e CConnectionPoint.

No passado, o Component Object Model (COM) definia um mecanismo geral (IUnknown::QueryInterface*) que permitia que objetos implementassem e expusessem a funcionalidade em interfaces. No entanto, um mecanismo correspondente que permitia que objetos exponham sua capacidade de chamar interfaces específicas não foi definido. Ou seja, o COM definiu como ponteiros de entrada para objetos (ponteiros para interfaces desse objeto) foram tratados, mas não tinha um modelo explícito para interfaces de saída (ponteiros que o objeto contém para interfaces de outros objetos). O COM agora tem um modelo, chamado de pontos de conexão, que dá suporte a essa funcionalidade.

Uma conexão tem duas partes: o objeto que chama a interface, chamado de origem e o objeto que implementa a interface, chamado de coletor. Um ponto de conexão é a interface exposta pela origem. Ao expor um ponto de conexão, uma fonte permite que os coletores estabeleçam conexões com eles mesmos (a origem). Por meio do mecanismo do ponto de conexão (a interface IConnectionPoint), um ponteiro para a interface do coletor é passado para o objeto de origem. Esse ponteiro fornece à fonte acesso à implementação do coletor de um conjunto de funções de membro. Por exemplo, para disparar um evento implementado pelo coletor, a origem pode chamar o método apropriado da implementação do coletor. A figura a seguir demonstra o ponto de conexão descrito.

Diagram showing an implemented connection point.
Um ponto de conexão implementado

O MFC implementa esse modelo nas classes CConnectionPoint e CCmdTarget. Classes derivadas de CConnectionPoint implementam a interface IConnectionPoint, que é usada para expor pontos de conexão com outros objetos. Classes derivadas de CCmdTarget implementam a interface IConnectionPointContainer, que podem enumerar todos os pontos de conexão disponíveis de um objeto ou encontrar um ponto de conexão específico.

Para cada ponto de conexão implementado em sua classe, você deve declarar uma parte de conexão que implementa o ponto de conexão. Se você implementar um ou mais pontos de conexão, também precisará declarar um só mapa de conexão em sua classe de controle. Um mapa de conexão é uma tabela de pontos de conexão com suporte do controle ActiveX.

Os exemplos a seguir demonstram um mapa de conexão simples e um ponto de conexão. O primeiro exemplo declara o mapa e o ponto de conexão; o segundo exemplo implementa o mapa e o ponto. Observe que CMyClass deve ser uma classe derivada de CCmdTarget. No primeiro exemplo, o código é inserido na declaração de classe, na seção 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()

As macros BEGIN_CONNECTION_PART e END_CONNECTION_PART declaram uma classe inserida, XSampleConnPt (derivada de CConnectionPoint) que implementa esse ponto de conexão específico. Se você quiser substituir qualquer função de membro CConnectionPoint ou adicionar funções de membro próprias, declare-as entre essas duas macros. Por exemplo, a macro CONNECTION_IID substitui a função de membro CConnectionPoint::GetIID quando colocada entre essas duas macros.

No segundo exemplo, o código é inserido no arquivo de implementação do controle (arquivo.cpp). Esse código implementa o mapa de conexão, que inclui o ponto de conexão SampleConnPt:

BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
    CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()

Se sua classe tiver mais de um ponto de conexão, insira macros CONNECTION_PART adicionais entre as macros BEGIN_CONNECTION_MAP e END_CONNECTION_MAP.

Por fim, adicione uma chamada para EnableConnections ao construtor da classe. Por exemplo:

CMyClass::CMyClass()
{
   EnableConnections();
}

Depois que esse código é inserido, sua classe derivada de CCmdTarget expõe um ponto de conexão para a interface ISampleSink. A figura a seguir ilustra esse exemplo.

Diagram showing a Connection point implemented by using MFC.
Um ponto de conexão implementado com MFC

Normalmente, os pontos de conexão dão suporte a "multicasting": a capacidade de difusão para vários coletores conectados à mesma interface. O seguinte fragmento de exemplo demonstra como realizar multicasting iterando em cada coletor em um ponto de conexão:

void CMyClass::CallSinkFunc()
{
   POSITION pos = m_xSampleConnPt.GetStartPosition();
   ISampleSink* pSampleSink;
   while (pos != NULL)
   {
      pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
      if (pSampleSink != NULL)
         pSampleSink->SinkFunc();
   }
}

Este exemplo recupera o conjunto atual de conexões no ponto de conexão SampleConnPt com uma chamada para CConnectionPoint::GetConnections. Em seguida, itera pelas conexões e chama ISampleSink::SinkFunc em todas as conexões ativas.

Confira também

MFC COM