ID do artigo: 194179 - Última revisão: quinta-feira, 2 de junho de 2005 - Revisão: 4.0

AtlEvnt.exe exemplo mostra como cria ATL coletores usando as classes ATL IDispEventImpl e IDispEventSimpleImpl

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.
Microsoft Visual C++ .NET (2002) e Microsoft Visual C++ .NET (2003) suportam tanto o modelo de código gerenciado que é fornecido pela .NET Framework como o modelo de código nativo não gerenciado do Windows. As informações neste artigo se aplicam a apenas código Visual C++ não gerenciado.

Nesta página

Expandir tudo | Recolher tudo

Sumário

AtlEvnt.exe mostra como implementar um coletor de eventos usando as classes ATL IDispEventImpl e IDispEventSimpleImpl. Para controles compostos ou caixas de diálogo do ATL, o Assistente insere IDispEventImpl na lista de herança para configurar o coletor. Portanto, o foco Este exemplo é criar coletores para outros tipos de objetos COM e clientes. Isso é aplicável somente para interfaces de origem de dispinterface de tipo.

Use IDispEventImpl quando tiver acesso a uma biblioteca de tipos. Use IDispEventSimpleImpl quando você não tem acesso à biblioteca de tipos ou quando desejar ser mais eficiente por não carregar a biblioteca de tipos.

Além de um link para o exemplo, a seção mais informações deste artigo inclui uma visão geral do projeto e informações sobre como implementar cada classe.

Mais Informações

Os seguintes arquivos estão disponíveis para download no Centro de download da Microsoft:

O Visual C++ 6.0

