|
I've a question about this example: It opens excel and inserts an eventsink to catch the events inside excel.
HOWTO: Catch Microsoft Excel Application Events Using VC++ Q186427
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q186427
I've tried this example using an MFC-EXE, and all works fine. When you press start, the excel application shows up. Clicking with the mouse results in a event messagebox.
But, if you want to include this functionality inside an MFC-DLL, it will not work. Excel shows up alright, but when you click something or press a button, the excel application will block. After a while a messagebox shows up saying: "Microsoft Excel is waiting for another application to complete an OLE action."
Short: using a .exe works fine, but the .dll blocks.
Why?
What's the difference here? (I've used MFC in both cases)
[VISUAL STUDIO 6.0] [MFC] [WIN98/2]
Bluute tette!
|
|
|
|
|
must do:
while(GetMessage())
DispatchMessage();
soptest
|
|
|
|
|
Hello,
I have a problem, the CoCreateInstance of some COM object that is in DLL, fails every two or three times.
I kill all processes involved, and then reload.
it tells me that interlocked increment has failed
any hint to how it might be traced out and eliminated?
thanks
s.
|
|
|
|
|
ATL has some macros that help you trace your problem:
_ATL_DEBUG_REFCOUNT
_ATL_DEBUG_QI
_ATL_DEBUG_INTERFACES
Read the following article in MSDN:
"Debugging Tips for ATL Objects".
Goodluck,
Dudi
|
|
|
|
|
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)
{
return 0;
}
return refCount;
}
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)
{
return S_OK;
}
};
[VISUAL STUDIO 6.0] [MFC] [WIN98/2]
Bluute tette!
|
|
|
|
|
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]
Bluute tette!
|
|
|
|
|
Try :
while(GetMessage())
DispatchMessage();
in your thread.
soptest
|
|
|
|
|
Does anyone know how to properly marshal the data from legacy app to
a .Net component? The legacy app uses the following IDL interface
definition:
interface IMyInterface2 : IUnknown
{
HRESULT doit( [in, size_is(msgLength)]UCHAR* msg, [in] ULONG
msgLength );
};
When my legacy COM Client calls my .Net component that implements this
interface, an access violation (0xC0000005) exception is thrown. I've
tried everything and can not figure out why the exception is thrown in
the
COM Client.
Here is the COM Client:
#include "stdafx.h"
#include "IMyInterface2_h.h"
#include "IMyInterface2_i.c"
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = ::CoInitialize( NULL );
CLSID rcid = { 0x5F850215, 0x7AC2, 0x48b8, { 0xA8, 0xCF, 0xA0, 0x08,
0xF7, 0x33, 0xD6, 0x61 } };
{
CComPtr<imyinterface2> iMyInterface2;
hr = iMyInterface2.CoCreateInstance( rcid, NULL, CLSCTX_INPROC_SERVER
);
UCHAR* pBytes = (UCHAR*)::CoTaskMemAlloc( 20 );
::ZeroMemory( pBytes, 20 );
iMyInterface2->doit( pBytes, 20 );
}
::CoUninitialize();
return 0;
}
The exception is thrown on the statement:
iMyInterface2->doit( pBytes, 20 );
The call never gets to the .Net component's method
And here is the .Net service component. The .Net component must be
copied in the same directory as the COM client.
using System;
using System.Runtime.InteropServices;
namespace ComSrv
{
[GuidAttribute("5F850215-7AC2-48b8-A8CF-A008F733D661")]
public class MyClass : IMyInterface2
{
public void doit( byte[] msg, ulong msgLength )
{
}
}
[ComImport]
[GuidAttribute("B55AFAEB-BC7D-4ca9-8065-F9A45FE378B6")]
[InterfaceTypeAttribute
ComInterfaceType.InterfaceIsIUnknown)]
public interface IMyInterface2
{
void doit(
[In, MarshalAs( UnmanagedType.LPArray,
SizeParamIndex=1, ArraySubType=UnmanagedType.U1 )]byte[]
msg, [In]ulong msgLength );
}
}
|
|
|
|
|
I have an application that is a MFC-based COM object that opens MS Word and opens a word document. I have added a custom button ontot he MS Word toolbar to the MS Word toolbar so that if the user hits this button, the document will be saved and MS Word will close down. Unfortunately, I do not know how to catch the event that my button has been pressed. I have looked and looked and looked and all the info I can find deals with sinking events and an ATL server. I did not create this as an ATL server and most of the information I can find deals with an ATL server. I need help badly, I am clueless as to how to continue. Can anybody help? How do I catch the event that my button has been pressed? Am I going to have to convert it to an ATL server and if so, how do I go about doing that?
PLEASE HELP!!!
|
|
|
|
|
On the topic of sinking events, please take a look here. The project contains code that sinks events to a custom toolbar created thru an Office addin. Ofcourse it is a pure ATL project.
HTH,
You yard yellow years yieldingly; you yanked your yearning yoke.-Jeremy Falcon-CPite.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
I have tried to implement something like that, using MSWord in place of Outlook and I cannot get it to work. It keeps giving me Link Errors because of duplicate IID_XXXX's. How do I get around this if I were to use pure ATL?
|
|
|
|
|
Try out various #import options keywords like no_namespace, rename etc to resolve link problem.
|
|
|
|
|
Could you be a little specific and tell me what are the errors?
|
|
|
|
|
Yeah, I came across a similar duplicate IID problem while building Word addin. I know how frustrating this is!!
If you already haven't figured out, the solution is to move the #import statement for importing Word typelib(the 2nd #import) to your addins .h file.
e.g. I put the following #imports in my Addin.h file. so it looks like :
#ifndef __ADDIN_H_
#define __ADDIN_H_
#include "resource.h" // main symbols
#import "D:\Program Files\Common Files\designer\MSADDNDR.TLB" raw_interfaces_only, raw_native_types, no_namespace, named_guids
#import "D:\Program Files\Microsoft Office\Office\MSWORD9.olb" rename_namespace("MSWORD"), rename("ExitWindows","WordExitWindows"), named_guids, raw_interfaces_only
using namespace MSWORD;
and then rebuild.
HTH,
'My capacity for happiness', he added, 'you could fit into a matchbox without taking out the matches first'.
- Marvin, the robot.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|
Hi,
I have a very simple program that is going to use ADO as the interface to a database.
I imported ADO in a wrapper class using the following line:
#import "C:\Program Files\Common Files\System\Ado\msado15.dll" no_namespace rename("EOF", "adoEOF")
My code to connect to the selected database looks like:
try
{
m_objConn.CreateInstance(__uuidof(Connection));
m_objConn->Open(strConn, strUser, strPass, m_lngConnOptions);
}
catch(_com_error &errConn)
{
m_strLastError = (char *) errConn.Description();
m_objConn = NULL;
}
If everything is fine so ADO can connect all is good.
However, when the connection fails (for any reason, such as bad connection string, DSN doesn't exist etc), I get the following error:
First-chance exception in MyDBApp.exe (MSVCRTD.DLL): 0xE06D7363: Microsoft C++ Exception.
I traced through the code, into the import .tli/.tlh file and the exception occurs in the call (or around the call) to _com_issue_errorex(...).
Has anyone ever encountered a problem with COM error handling like this before? If so, what is the solution, because so far the problem seems to lie with COM/ADO, not my application.
Under debug, the code continues, under release, it invalid page faults.
Please help!
Thanks in advance,
Simon
|
|
|
|
|
This is perfectly normal. Anytime an exception is raised, you will get some type of "First-chance exception" message. The rest of the message is just saying that it is a C++ exception (the _com_issue_errorex).
You catch statement will catch the error and you can process it and handle it.
Don't worry about first-chance exceptions that you are handling properly.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Tim,
Thanks for the response. I was obviously getting silly and became side-tracked by the (handled) unhandled exception!
However, my crash under release remains. Not sure if you can help, but I tracked it down to a worker thread using a window pointer to send a message (using SendMessage). After peeking in the documentation (I have little threading knowledge), it says windows handles are unreliable.
If this is the case, how can my thread tell the child frame it is running in that it has completed?
Thanks for any help,
Simon
|
|
|
|
|
You should be able to use the REAL window handle (as in HWND). Windows is smart enough, to thunk the SendMessage over to the proper thread. It is just that you can't use CWnd points.
One thing you can do is build your release build with debug information. This will allow you to run the optimized code in the debugger. Looking at local variables will be very hit or miss (and sometimes will just flat out tell you the wrong thing), but it might help to track down the problem.
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
I am developing an application which need to pass an
array from a com+ object to the client,the object runs at
the server and the client app runs at a workstation.the
problem is i can't get the actual array at the client's
side.
some represetative code follows:
//.idl
[id(15), helpstring("method GetAllPolicyID")] HRESULT
GetAllPolicyID([in,out]long* size,[out,size_is(,*size)]
long** PolicyID);
//.cpp
*size=pRst->RecordCount;
*PolicyID=(ULONG*)CoTaskMemAlloc(*size*sizeof(ULONG));
for(long i=0;i<*size;i++)
{
if(!pRst->adoEOF)
{
vt=pRst->GetCollect("POLICYID");
(*PolicyID)[i]=vt.lVal;
pRst->MoveNext();
}
}
Scratch
|
|
|
|
|
You must produce a proxy-stub DLL by compiling and linking the C files produced by MIDL. The ATL AppWizard produces a make file called projectps.mk to do this. You must make sure that your server does not register its component's interfaces as type library marshaled with the automation marshaler because automation does not recognize the array attributes. (marshaling done by custom marshaler in your proxy/stub DLL)
soptest
|
|
|
|
|
Thank for your help!
And how to avoid registerring the interfaces as automation marshaler?
Scratch
|
|
|
|
|
Hi there,
I have a simple ATL project (with MFC support) as generated by the wizard. I have a simple ATL object created, with nothing changed in the settings presented by the ATL wizard dialog box.
This object has "Start()" and "Stop()" methods which work fine when I test them in a VB app.
What I would LIKE to do now is be able to fire an event (is this correct terminology?), so that when in VB a subprocedure will run/fire when something in my COM dll decides it should.
How do I set about doing this?
TIA
Jason
|
|
|
|
|
Hi,
I think you might find the article here an interesting read.
sonork: 100:18407
You yard yellow years yieldingly; you yanked your yearning yoke.
-Jeremy Falcon
|
|
|
|
|
Thanks Jeremy. I appreciate your feedback, but the article appears to explain the reverse of what I want to do. I need to teach my ATL object to raise an even for VB, not the other way around.
Jason
|
|
|
|
|
Hi Jason,
One cheap trick(and saving yourself a lot of heartache ) would be to rig up a method in your VB module that uses the RaiseEvent keyword to fire your event. You could then simply call this VB method from your VC component or client after you instantiate the object.
You yard yellow years yieldingly; you yanked your yearning yoke.-Jeremy Falcon-CPite.
Amit Dey
sonork: 100:18407
msn: visualcdev
|
|
|
|
|