Handling COM events in Dolphin

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

Handling COM events in Dolphin

Paul Hudson
How do I do this?

I've found Laurent's fragment on the Wiki:

sink := AXEventSink target: someComponent sourceTypeInfo:
(_IComponentEvents typeInfoIfNone: [^nil]).
sink connect: someComponent.
someComponent when: #onSomeEvent send: #doSomething to:
aListener

so, I think if I have

someComponent = NewsControl_nntp new.

(to continue from my previous posting)

the only think I don't know what to do with is
_IComponentEvents. That's not a global, it seems, so how do I
work out what it will be for my component?

And if the doc for the control says it's a (say) DoneConnect
event, will it just be #DoneConnect in Dolphin?

P. (still near ignorant about all this stuff)


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Don Rylander-2
Paul,
"Paul Hudson" <[hidden email]> wrote in message
news:Xns9214D4EEAE69Ephudsonpoboxcom@127.0.0.1...
[snip]
> sink := AXEventSink target: someComponent sourceTypeInfo:
> (_IComponentEvents typeInfoIfNone: [^nil]).
> sink connect: someComponent.
> someComponent when: #onSomeEvent send: #doSomething to:
> aListener
[snip]
> the only think I don't know what to do with is
> _IComponentEvents. That's not a global, it seems, so how do I
> work out what it will be for my component?

Usually, you should get an event interface that's generated along with the
class (maybe something like NewsControlnntpEvents).  Sometimes, though, they
get a name that doesn't put them very close to their related class.  Take a
look in the package you created and see.  If it's just the three classes to
wrap the three controls, that would be a bit depressing, but if the events
are supposed to be available for COM use, I think there's got to be typelib
info for generating their interfaces.

HTH

Don

>
> And if the doc for the control says it's a (say) DoneConnect
> event, will it just be #DoneConnect in Dolphin?
>
> P. (still near ignorant about all this stuff)
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Blair McGlashan
In reply to this post by Paul Hudson
"Paul Hudson" <[hidden email]> wrote in message
news:Xns9214D4EEAE69Ephudsonpoboxcom@127.0.0.1...
> How do I do this?

In your case , you could do it like this:

    nntp := NewsControl_Nntp createObject: 'NewsControl.Nntp'.
    tiSink := nntp coclassTypeInfo defaultSourceInterface.
    sink := AXEventSink target: nntp sourceTypeInfo: tiSink.

This is essentially the way that AXControlSite (for hosting visual controls)
wires up to the default event set of OCXs - see AXControlSite>>connectSink.

>
> And if the doc for the control says it's a (say) DoneConnect
> event, will it just be #DoneConnect in Dolphin?

Not necessarily, and not in this particular case where it will be
#DoneConnect:Rs:. The event name will be a selector formed from the event
method definition in the type library so as to take the correct number of
arguments. Essentially this means that it if there are any arguments it will
be a keyword selector the first keyword of which will be the event name with
a colon suffix. Subsequent keywords are formed from the names of the
argument, the first argument name being dropped since the first keyword has
already been constructed from the event name. This is basically the pattern
we use for constructing FFI calls names. So you can either peruse the IDL to
work out the event names, or use the type library analyzer to tell you, for
example:

    tiSink functions collect: [:each | each selector]

In this case it appears that the control will work as an OCX, so it is
easiest just to load it up in the Active-X Control Browser tool (on the
Additional Tools menu, one opened press Ctrl+N and select 'NewsControl.Nntp'
from the list). In the browser the right most list pane displays the event
names. If you hover over the entries the IDL for that even is displayed,
including any help string. You can drag & drop the event names from the list
directly into your code.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Paul Hudson
"Blair McGlashan" <[hidden email]> wrote in
news:acd0ns$oj355$[hidden email]:

> "Paul Hudson" <[hidden email]> wrote in message
> news:Xns9214D4EEAE69Ephudsonpoboxcom@127.0.0.1...
>> How do I do this?
>
> In your case , you could do it like this:
>
>     nntp := NewsControl_Nntp createObject:
>     'NewsControl.Nntp'. tiSink := nntp coclassTypeInfo
>     defaultSourceInterface. sink := AXEventSink target:
>     nntp sourceTypeInfo: tiSink.
>
> This is essentially the way that AXControlSite (for hosting
> visual controls) wires up to the default event set of OCXs
> - see AXControlSite>>connectSink.

Thanks. I'm still not getting the events, though. Where will
they go to? (nntp, or sink)?

Is there some way of detecting when and which events get
triggered? (Debugging the expression doesn't seem to be enough)

What I've tried is:

nntp host: 'localhost'; port: 119; username: 'xxx';password:
'yyy'.
nntp when: #DoneDisconnect:Rs: send: #doDisconnect:Rs: to:
nntp.
nntp connect.

(expecting a DNU from nntp, because the username and password
are invalid, and the doc (and ActiveX browser) for the control
says it sends this). But I get nothing

I'm aware I seem to be asking stupid questions - is there
something I should be reading first?

P.


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Paul Hudson
Paul Hudson <[hidden email]> wrote in
news:Xns9215D820C41Fphudsonpoboxcom@127.0.0.1:
>
> Thanks. I'm still not getting the events, though. Where
> will they go to? (nntp, or sink)?

Right, got there. The answer's nntp.
 
> Is there some way of detecting when and which events get
> triggered? (Debugging the expression doesn't seem to be
> enough)

sink isTracingEnabled: true.

I think.

 
> What I've tried is:
>
> nntp host: 'localhost'; port: 119; username:
> 'xxx';password: 'yyy'.
> nntp when: #DoneDisconnect:Rs: send: #doDisconnect:Rs: to:
> nntp.
> nntp connect.

I missed

sink connect: nntp.

No idea why I need it, though :-)


