Discussion:
Interface Event Interfaces
(too old to reply)
a***@aol.com
2012-01-31 16:30:21 UTC
Permalink
I am attempting to utilize a HID device which provides a DLL which
includes a type library which I import into Delphi via Project |
Import Type Library. This imported _TLB.pas includes the definition of
an event interface for the device.

I have previously done a similar task similarly importing a type
library and then using Binh Ly’s (of Tech Vanguards) Event Implementor
to end up providing Delphi events which work fine. The _TLB provides
an inteface declaration for the device event. And AFAICS Binh Ly’s
code provides a Delphi class for the event interface and connects via
a Connection Point, which it finds by means of an event GUID placed in
the Registry by the device installer (I may be a bit hazy here because
I am presuming outside my real knowledge<g>).

The device I am now attempting to utilize has a method named Advise in
its main device interface which has a parameter for the event
interface. This IDeviceNotification (here I quote from the
documentation) “provides the status of notification from the device.
It is prepared on the client side and passes this interface to the
Advise method of the “ device “interface. The IdeviceNotification
interface is a callback interface implemented with a client
application in otder to be notified from the Device Manager of device
connections & disconnections”.

AFAICS I must provide an instance of the IDeviceNotification to
receive the events & so call the Delphi events.

But as the device notification instance must be passed to the device
in the Advise method it appears to me that there is no connection
point available to use Binh Ly’s code, and I must write separate Code
and generate class entries in the Registry which reference my
implementation class in a dll so that I can generate an instance with
a call to CreateComObject.

OR can I implement the interface in a normal Delphi class implementing
the interface, and call that class’s “Create as IDeviceNotification”
and pass the returned reference in the Advise method, without having
to make my additional registry entries.

AFAICS Binh Ly’s code does not make a specific separate instance of
the interface but implements Delphi code which connects via the
connection point. Perhaps my new device does not have a connection
point and the Advise method is its external way of implementing what
Binh Ly does.

As you can see I have no real knowledge of interfaces and am
struggling. Any helpful comments will be gratefully received.

Alan Lloyd
Chris Cheney
2012-01-31 18:39:08 UTC
Permalink
Post by a***@aol.com
The device I am now attempting to utilize has a method named Advise in
its main device interface which has a parameter for the event interface.
This IDeviceNotification (here I quote from the documentation) “provides
the status of notification from the device. It is prepared on the client
side and passes this interface to the Advise method of the “ device
“interface. The IdeviceNotification interface is a callback interface
implemented with a client application in otder to be notified from the
Device Manager of device connections & disconnections”.
Advise (and Unadvise) are methods that were needed to be called explicitly
by the user's program _in Delphi 3_. Subsequent versions of Delphi hid all
that from the programmer. IIRC one got a magic 32-bit integer back from
Advise that one used in Unadvise to get the correct event interface
disconnected .... or something like that. Eric Harmon's Delphi COM
Programming has an example with the appropriate code wrapped with a
DELPHI100 compiler conditional define. Although long out of print, used
copies of the book are available.

I think you can ignore Advise if you use the imported type library (or
maybe if you use the component wrapper), unless you are still using D3, of
course.

I'm now rather hazy about this stuff as I've moved to Linux, but I hope
this is of some help.

Chris
a***@aol.com
2012-01-31 19:42:13 UTC
Permalink
Post by Chris Cheney
Post by a***@aol.com
The device I am now attempting to utilize has a method named Advise in
its main device interface which has a parameter for the event interface.
This IDeviceNotification (here I quote from the documentation) “provides
the status of notification from the device. It is prepared on the client
side and passes this interface to the Advise method of the “ device
“interface. The IdeviceNotification interface is a callback interface
implemented with a client application in otder to be notified from the
Device Manager of device connections & disconnections”.
Advise (and Unadvise) are methods that were needed to be called explicitly
by the user's program _in Delphi 3_. Subsequent versions of Delphi hid all
that from the programmer. IIRC one got a magic 32-bit integer back from
Advise that one used in Unadvise to get the correct event interface
disconnected .... or something like that. Eric Harmon's Delphi COM
Programming has an example with the appropriate code wrapped with a
DELPHI100 compiler conditional define. Although long out of print, used
copies of the book are available.
I think you can ignore Advise if you use the imported type library (or
maybe if you use the component wrapper), unless you are still using D3, of
course.
I'm now rather hazy about this stuff as I've moved to Linux, but I hope
this is of some help.
Thanks for your comments, I am using D3, but D5 is little different.
I'm not using it as a Delphi component.

Advise & Unadvise are in the supplier's SDK as methods of the general
device interface (for all languages which might use the SDK). I've not
come across them elsewhere & certainly not with the working interface
system. Perhaps Binh Ly's code effectively replaces them.

The Advise method of the general interface certainly has a var
parameter which is called a "cookie" and is used as a parameter of the
Unadvise method.

Alan Lloyd
Chris Cheney
2012-01-31 20:54:37 UTC
Permalink
Post by a***@aol.com
Advise & Unadvise are in the supplier's SDK as methods of the general
device interface (for all languages which might use the SDK). I've not
come across them elsewhere & certainly not with the working interface
system. Perhaps Binh Ly's code effectively replaces them.
Take a look at Binh Ly's

http://www.techvanguards.com/com/tutorials/eventsystem.asp and the download

http://www.techvanguards.com/files/EventSystemDelphi.zip

Look in Chat/ChatEventsEvents.pas [sic] in the zip for

TChatEventsEventsBaseSink.Connect (line 222) and
TChatEventsEventsBaseSink.Disconnect; (line 240)

which wrap Advise and Unadvise respectively.

Chris
a***@aol.com
2012-02-05 11:05:41 UTC
Permalink
Post by Chris Cheney
Take a look at Binh Ly's
http://www.techvanguards.com/com/tutorials/eventsystem.aspand the download
http://www.techvanguards.com/files/EventSystemDelphi.zip
Look in Chat/ChatEventsEvents.pas [sic] in the zip for
TChatEventsEventsBaseSink.Connect (line 222) and
TChatEventsEventsBaseSink.Disconnect; (line 240)
which wrap Advise and Unadvise respectively.
Thanks Chris - I'm starting to understand events. However it seems
that the manufacturer-supplied interfaces in the DLL are half doing it
their own way.

They do not seem to have implemented IConnectionPointContainer but
provide their own Advise method in the interface providing the event.

So I use Bin Ly's event implementor to provide an implementation of
the event interface and then use a reference to that implementation in
the manufacter's Advise method. And never call Bin Ly's Connect.

If I attempted to use Bin Ly's Connect it failed on the . . .

OleCheck (ASource.QueryInterface (IConnectionPointContainer,
pcpc));

. . . line with an "Unable to Connect - No such interface supported"
exception message.

They've done a similar thing by providing their own
QueryInterfaceFunction as a method in an interface instead of the user
querying IUnknown in the interface.

Of course if I complained to Olympus they would say "We don't support
Delphi" - Far Eastern Barbarians <gg>

Alan Lloyd

Loading...