Точки подключения
В этой статье объясняется, как реализовать точки подключения (ранее известные как точки подключения OLE) с помощью классов CCmdTarget
MFC и CConnectionPoint
.
В прошлом объектная модель компонента (COM) определила общий механизм (IUnknown::QueryInterface
*), позволяющий объектам реализовывать и предоставлять функциональные возможности в интерфейсах. Однако соответствующий механизм, позволяющий объектам предоставлять возможность вызова определенных интерфейсов, не определен. То есть COM определяет, как обрабатываются входящие указатели на объекты (указатели на интерфейсы этого объекта), но у него нет явной модели для исходящих интерфейсов (указатель на объекты, удерживающие на интерфейсы других объектов). ТЕПЕРЬ COM имеет модель, называемую точками подключения, которая поддерживает эту функцию.
Соединение состоит из двух частей: объекта, вызывающего интерфейс, который называется источником, и объект, реализующий интерфейс, называемый приемником. Точка подключения — это интерфейс, предоставляемый источником. Предоставляя точку подключения, источник позволяет приемникам устанавливать подключения к себе (источнику). Через механизм точки подключения ( IConnectionPoint
интерфейс) указатель на интерфейс приемника передается исходному объекту. Этот указатель предоставляет источнику доступ к реализации приемника набора функций-членов. Например, чтобы вызвать событие, реализованное приемником, источник может вызвать соответствующий метод реализации приемника. На следующем рисунке показана только что описанная точка подключения.
Реализованная точка Подключение ion
MFC реализует эту модель в классах C Подключение ionPoint и 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
интерфейса. Этот пример показан на следующей схеме.
Точка Подключение ion, реализованная с помощью 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
для каждого активного подключения.