> (expecting a DNU from nntp, because the username and
> password are invalid, and the doc (and ActiveX browser) for
> the control says it sends this).

However, I didn't get a DNU (I did now get a message on the
Transcript, which was enough to get me going).

Is there some reason why this error doesn't raise a DNU?

P. (voodoo chicken programming, currently)


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Blair McGlashan
Paul

"Paul Hudson" <[hidden email]> wrote in message
news:Xns9216C8304D1C8phudsonpoboxcom@127.0.0.1...
> Paul Hudson <[hidden email]> wrote in
> news:Xns9215D820C41Fphudsonpoboxcom@127.0.0.1:
> >
> > Thanks. I'm still not getting the events, though. Where
> > will they go to? (nntp, or sink)?
>
> Right, got there. The answer's nntp.
>  ...

I thought you might, which is why I did not reply (sometimes the teacher
must let the student do his own exploration :-))

>...
> I missed
>
> sink connect: nntp.
>
> No idea why I need it, though :-)

As part of a two stage construct protocol that allows one to set up optional
parameters on the sink before connecting it, since some objects might send
an event as soon as they receive a new connection.

> > (expecting a DNU from nntp, because the username and
> > password are invalid, and the doc (and ActiveX browser) for
> > the control says it sends this).
>
> However, I didn't get a DNU (I did now get a message on the
> Transcript, which was enough to get me going).
>
> Is there some reason why this error doesn't raise a DNU?

Yes, the implementation of IDispatch::Invoke() traps exceptions in order to
convert them to HRESULT error codes to be passed back to the client - this
is what one wants in a runtime app., because one can't pass exceptions over
COM method boundaries. At development time it is unhelpful ("suppressing"
errors is almost always unhelpful of course), so it needs some sensible way
to control whether it happens at development time. Problem is the error may
be "expected" - one might be testing an exceptional condition - so just
behaving differently in runtime vs development sessions would not
necessarily be sufficient.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Paul Hudson
Ok, next problem :-(

The control supports getting a list of newsgroups. This takes
some time, so it appears the control returns immediately, and
later calls an event to say it's done.

How do I arrange to block the method that calls the "get list"
method until the event has been called?

Semaphore seems to be what I want, but it looks like the event
call back is in the same process as my main method (?), so I
get deadlock....

(I've got

getList:

nttp getList. "calls the control"
event wait. "event is a Semaphore"
"then process the data"

and

eventGetList: aReturnCode Rs: aMessage
"..."
 event signal. "data's there, go process it".

)

So, an overall question is what thread/process are events
called in, and do I have any control over this?

As usual,pointers to relevant documentation welcomed.

P.


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Bill Schwab
Paul,

> The control supports getting a list of newsgroups. This takes
> some time, so it appears the control returns immediately, and
> later calls an event to say it's done.
>
> How do I arrange to block the method that calls the "get list"
> method until the event has been called?
>
> Semaphore seems to be what I want, but it looks like the event
> call back is in the same process as my main method (?), so I
> get deadlock....

My first thought is to start a background thread to control the logic and
have it wait on the semaphore.  Since many Windows widgets like to be
synchronized with the message queue, you can use #queueDeferredAction: to
make the get list call after the semaphore is signalled.

What kind of user interface do you want?  If it's a progress-dialog, then
you might want to take a look at the timed evaluator on my web site.  It
works for the situations I've tried, but, I won't take offense if you make a
backup first :)

Have a good one,

Bill

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


Reply | Threaded
Open this post in threaded view
|

Re: Handling COM events in Dolphin

Paul Hudson
"Bill Schwab" <[hidden email]> wrote in
news:acqsfr$orf$[hidden email]:

> Paul,
>
>> The control supports getting a list of newsgroups. This
>> takes some time, so it appears the control returns
>> immediately, and later calls an event to say it's done.
>>
>> How do I arrange to block the method that calls the "get
>> list" method until the event has been called?
>>
>> Semaphore seems to be what I want, but it looks like the
>> event call back is in the same process as my main method
>> (?), so I get deadlock....
>
> My first thought is to start a background thread to control
> the logic and have it wait on the semaphore.

Yep, did that after the posting, but it seems the wrong way
about (I'd like the control logic in the main thread and the
events in the background thread).

Also makes playing with the functionality from a Workspace a
bit tricky (since that is the foreground thread, unless I've
missed a trick) - or every method that has this "kick an action
off, wait for event" pattern - and there's a lot  in this
control - needs to fork, which seems a bit ugly.

Ideally, I'd have a way of getting events handled on another
thread...

 Since many
> Windows widgets like to be synchronized with the message
> queue, you can use #queueDeferredAction: to make the get
> list call after the semaphore is signalled.


I probably don't know enough about Windows to be sure, but is
the Windows message queue here anything much to do with the
component I'm using (which is not a UI component)? If it does,
then this might be it, but my suspicion is not (the event gets
called when data arrives from a socket (in VB), using the async
Winsock calls. This could take ages, so my guess is it's not a
UI message queue.

> What kind of user interface do you want?

Haven't got as afar as a UI yet. Mostly, I'm just wrapping the
control in a class that presents a more usable interface/model,
then thinking about the P and V parts.

  If it's a
> progress-dialog, then you might want to take a look at the
> timed evaluator on my web site.  It works for the
> situations I've tried, but, I won't take offense if you
> make a backup first :)

Thanks. Your site was on my Smalltalk bookmarks already. I
think it's not what I want now, but I'll be sure to check it
out later.

P.