Is IDispatch>>asImplType supposed to downcast just 1 level?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Is IDispatch>>asImplType supposed to downcast just 1 level?

Yar Hwee Boon-3
Hi all,

Sending #asImplType to a IDispatch (which implements DispHTMLImg) answers  
an instance of IHTMLElement instead of DispHTMLImg. Is #asImplType meant  
to downcast a single level only? Also, sending #asImplType again to that  
IHTMLElement instance answers self rather than an instance of DispHTMLImg,  
do I have to #downcast directly? thanks.

PS: i've noticed that some ActiveX related questions seems not to be  
answered (if ever) as much as other Dolphin questions, is it because it is  
hardly used by anyone, especially the regulars? What should I do in this  
case, mail OA directly?

--
Regards
Hwee Boon
MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Bill Schwab-2
Hwee Boon,

> Sending #asImplType to a IDispatch (which implements DispHTMLImg) answers
> an instance of IHTMLElement instead of DispHTMLImg. Is #asImplType meant
> to downcast a single level only? Also, sending #asImplType again to that
> IHTMLElement instance answers self rather than an instance of DispHTMLImg,
> do I have to #downcast directly? thanks.

I don't know what to tell you.  Does sending it work?  If so, and if I
wanted the functionality, I'd probably send the message.  That sounds
flippant, which is not my intention - or maybe it is.  I could no doubt find
exceptions to this in my image, but I generally use ActiveX controls only
for things that I am willing to consider optional.  A great example is an
Agent-based help system.  It was very easy to create (building on the OA
package), adds a lot to my software, and if it goes away, then so be it -
the program will "realize" it and keep going.  I briefly used Word to print
until I could remove it from the app.  It was a skin-saver for a while.

While certainly not a large sampling, I have found most ActiveX controls
(that I considered using at one point) to be poorly designed, slow, and
unstable.  Also, Dolphin cannot overlap calls to them, so I consider them as
too risky for something that needs to run reliably - which is most of my
stuff.



> PS: i've noticed that some ActiveX related questions seems not to be
> answered (if ever) as much as other Dolphin questions, is it because it is
> hardly used by anyone, especially the regulars? What should I do in this
> case, mail OA directly?

Speaking only for myself, I have been avoiding COM and ActiveX for some
time, using them only when necessary.  The result is that I don't have ready
answers to challenging questions that arise.  When questions cover the
indended design of Dolphin's COM/ActiveX wrappers, I wouldn't presume to try
to answer.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Yar Hwee Boon-3
On Sun, 18 Jul 2004 18:13:59 -0400, Bill Schwab  
<[hidden email]> wrote:

> I don't know what to tell you.  Does sending it work?  If so, and if I
> wanted the functionality, I'd probably send the message.  That sounds
> flippant, which is not my intention - or maybe it is.

In fact that's what I did, ie. send the message. I was wondering what was  
the expected ("right") behavior though.

> While certainly not a large sampling, I have found most ActiveX controls
> (that I considered using at one point) to be poorly designed, slow, and
> unstable.

Unfortunately, I'm using the MSHTML webbrowser control for both editing  
and displaying HTML, and there doesn't seem to be an suitable alternative  
(available or roll my own).

> Speaking only for myself, I have been avoiding COM and ActiveX for some
> time, using them only when necessary.  The result is that I don't have  
> ready
> answers to challenging questions that arise.  When questions cover the
> indended design of Dolphin's COM/ActiveX wrappers, I wouldn't presume to  
> try
> to answer.

I suppose that partially confirms my suspicious that fewer people are  
using it :)

--
Regards
Hwee Boon
MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Schwab,Wilhelm K
Hwee Boon,

>> While certainly not a large sampling, I have found most ActiveX controls
>> (that I considered using at one point) to be poorly designed, slow, and
>> unstable.
>
> Unfortunately, I'm using the MSHTML webbrowser control for both editing  
> and displaying HTML, and there doesn't seem to be an suitable
> alternative  (available or roll my own).

Understood.



> I suppose that partially confirms my suspicious that fewer people are  
> using it :)

