![]()
Subclassing in the Visual DataFlex IDE
A Data Access Worldwide White Paper
by Vincent Oorsprong
December 2002
Last Edited: June 7th, 2003
Overview
The aim of this document is to
supply information about a new wizard I developed for Visual DataFlex. The
wizard helps in creating one or more subclasses by supplying the necessary DataFlex code
and by making the IDE aware of the new class.
Visual DataFlex, WebApp and Character Mode DataFlex (up from revision 3.0, released in 1990)
allow you to create an Object Oriented Program. When creating a visual or a
non-visual interface, you are creating objects of a certain class. The class library
delivered with the product might cover all your immediate wishes, but the
ability to create new classes will enhance your programming knowledge and
efficiency in the long run. As soon as you add a procedure, a function or a new property definition to an object, the compiler will
automatically create a class for you with the programmed extension and then base your object upon this class. If you instead want to use your own classes and want to use them in the Visual DataFlex IDE, you need to make the IDE aware of these new
classes.
Why
Subclassing?A
New Class is Born
Figure 1: Object coding instead of using a class.
Making the IDE
Aware of Our Class
Figure
2: Error reading source code
| Keyword | Description |
| No_Visible | This property will not appear in the property list |
| No_Generate | This will never get generated to a source file. Usually used in conjunction with No_Visible |
| Always_Generate | This property is always written to the source file |
| No_Execute | This property is not directly executed within the IDE. It can be loaded, changed and saved. This can be used when a sub-class is being defined in the meta-data that contains properties not known to the IDE. |
| Item | When loaded and saved this property is a zero item property. e.g., Set Value item 0 to var. |
What Else Can We Do with the DFC File?
The following table shows IDE instructions which are effective in the IDE design only.
These instructions will change the way the IDE works with the object of the class. For
example, the IDE can write the package name to include the Visual DataFlex code at compile time. This helps you in
that you do not need to write too many USE
statements anymore.
| Property Name | Description |
| ObjectNameMask | Initial object name. As a part of the name one can add <count> which will be the current counter for objects from this class. This makes object names like dbForm1, dbForm2 etc. |
| Control_Type | What type of control is it? Used to tell the IDE whether the control is database aware or not. |
| Band_Allowed | Can the control be Selected (rubber-band placed around it)? |
| Move_Allowed | Can the control be moved? |
| MoveSize_Allowed | Can the user move or size the control (for example, TabPages cannot be moved or sized, as their parent controls those properties) |
| Drop_Allowed | Can controls be dropped onto this class? Valid values are TRUE, FALSE and any number. When any number is used only objects of that number can be dropped on top of this object. Specifying this value is done via the Type_Of_Drag property. |
| Type_Of_Drag | What type of drag operations are permitted? |
| Item_Based_Object | Is the class item-based? |
| Floating_Menu_Id | What is the object-id of the Context Menu to use? Only predefined context menu's can be used. |
| Row_Based_Object | Is the class row-based? |
| Entry_Item_Object | Should an Entry_Item be generated? |
| ClassVersion | Implemented, but not currently used |
| ClassVendor | Implemented, but not currently used |
| ClassPackage | The name of the file that contains the VDF class. When an instance of the class is used, this property will be written out as a "Use" statement. For example, if you set this property to "BigButton.pkg", the SRC file would include a line: "Use BigButton.pkg". If you include all your classes in the pre-compiled package, you will not need to set this property, otherwise, you will always set it. |
Figure
3: Register the class in the IDE
The ClassCloner
Wizard
To make it easier for anyone to create a subclass from an existing DAW global or workspace class I wrote
a wizard that does the following:

Figure
4: Welcome to the ClassCloner wizard
If you have started the ClassCloner wizard you will see the screen as captured in figure 4. The only options here are 'next' and 'exit' and since we have the intention of creating a new subclass, the logical step is to click the Next button.

Figure
5: Select a workspace.
The next step in the subclassing process is to select the workspace of your choice. The current user workspace, if available, will be highlighted in the screen captured in figure 5. By selecting a workspace you will tell the wizard to load directory information and the subclass layer, if it exists, from this workspace. You can always go back to this screen if you think you made a wrong choice. If you select a different workspace all previously made choices will be undone.

Figure
6: Create one or more subclasses in one run.
The wizard page captured in figure 6 lets you make a choice between creating one subclass or multiple subclasses in this wizard session. The default choice is creating one subclass. The option to create multiple subclasses is built into the wizard to make it possible to subclass a complete workspace subclass layer.

Figure
7: Select source class.
The next few steps show how the single subclass process works. This is step 1 of this process. In this step you select in the comboform the source class to base your subclass on. The comboform shows all the global and workspace classes registered in the IDE's classlist. You can only continue after selecting a source class.

Figure
8: Enter new subclassname and IDE controls palette page.
The next step in our process will be entering the new subclassname and the location inside the IDE's Controls Palette. Do not use an existing classname since there is no checking here that prevents you from doing so. When you leave the palette pagename blank you cannot create an object of your subclass via drag-and-drop. The classname, however, will be known to the IDE and you can create objects based on this new class. This is particularly useful for subclassing component level classes (dbView, dbModalPanel, ReportView, ClientArea etc.) or classes that are treated in a special manner by the IDE (tabpages for example).

