AXControlSite questions

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

AXControlSite questions

Mikael Svane
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]


Reply | Threaded
Open this post in threaded view
|

Re: AXControlSite questions

Mikael Svane
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]


Reply | Threaded
Open this post in threaded view
|

Re: AXControlSite questions

Blair McGlashan
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


Reply | Threaded
Open this post in threaded view
|

Re: AXControlSite questions

Mikael Svane
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]


Reply | Threaded
Open this post in threaded view
|

Re: AXControlSite questions

Mikael Svane
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]