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 |
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] |
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 |
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] |
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 |
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 |
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] |
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 |
"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 |
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 |
Free forum by Nabble | Edit this page |