Perhaps, but it is important to note that the problem is not in Dolphin
- it's the generally poor state of binary components that I have
encountered.  Some say that object orientation has failed, and I think
that's rubbish.  I would not be so harsh with someone trying to argue
that component software is in less than stellar shape.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Blair McGlashan-3
In reply to this post by Yar Hwee Boon-3
"Yar Hwee Boon" <[hidden email]> wrote in message
news:[hidden email]...
> Hi all,
>
> Sending #asImplType to a IDispatch (which implements DispHTMLImg) answers
> an instance of IHTMLElement instead of DispHTMLImg. Is #asImplType meant
> to downcast a single level only? Also, sending #asImplType again to that
> IHTMLElement instance answers self rather than an instance of DispHTMLImg,
> do I have to #downcast directly? thanks.

The purpose of #asImplType in general is to provide a generic way to cast
from IDispatch to a more specific interface by using type information
(usually from a type library) to determine the default interface for the
component behind the IDispatch. The full source of all the Active-X
implementation is present in the image, so I would recommend debugging it
through to understand why it behaves as it does in your particular
situation, since this will depend on the type information served up by the
component. However #asImplType is really intended for cases where you don't
know in advance what interface you need. If you do know, then just query it:

        obj queryInterface: DispHTMLImg

Incidentally, isn't there a custom/dual interface equivalent of DispHTMLImg?
These are always to be preferred if available for reasons of significantly
(an order of magnitude or more) better performance, convenience and
debuggability. By convenience I am referring to the fact that Dolphin's type
library analyser will often generate better high level method wrappers for
custom/dual interfaces, and by debuggability I am referring to all the
dynamic dispatch support code that has to be run to issue a call through
IDispatch.

> PS: i've noticed that some ActiveX related questions seems not to be
> answered (if ever) as much as other Dolphin questions, is it because it is
> hardly used by anyone, especially the regulars?

I'm surprised (and disappointed) that you should have that impression. I
thought I'd answered almost every question anyone had asked on Active-X
here, but perhaps I am deluding myself :-). Anyway a quick search of Google
Groups gets eight hits for #asImplType (a detailed question/search after
all). More generally there is a mass of material in the newsgroup archive
concerning Active-X/COM in Dolphin.

>...What should I do in this  case, mail OA directly?

Free support is only offered via this newsgroup. For more details see:
>
> --
> Regards
> Hwee Boon
> MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Blair McGlashan-3
In reply to this post by Bill Schwab-2
"Bill Schwab" <[hidden email]> wrote in message
news:[hidden email]...
> ...
> While certainly not a large sampling, I have found most ActiveX controls
> (that I considered using at one point) to be poorly designed, slow, and
> unstable.  Also, Dolphin cannot overlap calls to them, so I consider them
> as
> too risky for something that needs to run reliably - which is most of my
> stuff.
>

Bill if you replace 'Active-X controls' with 'software'  in your statement
then it remains valid.

For myself I don't think Active-X controls are significantly worse than any
other software. The difference is that they tend to make the shortcomings
more obvious, because they expose a universally (if your universe is
Windows) accessible API. Those shortcomings become even more obvious when
you start driving the API/component from a live (image based) environment,
because we can really prod around in there :-).

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Schwab,Wilhelm K
Blair,

> Bill if you replace 'Active-X controls' with 'software'  in your statement
> then it remains valid.

I stand corrected :)


> For myself I don't think Active-X controls are significantly worse than any
> other software.

I will certainly reconsider it, but I do think they tend to be worse
than average.  A lot of it is probably poor interface design.  Also, VB
etc. created (creates??) a demand for controls for just about anything.
  Of course, one can hardly blame the VB programmers - who would want to
write much of anything in VB<g>?  Lots of demand leads to supply, and it
won't all be the highest quality.

Before I found Dolphin, I made a serious attempt at using VB to glue
together OCX controls written using C++.  I was _amazed_ at how tedious
it was to do a good job.  Granted, the machines were much slower than we
have now, and the operating system was MUCH flakier than win2k, but the
real problem was dealing with the interfaces.  Even Smallalk/V's IDE
seemed like paradise compared to changing something in one of the controls.

