Freigeben über


Verwenden von IDispEventSimpleImpl

IDispEventSimpleImpl Wenn Sie Ereignisse behandeln, müssen Sie Folgendes ausführen:

  • Leiten Sie Ihre Klasse von IDispEventSimpleImpl ab.

  • Fügen Sie ihrer Klasse eine Ereignissenkenzuordnung hinzu.

  • Definieren Sie _ATL_FUNC_INFO Strukturen, die die Ereignisse beschreiben.

  • Fügen Sie der Ereignissenkenzuordnung Einträge mithilfe des SINK_ENTRY_INFO Makros hinzu.

  • Implementieren Sie die Methoden, die Sie behandeln möchten.

  • Empfehlen und Aufheben der Veröffentlichung der Ereignisquelle.

Beispiel

Das folgende Beispiel zeigt, wie Sie das ereignis behandeln, das DocumentChange vom Application-Objekt von Word ausgelöst wird. Dieses Ereignis wird als Methode für die ApplicationEvents dispinterface definiert.

Das Beispiel stammt aus dem ATLEventHandling-Beispiel.

[ 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();
};

Im Beispiel werden #import die erforderlichen Headerdateien aus der Typbibliothek von Word generiert. Wenn Sie dieses Beispiel mit anderen Word-Versionen verwenden möchten, müssen Sie die richtige MSO-DLL-Datei angeben. Beispielsweise stellt Office 2000 mso9.dll und OfficeXP mso.dll bereit. Dieser Code wird von pch.h (stdafx.h in Visual Studio 2017 und früher vereinfacht):

#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)

Die einzigen Informationen aus der Typbibliothek, die tatsächlich in diesem Beispiel verwendet werden, sind die CLSID des Word-Objekts Application und die IID der ApplicationEvents Schnittstelle. Diese Informationen werden nur zur Kompilierungszeit verwendet.

Der folgende Code wird in "Simple.h" angezeigt. Der relevante Code wird durch Kommentare notiert:

// 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;
   }
};

Der folgende Code stammt aus 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)

Siehe auch

Ereignisbehandlung
ATLEventHandling-Beispiel