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





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