Bagikan melalui


Menggunakan IDispEventImpl

Saat menggunakan IDispEventImpl untuk menangani peristiwa, Anda harus:

  • Dapatkan kelas Anda dari IDispEventImpl.

  • Tambahkan peta sink peristiwa ke kelas Anda.

  • Tambahkan entri ke peta sink peristiwa menggunakan makro SINK_ENTRY atau SINK_ENTRY_EX .

  • Terapkan metode yang Anda minati untuk ditangani.

  • Beri saran dan batalkan penambahan sumber kejadian.

Contoh

Contoh di bawah ini menunjukkan cara menangani peristiwa yang DocumentChange diaktifkan oleh objek Aplikasi Word. Kejadian ini didefinisikan sebagai metode pada ApplicationEvents dispinterface.

Contohnya adalah dari sampel 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();
};

Contoh ini menggunakan #import untuk menghasilkan file header yang diperlukan dari pustaka jenis Word. Jika Anda ingin menggunakan contoh ini dengan versi Word lainnya, Anda harus menentukan file dll mso yang benar. Misalnya, Office 2000 menyediakan mso9.dll dan OfficeXP menyediakan mso.dll. Kode ini disederhanakan dari pch.h (stdafx.h di Visual Studio 2017 dan yang lebih lama):

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

Kode berikut muncul di NotSoSimple.h. Kode yang relevan dicatat oleh komentar:

// Note #import doesn't generate a LIBID (because we don't use 'named_guids')
// so we have to do it manually
namespace Word
{
   struct __declspec(uuid("00020905-0000-0000-C000-000000000046"))
      /* library */ Library;
};

class ATL_NO_VTABLE CNotSoSimple : 
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CNotSoSimple, &CLSID_NotSoSimple>,
   public IDispatchImpl<ISwitch, &IID_ISwitch, &LIBID_ATLEVENTHANDLINGLib>,
   // Note inheritance from IDispEventImpl
   public IDispEventImpl</*nID*/ 1, CNotSoSimple,
            &__uuidof(Word::ApplicationEvents2),
            &__uuidof(Word::Library), /*wMajor*/ 8, /*wMinor*/ 1>

{
public:
   CNotSoSimple()
   {
   }

DECLARE_REGISTRY_RESOURCEID(IDR_NOTSOSIMPLE)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CNotSoSimple)
   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("IDispEventImpl : Active Document Changed"), MB_OK);
   }

// Note the mapping from Word events to our event handler functions.
BEGIN_SINK_MAP(CNotSoSimple)
   SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Word::ApplicationEvents2), /*dispid =*/ 3, OnDocChange)
   SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Word::ApplicationEvents2), /*dispid =*/ 2, OnQuit)
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;
   }
};

Lihat juga

Penanganan Peristiwa
Sampel ATLEventHandling