Of course, one needs experience with dynamic languages to view the
problem as I describe above.  My sense is that those w/o dynamic
experience simply accept the complexities of what they create (it's
arguably job security), and never give any thought to whether there
might be a better way.


 > The difference is that they tend to make the shortcomings
> more obvious, because they expose a universally (if your universe is
> Windows) accessible API. Those shortcomings become even more obvious when
> you start driving the API/component from a live (image based) environment,
> because we can really prod around in there :-).

Excellent point.


Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Yar Hwee Boon-3
In reply to this post by Blair McGlashan-3
On Mon, 19 Jul 2004 22:46:12 +0100, Blair McGlashan <[hidden email]> wrote:

> The purpose of #asImplType in general is to provide a generic way to cast
> from IDispatch to a more specific interface by using type information
> (usually from a type library) to determine the default interface for the
> component behind the IDispatch. The full source of all the Active-X
> implementation is present in the image, so I would recommend debugging it
> through to understand why it behaves as it does in your particular
> situation, since this will depend on the type information served up by  
> the
> component.

Well, I did. #downCast looks intuitive enough, basically casting actually  
1 level down, if possible. But I was really looking at whether #asImplType  
is meant to send #downCast once and stop there (due to self class ==  
##(self)). That means that I have to keep sending downCast myself (since  
#asImplType only returns the base type) and do a comparison using self  
class. Anyway, my point of asking, instead of relying mainly on what I  
read from the code, was that the comment seem to indicate otherwise. Note  
the word "actual".

partial quote from IDispatch>>asImplType:

"Attempt to 'cast' the receiver down from IDispatch to its actual derived  
interface class if type information is available, and a wrapper class has  
previously been generated for the interface."
       
> However #asImplType is really intended for cases where you don't
> know in advance what interface you need. If you do know, then just query  
> it:
>
>         obj queryInterface: DispHTMLImg

I don't (specifically, this depends on whether the user clicks on an  
image, href, text, etc).

> Incidentally, isn't there a custom/dual interface equivalent of  
> DispHTMLImg?
> These are always to be preferred if available for reasons of  
> significantly
> (an order of magnitude or more) better performance, convenience and
> debuggability.

I believe this is what I am using? I did generate the types that are  
relevant (selectively) using the ActiveX Component Wizard.

>> PS: i've noticed that some ActiveX related questions seems not to be
>> answered (if ever) as much as other Dolphin questions, is it because it  
>> is
>> hardly used by anyone, especially the regulars?
>
> I'm surprised (and disappointed) that you should have that impression. I
> thought I'd answered almost every question anyone had asked on Active-X
> here, but perhaps I am deluding myself :-).

I do apologize if my (somewhat sweeping) statement was too demoralizing,  
but it did look that way, as compared to the other topics, I suppose it is  
all a user expectation thing :)

> Anyway a quick search of Google
> Groups gets eight hits for #asImplType (a detailed question/search after
> all).

Those didn't answer my query when I last checked.

> Free support is only offered via this newsgroup. For more details see:

Did you left out a link?

--
Regards
Hwee Boon
MotionObj


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Blair McGlashan-3
"Yar Hwee Boon" <[hidden email]> wrote in message
news:[hidden email]...

> On Mon, 19 Jul 2004 22:46:12 +0100, Blair McGlashan <[hidden email]> wrote:
>
>> The purpose of #asImplType in general is to provide a generic way to cast
>> from IDispatch to a more specific interface by using type information
>> (usually from a type library) to determine the default interface for the
>> component behind the IDispatch. The full source of all the Active-X
>> implementation is present in the image, so I would recommend debugging it
>> through to understand why it behaves as it does in your particular
>> situation, since this will depend on the type information served up by
>> the
>> component.
>
> Well, I did. #downCast looks intuitive enough, basically casting actually
> 1 level down, if possible.

