I am currently trying to use the AXControlSite for a basic view. Previously
I have only used controls in shell windows (by modifying AXControlSite class>>example2). I created a subclass of AXControlSite and called it MyAXControl. Then I created a #defaultProgId method and a new Presenter subclass (MyAXPresenter). I then evaluated: MyAXControl makeResource: 'Default view' inClass: MyAXPresenter This works as expected, but now I have a few questions. 1) The control generates a number of events, for example #Click. Where should I connect to the events in order to trigger them off MyAXControl? 2) I would like to generate the interface of the control using #queryInterface:. In which method should this be done for a basic control? And finally a few general MVP question regarding AX controls (both basic ones and shell based). 3) The View of an AX control is of course a subclass of AXControlSite. It's presenter class (according to the class comment) could (should?) also be AXControlSite. Is this true for both shell based controls and for basic ones? 4) Of course the control needs a model. The most appropriate model of a control seems to be it's interface. Is this correct? I guess that I don't quite understand MVP when working with AX controls (by the way, the 4.0 support for visual controls is very useful. Thanks a lot!). Regards, Mikael Svane [hidden email] |
By the way, wouldn't it be useful if this:
> >MyAXControl makeResource: 'Default view' inClass: MyAXPresenter > could be done in the Resource browser? /Mikael [hidden email] |
In reply to this post by Mikael Svane
Mikael
You wrote in message news:92cua5$6jde9$[hidden email]... > I am currently trying to use the AXControlSite for a basic view. Previously > I have only used controls in shell windows (by modifying AXControlSite > class>>example2). > > I created a subclass of AXControlSite and called it MyAXControl. Then I > created a #defaultProgId method and a new Presenter subclass > (MyAXPresenter). Fine. For a simple control (or simple use of a control) you may not need a specialized subclass. Just embed an 'AXControlSite.Default view' into a composite and set its prog id on an instance basis. You may not need the Presenter either, so I would recommend starting off without. It really depends what sort of abstraction you want to provide. Separate presenters make sense for the standard system controls because it allows for pluggability, and perhaps ultimately portability. Active-X controls may be generic enough to be used as Views on standard Presenters, or there may be an argument for creating a new Presenter to allow one to wire up different Views, be they Active-X controls or not. For example one might identify a need for a GraphPresenter that could support a number of different graph controls. On the other hand the control may be highly specialized and building a presenter for it might be pointless. I would err on the side of sticking with a View only to start with. >...I then evaluated: > > MyAXControl makeResource: 'Default view' inClass: MyAXPresenter You might find it easier to right-click on the view/presenter class and use the Views/New... command. > This works as expected, but now I have a few questions. > > 1) The control generates a number of events, for example #Click. Where > should I connect to the events in order to trigger them off MyAXControl? That will happen by default, assuming the #firesControlEvents aspect is true. The events are triggered off the presenter (the control site itself by default). To see this happening, experiment with your control in the Active-X Control Browser. AXControlSite>>example2 shows how to register a handler for an event, which is as normal for any other "triggered" event. The control browser shows the event names. > 2) I would like to generate the interface of the control using > #queryInterface:. In which method should this be done for a basic control? I'm not sure I entirely understand, but generating the interface is not usually a run-time task. Use the AX Component Wizard to generate wrappers for the component (or you can usually evaluate an expression such as 'self controlDispatch typeInfo generate' in the VC's workspace window with the control site selected). You can then #queryInterface: the generated interface (the default for the control that is) off the result of either #controlUnknown or #controlDispatch. It is OK to override #controlDispatch to answer an instance of the generated interface instead of IDispatch (it will be an IDispatch subclass). > And finally a few general MVP question regarding AX controls (both basic > ones and shell based). Andy is the MVP guru, and will hopefully chip in to correct my mistakes and offer more perceptive insights, but with that said... > 3) The View of an AX control is of course a subclass of AXControlSite. It's > presenter class (according to the class comment) could (should?) also be > AXControlSite. Is this true for both shell based controls and for basic > ones? The presenter will initially/by default be the View itself. If you identify a more abstract Presenter that you with to represent (for example you are wrapping a Grid OCX and want to implement a TablePresenter to represent the notion of presenting data in row/column form), then go ahead and implement that independently of the control. Although there will be an interface of messages and events between view and presenter, this should not be specific to one particular Active-X control. If it is, then there is probably little to be gained by create a Presenter. > > 4) Of course the control needs a model. The most appropriate model of a > control seems to be it's interface. Is this correct? I wouldn't have thought so, but it depends on the control and how you are using it. Consider Internet Explorer. One model that makes sense for this is a URL. I.E. can certainly be considered as something which displays a "document" with a particular URL. The Model for that is some kind of ValueModel holding a URL in String form, or perhaps as a URL object. Another model might be the (HTML/XML) document itself, and the Model for that (if we followed Dolphin's existing design for text presentation) would be something like RichText, or it might be the Interestingly these two different models are reflected by the two componentized forms of IE that MS supply, but in neither case do the COM interfaces exactly represent a Model in the MVP sense, for a start the events are separate. In many respects Active-X controls often represent a black-box MVP triad, and attempting to decompose them too much will be needless and probably fruitless, but as I say it depends on the control. > > I guess that I don't quite understand MVP when working with AX controls (by > the way, the 4.0 support for visual controls is very useful. Thanks a lot!). I'm sorry this is all a bit woolly. As we gain more experience with hosting AX controls in MVP we'll hopefully be able to come up with heuristics, rules of thumb, perhaps even patterns, for deciding what the model of a control should be, and whether it needs a presenter, but at the moment we are considering each case individually ourselves, and often getting it wrong. This is partly because it is new, but mostly because of the sheer number and variety of controls available. They range from simple presentation devices that are similar in nature to the common controls, to complex components that are closer to being full blown applications. Regards Blair |
Blair,
Thanks for your answer. I removed the presenter which probably isn't needed. >> MyAXControl makeResource: 'Default view' inClass: MyAXPresenter > >You might find it easier to right-click on the view/presenter class and use >the Views/New... command. But this doesn't work for new View subclasses (like MyAXControl), since they are not in the list. And choosing Resource/New/View from the menu only opens a View Composer. There seems to be no way of adding a new class to the Resource Browser class list from within the Resource Browser. >AXControlSite>>example2 shows how to register a handler for an event, which >is as normal for any other "triggered" event. The control browser shows the >event names. > >> 2) I would like to generate the interface of the control using >> #queryInterface:. In which method should this be done for a basic control? > >I'm not sure I entirely understand, but generating the interface is not >usually a run-time task. I meant: is there a special method where I should put the following code: dispControl := self controlUnknown queryInterface: MyInterface I don't know if it right, but I put it in #connectModel and it works. > >> This works as expected, but now I have a few questions. >> >> 1) The control generates a number of events, for example #Click. Where >> should I connect to the events in order to trigger them off MyAXControl? > >That will happen by default, assuming the #firesControlEvents aspect is >true. The events are triggered off the presenter (the control site itself by >default). To see this happening, experiment with your control in the >Active-X Control Browser. > But there is a small problem. The control triggers events from within the AX Control Browser but not in my AXControlSite subclass. Of course I am doing something wrong, but I don't know what. I decided to use #connectModel to create the wiring for the events like this (including the code above): connectModel "Connect the receiver to its model by wiring up event handlers, etc." dispControl := self controlUnknown queryInterface: MyInterface. presenter when: #Click send: #onClick to: self but this doesn't work. And that is also what I have done when using AXControlSite for controls in shells (like in #example2) but then it works. And I have checked that #firesControlEvents answers true. Any suggestions on what is wrong? Regards Mikael Svane [hidden email] |
Having done some more experimenting I have found some answers to the
questions that I asked. I have also discovered two possible and one certain bug. >connectModel > "Connect the receiver to its model by wiring up event handlers, etc." > dispControl := self controlUnknown queryInterface: MyInterface. > presenter when: #Click send: #onClick to: self > >but this doesn't work. Actually it did work when I removed the extra Presenter class. It turned out that although I was using a separate Presenter subclass as my presenter, at the time #connectModel is evaluated, the presenter of AXControlSite is always the AXControlSite itself. It is then later replaced by the proper Presenter. Another reason not to use a separate presenter, I suppose. If I instead use the AXControlSite as both presenter and view and add it to another presenter (Shell subclass) I run into other problems. Two methods have to be added to AXControlSite: #parentPresenter: #view: They can both be left empty. Is it a bug that they don't exist? Everything seems to work ok after adding them. Another bug (and this must be a bug): open the AX Control Browser and try to drag an event. This generates a walkback (Association does not understand #selector). By the way, why would one want to drag the events and where should they be dragged? Regards Mikael Svane [hidden email] |
Free forum by Nabble | Edit this page |