Suporte a IDispEventImpl
A classe de modelo IDispEventImpl pode ser usada para fornecer suporte para coletores de ponto de conexão em sua classe ATL. Um coletor de ponto de conexão permite que sua classe manipule eventos disparados por objetos COM externos. Esses coletores de ponto de conexão são mapeados com um mapa de coletores de eventos, fornecido pela sua classe.
Para implementar corretamente um coletor de ponto de conexão para sua classe, as seguintes etapas devem ser concluídas:
Importar as bibliotecas de tipos de cada objeto externo
Declarar as interfaces
IDispEventImpl
Declarar um mapa de coletores de eventos
Avisar e cancelar aviso dos pontos de conexão
As etapas envolvidas na implementação de um coletor de ponto de conexão são todas realizadas modificando apenas o arquivo de cabeçalho (.h) da classe.
Importando bibliotecas de tipos
Para cada objeto externo cujos eventos deseja manipular, você deve importar a biblioteca de tipos. Essa etapa define os eventos que podem ser tratados e fornece informações que são usadas ao declarar o mapa de coletores de eventos. A diretiva #import pode ser usada para isso. Adicione as linhas necessárias da diretiva #import
para cada interface de expedição que será compatível com o arquivo de cabeçalho (.h) da sua classe.
O exemplo a seguir importa a biblioteca de tipos de um servidor COM externo (MSCAL.Calendar.7
):
#import "PROGID:MSCAL.Calendar.7" no_namespace, raw_interfaces_only
Observação
Você deve ter uma instrução #import
separada para cada biblioteca de tipos externa compatível.
Declarando as interfaces IDispEventImpl
Agora que já importou as bibliotecas de tipos de cada interface de expedição, você precisa declarar interfaces IDispEventImpl
separadas para cada interface de expedição externa. Modifique a declaração da classe adicionando uma declaração IDispEventImpl
de interface para cada objeto externo. Para obter mais informações sobre os parâmetros, confira IDispEventImpl.
O código a seguir declara dois coletores de ponto de conexão, para a interface DCalendarEvents
e para o objeto COM implementado pela classe CMyCompositCtrl2
:
public IDispEventImpl<IDC_CALENDAR1, CMyCompositCtrl2, &__uuidof(DCalendarEvents), &__uuidof(__MSACAL), 7, 0>,
public IDispEventImpl<IDC_CALENDAR2, CMyCompositCtrl2, &__uuidof(DCalendarEvents), &__uuidof(__MSACAL), 7, 0>
Declarando um mapa de coletores de eventos
Para que as notificações de evento sejam manipuladas pela função adequada, sua classe deve encaminhar cada evento para o manipulador correto. Para isso, é preciso declarar um mapa de coletores de eventos.
A ATL fornece várias macros, BEGIN_SINK_MAP, END_SINK_MAP e SINK_ENTRY_EX, que facilitam esse mapeamento. O formato padrão é o seguinte:
BEGIN_SINK_MAP(comClass)
SINK_ENTRY_EX(id, iid, dispid, func)
. . . //additional external event entries
END_SINK_MAP()
O exemplo a seguir declara um mapa de coletores de eventos com dois manipuladores de eventos:
BEGIN_SINK_MAP(CMyCompositCtrl2)
//Make sure the Event Handlers have __stdcall calling convention
SINK_ENTRY_EX(IDC_CALENDAR1, __uuidof(DCalendarEvents), DISPID_CLICK,
&CMyCompositCtrl2::ClickCalendar1)
SINK_ENTRY_EX(IDC_CALENDAR2, __uuidof(DCalendarEvents), DISPID_CLICK,
&CMyCompositCtrl2::ClickCalendar2)
END_SINK_MAP()
A implementação está quase concluída. A última etapa é avisar e cancelar o aviso nas interfaces externas.
Avisando e cancelando o aviso nas interfaces IDispEventImpl
A etapa final é implementar um método que avisará (ou cancelará o aviso) todos os pontos de conexão nos horários apropriados. Esse aviso deve ser feito antes da comunicação entre os clientes externos e o seu objeto. Antes que seu objeto fique visível, cada interface de expedição externa compatível com o objeto é consultada sobre as interfaces de saída. Uma conexão é estabelecida e uma referência à interface de saída é usada para manipular eventos do objeto. Esse procedimento é chamado de "aviso".
Depois que o objeto for concluído com as interfaces externas, as interfaces de saída deverão ser notificadas de que não serão mais usadas pela sua classe. Esse processo é chamado de "cancelamento do aviso".
Devido à natureza exclusiva dos objetos COM, esse procedimento varia, nos detalhes e na execução, entre implementações. Esses detalhes estão além do escopo deste tópico e não são abordados.