Поделиться через


Точки подключения

В этой статье объясняется, как реализовать точки подключения (ранее известные как точки подключения OLE) с помощью классов CCmdTarget MFC и CConnectionPoint.

В прошлом объектная модель компонента (COM) определила общий механизм (IUnknown::QueryInterface*), позволяющий объектам реализовывать и предоставлять функциональные возможности в интерфейсах. Однако соответствующий механизм, позволяющий объектам предоставлять возможность вызова определенных интерфейсов, не определен. То есть COM определяет, как обрабатываются входящие указатели на объекты (указатели на интерфейсы этого объекта), но у него нет явной модели для исходящих интерфейсов (указатели, которые объект хранит к интерфейсам других объектов). ТЕПЕРЬ COM имеет модель, называемую точками подключения, которая поддерживает эту функцию.

Соединение состоит из двух частей: объекта, вызывающего интерфейс, который называется источником, и объект, реализующий интерфейс, называемый приемником. Точка подключения — это интерфейс, предоставляемый источником. Предоставляя точку подключения, источник позволяет потребителям устанавливать подключения к нему (источнику). Через механизм точки подключения ( IConnectionPoint интерфейс) указатель на интерфейс приемника передается исходному объекту. Этот указатель предоставляет источнику доступ к реализации набора методов объекта-приёмника. Например, чтобы вызвать событие, реализованное приемником, источник может вызвать соответствующий метод реализации приемника. На следующем рисунке показана только что описанная точка подключения.

Схема, показывающая реализованную точку подключения.
Реализованная точка подключения

MFC реализует эту модель в классах CConnectionPoint и CCmdTarget . Классы, производные от CConnectionPoint, реализуют интерфейс IConnectionPoint, используемый для предоставления точек подключения другим объектам. Классы, производные от CCmdTarget, реализуют интерфейс IConnectionPointContainer, который может перечислять все доступные точки подключения объекта или находить конкретную точку подключения.

Для каждой точки подключения, реализованной в классе, необходимо объявить часть подключения, реализующую точку подключения. При реализации одной или нескольких точек подключения необходимо также объявить одну карту подключения в классе. Карта подключения — это таблица точек подключения, поддерживаемых элементом управления ActiveX.

В следующих примерах показана простая карта подключения и одна точка подключения. Первый пример объявляет карту подключения и точку; второй пример реализует карту и точку. Обратите внимание, что CMyClass должен быть производным классом CCmdTarget. В первом примере код вставляется в объявление класса в разделе 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 и END_CONNECTION_PART объявляют внедренный класс XSampleConnPt (производный отCConnectionPoint), который реализует эту конкретную точку подключения. Если вы хотите переопределить любые функции-члены CConnectionPoint или добавить собственные функции-члены, объявите их между этими двумя макросами. Например, CONNECTION_IID макрос переопределяет CConnectionPoint::GetIID функцию-член при размещении между этими двумя макросами.

Во втором примере код вставляется в файл реализации элемента управления (.cpp-файл). Этот код реализует карту подключения, которая включает точку подключения, SampleConnPt:

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

Если класс имеет несколько точек подключения, вставьте дополнительные макросы CONNECTION_PART между макросами BEGIN_CONNECTION_MAP и END_CONNECTION_MAP .

Наконец, добавьте вызов EnableConnections в конструктор класса. Рассмотрим пример.

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

После вставки этого кода производный CCmdTargetкласс предоставляет точку подключения для ISampleSink интерфейса. Этот пример показан на следующей схеме.

Схема, показывающая точку подключения, реализованную с помощью MFC.
Точка подключения, реализованная с помощью MFC

Как правило, точки подключения поддерживают мультикаст — способность передавать на несколько приёмников, подключенных к одному и тому же интерфейсу. В следующем примере фрагмента показано, как выполнять многоадресную рассылку путем итерации по каждому приемнику в точке подключения:

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

В этом примере, с помощью вызова SampleConnPt, извлекается текущий набор подключений на точке подключения CConnectionPoint::GetConnections. Затем он выполняет итерацию по подключениям и вызывает ISampleSink::SinkFunc для каждого активного подключения.

См. также

MFC COM