ActiveForms, Part I

by Bob Swart

In this article, you will see how to build and deploy ActiveForms using C++Builder… all without writing a single line of code! In Part II of this series I will show you how to deploy your ActiveForms. In Part III, I will show you how to build thin client ActiveForms by incorporating Inprise MIDAS techniques.

Creating an ActiveForm

TActiveForm is the base class for a VCL form exposed as an ActiveX control. TActiveForm represents a form that is created via the Active Template Library (ATL) and used as an ActiveX control in a host application. This makes it very easy to embed visual and non-visual components on the ActiveForm. The result is a complex ActiveX control that can be used in C++Builder itself, on a Web page, or in other development environments such as Visual Basic or Delphi.

To create an ActiveForm in C++Builder, first select File | New from the main menu. Next click the ActiveX tab in the Object Repository, and double-click the ActiveForm icon. When you do, the ActiveForm Wizard will be displayed. In the ActiveForm Wizard, you need to specify the name of the ActiveForm (the default name is ActiveFormX), the name of the implementation unit, and the project name. When you change the ActiveX name, C++Builder will change the name of the implementation file and the project file. You can change the filenames, of course, to use names you prefer. The project name will also result in the final name of the ActiveX control. For this example I named the project ActiveF so the final output file will be named ACTIVEF.OCX. Starting with version 4 of C++Builder, the threading model is set to Apartment. This model is required to use the ActiveForm in Internet Explorer version 4 or higher.

You have the option to include an About box for your ActiveForm, a design-time license, and version information. Including a design-time license will result in an ActiveForm that can only be used in a run-time environment, or at design-time if the license file is present. More importantly, choosing this option will also result in an ActiveForm that won’t work inside Internet Explorer because the ActiveX is designated as a design-time control. I seldom use this option, but it can certainly be useful for demo editions of commercial ActiveForms.

The option that you should always check is Include Version Information. You'll need this information when deploying new versions of your ActiveForms (updates, bug fixes, and so on). Obviously, without version information, there is no way the browser can detect that an update is available for download.

Easy COM, easy go

After you click on the OK button of the ActiveForm Wizard, C++Builder generates a number of source files. One file is the source for your new ActiveX project (ACTIVEF.CPP in this case). This file defines the four routines you need to export in order to turn the library into a real OCX control.

Another file is the source for the ActiveForm itself, ACTIVEFORMIMPL.CPP, which contains almost 650 lines of code. Much of this code consists of complex COM interface methods that you really don't need to be concerned with. This is especially true if you just want to design and deploy an ActiveForm inside a Web browser without learning everything there is to know about COM, type libraries, and DCOM.

If you take a look at the ActiveX project source file, you will see that the project uses two more files called ACTIVEF_ATL.CPP and ACTIVEF_TLB.CPP. These two files are the ATL source and the COM type library for the ActiveForm. The main thing you need to know about these files is that they are generated automatically whenever the type library changes. As such, you should never make any manual changes to these files, as they will always be overwritten when the type library is regenerated.

For the rest of this article you should consider the ActiveForm a regular visual form that merely needs to be deployed in a somewhat special manner. Before you continue, however, you must make sure to create a stand-alone ActiveForm, one that doesn't require additional files or packages. To do this, go to the Packages tab of the Project Options dialog and un-check the Build with runtime packages option. Next, select the Linker page and uncheck the Use dynamic RTL option. I'll explain the importance of creating a stand-alone ActiveForm in Part II of this series when I discuss how to deploy your ActiveForm.



An ActiveForm client

As an example, you will create an ActiveForm that shows a master-detail relationship between two tables. First, resize the form to 600 x 400. Next drop a TPanel component on the ActiveForm, clear its Caption property, and set its Align property to alTop. Now drop a TTable (name it TableCustomer), a TDataSource, and a TDBNavigator on the panel. Set the DataSource component’s DataSet property to TableCustomer, and the DBNavigator’s DataSource property to DataSource1. Set the Table’s DatabaseName property to BCDEMOS, and its TableName property to CUSTOMER.DB.

Now double-click on the table component to invoke the Fields Editor. Right-click in the Fields Editor and choose Add all fields from the context menu. This will add all fields from the table into the fields list. Select the fields you want to display on the ActiveForm, drag them to the client area of the ActiveForm, and arrange them to your liking. I added the customer number and address information so I ended up with the form shown in Figure A.

Figure A

The ActiveForm looks like a regular form at design time.

Before you continue, you can make sure the database navigator bar always stays at the upper-right corner of the ActiveForm. In C++Builder 4 you can do this easily by modifying the DBNavigator’s Anchors property. Set the Anchor property’s skLeft value to false, and akRight to true. Now the DBNavigator will always be in the upper-right corner of the ActiveForm.

The master-detail relationship

At this point you have the master table finished and you need to set up the details table. Drop another TTable on the ActiveForm and name it TableOrders. Drop a TDataSource and a TDGBrid component on the form as well. Connect the DBGrid to the TableOrders table through DataSource2. Set the DBGrid’s Align property to alBottom. Set the table’s DatabaseName property to BCDEMOS and its TableName property to ORDERS.DB.

To define a master-detail relationship, select the TableOrders table and set its MasterSource property to DataSource1. Now select the MasterFields property in the Object Inspector and click on the ellipsis button to bring up the Field Link Designer. In the Field Link Designer, select the CustNo index from the Available Indexes combo box. Then select the CustNo field in both the Detail Fields and Master Fields list boxes. Now you only need to click on the Add button to link the two tables in a master-detail relationship as shown in Figure B. When you set the Active property of TableCustomer and TableOrders to true, and you get live data at design-time.

Figure B

Setting up a master-detail relationship is easy with the Field Link Designer.

Using the ActiveForm

At this point your ActiveForm is completed. With a few exceptions, all components work just like on a regular form. The exceptions are menus (which will not appear) and the caption of the ActiveForm, which will disappear when the ActiveForm is shown at run-time. (If you want your ActiveForm to show a caption, drop a panel on the form, set its Align property to alTop, and give it the color normally used for the active caption.)

Now save the project and then compile it. After the project is built, choose, Run | Register ActiveX Server from the C++Builder main menu. This registers the ActiveX control with Windows. Next you need to install the ActiveForm into the C++Builder component palette. Close your project and then choose Component | Import ActiveX Control from the main menu. Find "ActiveF Library" in the list of installed controls, select it, and click the Install button. C++Builder will then ask you for the name of the package in which to install the ActiveX control. Choose the default user package, DCLUSR40.BPK, and click OK. C++Builder will then build the package. After the package is built your ActiveForm will be on the ActiveX page of the component palette.

Now create a new project. Select the ActiveFormX control from the ActiveX page and drop it on your form. Resize the control to your liking and run the program. It’s as easy as that! Figure C shows the ActiveForm hosted in a C++Builder program.

Figure C

Here the ActiveForm is hosted in a C++Buidler program.

Conclusion

ActiveForms are convenient for creating complex ActiveX controls. This is especially interesting when you consider that the ActiveForm can be used on a Web page. Next month, in Part II of this series, I will show you how to deploy an ActiveForm on a Web page.