HOWTO: Catch Microsoft Word97 Application Events Using VC++ID: Q183599
|
This article demonstrates how to catch Microsoft Word 97 application events using Microsoft Visual C++. However, the concepts and code in this article are not specific to Microsoft Word; they are applicable to the entire suite of Microsoft Office applications, as well as any other applications that expose events.
The following steps illustrate how to create an MFC application that catches the Microsoft Word 97 Application events Startup(), DocumentChange(), and Quit():
// Check to see if we've already started the server.
if(m_app.m_lpDispatch != NULL) {
AfxMessageBox("Server already started.");
return;
}
char buf[256]; // General purpose buffer.
// Start Automation server.
COleException e;
if(!m_app.CreateDispatch("Word.Application.8", &e)) {
sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",
e.m_sc, e.m_sc);
AfxMessageBox(buf, MB_SETFOREGROUND);
return;
}
// Make server visible through automation.
// I.e.: Application.Visible = TRUE
DISPID dispID;
unsigned short *ucPtr;
BYTE *parmStr;
ucPtr = L"visible";
m_app.m_lpDispatch->GetIDsOfNames(
IID_NULL, &ucPtr, 1, LOCALE_USER_DEFAULT, &dispID
);
parmStr = (BYTE *)( VTS_VARIANT );
m_app.InvokeHelper(
dispID, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, VT_EMPTY,
NULL, parmStr, &COleVariant((short)TRUE)
);
// Declare the events we want to catch.
// {000209F7-0000-0000-C000-000000000046}
static const GUID IID_IWord8AppEvents =
{0x000209f7,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } };
// Steps for setting up events.
// 1. Get server's IConnectionPointContainer interface.
// 2. Call IConnectionPointContainerFindConnectionPoint()
// to find the event we want to catch.
// 3. Call IConnectionPoint::Advise() with the IUnknown
// interface of our implementation of the events.
HRESULT hr;
// Get server's IConnectionPointContainer interface.
IConnectionPointContainer *pConnPtContainer;
hr = m_app.m_lpDispatch->QueryInterface(
IID_IConnectionPointContainer,
(void **)&pConnPtContainer
);
ASSERT(!FAILED(hr));
// Find connection point for events we're interested in.
hr = pConnPtContainer->FindConnectionPoint(
IID_IWord8AppEvents,
&m_pConnectionPoint
);
ASSERT(!FAILED(hr));
// Get the IUnknown interface of our event implementation.
LPUNKNOWN pUnk = m_myEventSink.GetInterface(&IID_IUnknown);
ASSERT(pUnk);
// Setup advisory connection!
hr = m_pConnectionPoint->Advise(pUnk, &m_adviseCookie);
ASSERT(!FAILED(hr));
// Release IConnectionPointContainer interface.
pConnPtContainer->Release();
// Check if we've started the server.
if(m_app.m_lpDispatch == NULL) {
AfxMessageBox("You haven't started the server yet.");
return;
}
m_pConnectionPoint->Unadvise(m_adviseCookie);
// Tell server to quit.
// Application.Quit()
DISPID dispID; // Temporary DISPID
unsigned short *ucPtr; // Temporary name holder
ucPtr = L"quit";
m_app.m_lpDispatch->GetIDsOfNames(
IID_NULL, &ucPtr, 1, LOCALE_USER_DEFAULT, &dispID
);
m_app.InvokeHelper(dispID, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
// Release application object.
m_app.ReleaseDispatch();
void Startup()
void Quit()
void DocumentChange()
void MyEventSink::Startup()
{
AfxMessageBox("MyEventSink::Startup() called.");
}
void MyEventSink::Quit()
{
AfxMessageBox("MyEventSink::Quit() called.");
}
void MyEventSink::DocumentChange()
{
AfxMessageBox("MyEventSink::DocumentChange() called.");
}
COleDispatchDriver m_app;
IConnectionPoint *m_pConnectionPoint;
DWORD m_adviseCookie;
MyEventSink m_myEventSink;
#include "MyEventSink.h"
// Implementation
protected:
virtual ~MyEventSink();
virtual ~MyEventSink();
// Implementation
protected:
// virtual ~MyEventSink(); // Or this line may be removed.
// Ole-initialization class.
class OleInitClass {
public:
OleInitClass() {
OleInitialize(NULL);
}
~OleInitClass() {
OleUninitialize();
}
};
// This global class calls OleInitialize() at
// application startup, and calls OleUninitialize()
// at application exit.
OleInitClass g_OleInitClass;
For more information about creating sink interfaces, and simplifying the
connection process, see the following article in the Microsoft Knowledge
Base:
For more information about how to catch events in Microsoft Excel, see the
following article in the Microsoft Knowledge Base:
Q186427 HOWTO: Catch Microsoft Excel Application Events Using VC++
Q181845 HOWTO: Create a Sink Interface in MFC-Based COM ClientFor a general example of, and more information about, connection points, see the Connpts.exe sample described in the following article in the Microsoft Knowledge Base:
Q152087 SAMPLE: Connpts.exe Implements Connection Points in MFC Apps(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Joe Crump, Microsoft Corporation
Additional query words: IConnectionPointContainer IConnectionPoint advise IAdviseSink coclass dispinterface sink
Keywords : kbcode kbinterop kbole kbAutomation kbMFC kbVC500 kbVC600 kbWord kbGrpDSO kbOffice2000
Version : WINDOWS:97; winnt:5.0,6.0
Platform : WINDOWS winnt
Issue type : kbhowto
Last Reviewed: June 3, 1999