Главная страница | назад





Article #19622: OLE exceptions

 Question and Answer Database
FAQ: FAQ4622C — OLE exceptions
Category: ActiveX/OLE/COM/ActiveForm
Platform: All-32Bit
Product: C++Builder4.x,
Question:
I have a DLL containing COM objects written in VisC++ 6,
which return rich error information via IErrorInfo.
I have imported my type library into both C++ Builder 4
and Delphi 4, and have found an inconsistency.
In Delphi, i deliberately call a method of one of my COM
objects with arguments which will force an error.
Delphi succesfully catches this exception in a catch block
as an EOleException, ie:
var
myObj : IMyObject;
begin
try
myObj := CoMyObject.Create;
myObj.Load(1,1,1); // this will return E_FAIL and some rich error
information
except
on e : EOleException do
MessageDlg(e.Message,mtWarning,[mbOk],0); // message displays ok
end;
end;
.. however I do the equivalent in C++ Builder4, and the
exception is never thrown. CB4 simply returns an HRCHECK
failed message, but then carries on executing ie:
CoMyObject oMyObject;
TCOMIMyObject pIMyObject = oMyObject.Create();
try
{
pIMyObject->Load(1,1,1);
}
catch(EOleException *e)
{
ShowMessage(e->Message);
}
Why does is the exception not thrown is C++ Builder?????
Answer:
Server Support for Rich Error Information
===============================
ATL exposes overloaded versions of Error(...) that provide the support on
the server side. And we already generate code that uses that support. The
typical C++Builder Server implementation method looks as follows:
STDMETHODIMP TCoClassNameImpl::MethodName(...)
{
try
{
// Do something here
}
catch(Exception &e)
{
// << This sets Rich Error Information — see ComCoClass<>::Error()
return Error(e.Message.c_str(), IID_ICoClassName);
}
return S_OK;
}
We expect Server builders to enhance the call to Error(..) to use the full
functionality exposed by the various/overload ATL's ComCoClass<>::Error()
methods. The wizard cannot fill in the additional information but the
programmer of the Server simply needs to tweak the Error(..) call to pass
additional information to the client.
[NOTE: Comobj::HandleSafeCallException provides similar support in a more
VCL-ish way]
Client Support for Rich Error Information
===============================
Client side support is harder to access: System.hpp exposes a pointer,
SafeCallErrorProc, that maps to Comobj's SafeCallError(). The latter handles
the Client side of retrieving the IErrorInfo, loading an EOleException
instance with the error information, and raising an exception. We *don't*
expect Client builders to access 'SafeCallErrorProc' because System.hpp
exposes it as an opaque pointer. In Delphi this function is invoked behind
the scene by the code generated by the compiler when one invokes a SafeCall
method. In C++ we would wrap calls to __stdcall methods to jump to
SafeCallErrorProc automatically if the call fails.
8/4/99 11:49:28 AM

Last Modified: 01-SEP-99