I wouldn't describe it as casting down any number of "levels". It attempts
to 'cast' a generic IDispatch down to the actual interface class (if defined
in Dolphin) by asking the IDispatch for type information. This is
essentially a dynamic down cast.

>....But I was really looking at whether #asImplType  is meant to send
>#downCast once and stop there (due to self class ==  ##(self)). That means
>that I have to keep sending downCast myself (since  #asImplType only
>returns the base type) and do a comparison using self  class. Anyway, my
>point of asking, instead of relying mainly on what I  read from the code,
>was that the comment seem to indicate otherwise. Note  the word "actual".
>
> partial quote from IDispatch>>asImplType:
>
> "Attempt to 'cast' the receiver down from IDispatch to its actual derived
> interface class if type information is available, and a wrapper class has
> previously been generated for the interface."
>

Let me explain it another way, but forgive me if I am teaching granny to
suck eggs; I'm sure you understand much of this already, but I think it will
be useful if this is recorded here for the benefit of others in the future.

In statically typed languages or object models (COM being an object model
based on C++ with the removal of state representation. and a lot of other
complexity, and the addition of reference counting for lifetime management
and QueryInterface for run-time casting), variables are typed. In COM the
variables of particular interest are pointers to interfaces. Static typing
(in the absence of generics anyway) means that any place I need to
pass/return more than one type of interface I have to declare the variable
as being the most general interface type which is a supertype of those
interfaces. Typically this means IDispatch, ultimately it means IUnknown.
Any time that I need to get to a more specific interface I have to downcast
back to that interface. COM provides a mechanism to do this (QueryInterface)
that allows for safe runtime typing if used correctly. However I either have
to know what the interface really is, so I can down cast back to it (an
example being where I supplied the object in the first place, perhaps to put
in a collection or other store), or if I don't "know" what it is then I at
least expect it to implement a particular interface in order that it can
participate polymorphically. These uses don't address the case where you
have a generic tool that wants to be able to display/make use of all the
capabilities of an object without predefining the objects it can support,
for example a generic object inspector. IDispatch addresses this need in
static languages by providing a (very slow and ponderous) dynamic
dispatching capability.

In Smalltalk, of course, we don't have typed variables. Only objects have
type. Hence we have to introduce an artifical "interface pointer" object to
represent interface pointer variables, with this allowing the type of the
Smalltalk object to represent the type of the variable. By introducing a
first class object to represent the variable/interface ponter not only can
we constrain the virtual calls we perform through that interface pointer
(necessary to keep to the static type contract), but we can also introduce
additional Smalltalk behaviour in the interface class itself. This
additional behaviour is very commonly used to make the COM interface easier
to use (the high-level wrapper methods generated by the AX Component Wizard
are an example of this), but also to provide additional services. If you
were writing an HTML editor, for example, you could use this as a way of
introducing some Smalltalk behaviour you need for the editor into the
interface classes. In order to make this work (perhaps what you want to do),
you have to cast from the generic type of pointer object that gets created
to represent a statically declared interface pointer variable down to the
more specific type of the actual interface that is behind that generic
pointer. In order to do this we have to be able to query through the generic
interface we have for the type of the interface that is underlying it, i.e.
we have to ask that object. IDispatch itself provides a method to ask for
type information, and from this we can look up the unique interface id (a
GUID) for that underlying interface. If an interface with that GUID has
previously been generated in Dolphin then we can substitute that more
specific interface (which will be a subclass of IDispatch) in place of the
IDispatch. Which interface you get it entirely dependent upon the type
information answered by the COM object through the IDispatch.

This is a very long winded way of saying what that method comment does -
you'll get what the IDispatch claims it is. If you're getting IHTMLElement,
then that must be because for that particular IDispatch pointer the type
information it supplied indicated that it was an IHTMLElement. Note that
this is not attempting to provide the default interface for the underlying
COM object, just the 'actual' type of the IDispatch. If you want the default
interface (as declared in the type library) for the underlying COM object,
you could acquire it something like this:

    iid := anIDispatch coclassTypeInfo defaultInterface guid.
    interfaceClass := COMInterface classForIID: iid.
    anDispatch queryInterface: interfaceClass.

