When using IDispEventImpl to handle events, you will need to:
Example
The example below shows you how to handle the DocumentChange event fired by Word's Application object. This event is defined as a method on the ApplicationEvents dispinterface:
[
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();
};
The example uses #import to generate the required header files from Word's type library:
#pragma warning (disable : 4146)
#import "C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\MSO97.DLL" raw_interfaces_only
#import "C:\PROGRAM FILES\COMMON FILES\MICROSOFT SHARED\VBA\VBEEXT1.OLB" raw_interfaces_only
#import "C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\MSWORD8.OLB" rename("ExitWindows", "WordExitWindows") raw_interfaces_only
#pragma warning (default : 4146)
The following code appears in NotSoSimple.h. The relevant code is in bold:
// #import doesn't generate a LIBID (since 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_DISPEVENTLib>,
public IDispEventImpl</*nID*/ 1, CNotSoSimple,
&__uuidof(Word::ApplicationEvents),
&__uuidof(Word::Library), /*wMajor*/ 8, /*wMinor*/ 0>
{
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 handler
// Note the __stdcall calling convention and
// dispinterface-style signature
void __stdcall OnDocChange()
{
// 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;
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("Active Document Changed"), MB_OK);
}
BEGIN_SINK_MAP(CNotSoSimple)
SINK_ENTRY_EX(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 3, OnDocChange)
END_SINK_MAP()
// ISwitch
public:
STDMETHOD(Start)()
{
// If you already have an object, just return
if (m_pApp)
return S_OK;
// Create an instance of Word's Application object
m_pApp.CoCreateInstance(__uuidof(Word::Application), NULL, CLSCTX_SERVER);
// Make the Word user interface visible
m_pApp->put_Visible(true);
// Forge a connection to enable you to receive events
DispEventAdvise(m_pApp);
return S_OK;
}
STDMETHOD(Stop)()
{
// Check you have an object to unadvise on
if (!m_pApp)
return S_OK;
// Break the connection with the event source
DispEventUnadvise(m_pApp);
// Release the Word application
m_pApp.Release();
return S_OK;
}
};
See Also