PSS ID Number: 186427
Article Last Modified on 5/21/2003
183599 HOWTO: Catch Microsoft Word97 Application Events Using VC++
COleDispatchDriver m_app;
IConnectionPoint *m_pConnectionPoint;
DWORD m_adviseCookie;
// Check to see if you've already started the server.
if(m_app.m_lpDispatch != NULL) {
AfxMessageBox("Server already started.");
return;
}
char buf[256]; // General purpose buffer.
// Start the Automation server.
COleException e;
if(!m_app.CreateDispatch("Excel.Application", &e)) {
sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",
e.m_sc, e.m_sc);
AfxMessageBox(buf, MB_SETFOREGROUND);
return;
}
// Make the 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 you want to catch.
// {00024413-0000-0000-C000-000000000046}
static const GUID IID_IExcel8AppEvents =
{0x00024413,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } };
// Steps for setting up events:
// 1. Get server's IConnectionPointContainer interface.
// 2. Call IConnectionPointContainer::FindConnectionPoint()
// to find the event you want to catch.
// 3. Call IConnectionPoint::Advise() with the IUnknown
// interface of your 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 the connection point for events you're interested in.
hr = pConnPtContainer->FindConnectionPoint(
IID_IExcel8AppEvents,
&m_pConnectionPoint
);
ASSERT(!FAILED(hr));
// Setup advisory connection.
hr = m_pConnectionPoint->Advise(&g_XLEventDispatch, &m_adviseCookie);
ASSERT(!FAILED(hr));
// Release IConnectionPointContainer interface.
pConnPtContainer->Release();
// Check whether you've started the server.
if(m_app.m_lpDispatch == NULL) {
AfxMessageBox("You haven't started the server yet.");
return;
}
m_pConnectionPoint->Unadvise(m_adviseCookie);
m_pConnectionPoint->Release(); //don't forgot to release pointer
// Tell the 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 the application object.
m_app.ReleaseDispatch();
//=============================================================
//=============================================================
// A simple IDispatch implementation to catch Excel's events.
class CMyEventDispatch : public IDispatch
{
public:
ULONG refCount;
CMyEventDispatch::CMyEventDispatch() {
refCount = 1;
}
CMyEventDispatch::~CMyEventDispatch() {
}
// IUnknown methods.
virtual HRESULT __stdcall QueryInterface(
REFIID riid, void **ppvObject) {
if(
IsEqualGUID(riid, IID_IDispatch) ||
IsEqualGUID(riid, IID_IUnknown)
) {
this->AddRef();
*ppvObject = this;
return S_OK;
}
*ppvObject = NULL;
return E_NOINTERFACE;
}
virtual ULONG _stdcall AddRef(void) {
return ++refCount;
}
virtual ULONG _stdcall Release(void) {
if(--refCount <= 0) {
//Delete this;
return 0;
}
return refCount;
}
// IDispatch methods.
virtual HRESULT _stdcall GetTypeInfoCount(UINT *pctinfo) {
if(pctinfo) *pctinfo = 0;
return E_NOTIMPL;
}
virtual HRESULT _stdcall GetTypeInfo(
UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) {
return E_NOTIMPL;
}
virtual HRESULT _stdcall GetIDsOfNames(
REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid,
DISPID *rgDispId) {
return E_NOTIMPL;
}
virtual HRESULT _stdcall Invoke(
DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr) {
char *ptr = "Unknown-Event";
switch(dispIdMember) {
case 0x61d: ptr = "NewWorkbook"; break;
case 0x616: ptr = "SheetSelectionChange"; break;
case 0x617: ptr = "SheetBeforeDoubleClick"; break;
case 0x618: ptr = "SheetBeforeRightClick"; break;
case 0x619: ptr = "SheetActivate"; break;
case 0x61a: ptr = "SheetDeactivate"; break;
case 0x61b: ptr = "SheetCalculate"; break;
case 0x61c: ptr = "SheetChange"; break;
case 0x61f: ptr = "WorkbookOpen"; break;
case 0x620: ptr = "WorkbookActivate"; break;
case 0x621: ptr = "WorkbookDeactivate"; break;
case 0x622: ptr = "WorkbookBeforeClose"; break;
case 0x623: ptr = "WorkbookBeforeSave"; break;
case 0x624: ptr = "WorkbookBeforePrint"; break;
case 0x625: ptr = "WorkbookNewSheet"; break;
case 0x626: ptr = "WorkbookAddinInstall"; break;
case 0x627: ptr = "WorkbookAddinUninstall"; break;
case 0x612: ptr = "WindowResize"; break;
case 0x614: ptr = "WindowActivate"; break;
case 0x615: ptr = "WindowDeactivate"; break;
}
MessageBox(NULL, ptr, "Event was fired!!!", MB_SETFOREGROUND);
return S_OK;
}
};
CMyEventDispatch g_XLEventDispatch;
//=============================================================
//=============================================================
// 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;
183599 HOWTO: Catch Microsoft Word97 Application Events Using VC++
181845 HOWTO: Create a Sink Interface in MFC-Based COM Client
152087 SAMPLE: Connpts.exe Implements Connection Points in MFC Apps
Keywords: kbAutomation kbFAQ kbhowto kbinterop KB186427
Technology: kbAudDeveloper kbExcel2000 kbExcel2000Search kbExcel2002 kbExcel2002Search kbExcel97Search kbExcelSearch kbExcelWinSearch kbOffice2000 kbOffice2000DevSearch kbOffice2000Search kbOfficeSearch kbOfficeXP kbOfficeXPDevSearch kbOfficeXPSearch kbVC32bitSearch kbVC500 kbVC500Search kbVC600 kbVCsearch kbZNotKeyword3