The LazActiveX package contains the TActiveXContainer component and the IDE integration of the necessary tools to create ActiveX components from a type library or directly from the object (exe or dll). ActiveX is a Microsoft Windows technology and can only be used on that platform. Cross compilation to windows is possible but the typelib importer used to create the COM bindings works only on Windows (wine not tested).
- WARNING: LazActiveX needs FPC >= 2.6.1. Importing type libraries only works on Windows XP or newer.
From the 'Package'/'Install/Uninstall Packages ...' window, select LazActiveX 0.1, click 'Install Selected' and then 'Save and Rebuild IDE'. Alternatively, open the LazActiveX.lpk package and click on 'Use >>'/'Install'.
When the installation succeeds, a new 'ActiveX' tab is added to you component palette.
There are 3 different ways of using ActiveX components:
- drop the TActiveXContainer on a form and assign the ActiveX ClassName to the OleClassName property. Suitable for late binding and without direct event support.
- import the ActiveX type library, drop the TActiveXContainer on a form, instantiate the ActiveX object and assign it to the ComServer property. Suitable for early binding and with event support.
- create a new component from the type library or the object and drop that new component on the form. This also uses early binding and has full event support. Event handlers can be assigned from the IDE.
TActiveXContainer late binding
Although the theory is quite complex, late binding is the fastest way to get an ActiveX component running.
Late binding refers to the fact that the interfacing to the object is all done at run-time. References to objects are stored as dispinterfaces in variants and the methods and properties of the objects are "discovered" at run-time. The compiler generates all the run-time magic for you but the downside is that the compiler isn't able to help you in finding the names of methods or properties at design time. Good documentation for the ActiveX object is very important (sample code for VB can easily be translated to pascal). All errors in method names and their parameters are run-time errors. The run-time "discovery" is also adding quite some overhead.
Example: Embed VLC player in a form. VLC has to be installed !!
- Drop a TActiveXContainer, a TButton and a TFileNameEdit on a form.
- Resize and position TActiveXContainer to your liking and enter 'VideoLAN.VLCPlugin.2' as OleClassName, set Active to true. This will give a form that resembles the following:
- create an Onclick event for the button and enter
procedure TForm1.Button1Click(Sender: TObject); var Actx:variant; begin Actx:=ActiveXContainer1.ComServer; Actx.playlist.add(widestring(FileNameEdit1.FileName)); Actx.playlist.play; end;
- Run the program, select a movie and click the button to view the movie. Note that vlc and gdb seem to cause some problems (slow start-up in the best case, hangs or crashes). Run the program preferably outside the IDE.
TActiveXContainer early binding
Early binding means that all interfaces are known to the compiler. So we need to create the pascal bindings for the ActiveX object. The importtl.exe tool in the fpc utils directory does that for you and creates coclasses and event listeners to facilitate the use of the objects in pascal. A GUI for the importtl.exe tool is integrated with the LazActiveX package and is accessible in the Tools menu: Import Type Library.
Check 'Convert dependent typelibs' to convert also the typelibs for the COM objects that are eventually used by the selected object. Clicking OK will start the typelib import and create new units in the IDE. The units have the following naming: LibraryName_MajorVersion_MinorVersion_TLB. Ex: Access_9_0_TLB.
- Delphi users: Delphi unit naming does not use version numbers.
Instantiating an ActiveX object is done at run-time by calling the Create method for the appropriate CoClass created for the library. Some ActiveX libraries expose several objects and multiple CoClasses are created. Consult the documentation for the ActiveX library in case of doubt. Assigning the instantiated ActiveX object to the ComServer property of an TActiveXContainer on a form and setting it's active property to true is all that is needed to embed it in the application.
Example: Embed VLC player in a form. VLC has to be installed !!
- Drop a TActiveXContainer, a TButton and a TFileNameEdit on a form. Resize and position TActiveXContainer to your liking
- Open 'Import Type Library' from the tools menu and select 'axvlc.dll' in your VLC installation directory. Click OK. The AXVLC_1_0_TLB unit is created.
- Add AXVLC_1_0_TLB to the uses clause.
- Create an OnClick event for the button and an OnCreate event for the form. Enter the following code:
var VLC:IVLCControl2; procedure TForm1.Button1Click(Sender: TObject); begin VLC.playlist.add(utf8decode(FileNameEdit1.FileName),'',vararrayof([':aspect-ratio=16:9'])); VLC.playlist.play; end; procedure TForm1.FormCreate(Sender: TObject); begin VLC:=CoVLCPlugin2.Create; ActiveXContainer1.ComServer:=VLC; ActiveXContainer1.Active:=true; end;
The typelib importer adds also support for ActiveX objects that use them. In tath case, alongside the CoClass a TEventSink descendant is defined that implements the ActiveX object and all its OnEvent properties. Use the TEventSink descendant instead of the CoClass if you want to use the events. Its name starts with TEvs followed by the class name.
Example: Internet Explorer in a form with event support. - Drop a TActiveXContainer, a TButton, TLabel and a TEdit on a form. Resize and position TActiveXContainer to your liking
- Open 'Import Type Library' from the tools menu and select 'C:\WINDOWS\system32\ieframe.dll'. Click OK. The SHDocVw_1_1_TLB unit is created.
- Add SHDocVw_1_1_TLB to the uses clause.
- Create an OnClick event for the button and an OnCreate event for the form.
- Create in class TForm1 the private procedure OnStatusTextChange(Sender: TObject;Text_:WideString);
- Enter the following code:
var Browser:TEvsWebBrowser; procedure TForm1.Button1Click(Sender: TObject); var url,onull:Olevariant; begin url:=Utf8decode(Edit1.Text); onull:=NULL; Browser.ComServer.Navigate2(url,onull,onull,onull,onull); end; procedure TForm1.FormCreate(Sender: TObject); begin Browser:=TEvsWebBrowser.Create(Self); ActiveXContainer1.ComServer:=Browser.ComServer; ActiveXContainer1.Active:=true; Browser.OnStatusTextChange:=@OnStatusTextChange; end; procedure TForm1.FormDestroy(Sender: TObject); begin Browser.Free; end;
-Run the program, enter an URL in the Edit control and click the button to navigate to the URL. Label1 will show the status messages sent by the browser.
Note that CoClasses are not destroyed. As all COM objects they are reference counted and destroy themselves when the last reference goes out of scope. The TEventSink descendant has to be destroyed.