An ActiveX control is a software component that integrates into and extends the functionality of any host application that supports ActiveX controls, such as C++Builder, Delphi, Visual dBASE, Visual Basic, Internet Explorer, and Netscape Navigator.
For example, Delphi comes with several ActiveX controls, including charting, spreadsheet, and graphics controls. You can add these controls to the component palette in the IDE, and then use them like any standard VCL component, dropping them on forms and setting their properties using the Object Inspector.
An ActiveX control can also be deployed on the Web, allowing it to be referenced in HTML documents and viewed with ActiveX-enabled Web browsers.
This chapter provides an overview of how to create an ActiveX control in the Delphi environment. It is not intended to provide complete implementation details of writing ActiveX control. For that information, refer to your Microsoft Developer's Network (MSDN) documentation or search the Microsoft Web site for ActiveX information.
Delphi provides two wizards for ActiveX development:
The ActiveX Control wizard generates an implementation unit that descends from two objects, TActiveXControl for the ActiveX control specifics, and the VCL object of the control that you choose to encapsulate. The ActiveForm wizard generates an implementation unit that descends from TActiveXForm.
To create a new ActiveX control, you must perform the following steps:
Use the ActiveForm wizard to create an ActiveX control based on a VCL form for Web deployment.
An ActiveX control consists of the VCL control from which it is built, as well as properties, methods, and events that are listed in the control's type library.
An ActiveX control involves many elements which each perform a specific function. The elements include a VCL control, properties, methods, events, and one or more associated type libraries.
An ActiveX control in Delphi is simply a VCL control that has been made accessible to applications and objects that support ActiveX controls. When you create an ActiveX control, you must first design or choose the VCL control from which you will make your ActiveX control.
Note: The controls available from the wizard list are controls derived from TWinControl. Some controls, such as EditControl, are registered as a NonActiveX control, therefore, they do not appear in the list.
A type library contains the type definitions for the control and is created automatically by the ActiveX control wizard. This type information, which provides more details than the interface, provides a way for controls to advertise its services to host applications. When you design your control, type library information is stored in a file with the TLB extension and a corresponding Pascal file containing the Pascal translations. When you build the ActiveX control, the type library information is automatically compiled into the ActiveX control DLL as a resource.
The properties, events, and methods of the VCL control become those of the ActiveX control.
The property page allows the user of a control to view and edit its properties. You can group several properties on a page, or use a page to provide a dialog-like interface for a property. For information on how to create property pages, see "Enabling simple data binding of ActiveX controls in the Delphi container".
When designing an ActiveX control, you start by creating a custom VCL control. This forms the basis of your ActiveX control. For information on this, see "Creating custom components."
When designing ActiveX controls from either existing VCL controls or from new ActiveForms, keep in mind that you are implementing an ActiveX control that will be embedded in another application; this control is not an application in itself.
For this reason, you probably do not want to use elaborate dialog boxes or other major user-interface components. Your goal is typically to make a simple control that works inside of, and follows the rules of the main application.
Whether you create an ActiveX control from a VCL control or ActiveForm depends on whether you already have an existing control that you simply want to encase in an ActiveX control wrapper. In this case, use the ActiveX control wizard as described in"Generating an ActiveX control from a VCL control".
If you are creating a more complete ActiveX application, use the ActiveForm wizard as described in "Generating an ActiveX control based on a VCL form". Typically, you use an ActiveForm to create and supply ActiveX applications for the Web.
The wizards implement all the necessary ActiveX interfaces required using the VCL objects, TActiveXControl or TActiveForm. You need only implement any additional interfaces you may have added to your control.
Once you have generated the control using either wizard, you can modify the control's properties, methods, and events using the Type Library editor.
You generate an ActiveX control from a VCL control by using the ActiveX Control wizard. The properties, methods, and events of the VCL control become the properties, methods, and events of the ActiveX control.
For information about creating VCL controls, see "Creating custom components."
The ActiveX control wizard actually puts an ActiveX class wrapper around a VCL control and builds the ActiveX control that contains the object. This ActiveX wrapper exposes the capabilities of the VCL control to other objects and servers.
Before using the ActiveX control wizard, you must select the VCL control from which to build the ActiveX control.
To bring up the ActiveX control wizard,
In the wizard, specify the following:
Choose the VCL control from the drop-down list. For example, to create an ActiveX control that allows client applications to use a TButton object, select TButton. For ActiveForms, the VCL class name option is dimmed because Active forms are always based on TActiveForm. | |
The wizard supplies a default name that clients will use to identify your ActiveX control. Change this name to provide a different OLE class name. | |
The wizard supplies a default name for the unit that contains code to implement the behavior of the ActiveX control. Accept the default or type in a new name. | |
The wizard supplies a default name for the ActiveX library project for your ActiveX control, if no project is currently open. If you have an ActiveX library open, this option is disabled. | |
Choose the threading model to indicate how client applications can call your control's interface. This is the threading model that you commit to implementing in the control. For more information on threading models, see "Choosing a threading model". Note: The threading model you choose determines how the object is registered. You must make sure that your object implementation adheres to the model selected. |
Specify the following ActiveX control options:
The wizard generates the following files:
Licensing an ActiveX control consists of providing a license key at design-time and supporting the creation of licenses dynamically, when the control is created at runtime.
To provide design-time licenses, the ActiveX wizard creates a key for the control that is stored in a file with the same name as the project and with the LIC extension. The user of the control must have a copy of the LIC file to open the control in a development environment. Each control in the project that has Make Control Licensed checked will have a separate key entry in the LIC file.
To support the creation of runtime licenses, the license is generated by querying the control for the license (at design time), storing it, and then passing the license to the control when it is created in the context of an EXE. When the runtime license is passed to the control, the design time license is no longer required.
Runtime licenses for the Internet Explorer requires an extra level of indirection because users can view HTML source code for any Web page, and because an ActiveX control is copied to the user's computer before it is displayed. To create runtime licenses for controls used in IE, you must first generate a license package file (LPK file) and embed this file in the HTML page that contains the control.
The LPK file is essentially an array of ActiveX control CLSIDs and license keys.
Note: To generate the LPK file, use the utility, LPK_TOOL.EXE, which you can download from the Microsoft Web site (www.microsoft.com).
To embed the LPK file in a Web page, use the HTML objects, <OBJECT> and <PARAM> as follows:
<OBJECT CLASSID="clsid:6980CB99-f75D-84cf-B254-55CA55A69452">
<PARAM NAME="LPKPath" VALUE="ctrllic.lpk">
</OBJECT>
The CLSID identifies the object as a license package and PARAM specifies the relative location of the license package file with respect to the HTML page.
When IE tries to display the Web page containing the control, it parses the LPK file, extracts the license key, and if the license key matches the control's license, it renders the control on the page. If more than one LPK is included in a Web page, IE ignores all but the first.
For more information, search for Licensing ActiveX Controls on the Microsoft Web site.
The ActiveForm wizard generates an ActiveX control based on a VCL form which you design when the wizard leaves you in the Form Designer. You can use the ActiveForm to create applications that you can deploy on the Web.
When an ActiveForm is deployed, an HTML page is created to contain the reference to the ActiveForm and specify its location within the page. The ActiveForm is then displayed and run from within a Web browser. Inside the Web browser, the form behaves just like a stand-alone Delphi form. The form may contain any VCL or ActiveX components, including custom-built VCL controls.
To start the ActiveForm wizard,
In the wizard, specify the following:
The VCL class name option is dimmed because Active forms are always based on TActiveForm. | |
The wizard supplies a default name that clients will use to identify your ActiveX control. Change this name to provide a different OLE class name. | |
The wizard supplies a default name for the unit that contains code to implement the behavior of the ActiveX control. Accept the default or type in a new name. | |
The wizard supplies a default name for the ActiveX library project for your ActiveX control, if no project is currently open. If you have an ActiveX library open, this option is disabled. | |
Choose the threading model to indicate how client applications can call your control's interface. This is the threading model that you commit to implementing in the control. For more information on threading models, see "Choosing a threading model". Note: The threading model you choose determines how the object is registered. You must make sure that your object implementation adheres to the model selected. |
Specify the following ActiveX control options:
The wizard generates the following files:
At this point, the wizard adds a blank form to your ActiveX library project. Now you can add controls and design the form as you like.
After you have designed and compiled the ActiveForm project into an ActiveX library (which has the OCX extension), you can deploy the project to your Web server and Delphi will create a test HTML page with a reference to the ActiveForm.
The ActiveX Control and ActiveForm wizards generate a type library that defines and implements the properties, methods, and events of the original VCL control or form, with the following exceptions:
Therefore, you may need to add some properties, methods, and events manually.
Note: Since ActiveX controls have a different mechanism for making controls data-aware than a VCL control, the wizards do not convert the properties related to data. You may want to add some of the ActiveX data aware properties to your control as described in "Enabling simple data binding with the type library".
You can add, edit, and remove the properties, methods, and events in an ActiveX control by editing the type library using either of the following ways:
Note: Any changes you make to the type library will be lost if you regenerate the ActiveX control from the original VCL control or form.
Note: Non-published properties that are manually added to the type library will appear in a development environment, but changes made to them will not persist. That is, when the user of the control changes the value of a property, the changes will not be reflected when the control is run. If the source is a VCL object and the property is not already published, you must create a descendant of the VCL object and publish the property in the descendant.
You can add additional properties, methods, and events to the control as follows.
property Top:integer;
If you check the Syntax helper check box, pop-up windows appear as you type, prompting you for what is expected at each point.
The declaration is automatically added to the control's implementation unit, type library (TLB) file, and type library unit. The specifics of what Delphi supplies actually depends on whether you have added a property, method, or event.
Since the interface is a dual interface, the properties are implemented using read and write access methods in the Pascal file (with the PAS extension). When adding a Caption property, the wizard would actually add the following declaration to the implementation unit:
property Caption: Integer read Get_Caption write Set_Caption;
The read and write access method declarations and implementations for the property would be the following:
function Get_Caption: Integer; safecall; procedure Set_Caption(Value: Integer); safecall; function TButtonX.Get_Caption: Integer; begin Result := FDelphiControl.Caption; end; procedure TButtonX.Set_Caption(Value: Integer); begin FDelphiControl.Caption := Value; end;
Note: Because the Automation interface methods are declared safecall, you do not have to implement COM exception code for these methods--the Delphi compiler handles this for you by generating code around the body of safecall methods to catch Delphi exceptions and to convert them into COM error info structures and return codes.
The interface implementation methods simply pass through the behavior to the VCL control. In some cases, you may need to add code to convert the COM data types to native Delphi types.
When you add a method, an empty implementation is added for you to add its functionality. For example, if you added:
procedure Move;
the following declaration and code would be added to the unit:
procedureMove;safecall;procedure TButtonX.Move; begin end;
Note: Because the Automation interface methods are declared safecall, you do not have to implement COM exception code for these methods--the Delphi compiler handles this for you by generating code around the body of safecall methods to catch Delphi exceptions and to convert them into COM error info structures and return codes.
An ActiveX control can fire events to its container. You add events to specify which events can be fired by the control. The following items are created for each event on the control:
procedure KeyPressEvent(Sender: TObject; var Key: Char); procedure TButtonX.KeyPressEvent(Sender: TObject; var Key: Char); var TempKey: Smallint; begin TempKey := Smallint(Key); if FEvents <> nil then FEvents.OnKeyPress(TempKey); Key := Char(TempKey); end;
Unlike the Automation interface, the events interface is not added to the control's interface list. The control does not receive these events--the container does.
With simple data binding, you can bind a property of your ActiveX control to a specific field within a database. You can do so by setting the property's binding flags using the Type Library editor.
This sectiondescribes how to bind data-aware properties in an ActiveX control. For information on binding data-aware properties in a Delphi container, see "Enabling simple data binding of ActiveX controls in the Delphi container".
By marking a property bindable, when a user modifies the property (such as a field in a database), the control notifies the database that the value has changed and requests that the database record be updated. The database then notifies the control whether it succeeded or failed to update the record.
Use the type library to enable simple data binding,
To test a data-binding control, you must register it first.
For example, to make a TEdit control a data-bound ActiveX control, create the ActiveX control from a TEdit and then change the Text property flags to Bindable, Display Bindable, Default Bindable, and Immediate Bindable. After the control is registered and imported, it can be used to display data.
After installing a data-aware ActiveX control in the ActiveX tab of the Palette, and placing the control in the form designer, right-click the data-aware ActiveX control to display a list of options. In addition to the basic options, the additional DataBindings item appears.
Note: You must set the data source property to the data source component on the form before invoking the Data Bindings Editor. In doing so, the dialog supplies the Field Name and Property fields from the data source component. The editor lists only those properties from the data source component that can be data-bound properties of the ActiveX control.
To bind a field to a property,
Field Name lists the fields of the database and Property Name lists the ActiveX control properties that can be bound to a database field. The DispID of the property is in parentheses, for example, Value(12).
Note: If no properties appear in the dialog, the ActiveX control contains no data-aware properties. To enable simple data binding for a property of an ActiveX control, use the type library as described in "Enabling simple data binding with the type library".
The following example walks you through the steps of using a data-aware ActiveX control in the Delphi container. In this example, we use the Microsoft Calendar Control, which is available if you have Microsoft Office 97 installed on your system.
Field Name lists all the fields in the active database. Property Name lists those properties of the ActiveX Control that can be bound to a database field. The DispID of the property is in parentheses.
With the HireDate field displayed in the DBGrid object, navigate through the database using the Navigator object. The dates in the ActiveX control change as you move through the database.
A property page is a dialog box similar to the Delphi Object Inspector in which users can change the properties of an ActiveX control. A property page dialog allows you to group many properties for a control together to be edited at once. Or, you can provide a dialog box for more complex properties.
Typically, users access the property page by right-clicking the ActiveX control and choosing Properties.
The process of creating a property page is similar to creating a form, you
Note: When adding properties to an ActiveX control or ActiveForm, you must publish the properties that you want to persist. For details see "Exposing properties of an ActiveX control".
You use the Property Page wizard to create a new property page.
To create a new property page,
The wizard creates a new form and implementation unit for the property page.
You must add a control to the property page for each property of the ActiveX control that you want the user to access.
For example, the following illustration shows a property page for setting the MaskEdit property of an ActiveX control.
The list box allows the user to select from a list of sample masks. The edit controls allow the user to test the mask before applying it to the ActiveX control. You add controls to the property page the same as you would to a form.
After you have added all the controls you need to the property page, you must associate each control with its corresponding property. You make this association by adding code to the property page's implementation unit. Specifically, you must add code to the UpdatePropertyPage and UpdateObject methods.
Add code to the UpdatePropertyPage method to update the property's control on the property page when the properties of the ActiveX control change. You must add code to the UpdatePropertyPage method to update the property page with the current values of the ActiveX control's properties.
For example, the following code updates the property page's edit box control (InputMask) with the current value of the ActiveX control's (OleObject's) EditMask property:
procedure TPropertyPage1.UpdatePropertyPage;
begin
{ Update your controls from OleObjects }
InputMask.Text := OleObject.EditMask;
end;
Add code to the UpdateObject method to update the property when the user changes the controls on the property page. You must add code to the UpdateObject method in order to set the properties of the ActiveX control to their new values.
For example, the following code sets the EditMask property of an ActiveX control (OleObject) using the value in the property page's edit box control (InputMask):
Note: Include the .TLB file that declares the ICoClassNameDisp interface.
procedureTPropertyPage1.UpdateObject;begin{Update OleObjects from your controls }OleObject.EditMask := InputMask.Text; end;
To connect a property page to an ActiveX control,
procedure TButtonX.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage);
begin
DefinePropertyPage(Class_PropertyPage1);
end;
The GUID constant, Class_PropertyPage1, of the property page can be found in the property pages unit.
The GUID is defined in the property page's implementation unit; it is generated automatically by the Property Page wizard.
The properties of an ActiveX control or ActiveForm can appear in a development environment such as Visual Basic, Delphi, or C++Builder. The user of the control or form can then visually manipulate the properties of the control. For properties to appear, they must be defined in the control's type library. For property changes to persist, they must be published. You can add properties to the type library manually, or let Delphi add them automatically. Delphi automatically adds published properties to the type library for you.
Note: Non-published properties that are manually added to the type library will appear in a development environment, but changes made to them will not persist. That is, when the user of the control changes the value of a property, the changes will not be reflected when the control is run.
To expose a property for a control that you created using the ActiveX control wizard, go to the source of the VCL control to expose the necessary properties. If the source is a VCL object and the property is not already published, you must create a descendant of the VCL object and publish the property in the descendant. For example, to publish the Align property of TButton, you can add the following code to the implementation unit of the ActiveX control:
TAlignButton = class (TButton) published property Align; end;
To expose a property for an ActiveForm,
property MyButtonCaption: WideString;
function TActiveFormX.Get_MyButtonCaption: WideString; begin Result := Button1.Caption; end; procedure TActiveFormX.Set_MyButtonCaption(const Value: WideString); begin Button1.Caption := Value; end;
Since an ActiveForm is an ActiveX control, there is a type library associated with it, and you can add additional properties and methods to the ActiveForm. For information on how to do this, see "Working with properties, methods, and events in an ActiveX control".
After you have created your ActiveX control, you must register it so that other applications can find and use it.
To register an ActiveX control:
Note: Before you remove an ActiveX control from your system, you should unregister it.
To unregister an ActiveX control:
As an alternative, you can use the tregsvr command from the command line or run the regsvr32.exe from the operating system.
To test your control, add it to a package and import it as an ActiveX control. This procedure adds the ActiveX control to the Delphi component palette. You can drop the control on a form and test as needed.
Your control should also be tested in all target applications that will use the control.
To debug the ActiveX control, select Run|Parameters and type the client name in the Host Application edit box.
The parameters then apply to the host application. Selecting Run|Run will run the host or client application and allow you to set breakpoints in the control.
Before the ActiveX controls that you create can be used by Web clients, they must be deployed on your Web server. Every time you make a change to the ActiveX control, you must recompile and redeploy it so that client applications can see the changes.
Before you can deploy your ActiveX control, you must have a Web Server that will respond to client messages. You can purchase a third-party Web Server, such as the Inprise Web Server that ships with the IntraBuilder product, or you can build your own Web Server if you have a version of Delphi that ships with socket components.
The process of deploying an ActiveX control,
This creates a deployment code base that contains the ActiveX control in an ActiveX library (with the OCX extension). Depending on the options you specify, this deployment code base can also contain a cabinet (with the CAB extension) or information (with the INF extension).
The ActiveX library is placed in the Target Dir of step 2. The HTML file has the same name as the project file but with the HTM extension. It is created in the HTML Dir of step 4. The HTML file contains a URL reference to the ActiveX library at the location specified in step 3.
Note: If you want to put these files on your Web server, use an external utility such as ftp.
When this HTML page is viewed in the Web browser, your form or control is displayed and runs as an embedded application within the browser. That is, the library runs in the same process as the browser application.
Before deploying an ActiveX control, specify the Web deployment options that should be followed when creating the ActiveX library.
Web deployment options include settings to allow you to set the following:
If you choose different combinations of package, CAB file compression, and code signing options for your ActiveX library, the resulting ActiveX library may be an OCX file, a CAB file containing an OCX file, or an INF file. See the Option combinations table below for details.
Checking this box saves the current settings from the Project, Packages, Additional Files and Code Signing pages of the Web Deployment Options dialog box as the default options. If it is not checked, the settings affect only the open ActiveX project.
To restore the original settings, delete or rename the DEFPROJ.DOF file.
If your ActiveX control depends on any packages or other additional files, these must be included when you deploy the ActiveX control. When the ActiveX control is deployed with additional packages or other additional files, a file with the INF extension (for INFormation) is automatically created. This file specifies various files that need to be downloaded and set up for the ActiveX library to run. The syntax of the INF file allows URLs pointing to packages or additional files to download.
Web deployment options are displayed in the following tabs and described in sections below:
The following table summarizes the results of choosing different combinations of package, CAB file compression and code signing Web deployment options.
The project tab enables you to specify file locations, URL, and other deployment options for the project. The options on the project tab apply to the ActiveX library file or CAB file containing the ActiveX control and become the default options for any packages and additional files deployed with the project.
Note: The locations specified are paths only, not complete file names.
In addition to specifying the locations for your ActiveX files, the project tab also allows you to specify whether to use CAB file compression, version numbers, code signing, and so on. The following table lists the options you can select:
The packages tab lets you specify how to deploy the packages used by the project. Each package can have its own settings. When deploying your ActiveX control, you can specify individual deployment options for each required package file used by the project as part of your deployment. Each of these packages can be code signed and put into CAB files. Packages that ship with Delphi are already code signed with the Inprise signature.
To modify the settings for a particular package, select the package in the "Packages used by project" list box, and modify the settings as needed.
The output options allow you to specify if the package has version info and if it is code signed.
Get the version info from the resource in the package file and enter it into the INF file for the project. | |
The Additional Files tab enables you to specify additional files, such as .DLL files, .INI files, resources, etc., that must be deployed with the ActiveX control.
To add a file to be deployed, click on the Add button. This brings up a dialog from which you can browse and select a file. Each file you add is added to the "Files associated with project" list box.
To modify the settings for a particular file, select the file in the "Files associated with project" list box, and modify the settings as needed.
If the file contains VersonInfo resources, get the version info from the resource in the file and enter it into the INF file for the project. | |
The Code Signing tab provides a way for users of the control to determine who wrote the control and to be assured that the control has not been modified since it was signed. Each file that you deploy can be code signed. Signing data does not alter it; it generates a digital signature that is added to the file.
To create a digital signature, a hash value (also known as a message digest) is first created using the selected Cryptographic digest algorithm. This hash value is then signed, using the Private key.
For the private key and credentials certificate files, contact Microsoft Corporation.
To code sign your ActiveX control, you must provide a private key and credentials certificate file. Specify these values in the Required Information section of the Code signing tab.
The private key is known only to its owner and is used to generate the signature. To obtain this file, contact Microsoft. |
In addition to the required information, you can optionally add information to allow clients to obtain the application and company name:
Application name as you would like it to appear in the digital certificate displayed by the Web browser. | |
A URL that provides a link to a Web tab for the product or company. |
Each vendor has a certificate that they use when code signing the file and this certificate must be renewed each year. Vendors often timestamp their digital signatures to verify that their vendor certificate was valid when the file was code signed. You can choose a timestamp server that generates the timestamp for your digital signature.
Choose one of the following cryptographic digest algorithms. MD5 is the most commonly used and the default. You may want to select one algorithm over the other if your browser does not support the other.
pubsweb@inprise.com
Copyright © 1999, Inprise Corporation. All rights reserved.