When using IDispEventSimpleImpl 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 only information from the type library actually used in this example is the CLSID of the Word Application object and the IID of the ApplicationEvents interface. This information is only used at compile time.
The following code appears in Simple.h. The relevant code is in bold:
// Declare structure for type information
extern _ATL_FUNC_INFO OnDocChangeInfo;
class ATL_NO_VTABLE CSimple :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CSimple, &CLSID_Simple>,
public IDispatchImpl<ISwitch, &IID_ISwitch, &LIBID_DISPEVENTLib>,
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 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(CSimple)
SINK_ENTRY_INFO(/*nID =*/ 1, __uuidof(Word::ApplicationEvents), /*dispid =*/ 3, OnDocChange, &OnDocChangeInfo)
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;
}
};
The following code is from Simple.cpp:
// Define type info structure
_ATL_FUNC_INFO OnDocChangeInfo = {CC_STDCALL, VT_EMPTY, 0};
See Also