lock-up catching excel events
-
I'm controlling excel from another app: create sheets, set ranges, modify properties and so on. Now, I've implemented an eventlistener like described as on the msdn-website, automation, creating our own IDispatch for catching events. The strange thing is that it handles pretty well events like WINDOW_ACTIVATE, SHEET_CALCULATE, ... if those things are modified from the outside-application. BUT if we select a range or double click on the sheet, excel blocks. Our app doesn't block, but it doesn't receive anymore events. We still can close excel though. Is this a common problem? Anybody solved it yet? Or where to look? initialising:
CEventsDispatch g_XLEventDispatch;
IConnectionPoint *m_pConnectionPoint;
DWORD m_adviseCookie;static const GUID IID\_IExcel8AppEvents = {0x00024413,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } }; HRESULT hr; IConnectionPointContainer \*pConnPtContainer; hr = m\_pXlApp->QueryInterface(IID\_IConnectionPointContainer,(void \*\*)&pConnPtContainer); if(hr!=0) return; hr = pConnPtContainer->FindConnectionPoint(IID\_IExcel8AppEvents,&m\_pConnectionPoint); if(hr!=0) return; hr = m\_pConnectionPoint->Advise(&g\_XLEventDispatch, &m\_adviseCookie); if(hr!=0) return; pConnPtContainer->Release();
our idispatch:
class CEventsDispatch : public IDispatch
{
public:
ULONG refCount;CEventsDispatch::CEventsDispatch() { refCount=1; } CEventsDispatch::~CEventsDispatch() { } 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 \*pVarR
-
I'm controlling excel from another app: create sheets, set ranges, modify properties and so on. Now, I've implemented an eventlistener like described as on the msdn-website, automation, creating our own IDispatch for catching events. The strange thing is that it handles pretty well events like WINDOW_ACTIVATE, SHEET_CALCULATE, ... if those things are modified from the outside-application. BUT if we select a range or double click on the sheet, excel blocks. Our app doesn't block, but it doesn't receive anymore events. We still can close excel though. Is this a common problem? Anybody solved it yet? Or where to look? initialising:
CEventsDispatch g_XLEventDispatch;
IConnectionPoint *m_pConnectionPoint;
DWORD m_adviseCookie;static const GUID IID\_IExcel8AppEvents = {0x00024413,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } }; HRESULT hr; IConnectionPointContainer \*pConnPtContainer; hr = m\_pXlApp->QueryInterface(IID\_IConnectionPointContainer,(void \*\*)&pConnPtContainer); if(hr!=0) return; hr = pConnPtContainer->FindConnectionPoint(IID\_IExcel8AppEvents,&m\_pConnectionPoint); if(hr!=0) return; hr = m\_pConnectionPoint->Advise(&g\_XLEventDispatch, &m\_adviseCookie); if(hr!=0) return; pConnPtContainer->Release();
our idispatch:
class CEventsDispatch : public IDispatch
{
public:
ULONG refCount;CEventsDispatch::CEventsDispatch() { refCount=1; } CEventsDispatch::~CEventsDispatch() { } 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 \*pVarR
After a few minutes, a messagebox comes up saying: "Microsoft excel is waiting for another application to complete an OLE action." I've implemented everything I've found on the msdn example (automating excel using vc++), so they must have forgotten something?
[VISUAL STUDIO 6.0] [MFC] [WIN98/2]
X| Bluute tette! X|
-
After a few minutes, a messagebox comes up saying: "Microsoft excel is waiting for another application to complete an OLE action." I've implemented everything I've found on the msdn example (automating excel using vc++), so they must have forgotten something?
[VISUAL STUDIO 6.0] [MFC] [WIN98/2]
X| Bluute tette! X|