Compartir a través de


Usar IDispEventSimpleImpl

Cuando use IDispEventSimpleImpl para controlar eventos, deberá hacer lo siguiente:

  • Derive la clase de IDispEventSimpleImpl.

  • Agregue un mapa receptor de eventos a la clase.

  • Defina las estructuras _ATL_FUNC_INFO que describen los eventos.

  • Agregue entradas al mapa del receptor de eventos mediante la macro SINK_ENTRY_INFO.

  • Implemente los métodos a los que le interesan en el control.

  • Aconsejar y desaconsejar el origen del evento.

Ejemplo

En el ejemplo siguiente se muestra cómo controlar el evento desencadenado por el DocumentChange objeto Aplicación de Word. Este evento se define como un método en el ApplicationEvents dispinterface.

El siguiente ejemplo es del ejemplo ATLEventHandling.

[ uuid(000209F7-0000-0000-C000-000000000046), hidden ]
dispinterface ApplicationEvents {
properties:
methods:
    [id(0x00000001), restricted, hidden]
    void Startup();

    [id(0x00000002)]
    void Quit();

    [id(0x00000003)]
    void DocumentChange();
};

En el ejemplo se usa #import para generar los archivos de encabezado necesarios de la biblioteca de tipos de Word. Si desea usar este ejemplo con otras versiones de Word, debe especificar el archivo mso dll correcto. Por ejemplo, Office 2000 proporciona mso9.dll y OfficeXP mso.dll. Este código se simplifica desde pch.h (stdafx.h en Visual Studio 2017 y versiones anteriores):

#pragma warning (disable : 4146)

// Paths to required MS OFFICE files (replace "MSO.DLL" and "MSWORD.OLB" with the actual paths to those files...)
#define _MSDLL_PATH "MSO.DLL"
// Delete the *.tlh files when changing import qualifiers
#import _MSDLL_PATH rename("RGB", "MSRGB") rename("DocumentProperties", "WordDocumentProperties") raw_interfaces_only

#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" raw_interfaces_only

#define _MSWORDOLB_PATH "MSWORD.OLB"
#import _MSWORDOLB_PATH rename("ExitWindows", "WordExitWindows") rename("FindText", "WordFindText") raw_interfaces_only

#pragma warning (default : 4146)

La única información de la biblioteca de tipos que se usa en este ejemplo es el CLSID del objeto de Word Application y el IID de la interfaz ApplicationEvents. Esta información solo se usa en el momento de la compilación.

El código siguiente aparece en Simple.h. Los comentarios indican el código correspondiente:

// Note declaration of structure for type information
extern _ATL_FUNC_INFO OnDocChangeInfo;
extern _ATL_FUNC_INFO OnQuitInfo;

class ATL_NO_VTABLE CSimple : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CSimple, &CLSID_Simple>,
   public IDispatchImpl<ISwitch, &IID_ISwitch, &LIBID_ATLEVENTHANDLINGLib>,
   // Note inheritance from IDispEventSimpleImpl
   public IDispEventSimpleImpl</*nID =*/ 1, CSimple, &__uuidof(Word::ApplicationEvents)>
{
public:
   CSimple()
   {
   }

DECLARE_REGISTRY_RESOURCEID(IDR_SIMPLE)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSimple)
   COM_INTERFACE_ENTRY(ISwitch)
   COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

   CComPtr<Word::_Application> m_pApp;

   // Event handlers
   // Note the __stdcall calling convention and 
   // dispinterface-style signature
   void __stdcall OnQuit()
   {
      Stop();
   }

   void __stdcall OnDocChange()
   {
     ATLASSERT(m_pApp != NULL);

      // Get a pointer to the _Document interface on the active document
      CComPtr<Word::_Document> pDoc;
      m_pApp->get_ActiveDocument(&pDoc);

      // Get the name from the active document
      CComBSTR bstrName;
     if (pDoc)
      pDoc->get_Name(&bstrName);

      // Create a display string
      CComBSTR bstrDisplay(_T("New document title:\n"));
      bstrDisplay += bstrName;

      // Display the name to the user
      USES_CONVERSION;
      MessageBox(NULL, W2CT(bstrDisplay), _T("IDispEventSimpleImpl : Active Document Changed"), MB_OK);
   }

// Note the mapping from Word events to our event handler functions.
BEGIN_SINK_MAP(CSimple)
   SINK_ENTRY_INFO(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 3, OnDocChange, &OnDocChangeInfo)
   SINK_ENTRY_INFO(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 2, OnQuit, &OnQuitInfo)
END_SINK_MAP()

// ISwitch
public:
   STDMETHOD(Start)()
   {
      // If we already have an object, just return
      if (m_pApp)
         return S_OK;
      
      // Create an instance of Word's Application object
      HRESULT hr = m_pApp.CoCreateInstance(__uuidof(Word::Application), NULL, CLSCTX_SERVER);
     if (FAILED(hr))
        return hr;

     ATLASSERT(m_pApp != NULL);

      // Make the Word user interface visible
      m_pApp->put_Visible(true);

      // Note call to advise
      // Forge a connection to enable us to receive events
      DispEventAdvise(m_pApp);

      return S_OK;
   }

   STDMETHOD(Stop)()
   {
      // Check we have an object to unadvise on
      if (!m_pApp)
         return S_OK;

      // Note call to unadvise
      // Break the connection with the event source
      DispEventUnadvise(m_pApp);

      // Release the Word application
      m_pApp.Release();

      return S_OK;
   }
};

El código siguiente procede de Simple.cpp:

// Define type info structure
_ATL_FUNC_INFO OnDocChangeInfo = {CC_STDCALL, VT_EMPTY, 0};
_ATL_FUNC_INFO OnQuitInfo = {CC_STDCALL, VT_EMPTY, 0};
// (don't actually need two structure since they're the same)

Consulte también

Control de eventos
Ejemplo ATLEventHandling