Recolher esta imagemExpandir esta imagem
Download
Download Atlevnt.exe now (http://download.microsoft.com/download/vc60pro/sample7/1/win98/en-us/atlevnt.exe)
Para obter mais informações sobre como baixar arquivos de suporte da Microsoft, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
119591  (http://support.microsoft.com/kb/119591/ ) Como obter arquivos de suporte da Microsoft de serviços on-line
Microsoft examinou esse arquivo em busca de vírus. Microsoft utilizou o mais recente software de detecção de vírus que estava disponível na data em que o arquivo foi publicado. O arquivo é armazenado em servidores com segurança avançada que ajudam a evitar qualquer alteração não autorizada no arquivo.

O Visual C++ .NET

Recolher esta imagemExpandir esta imagem
Download
Download Atlevntvcnet.exe now (http://download.microsoft.com/download/visualstudionet/sample/1.11/win98mexp/en-us/atlevntvcnet.exe)
Data de lançamento: 25 de junho de 2002

Para obter mais informações sobre como baixar arquivos de suporte da Microsoft, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
119591  (http://support.microsoft.com/kb/119591/ ) Como obter arquivos de suporte da Microsoft de serviços on-line
Microsoft examinou esse arquivo em busca de vírus. Microsoft utilizou o mais recente software de detecção de vírus que estava disponível na data em que o arquivo foi publicado. O arquivo é armazenado em servidores com segurança avançada que ajudam a evitar qualquer alteração não autorizada no arquivo. O espaço de trabalho ATLEVNT consiste em dois projetos, AtlEvnt e EventSrc. Use a opção -d quando você executa AtlEvnt.exe:
AtlEvnt.exe -d

Visão geral do projeto

O espaço de trabalho AtlEvnt consiste em dois projetos, AtlEvnt e EventSrc.

O projeto EventSrc é um padrão ATL DLL projeto com um "objeto Simple". O objeto simples não possui métodos e foi modificado para oferecer suporte a pontos de conexão e a interface IPersist. O objeto COM expõe uma fonte de interface padrão (abaixo) que tem um único método chamado escala. O COM objeto chama esse método em todos os objetos de coletor conectados a ele, com base em um timer:
   dispinterface _EventSink
   {

      properties:
      methods:
      [id(1), helpstring("method Tick")] HRESULT Tick([in] long tckcnt);

   }

				
The AltEvnt projeto é um projeto ATL EXE. Uma classe CDialogImpl ATL foi adicionada ao transformar o projeto em um aplicativo de simples caixa de diálogo. Quatro coletores foram adicionados ao projeto (usando IDispEventImpl e dois usando IDispEventSimpleImpl dois). Cada coletor ilustra uma maneira diferente de fornecer um objeto de coletor de manipular o evento Tick acionado pelo objeto COM EventSrc.

A caixa de diálogo tem quatro botões e um botão permite conectar-se o coletor correspondente ao objeto COM EventSrc. A caixa de listagem exibe uma seqüência de formulário "Sinkn: recebido de eventos Tick - x" cada vez que o manipulador de eventos no coletor é chamado de escala. Depois que uma conexão for estabelecida, o botão é desabilitado. Se houver qualquer problema estabelecer a conexão com o texto de botão é substituído com uma seqüência de caracteres do formulário "Conectar Err-hr" onde "hr" representa a falha HRESULT. Use a ferramenta "Pesquisa de erro" que é fornecido com o Visual C++, versão 6.0 para obter uma explicação sobre o erro.

Para executar esse exemplo, primeiro criar o projeto EventSrc e verifique se que o objeto EventSrc é registrado com êxito. Em seguida, criar o projeto AtlEvnt e executá-lo. É exibida uma caixa de diálogo com quatro botões (além de OK e Cancel) e uma caixa de listagem. Os quatro botões representam quatro receptores. Clicar em um botão conecta-se o coletor à fonte. Após a conexão é feita, seqüências de caracteres são adicionadas à caixa de listagem cada vez que um manipulador é chamado.

Etapas para implementar IDispEventImpl

  1. Crie uma nova classe derivada de IDispEventImpl. Você pode clicar em Nova classe no menu Inserir para gerar uma nova classe. Para cada coletor diferente, adicione uma classe IDispEventImpl à lista de herança com uma identificação exclusiva, como o primeiro parâmetro. A classe de coletor pode ser um objeto COM (como em um controle composto) ou uma classe que deriva apenas IdispEventImpl:
    // Just a sink.
          class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>
          {
             ...
          }
    - ou -
    // COM object that also implements a sink (as in a composite
          // control).
          class ATL_NO_VTABLE CSinkObj :
             public CComObjectRootEx<CComSingleThreadModel>,
             public CComCoClass<CSinkObj, &CLSID_SinkObj>,
             public IDispatchImpl<ISinkObj, &IID_ISinkObj, &LIBID_SINKPROJLib>,
             public IDispEventImpl<IDC_SRCOBJ, CSinkObj>
          {
             ...
          }
  2. Você pode especificar a identificação de interface de origem, a identificação do tipo de biblioteca, números de versão primária e secundária da biblioteca de tipo que contém a interface de origem explicitamente como parâmetros de IdispEventImpl ou usar o AtlGetObjectSourceInterface() para extrair essas informações de biblioteca de tipos. O uso de AtlGetObjectSourceInterface() requer que o objeto COM disparando o evento implementar IProvideClassInfo2 ou IPersist 1:
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj>
          {
             ...
          }
    - ou -
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,
             &DIID__EventSink, // Source interface GUID.
             &LIBID_COMOBJLib, // typelib ID containing source interface.
             1,                // Major version # of LIBID_COMOBJLib.
             0>                // Minor version # of LIBID_COMOBJLib.
          {
             ...
          }
  3. Adicione um mapa coletor a classe acima e uma entrada de coletor correspondente a cada evento de uma interface de origem que você deseja manipular. Use SINK_ENTRY_EX() quando a interface de origem é especificada como um parâmetro em IDispEventImpl, caso contrário, use SINK_ENTRY():
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY(IDC_SRCOBJ, 1 /*DISPID*/, OnTick /*Event Handler*/)
             END_SINK_MAP()
             ...
          }
    - ou -
    class CSinkObj : public IDispEventImpl<IDC_OBJ, CSinkObj,
                                  &DIID__EventSink, &LIBID_COMOBJLib, 1, 0>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)
             END_SINK_MAP()
             ...
          }
  4. Adicione métodos manipuladores de eventos à sua classe. Verifique se eles tem __stdcall convenção de chamada:
    class CSinkObj : public IDispEventImpl<IDC_SRCOBJ, CSinkObj3>
          {
          public:
             BEGIN_SINK_MAP(CSinkObj)
                SINK_ENTRY(IDC_SRCOBJ, 1 , OnTick)
             END_SINK_MAP()
    
    
             // event handler for event defined in idl as
             // [id(1)] HRESULT Tick([in] long tckcnt);
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
          }
  5. Conectar-se o coletor ao objeto COM por chamada DispEventAdvise(). Se a interface de origem é especificada como um parâmetro para IDispEventImpl, em seguida, ligue para:
    // pUnk is the IUnknown pointer of the COM object that fires events.
       // pSinkObj is an instance of the CSinkObj class.
          pSinkObj->DispEventAdvise(pUnk);
    ou outra chamada:
    // Make sure the COM object corresponding to pUnk implements
          // IProvideClassInfo2 or IPersist*.
          // Call this method to extract info about source type library if you
          // specified only two parameters to IdispEventImpl.
          AtlGetObjectSourceInterface(pUnk, &pSinkObj->m_libid,
             &pSinkObj->m_iid, &pSinkObj->m_wMajorVerNum,
             &pSinkObj->m_wMinorVerNum);
    
          hr = pSinkObj->DispEventAdvise(pUnk, &pSinkObj->m_iid);
  6. Desconectar-se o coletor chamando DispEventUnadvise():
    pSinkObj->DispEventUnadvise(pUnk);

Etapas para implementar IDispEventSimpleImpl

  1. Crie uma classe derivada de IDispEventSimpleImpl. Interface de origem deve ser especificado.
  2. Siga etapa 3 acima, exceto adicionar SINK_ENTRY_INFO() para cada método de uma interface de origem que você deseja manipular. Como IDispEventSimpleImpl não tem acesso à biblioteca de tipos que você precise fornecer informações sobre cada manipulador de eventos por meio de uma estrutura _ATL_FUNC_INFO, um para cada manipulador de eventos.

    Em vez de especificar uma estrutura _ATL_FUNC_INFO no SINK_ENTRY_INFO(), você pode usar o SINK_ENTRY_EX() macro e substituição a função virtual GetFuncInfoFromId() para preencher o _ATL_FUNC_INFO estrutura, como mostra o código a seguir.
  3. Execute as etapas 4 a 6 acima:
    static _ATL_FUNC_INFO OnTickInfo = {
             CC_STDCALL,   // Calling convention.
             VT_I4,        // Return type.
             1,            // Number of arguments.
             {VT_I4}       // Argument types.
          };
    
          class CSinkObj :
             public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,
                    &DIID__EventSink>
          {
          public:
          BEGIN_SINK_MAP(CSinkObj)
             SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick,
                             &OnTickInfo)
          END_SINK_MAP()
    
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
    
          }
    - ou -
    class CSinkObj :
             public IDispEventSimpleImpl<IDC_SRCOBJ, CSinkObj,
                    &DIID__EventSink>
          {
          public:
          BEGIN_SINK_MAP(CSinkObj4)
             SINK_ENTRY_EX(IDC_SRCOBJ, DIID__EventSink, 1, OnTick)
             // Equivalent to:
             // SINK_ENTRY_INFO(IDC_SRCOBJ, DIID__EventSink, 1, OnTick, NULL)
          END_SINK_MAP()
    
             HRESULT GetFuncInfoFromId(const IID& iid, DISPID dispidMember,
                LCID lcid, _ATL_FUNC_INFO& info)
             {
                if (InlineIsEqualGUID(iid, DIID__EventSink))
                {
                   info.cc = CC_STDCALL;
                   switch(dispidMember)
                   {
                      case 1:
                         info.vtReturn = VT_I4;
                         info.nParams = 1;
                         info.pVarTypes[0] =  VT_I4;
                         return S_OK;
    
                      default:
                         return E_FAIL;
                   }
                }
                return E_FAIL;
             }
    
             HRESULT __stdcall OnTick(long tickcnt)
             {
                ATLTRACE("CSinkObj::OnTick\n");
                return S_OK;
             }
             ...
          }

Referências

Para obter mais informações, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
181277  (http://support.microsoft.com/kb/181277/ ) AtlSink usa ATL para criar um coletor dispinterface

A informação contida neste artigo aplica-se a:
  • Microsoft ActiveX Template Library 3.0 nas seguintes plataformas
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++, 32-bit Learning Edition 6.0
    • Microsoft Visual C++ .NET 2002 Standard Edition
    • Microsoft Visual C++ .NET 2003 Standard Edition
Palavras-chave: 
kbmt kbtshoot kbdownload kbactivexevents kbconnpts kbfaq kbfile kbhowto kbsample KB194179 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 194179  (http://support.microsoft.com/kb/194179/en-us/ )