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?????
Thanks
Simon
This is built into the exception handling of the Delphi language so it is
seamless. On the C++ side you must handle and raise it explicitly.
Here is an example of raising it on the Server side.
STDMETHODIMP TMTSFoo1Impl::Method1()
{
IErrorInfo *errorInfo;
ICreateErrorInfo *createErrorInfo;
if (SUCCEEDED(CreateErrorInfo(&createErrorInfo)))
{
createErrorInfo->SetGUID(IID_IMTSFoo1);
createErrorInfo->SetSource(WideString("MTSProj1.MTSFoo1").Detach());
createErrorInfo->SetDescription(WideString("I raised an
error").Detach());
if (SUCCEEDED(createErrorInfo->QueryInterface(IID_IErrorInfo,
(void**)&errorInfo)))
{
SetErrorInfo(0, errorInfo);
createErrorInfo->Release();
errorInfo->Release();
}
}
return E_UNEXPECTED;
}
Here is an example of the cllient handling IErrorInfo.
if (!(SUCCEEDED(Test.Method1())))
{
IErrorInfo *errorInfo;
wchar_t *ErrorMessage;
if (SUCCEEDED(GetErrorInfo(0, &errorInfo)))
{
errorInfo->GetDescription(&ErrorMessage);
ShowMessage("Client " + AnsiString(ErrorMessage));
errorInfo->Release();
}
SysFreeString(ErrorMessage);
}
Hope this helps,
//jt
The failure here was the result of whether or not OLE clients should assume
VCL usage. Back in the early phase of the project, there was a big push to
have light-weight ActiveX support. Among other things, that meant not
requiring VCL in Auto/COM servers and ActiveX Clients accessing these. I
should add that this push was triggered by COM/Internet/ATL/VC5 etc.
So early on we opted to refrain from using VCL types whenever possible. This
meant that we would not pull in the VCL exception hierarchy. As the project
moved along several issues took place that lighten the light-weight issue
but nothing was definite. Net result: we left the exception issue open. I
intentionally made sure to mode the code from .CPP to a template in a header
(UTILCLS.H) so that we could update this easily without re-deploying new
libraries/packages etc.
I have a version of UTILCLS.H that throws the VCL exception. I cannot commit
that that's the route we'll take eventually. However, I'll be happy to make
the file available. I've also asked our management team to give me a feel
for the importance of light-weight, VCL-less ActiveX projects.
I hope the above explains the issue a little. I wished we had made a firmer
decision but... I don't want to complicate matters but we also wanted to see
how well #import is adopted. The exception thrown there is _com_error. Any
feedback on this and all the related items mentioned above is welcome.
Regards,
Bruneau.
Simon Gibbs wrote in message <7i3nv1$ja...@forums.borland.com>...
>Hi
>
>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:
>
Martin
PS Your presence on this newsgroup is really terrific. Thanks for your
efforts.
Thank you for the feedback. I'm relaying your message to the
decision-makers. I think I should put together some key questions that will
help us decide how to proceed (both regarding fixes and improvements). I've
mentioned that we will soon have a patch available. This will contain a few
enhancements too. However, I've refrained from enhancements that tie us
regarding issues of light-weight, Client wrappers (TLIBIMP style vs. the
relatively new #import VC style). One big issue for me is to understand
whether our users need better Client or Server support. From scanning this
forum, it seems to me, for example, that no one is using the
VCLControl->ActiveXControl feature. ActiveForm is well used but not the
other TWinControl-widgets-exposed-as-OCX. If that's the case, I want to
relay this to management and suggest not spending any resources on this area
(safe for bug fixes).
Thank you again. I'll start thinking about formulating the 'right' questions
and post a Survey on the newsgroup.
Regards,
Bruneau.
Martin Tarlie wrote in message <7i4aq6$jo...@forums.borland.com>...
Thank you for posting the low-level code. I wanted to add that similar
routines are already accessible/encapsulated in our libraries.
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)
{
return Error(e.Message.c_str(), IID_ICoClassName); // << This sets
Rich Error Information - see ComCoClass<>::Error()
}
return S_OK;
}
I 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. I *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. As I mentioned in my
previous post, there's still the problem of what to pull in, what approach
to use and other issues...
[After the previous post, I started thinking about this and realized that we
should have investigated the use SafeCallErrorProc in the xxxx_OCX.H IDE
wrappers. These are VCL by default - hence, there's no issue with VCL usage.
Unfortunately, these wrappers call via interface pointers that themselves
may have/need a different mechanism for when we overload to make out|retval
the return type. So it's not a trivial switch of the OLECHECK macro to do
something else. The handler in the xxxx_OCX file may not be called if the
method was overloaded to hide-HRESULT in the interface. I've already started
throwing out ideas with other ActiveX and VCL members of the team. It will
take a little more thinking but I definitely want some form of
Client-Rich-ErrorInformatin support. I'll come by to get your feel on
various approaches we're thinking about.]
Regards,
Bruneau.
JT(Borland) wrote in message <37458604...@borland.com>...
>> 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:
>
Thanks very for comprehensively answering my question - this is the third
time I have asked this question and I wasnt expecting much response!!
I suppose I am in the minority -- I am actually using C++ Builder as a COM
client, the intention was to use Delphi but to avoid retraining several C++
developers in Pascal we chose Builder.
I am quite happy to use the #import and _com_error route - Just reassure me
that #import and smart pointers all work correctly in C++ Builder!!!....
I would prefer this to using an unsupported header file to fix the problem.
Is this not something which could be implemented as a compiler flag to
specify if VCL exceptions are or are not used??
Thanks
Simon
Jean-Marie Babet wrote in message <7i4467$jo...@forums.borland.com>...
>Simon,
>
>The failure here was the result of whether or not OLE clients should assume
>VCL usage. Back in the early phase of the project, there was a big push to
>have light-weight ActiveX support. Among other things, that meant not
>requiring VCL in Auto/COM servers and ActiveX Clients accessing these. I
>should add that this push was triggered by COM/Internet/ATL/VC5 etc.
>
>So early on we opted to refrain from using VCL types whenever possible.
This
>meant that we would not pull in the VCL exception hierarchy. As the project
>moved along several issues took place that lighten the light-weight issue
>but nothing was definite. Net result: we left the exception issue open. I
>intentionally made sure to mode the code from .CPP to a template in a
header
>(UTILCLS.H) so that we could update this easily without re-deploying new
>libraries/packages etc.
>
>I have a version of UTILCLS.H that throws the VCL exception. I cannot
commit
>that that's the route we'll take eventually. However, I'll be happy to make
>the file available. I've also asked our management team to give me a feel
>for the importance of light-weight, VCL-less ActiveX projects.
>
>I hope the above explains the issue a little. I wished we had made a firmer
>decision but... I don't want to complicate matters but we also wanted to
see
>how well #import is adopted. The exception thrown there is _com_error. Any
>feedback on this and all the related items mentioned above is welcome.
>
>Regards,
>
>
>Bruneau.
>
>Simon Gibbs wrote in message <7i3nv1$ja...@forums.borland.com>...
>>Hi
>>
>>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:
>>
Can you use #import in C++ Biulder - I have tried and it fails to compile.
Are there some headers I need to include??
Chris.
Just a small note regarding your implementation of Error in the auto-generated
code from the Typle Library Wizard/Editor:
The try / catch / Error() code only seems to be generated for getter/setter
methods for properties, and not just for pure "methods". I.E., if I use the TLE
(type lib editor) and choose "New Method", I do not get this block of code.
I cut and paste this code from a getter/setter routine manually to my methods
and it works great there.
Is there something special the Team had in mind when not generating the
try/finally in non-property methods??
Michael
Jean-Marie Babet wrote:
> >> 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:
> >
Thanks for reminding me of this - Charlie Calvert brought this to my
attention a while ago and it's logged but I had totally forgotten about it.
Again, it's the half-baked non-VCL lightweight support that was big at the
beginning of the Dev. Cycle. Then things changed (at a much higher level in
the company) and so did the focus (Back then I used to tell one of my
colleagues "You're under the charm of the COBRA"; of course, I've lightened
up since:). The initial goal was to avoid pulling in VCL classes (the
Exception hierarchy included).
I'm currently gathering information about these issues and plan to relay
them to the decision makers so that we're clear about what's needed and what
we will be focusing on.
Regards,
Bruneau.
Michael Lovett wrote in message <37494A47...@morpace.com>...
First of all, let me say that you're not in the minority when it comes to
rich error info support. It's part of COM and we plan to expose this
feature. There were some things I needed to understand better about our user
needs in the previous version. A big one was whether C++Builder COM users
are also VCL users. For the most part the implementation approach we took
will reflect this need to stay flexible. For example, TVariant was made a
template with the idea that it would be specialized for Variant or the raw
VARIANT. In the case of the former, I even thought that we would 'hide' the
current Variant under another name and make TVariant<OldVariant> Variant
itself.
My reference to #import and _com_error comes from the fact that we did not
want to assume that the C++ COM world would adopt #import and its helper
classes and did not want to force all of our users to switch from WideString
to _bstr_t, or EOlexxxx to _com_error. The current shipping compiler does
not support #import. This feature is being evaluated in light of our COM
support as a whole. The support will have to be coherent though (we lack
some of that currently).
The use of VCL exception classes could be controlled by a flag to TLIBIMP,
the utility that generates xxxx_TLB files (the IDE uses a packaged version,
TLIB40.BPL). For now, however, the simplest solution would be a solution
dropped in UTILCLS.H.
Regards,
Bruneau.
Simon Gibbs wrote in message <7ib2vj$pq...@forums.borland.com>...
>Hi Bruneau
>
>Thanks very for comprehensively answering my question - this is the third
>time I have asked this question and I wasnt expecting much response!!
>
>I suppose I am in the minority -- I am actually using C++ Builder as a COM
>client, the intention was to use Delphi but to avoid retraining several C++
>developers in Pascal we chose Builder.
>
>I am quite happy to use the #import and _com_error route - Just reassure me
>that #import and smart pointers all work correctly in C++ Builder!!!....
>
>I would prefer this to using an unsupported header file to fix the problem.
>Is this not something which could be implemented as a compiler flag to
>specify if VCL exceptions are or are not used??
>
>Thanks
>
>>how well #import is adopted. The exception thrown there is _com_error. Any
>>feedback on this and all the related items mentioned above is welcome.
>>
>>Regards,
>>
>>
>>Bruneau.
>>
>>Simon Gibbs wrote in message <7i3nv1$ja...@forums.borland.com>...
>>>Hi
>>>
>>>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:
>>>
Thanks for the explanation.
Could you possibly send me the UTILCLS.H header file which throws the
exceptions. I assume it is safe for me to use this although Im not entirely
sure what would happen if we upgraded to BCB5 in the future...
How would I control this using TLIBIMP? Surely this is a better solution (I
am not keen on tying my project to a specifc copy of a system header file).
Could you expand on this solution for me??
Thanks very much
Simon
Jean-Marie Babet wrote in message <7ibpai$qi...@forums.borland.com>...
I think that ability to create lightweight ATL controls is very
important. At least I could benefit from this tremendously ;)
Alex
Jean-Marie Babet wrote:
[snip]
--
HotSend - portable documents technology
http://www.hotsend.com/
eFax - get your faxes via email - Free !
http://www.efax.com
My message might have been a little confusing. An option could be added to
TLIBIMP to govern how HRESULT failures are handled. Similar to the other
options currently available (run TLIBIMP with no parameters). However,
there's no such option currently.
I'm currently at home and don't have an updated UTILCLS.H handy to
illustrate but the approach is via template specialization. Basically, the
code generated invokes a macro, OLECHECK, which is defined in the header
UTILCLS.H. That macro eventually resorts to a template, DebugHlpr_THROW to
throw an exception. Typically the compiler resorts to the template. However,
you can specialize DebugHlpr_THROW for the type TCHAR, the type used by the
OLECHECK macro, to do the ::GetErrorInfo(...) call, grab the information,
load an EOleException and throw the latter. The only issue would be to make
sure the compiler 'sees' your specialization.
Hopefully things will lighten up a little at work tomorrow and I'll be able
to make time to illustrate this.
More to come...
Bruneau.
Simon Gibbs wrote in message <7ibrao$qh...@forums.borland.com>...
Thanks for the feedback. I'm currently looking at keeping things open.
Towards the end of the week I'll present some proposals for Event sinking
that, with the help of template, will hopefully allow VCL and non-VCL usage.
Regards,
Bruneau.
PS: Are you dealing with ActiveX Controls or Automation/COM servers? I don
't sense that C++Builder's AX Control support is in heavy use (no pun
intended:). ActiveForm, in my opinion, is worth the overhead but not plain
VCL components exposed as OLE Controls.
Alex Bakaev [TeamB] wrote in message <37499F89...@jetsuite.com>...
Simon Gibbs wrote:
>
> Hi
>
> Can you use #import in C++ Biulder - I have tried and it fails to compile.
> Are there some headers I need to include??
Nope. #import is not supported in BCB4.0.
Jean-Marie Babet wrote:
>
> Alex,
>
> Thanks for the feedback. I'm currently looking at keeping things open.
> Towards the end of the week I'll present some proposals for Event sinking
> that, with the help of template, will hopefully allow VCL and non-VCL usage.
>
That's the perfect solution !
> Regards,
>
> Bruneau.
>
> PS: Are you dealing with ActiveX Controls or Automation/COM servers? I don
I'm thinking of AX controls.
> 't sense that C++Builder's AX Control support is in heavy use (no pun
> intended:). ActiveForm, in my opinion, is worth the overhead but not plain
> VCL components exposed as OLE Controls.
>
ActiveForm is worth the overhead. But in some ( most ? ) cases an AX
downloadable from the Net must be as small as possible. It would be
great if BCB had an ability to create all of the AX infrastructure and
use some other window for the control ( like TWindow in OWL could be
constructed with an HWND of some other non-OWL window ). I.E. we have an
app that I'd like to convert to an AX control. So I just plug that app
in ( well, recompile it without WinMain ) an AX control skeleton and be
on my way. Zero ActiveForm overhead, maximum AX/ATL conveniences.
Alex
The only thing that worries me is when?
My Manager is currently evaluating Builder against VB, and if we cant get
the Rich error stuff easily I am loathed to think he might choose
VB!! - -and I do not want to be developing in that for the next 2 years!!1
Simon
Jean-Marie Babet wrote in message <7idh6o$s2...@forums.borland.com>...
>Alex,
>
>Thanks for the feedback. I'm currently looking at keeping things open.
>Towards the end of the week I'll present some proposals for Event sinking
>that, with the help of template, will hopefully allow VCL and non-VCL
usage.
>
>Regards,
>
>
>Bruneau.
>
>PS: Are you dealing with ActiveX Controls or Automation/COM servers? I don
>'t sense that C++Builder's AX Control support is in heavy use (no pun
>intended:). ActiveForm, in my opinion, is worth the overhead but not plain
>VCL components exposed as OLE Controls.
>
>Alex Bakaev [TeamB] wrote in message <37499F89...@jetsuite.com>...
>>Bruneau,
>>
>>I think that ability to create lightweight ATL controls is very
>>important. At least I could benefit from this tremendously ;)
>>
>>Alex
>>
>>Jean-Marie Babet wrote:
We will soon be releasing an update where I've tried really hard to
incorporate requests I've been reading from this forum in the past two weeks
I've participated in the newsgroup. I cannot give you a timeframe (for one,
I'll get myself in trouble and also, the timing depends on the readiness of
various areas that I don't work on). All I can say is that it will be very
soon.
Once that's out, I will illustrate how to retrieve rich error information.
Currently you would have to munge VCL\UTILCLS.H to do so. And, as you
mentioned, that's not a good idea.
More on this issue... hopefully in just a few days.
Regards,
Bruneau.
Simon Gibbs wrote in message <7ijc8q$46...@forums.borland.com>...
Re: VCL and ActiveX... FWIW we are doing a fair amount of COM work with BCB
in this company and, in order, here are the technologies we
are using:
1. Creating Automation servers
My dept (R&D) is writing a lot of our "toolset" as Automation servers
that can be easily manipulated by other not-so-technical areas of the
company through scripting languages. So far this has been very
successful.
Our Automation servers are written as local (EXE) servers, not
in-process DLL's. We tried in-process server but had trouble
instantiating VCL components in them and found them harder to
debug than EXE's. We do create and use VCL components
and objects inside these servers.
FWIW we've had trouble (BCB4) adding more than one interface
to a CoClass (type lib guy isn't always generating code when it's
supposed
to) so we've ended up creating a CoClass for every unique interface we
need. Kinda klunky, but it works reliably and the various "wizards" play
nice when you do this.
2. Automation Clients in BCB.
We control other apps through Automation, using TAutoDriver where
possible.
3. Initially we tried making VCL components into ActiveX.
We didn't have very good luck with this, but we'd like to use the
technology. So far, we have been able to accomplish everything
we need by creating Automation servers and just instantiating them
in code for whatever platform the client code is written in.
Suggestions for areas to improve on:
Type Lib Editor
- Generate try/catch(...) and call to Error in methods, not just
properties
- Generate implementation code when user creates an interface for
an existing CoClass (as stated above, we always go to New:ActiveX:
AutoObject when we need a new interface, because this works and
the implementation is create, but it's not very efficient making every
interface it's own CoClient)
- Option for editor to remove code it generated if you use editor to
remove a method or property .. manual clean up is confusing to
newbies.
Other Suggestions
- Improve comments that are automatically emedded in type library files
when they are imported. The current comments are a little to vague to
be of value to anyone except those we'd consider experts. Why is
it so hard to create a comment that shows how to instantiate and call
a TAutoDriver object, for example? It would be much more useful
to the average user than the current text.
On the same note, why not embedd a comment in the top of the
generated file which describes what user can and can't expect to find
in
there? Many of our group has been initially confused about what's in
this file and what's not. You could address topics like: why not all
TAutoObjects have __properties, and what is the difference between
Smart Interfaces and AutoObjects, etc.
Hope this helps,
Michael Lovett
Jean-Marie Babet <brun...@msn.com> wrote in message
news:7i4467$jo...@forums.borland.com...
> Regards,
>
>
> Bruneau.
>
These are excellent suggestions. Often I/we don't realize that a simple
comment/example makes a big difference. Just recently someone at Borland
sent me email asking how to use the new TSafeArray<> template they've heard
about (I dropped this into the product from a project, ORBPAS.DLL, I worked
on for Delphi4; I hated to manipulate SAFEARRAYs via Variant methods and
wanted to use the more natural subscript[] operator). I pointed out that
this file was pretty much dropped at the last minute I had put some samples
at the end of the file (SAFEARRY.H). I received a reply back "This is
exactly what I needed". Later on I talked to the person and found out that
he had looked at the file and did not realize that the comments would be at
the end. I moved them at the top of the file for the upcoming update.
TypeLibraryEditor not handling CoClass with more than one interface:
This is a known weak area that we're struggling with. There's a
peripheral/parallel issue which is that the TypelibEditor does not provide
implementation for the methods of your base interfaces when they are not
IUnknown, IDispatch etc. There's also another issue where the TypeLib Editor
always assume that additional interfaces of a CoClass are all
automation/IDispatch-derived interfaces. For now, I'll say that your
approach is the best workaround: One CoClass/One interface.
Generate try/catch in Implementation:
This is a sloppy area - there was a move towards light-weight/VCL-less
support that was thwarted when resources were diverted to the charming COBRA
(that's a joke BTW - I support other Distributed Computing Models:). Once we
settle the VCL vs. non-VCL issue, the try/catch and, more importantly, the
Exception hierarchy used, will be tidied.
Comment the xxxx_TLB file:
Thank you! I hear you. My past three weeks on the forum have definitely
taught me that a lot of things need documentation. I've brought up to
Borland's attention that ActiveX is not like the rest of C++Builder's
Framework/Library support. It's the one area where we don't use Delphi's
VCL. Rather we use most ATL for server side, as home-grown templates for
Client-side. Adding comments to the xxx_TLB is easy as you can imagine.
Providing samples is a little more time consuming but I plan to do that.
Comment on Internal Logic:
This is the area that's interesting to me because I can learn at lot from
the experience of our users. Earlier during the cycle I mentioned to some
Beta Testers that I was struggling with the fact that in 'AppObject'
hierarchies (Word, Excel, etc), the application object gets you documents,
and documents gets back an application. I wanted to avoid pointer semantics
and aim for a VB-like syntax but that catch-22 made it hard to implement
because I could only forward reference for reference or pointer. I was
amazed at the various solutions I received. This problem had been thought
about and solved many times before. I would love to explain why we refrain
from generating __properties, why a parameter is often exposed as a raw
TVariant&, why we expose index properties but refrain to do so if the index
is exposed as Variants, etc.
Thank you very much for the comments. We're in hectic mode right now (I
won't say why but I hope that this newsgroup can guess:).
More to come...
Bruneau.
Michael Lovett wrote in message <7j3vi8$j7...@forums.borland.com>...
Michael Lovett wrote:
> Hi,
>
> Just a small note regarding your implementation of Error in the auto-generated
> code from the Typle Library Wizard/Editor:
>
> The try / catch / Error() code only seems to be generated for getter/setter
> methods for properties, and not just for pure "methods". I.E., if I use the TLE
> (type lib editor) and choose "New Method", I do not get this block of code.
>
> I cut and paste this code from a getter/setter routine manually to my methods
> and it works great there.
>
> Is there something special the Team had in mind when not generating the
> try/finally in non-property methods??
>
> Michael
>
> Jean-Marie Babet wrote:
>
> ? John,
> ?
> ? Thank you for posting the low-level code. I wanted to add that similar
> ? routines are already accessible/encapsulated in our libraries.
> ?
> ? 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)
> ? {
> ? return Error(e.Message.c_str(), IID_ICoClassName); // ?? This sets
> ? Rich Error Information - see ComCoClass??::Error()
> ? }
> ? return S_OK;
> ? }
> ?
> ? I 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. I *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. As I mentioned in my
> ? previous post, there's still the problem of what to pull in, what approach
> ? to use and other issues...
> ?
> ? [After the previous post, I started thinking about this and realized that we
> ? should have investigated the use SafeCallErrorProc in the xxxx_OCX.H IDE
> ? wrappers. These are VCL by default - hence, there's no issue with VCL usage.
> ? Unfortunately, these wrappers call via interface pointers that themselves
> ? may have/need a different mechanism for when we overload to make out|retval
> ? the return type. So it's not a trivial switch of the OLECHECK macro to do
> ? something else. The handler in the xxxx_OCX file may not be called if the
> ? method was overloaded to hide-HRESULT in the interface. I've already started
> ? throwing out ideas with other ActiveX and VCL members of the team. It will
> ? take a little more thinking but I definitely want some form of
> ? Client-Rich-ErrorInformatin support. I'll come by to get your feel on
> ? various approaches we're thinking about.]
> ?
> ? Regards,
> ?
> ? Bruneau.
> ?
> ? JT(Borland) wrote in message ?37458604...@borland.com?...
> ? ?? 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:
> ? ?
> ? ?This is built into the exception handling of the Delphi language so it is
> ? ?seamless. On the C++ side you must handle and raise it explicitly.
> ? ?Here is an example of raising it on the Server side.
> ? ?
> ? ?STDMETHODIMP TMTSFoo1Impl::Method1()
> ? ?{
> ? ? IErrorInfo *errorInfo;
> ? ? ICreateErrorInfo *createErrorInfo;
> ? ?
> ? ? if (SUCCEEDED(CreateErrorInfo(?createErrorInfo)))
> ? ? {
> ? ? createErrorInfo-?SetGUID(IID_IMTSFoo1);
> ? ? createErrorInfo-?SetSource(WideString("MTSProj1.MTSFoo1").Detach());
> ? ? createErrorInfo-?SetDescription(WideString("I raised an
> ? ?error").Detach());
> ? ? if (SUCCEEDED(createErrorInfo-?QueryInterface(IID_IErrorInfo,
> ? ? (void**)?errorInfo)))
> ? ? {
> ? ? SetErrorInfo(0, errorInfo);
> ? ? createErrorInfo-?Release();
> ? ? errorInfo-?Release();
> ? ? }
> ? ? }
> ? ? return E_UNEXPECTED;
> ? ?}
> ? ?
> ? ?Here is an example of the cllient handling IErrorInfo.
> ? ?
> ? ?if (!(SUCCEEDED(Test.Method1())))
> ? ? {
> ? ? IErrorInfo *errorInfo;
> ? ? wchar_t *ErrorMessage;
> ? ?
> ? ? if (SUCCEEDED(GetErrorInfo(0, ?errorInfo)))
> ? ? {
> ? ? errorInfo-?GetDescription(?ErrorMessage);
> ? ? ShowMessage("Client " + AnsiString(ErrorMessage));
> ? ? errorInfo-?Release();
> ? ? }
> ? ? SysFreeString(ErrorMessage);
> ? ? }
> ? ?
> ? ?Hope this helps,
> ? ?//jt
> ? ?