Figure
9: Finish the wizard.
This page shows you a summary of the actions that will take place when you click the
'Finish' button. If you do not agree with the information you should click 'exit' or go back through the wizard and change your choices. Until the
'Finish' button has been clicked nothing is permanent yet.
The next 4 paragraphs are important for
you if you choose "multiple classes" in the wizard page capture by figure 6 .

Figure
10: Select multiple source classes.
This is the first step if you choose the option to subclass more than one class at the same wizard session. Select the classes you want to subclass by clicking the checkbox or clicking the button labeled 'Select All' if you want all or almost all classes. It might be easier to deselect a few classes after clicking the 'Select All' button instead of selecting all classes that you want to subclass individually. You need to select at least one class before you can continue with the wizard in forward navigation.

Figure
11: Enter options to apply to all the new subclass names.
In this page you can specify what general options you want to apply to all the classes you are subclassing. The first choice is the prefix you want to use for your subclassing. Entering no prefix is possible but then you should add the prefix or suffix in the next wizard page to avoid duplicate classnames. The sample box will show you how the prefix will look like. The second form in this page lets you enter a prefix to be used for all palette pages. When you do not enter a prefix here the subclasses end up in the same palette page as the source class. This is allowed and it is up to you whether you like this or not. The last choice on this page gives you the option to remove a leading 'c' in front of classname or not . The 'c' in Hungarian Notation (HN) stands for 'class' and it is considered a bit weird to have a classname like 'cMycImageList' when creating a subclass from 'cImageList'. A subclassname like 'cMyImageList' would be better. The default for the checkbox is true and the sample form shows the result. Do not use this if the 'c' is really part of the name and not there because of HN reasons.

Figure
12: Check the new classnames or edit the names individually.
This list will contain the selected classes for subclassing. Each subclassname and/or palette pagename can be changed manually. Verify that you are happy with the information shown in this page. You cannot remove classes from this list here. Instead, you will need to go back to the step where you selected one or more classes for subclassing in order to remove a class.

Figure
13: Finish the wizard.
This page shows you what the wizard is going to do when you click the 'Finish' button. This time it does not list all the classes individually but information about the destination location. If you do not agree with the information you should click 'exit' or go back through the wizard and change your choices. Until the 'Finish' button has been clicked nothing is permanent yet.
To incorporate the wizard into your VDF environment, download the attached ClassCloner wizard for VDF8.3 or the ClassCloner wizard for VDF9.0. The wizard is created with Visual DataFlex 8.3 or 9.0 and
only runs with that revisions. To use this wizard unzip the ClassCloner.Exe from the archive and place it in the BIN directory of your Visual DataFlex development set. You can start the wizard by double clicking
or by adding the wizard to the utilities menu in the IDE (the better
alternative).

Figure
14: Add the wizard to the utilities menu of the IDE.
Data Access
Worldwide
14000 SW 119 Ave
Miami, FL 33186
305-238-0012
Domestic Sales: 800-451-3539
Fax: 305-238-0017
email: sales@dataaccess.com
Newsgroup Server: news.dataaccess.com
Internet: http://www.dataaccess.com
Data Access Worldwide - Asia Pacific
Suite 5, 333 Wantirna Road, Wantirna VIC 3152 Australia
Phone: +61 3 9800 4233 f: +61 3 9800 4255
Sales: asiapacific@DataAccess.com
Support: support.asiapacific@DataAccess.com
Internet: http://www.DataAccess.com/AsiaPacific
Data Access Worldwide - Brasil
Av.Paulista, 1776 - 21st.Floor
São Paulo -SP - Brazil
CEP 01310-921
Phone: 5511-3262-2000
Fax 5511-3284-1579
Sales: info@dataaccess.com.br
Support: suporte@dataaccess.com.br
Internet: http://www.dataaccess.com.br
Data Access Worldwide - Europe
Lansinkesweg 4
7553 AE Hengelo
The Netherlands
Telephone: +31 (0)74 - 255 56 09
Fax: +31 (0)74 - 250 34 66
Sales: info@dataaccess.nl
Support: support@dataaccess.nl
Internet: http://www.dataaccess.nl
Data Access
Technical Support
800-451-3539 / 305-232-3142
email: support@dataaccess.com
Visit our Support Home page to see all of our Support options: http://www.dataaccess.com/support
Copyright Notice
This document is property of Data Access Corporation. With credit to Data
Access Corporation for its authorship, you are encouraged to reproduce
this information in any format either on paper or electronically, in
whole or in part. You may publish this paper as a stand alone document within
your own publications conditional on the maintenance of the intent,
context, and integrity of the material as it is presented here.
DataFlex
is a registered trademark of Data
Access Corporation.
Windows is a
registered trademark of Microsoft Corporation.
NO LIABILITY FOR CONSEQUENTIAL
DAMAGES
To the maximum extent permitted by applicable law, in no event shall Data Access
Corporation be liable for any special, incidental, indirect, or consequential
damages whatsoever (including, without limitation, damages for loss of business
profits, business interruption, loss of business information, or any other
pecuniary loss) arising out of the use of or inability to use any information
provided in this document, even if Data Access Corporation has been advised of
the possibility of such damages. Because some states and jurisdictions do not
allow the exclusion or limitation of liability for consequential or incidental
damages, the above limitation may not apply to you.