Note that I am not handling any errors here (there may be no accessible
coclass type info, no default interface, or the interface may not have been
generated), and that the type of interface you get will still be dependent
on the type information supplied by the component itself.

>> However #asImplType is really intended for cases where you don't
>> know in advance what interface you need. If you do know, then just query
>> it:
>>
>>         obj queryInterface: DispHTMLImg
>
> I don't (specifically, this depends on whether the user clicks on an
> image, href, text, etc).

As an experiment I tried out the following, and I did get a DispHTMLImg for
the image element in the OA home page:

    u := URLPresenter showOn: 'http://www.object-arts.com'.
    "Evaluate the above, and wait until the page has downloaded before
proceeding..."
    doc := u view controlDispatch Document.

    "Create a virtual tree model onto the HTML node hierarchy"
    model := VirtualTreeModel new.
    model getChildrenBlock: [:each | each children contents collect: [:child
| child asImplType]].
    model addRoot: doc documentElement.

    "Show a tree view on the model"
    t := TreePresenter showOn: model.
    t view getTextBlock: [:each | each printString].

If you expand out the entire tree (press NUM PAD-* at the root) you should
see a DispHTMLImg near the bottom. If you take out the #asImplType and try
again you'll see a tree of IDispatch.

This implies either a difference in the versions of IE we are using, or that
the particular way in which you have acquired the IDispatch means that it
throws back something different.

>
>> Incidentally, isn't there a custom/dual interface equivalent of
>> DispHTMLImg?
>> These are always to be preferred if available for reasons of
>> significantly
>> (an order of magnitude or more) better performance, convenience and
>> debuggability.
>
> I believe this is what I am using? I did generate the types that are
> relevant (selectively) using the ActiveX Component Wizard.

DispHTMLImg is a generated wrapper for a dispatch interface (dispinterface),
i.e. it accesses properties and methods through the clunky/slow IDispatch
late binding mechanism, which will be apparent if you browse that class. I'm
referening to a class like IHTMLImgElement, the "dual" equivalent of
DispHTMLImg. This has direct virtual calls for properties and methods.

Unfortunately though, for your purposes you are probably stuck with the
dispinterfaces, since these are declared as the defaults in the type library
as far as I can tell from a brief look.

> ...
>> Anyway a quick search of Google
>> Groups gets eight hits for #asImplType (a detailed question/search after
>> all).
>
> Those didn't answer my query when I last checked.

I was using that as an example of the volume of questions/answers on Dolphin
Active-X issues. If I'd found that they did answer your question, then I
would have just pointed you there immediately.

>
>> Free support is only offered via this newsgroup. For more details see:
>
> Did you left out a link?

Yes, sorry. Went away to find it and got distracted. It should be:

    http://www.object-arts.com/Support.htm

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Is IDispatch>>asImplType supposed to downcast just 1 level?

Yar Hwee Boon-3
On Wed, 21 Jul 2004 14:24:56 +0100, Blair McGlashan <[hidden email]> wrote:

> This implies either a difference in the versions of IE we are using, or  
> that
> the particular way in which you have acquired the IDispatch means that it
> throws back something different.

I'm seeing the same result. Indeed, I am using something different:

     u := URLPresenter showOn: 'http://www.object-arts.com'.
     "Evaluate the above, and wait until the page has downloaded before
proceeding..."
     doc := u view controlDispatch Document.
     doc body contentEditable: true.

     "Click the image before proceeding"
     doc selection createRange commonParentElement asImplType inspect.
     doc selection createRange asImplType commonParentElement asImplType  
inspect

I was using the latter (with an additional #asImplType) which answers  
IHTMLElement. I guess I'll just send #downCast at the end, which fixes the  
problem.

>> Those didn't answer my query when I last checked.
>
> I was using that as an example of the volume of questions/answers on  
> Dolphin
> Active-X issues. If I'd found that they did answer your question, then I
> would have just pointed you there immediately.

Sorry, I misunderstood. Thanks for the thorough explanation.

--
Regards
Hwee Boon
MtionObj