[fpc-pascal] support for using an activex

Ludo Brands ludo.brands at free.fr
Wed May 25 15:49:31 CEST 2011

Regarding the tlb to pascal "conversion", AFAIK there is no support in fpc.
Delphi is clearly better equiped to work with COM objects.

I have also been playing around with a generic eventsink class but the
problem is that events can have parameters (and a lot do). Your suggestion
of using TNotifyEvents could work for events without parameters. You could
leave the parameter stuff to the user of the eventsink, eventually helping
him by exposing the number and type of parameters, but that means that the
user has to have a reasonable good understanding of COM, including the data
types compatible with COM marshalling.

Simply mapping dispid's to array index isn't working for all real life
ActiveX objects. Take a look at fe. Comct332.ocx
  _CoolBarDisp = dispinterface
    procedure GhostMethod__CoolBar_28_0; dispid 1610743808;
    procedure GhostMethod__CoolBar_32_1; dispid 1610743809;
    procedure OLEDrag; dispid 1610809364;
    procedure Refresh; dispid -550;
    procedure AboutBox; dispid -552;

Delphi solves the problem not by creating a generic eventsink type but by
creating a pascal wrapper with the "import ActiveX control" tool. All
parameters are already converted to the correct types. Here the user doesn't
need to understand COM at all.

Here is an excerpt of the Delphi conversion of the aol winampxchat library
(only event related stuff):
  TIWinAmpActiveXChatWinampMsgEvent = procedure(Sender: TObject; msgId:
Integer) of object;
  TIWinAmpActiveXChatWinampStatus = procedure(Sender: TObject; msgId:
Integer; comp: Integer) of object;

  TIWinAmpActiveXChat = class(TOleControl)
    FOnWinampMsgEvent: TIWinAmpActiveXChatWinampMsgEvent;
    FOnWinampStatus: TIWinAmpActiveXChatWinampStatus;
    property OnWinampMsgEvent: TIWinAmpActiveXChatWinampMsgEvent read
FOnWinampMsgEvent write FOnWinampMsgEvent;
    property OnWinampStatus: TIWinAmpActiveXChatWinampStatus read
FOnWinampStatus write FOnWinampStatus;

procedure TIWinAmpActiveXChat.InitControlData;
  CEventDispIDs: array [0..1] of DWORD = (
    $00000001, $00000002);
  CControlData: TControlData2 = (
    ClassID: '{E3852604-B619-11D6-94EC-00047521F020}';
    EventIID: '{E3852603-B619-11D6-94EC-00047521F020}';
    EventCount: 2;
    EventDispIDs: @CEventDispIDs;
    LicenseKey: nil (*HR:$80004002*);
    Flags: $00000000;
    Version: 401);
  ControlData := @CControlData;
  TControlData2(CControlData).FirstEventOfs := Cardinal(@@FOnWinampMsgEvent)
- Cardinal(Self);

Note CEventDispIDs which holds the dispid values. When an event is invoked
the DISPID is looked up in CEventDispIDs. The index is used to calculate an
offset with FOnWinampMsgEvent. Index 0 points to FOnWinampMsgEvent, 1 to


-----Message d'origine-----
De : fpc-pascal-bounces at lists.freepascal.org
[mailto:fpc-pascal-bounces at lists.freepascal.org] De la part de Roberto
Envoyé : mercredi 25 mai 2011 13:18
À : FPC-Pascal users discussions
Objet : Re: RE : RE : RE : [fpc-pascal] support for using an activex

2011/5/24 Ludo Brands <ludo.brands at free.fr>:
> The following delphi articles should help creating an event sink:
> http://www.informit.com/articles/article.aspx?p=130494&seqNum=5  This 
> is an interesting one since it is written for Delphi 3-4 which missed 
> a lot of the automated COM handling. This is much closer to where fpc 
> is now.
> http://www.blong.com/Conferences/IConUK2000/DelphiMoreAutomation/More%
> 20Auto
> mation%20In%20Delphi.htm#HandcraftedEventSink
> A good intruduction to connectable objects: 
> http://www.gtro.com/delphi/comevents_e.php

Thanks a lot!

I'm reading it all and writing some code.
But in all of those docs there the "InterfaceConnect" routine is used....but
I can't find it anywhere. Besides, is there something to convert the tlb to
pascal? Or shall I do it manually?

I might be wrong, but it seems to me that it should be possible to write a
general TSimpleEventSink class which does most of all the COM work, and
exposes a pascal-standard event management. The TSimpleEventSink class might
have an Events property which is a dynamic array of TNotifyEvents; the
client could resize it and link its event handlers. At the same time the
TSimpleEventSink reacts to the server events by mapping the dispid's to the
Events array index, up to its current maximum dimension.

Well, I'm still quite confused.... besides the missing InterfaceConnect
method, is there any freepascal example available? On the web I can only
find delphi ones.


fpc-pascal maillist  -  fpc-pascal at lists.freepascal.org

More information about the fpc-pascal mailing list