Re: RE : RE : RE : RE : RE : RE : [fpc-pascal] support for using an activex
Hi Ludo, I really cannot get the items to work. I simplyfied the source code to the minimum in order to test the items stuff. var obj, item, items : variant; obj := CreateOleObject('WRGactiveX.Device'); // OK items := obj.Transducers; // OK writeln('Count: ', items.Count); // OK , always prints 8 item := items.item[1]; // Crash: EOleSysError : Numero di parametri non valido. Where the exception comment translates to "wrong number of parameters". Instead, writing item := items[1] gives the exception EVariantInvalidArgError : Invalid argument: Dispatch In the activex source code I hav these interface declarations: interface ITransducer : IDispatch { [propget, id(1), helpstring("property Name")] HRESULT Name([out, retval] BSTR *pVal); [propget, id(2), helpstring("property Status")] HRESULT Status([out, retval] WRG_TransdStatus *pVal); [propget, id(4), helpstring("property Meas")] HRESULT Meas([out, retval] double *pVal); }; interface ITransducers : IDispatch { [propget, id(1), helpstring("property Count")] HRESULT Count([out, retval] long *pVal); [propget, id(DISPID_VALUE), helpstring("property Item")] HRESULT Item(long Index, [out, retval] ITransducer* *pVal); [propget, id(DISPID_NEWENUM), helpstring("property _NewEnum"), hidden] HRESULT _NewEnum([out, retval] LPUNKNOWN *pVal); }; and used inside the IDevice class like: [propget, id(21), helpstring("property Transducers")] HRESULT Transducers([out, retval] ITransducers* *pVal); I would be very grateful if you could help me once more. Roberto 2011/5/25 Ludo Brands : > Using variants you can transparently "walk" along the exposed objects. The > variant contains the Idispatch of the object and gets the exposed methods at > runtime. Properties are implemented as get and put methods or just get > methods for read only properties. > > If you have something like > Itransducers = interface > .. > property transducer[Index:integer]:Itransducer; > end; > > Then you would do > transducer := transducers.transducer[index]; > > transducer := transducers[index]; works only if transducer is the default > property for Itransducers. I'm not sure if fpc supports this. > > Ludo > > > -Message d'origine- > De : fpc-pascal-boun...@lists.freepascal.org > [mailto:fpc-pascal-boun...@lists.freepascal.org] De la part de Roberto > Padovani > Envoyé : mercredi 25 mai 2011 19:34 > À : FPC-Pascal users discussions > Objet : Re: RE : RE : RE : RE : RE : [fpc-pascal] support for using an > activex > > > 2011/5/25 Ludo Brands : >> The code in article >> http://www.informit.com/articles/article.aspx?p=130494&seqNum=5 goes a >> long way in doing what you want to do. Unit Eventsink does pretty much >> of the legwork. You should remove the procedure register since that is >> the Delphi way to get a component on the toolbar. Remove also the >> {$IFDEF VER100} and {$ENDIF}. The unit actually includes the code for >> InterfaceConnect!! > > found that! great! > > >> As for the tlb conversion, in your case >> >> IEventIntfEvents = dispinterface >> ['{168F5642-5751-49F5-9AA4-B8A7A5F6A5B8}'] >> end; >> >> should do (that is for the events part). AFAIK the procedure and >> dispid definitions are only needed for the server. You are only >> concerned with dispid's. No need to create prototypes for >> OnCommChanged() etc. EventSink1Invoke would be a simple case DispID of >> 1: // do CommChanged >> 2: // do StatesChanged >> ... >> end; >> >> > > Now I am "wasting" time making the tlb pascal definitions. > For the event part I'm fine with the dispid's > Until now I was calling the activex method with variants, in and out, but > now I discovered that this IDevice class has a property like: property > Sensors: ISensors; > which inside is a list of items like Sensor: ISensor. > > Can I read the sensores with a variant? Then, to see the fields inside each > sensor, I think a I need a class to do that... The activex has all of these > classes with the suitable dispinterfaces and uuids and so on. But if I > define > var device, transducers, transducer : variant; > and create > device := CreateOleObject('Device'); > then, can i simply write the following ? > transducers := device.Transducers; > transducer := transducers[index]; > > > It's a long path until
Re: RE : RE : RE : RE : RE : RE : [fpc-pascal] support for using an activex
Always thanks! Given your evident experience on this matter, I kindly ask your advice on what is best to do. opt 1) create a fpc class with some pascal style methods, which in their implementation use variants and call the IDevice class with late-binding . meaning that there is no compiler check and if my collegue changes the dll, then I have to change these implementations opt 2) in a reference of those you sent me, there is some example code from which I take the lines below. In the tlb conversion unit, the interface and dispinterface of the class are some replicated. Then also the eventinterface is defined. The main interface class is defined without and with dispids. With the dispids, only the properties are defined and not the methods. IFileZapper = interface(IDispatch) ['{2E2FC5E0-5C0E-4C4F-8CC1-D9F6C5A92BA6}'] function Get_Directory: WideString; safecall; procedure Set_Directory(const Value: WideString); safecall; function Get_FileMask: WideString; safecall; procedure Set_FileMask(const Value: WideString); safecall; procedure BringToFront; safecall; property Directory: WideString read Get_Directory write Set_Directory; property FileMask: WideString read Get_FileMask write Set_FileMask; end; IFileZapperDisp = dispinterface ['{2E2FC5E0-5C0E-4C4F-8CC1-D9F6C5A92BA6}'] property Directory: WideString dispid 1; property FileMask: WideString dispid 3; procedure BringToFront; dispid 10; end; IFileZapperEvents = dispinterface ['{7B6F8ADD-7980-4A35-838B-E1600C43D29E}'] procedure OnSelectionChanged; dispid 1; procedure OnDirectoryChanged(const DirName: WideString); dispid 2; end; Is this somewhat the same thing as the wrapper of option 1? If I write all of this conversion (and, by the way, how to convert C++ data types to pascal?? widestring ?), then how can I use it? In the end, maybe the wiki page about COM interfaces should be update to something more than 'Word.Application.NewFile'. I can't share the activex I have, otherwise it would be a good example to see something useful to start with. Roberto 2011/5/25 Ludo Brands : > Using variants you can transparently "walk" along the exposed objects. The > variant contains the Idispatch of the object and gets the exposed methods at > runtime. Properties are implemented as get and put methods or just get > methods for read only properties. > > If you have something like > Itransducers = interface > .. > property transducer[Index:integer]:Itransducer; > end; > > Then you would do > transducer := transducers.transducer[index]; > > transducer := transducers[index]; works only if transducer is the default > property for Itransducers. I'm not sure if fpc supports this. > > Ludo > > > -Message d'origine- > De : fpc-pascal-boun...@lists.freepascal.org > [mailto:fpc-pascal-boun...@lists.freepascal.org] De la part de Roberto > Padovani > Envoyé : mercredi 25 mai 2011 19:34 > À : FPC-Pascal users discussions > Objet : Re: RE : RE : RE : RE : RE : [fpc-pascal] support for using an > activex > > > 2011/5/25 Ludo Brands : >> The code in article >> http://www.informit.com/articles/article.aspx?p=130494&seqNum=5 goes a >> long way in doing what you want to do. Unit Eventsink does pretty much >> of the legwork. You should remove the procedure register since that is >> the Delphi way to get a component on the toolbar. Remove also the >> {$IFDEF VER100} and {$ENDIF}. The unit actually includes the code for >> InterfaceConnect!! > > found that! great! > > >> As for the tlb conversion, in your case >> >> IEventIntfEvents = dispinterface >> ['{168F5642-5751-49F5-9AA4-B8A7A5F6A5B8}'] >> end; >> >> should do (that is for the events part). AFAIK the procedure and >> dispid definitions are only needed for the server. You are only >> concerned with dispid's. No need to create prototypes for >> OnCommChanged() etc. EventSink1Invoke would be a simple case DispID of >> 1: // do CommChanged >> 2: // do StatesChanged >> ... >> end; >> >> > > Now I am "wasting" time making the tlb pascal definitions. > For the event part I'm fine with the dispid's > Until now I was calling the activex method with variants, in and out, but > now I discovered that this IDevice class has a property like: property > Sensors: ISensors; > which inside is a list of items like Sensor: ISensor. > > Can I read the sensores with a variant? Then, to see the fields inside each > sensor, I think a I need a class to do that... The activex has all of these > classes with the suitable dispinterfaces and uuids and so on. But if I > define
RE : RE : RE : RE : RE : RE : [fpc-pascal] support for using an activex
Using variants you can transparently "walk" along the exposed objects. The variant contains the Idispatch of the object and gets the exposed methods at runtime. Properties are implemented as get and put methods or just get methods for read only properties. If you have something like Itransducers = interface .. property transducer[Index:integer]:Itransducer; end; Then you would do transducer := transducers.transducer[index]; transducer := transducers[index]; works only if transducer is the default property for Itransducers. I'm not sure if fpc supports this. Ludo -Message d'origine- De : fpc-pascal-boun...@lists.freepascal.org [mailto:fpc-pascal-boun...@lists.freepascal.org] De la part de Roberto Padovani Envoyé : mercredi 25 mai 2011 19:34 À : FPC-Pascal users discussions Objet : Re: RE : RE : RE : RE : RE : [fpc-pascal] support for using an activex 2011/5/25 Ludo Brands : > The code in article > http://www.informit.com/articles/article.aspx?p=130494&seqNum=5 goes a > long way in doing what you want to do. Unit Eventsink does pretty much > of the legwork. You should remove the procedure register since that is > the Delphi way to get a component on the toolbar. Remove also the > {$IFDEF VER100} and {$ENDIF}. The unit actually includes the code for > InterfaceConnect!! found that! great! > As for the tlb conversion, in your case > > IEventIntfEvents = dispinterface > ['{168F5642-5751-49F5-9AA4-B8A7A5F6A5B8}'] > end; > > should do (that is for the events part). AFAIK the procedure and > dispid definitions are only needed for the server. You are only > concerned with dispid's. No need to create prototypes for > OnCommChanged() etc. EventSink1Invoke would be a simple case DispID of > 1: // do CommChanged > 2: // do StatesChanged > ... > end; > > Now I am "wasting" time making the tlb pascal definitions. For the event part I'm fine with the dispid's Until now I was calling the activex method with variants, in and out, but now I discovered that this IDevice class has a property like: property Sensors: ISensors; which inside is a list of items like Sensor: ISensor. Can I read the sensores with a variant? Then, to see the fields inside each sensor, I think a I need a class to do that... The activex has all of these classes with the suitable dispinterfaces and uuids and so on. But if I define var device, transducers, transducer : variant; and create device := CreateOleObject('Device'); then, can i simply write the following ? transducers := device.Transducers; transducer := transducers[index]; It's a long path until I get this stuff working... R# ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: RE : RE : RE : RE : RE : [fpc-pascal] support for using an activex
2011/5/25 Ludo Brands : > The code in article > http://www.informit.com/articles/article.aspx?p=130494&seqNum=5 goes a long > way in doing what you want to do. Unit Eventsink does pretty much of the > legwork. You should remove the procedure register since that is the Delphi > way to get a component on the toolbar. Remove also the {$IFDEF VER100} and > {$ENDIF}. The unit actually includes the code for InterfaceConnect!! found that! great! > As for the tlb conversion, in your case > > IEventIntfEvents = dispinterface > ['{168F5642-5751-49F5-9AA4-B8A7A5F6A5B8}'] > end; > > should do (that is for the events part). AFAIK the procedure and dispid > definitions are only needed for the server. You are only concerned with > dispid's. No need to create prototypes for OnCommChanged() etc. > EventSink1Invoke would be a simple > case DispID of > 1: // do CommChanged > 2: // do StatesChanged > ... > end; > > Now I am "wasting" time making the tlb pascal definitions. For the event part I'm fine with the dispid's Until now I was calling the activex method with variants, in and out, but now I discovered that this IDevice class has a property like: property Sensors: ISensors; which inside is a list of items like Sensor: ISensor. Can I read the sensores with a variant? Then, to see the fields inside each sensor, I think a I need a class to do that... The activex has all of these classes with the suitable dispinterfaces and uuids and so on. But if I define var device, transducers, transducer : variant; and create device := CreateOleObject('Device'); then, can i simply write the following ? transducers := device.Transducers; transducer := transducers[index]; It's a long path until I get this stuff working... R# ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal