5.3 What s the deal with the VCX file?

What's the deal with the VCX file?

Visual FoxPro stores all its visual classes in a file with the extension .VCX. Actually, it stores its classes in two files: The VCX and the VCT, which is a familiar combination for FoxPro programmers. Really and truly, those two files are DBF and FPT files. So you could open the VCX with a regular USE command and BROWSE through the records like so:

USE Base.vcx
BROWSE

This is useful when you want to make certain kinds of changes (like correcting typos that point 50 classes to the wrong parent class) or to fix broken VCX files (yes, it can happen). Also, there are special fields that are just there for the programmer so he can extend the VCX (see below).

The VCX structure

The VCX structure is relatively simple. Most of the information is stored in a handful of memo fields, mostly in plain English. Some of the memo fields have binary information (like compiled code or OLE information). The VCX (visual class libraries) file structure is identical to the SCX (forms) file structure.

Later in this section, I'll describe how this structure is used in different scenarios to store classes. Table 2 describes the basic structure and the meaning of the fields.

 

Table 2. The VCX/SCX structure.

Field Name

Type

Description

Example

Platform

C (8)

VCX/SCX Used to specify the platform where this object is used. In single platform VCXes, there is one record per object. In multi-platform environments (Windows and Mac, for instance), there will be one record per platform. In this case, both records that describe the same object share the same unique ID.

Records that aren't platform-specific are usually listed as "COMMENT". Also, the header record (the very first record) is marked as a "COMMENT".
Visual FoxPro isn't a cross-platform tool anymore (once upon a time, FoxPro was available on DOS, Windows, Macintosh and UNIX platforms, but now it is Windows only). Therefore, this field exists only for compatibility reasons.

WINDOWS

UniqueID

C (10)

VCX/SCX Unique ID for classes and objects. Records that describe the same object for different platforms share the same unique ID. Records that don't describe a class or object don't have unique IDs; instead, they have special keywords that describe the record type. The header record (record number 1), for instance, has the keyword "Class".

SCX These files have the keyword "Screen" in the header record, instead of "Class".

_QVW1055YU

TimeStamp

N (10)

VCX/SCX Contains the date of creation (or last modification) of this particular record in an encoded format. Records that don't describe a class or object have TIMESTAMP=0.

498761340

Class

Memo

VCX/SCX Defines the parent class if the current record is a class. If the current record describes a member object, this field defines the class for the object.

Note: The class name is always in lowercase.

mycommandbutton

ClassLoc

Memo

VCX/SCX The relative path to the class library that contains the class referenced in the "Class" field. If the class is a Visual FoxPro base class, this field is empty.

..\libs\test.vcx

BaseClass

Memo

VCX/SCX Contains the name of the Visual FoxPro base class that is the root of the current class (or object).

commandbutton

ObjName

Memo

VCX/SCX Defines the name of the current class or member object.

cmdOkButton

Parent

Memo

VCX/SCX Defines the parent object of the current object. This field is used only if the current record describes a member object. Otherwise it is empty.

form1

Table 2, continued

Field Name

Type

Description

Example

Properties

Memo

VCX/SCX Contains a list of all overwritten and new defined properties and their values.

Note: This field is used to store the values of the properties. It is not used to define new properties.

Height = 22
Width = 69
FontSize = 8
Caption = "OK"
Name = "cmdok"

Protected

Memo

VCX/SCX Contains a list of all properties and methods that are protected or hidden. If a property or method is hidden, its name is followed by a caret (^).

scAlias
slUpdated^
scCodeWord

Methods

Memo

VCX/SCX Contains the source code for all methods of the current class or object. If the current record describes a subclass of a subclassed composite class that has overwritten methods for member objects (pseudo subclassing), this field might also contain code for one of the member objects of the current class. (See below for more information about pseudo subclassing and how this is stored in VCX files.)

Note: After code changes in this field, the VCX has to be recompiled. Otherwise, results are unpredictable.

PROCEDURE Click
this.Save()
thisform.Release()
ENDPROC

PROCEDURE Save
wait window "Save"
ENDPROC

ObjCode

Memo

VCX/SCX Stores the compiled version of the code in the Methods field.

 

Ole

Memo

VCX/SCX Contains binary information about OLE and ActiveX classes and objects.

 

Ole2

Memo

VCX/SCX Contains binary information about OLE and ActiveX classes and objects.

 

Reserved1

Memo

VCX Used to define the beginning of a new class definition. If the current record is the beginning of a new class definition, this field contains the word "Class". Otherwise, it is empty.

SCX Not used.

Class

Reserved2

Memo

VCX/SCX Contains the number of records that define the actual class. If the class has member objects, each member object has its own record in addition to the actual class record. The actual class record is counted as well as all the records for the member objects. So if the number is 2, this indicates a container with one member object. If the actual class doesn't have any member objects, the value of this field is 1.

2

Reserved3

Memo

VCX Contains a list of all new defined properties and methods as well as a short description. The description is separated from the property/method name by a space. Array properties have a leading caret (^). Methods begin with an asterisk (*).

SCX Not used.

ScAlias
snResult
slUpdated
^saMyArray
*MyMethod

Table 2, continued

Field Name

Type

Description

Example

Reserved4

Memo

VCX The relative path and file name for a bitmap that will be displayed in the Form Controls toolbar.

SCX Not used.

..\bmps\ok.bmp

Reserved5

Memo

VCX The relative path and file name for a bitmap that will be displayed in the Class Browser.

SCX Not used.

..\bmps\ok.bmp

Reserved6

Memo

VCX/SCX Defines the scale mode (Pixels/Foxels) for the current class or object.

Pixels

Reserved7

Memo

VCX/SCX Contains the description of the current class or object. This description can be defined in the Class Information dialog, or in the Class Browser.

This class saves the current form.

Reserved8

Memo

VCX/SCX If the current record describes a class, this field contains the relative path and the file name of a header file. If the current record is a member object and NoInit is selected in the Class Information dialog, the value of this field is "NOINIT".

..\vfp\foxpro.h

NOINIT

User

Memo

VCX/SCX Not used by Visual FoxPro. Available for the user/programmer to extend the VCX structure.

*:GenX

How Visual FoxPro stores visual classes

Now you know the basic structure of a visual class library, but this isn't quite enough to understand VCXes. Every class library has a number of records, most of which define classes; others hold additional information about the library in general.

The first record of every VCX is the so-called "header record." This record gets added as soon as class libraries (including empty ones) are created. It specifies whether the current file is a class library (VCX) or a form (SCX). If it is a class library, the UniqueID is "class"; otherwise it is "screen". In addition, the Reserved1 field contains some information about the version of the class library, but this is all relatively trivial.

Once you start to add classes to a library, it gets a bit more complex. Let's start with a subclass of the Visual FoxPro base class Custom. This is a simple case, because custom classes don't have member objects (at least not in the visual editor). For this reason, a single record can describe this class. Refer to Table 1 to see the values of each field. Because we created a subclass of a Visual FoxPro base class, the name of the parent class is the same as the name of the base class, and the name of the class library is empty. By the way, this information is always stored in lowercase. The only other detail worth explaining is the Reserved2 field, which contains the number of records that describe the class. In this case it would be 1. This seems obvious, but a lot of people get confused for a couple of reasons. First of all, everybody seems to think that the Reserved2 field contains the number of records describing member objects. This is incorrect. The actual class record itself gets counted as well. The second reason for the confusion is a comment record that gets added after the class definition. A lot of people seem to think that this record should be counted as well, and therefore, the number in Reserved2 should be 2. This is incorrect, too, because the comment record is optional. If you created a low-level visual class by directly hacking the VCX, you wouldn't have to worry about the comment record. But the first time this class was modified using the Visual Class Designer, Visual FoxPro would add this record automatically.

Let's have a look at a composite class. As an example, we'll use a form class that has an OK button as a member object. Two records can describe this construction: one for the form class and the other for the member object (the button). Still, this construction is very simple. All properties and methods belonging to the form will be stored in the first record, and all the ones belonging to the button will go in the second record. Some information will be defined in the first record only, like the scalemode (pixels or foxels) because they are valid for the whole class. However, don't confuse this information the ScaleMode property.

Let's take a closer look at the Methods memo. As mentioned before, this field holds the source code for all methods we create. To allow FoxPro to differentiate between different snippets, a simple solution is applied: Every method gets an additional PROCEDURE and ENDPROC line, as in the following example:

PROCEDURE Click

wait window "Test"

ENDPROC

PROCEDURE Destroy

wait window "Destroy"

ENDPROC

When you modify this code in the Visual Class Designer, Visual FoxPro does not show those two lines. The example above only has two lines of code in the Visual Class Designer.

The properties are stored in an even simpler fashion one line per property. Here are the contents of the form record:

DoCreate = .T.

Caption = "Form2"

Name = "test"

And here we have the contents of the member object's (the button's) Property field:

Top = 84

Left = 120

Height = 23

Width = 70

Caption = "\<OK"

Name = "cmdOK"

All properties start with capital letters because they are internal properties defined by the base class. As soon as you use user-defined properties, they will be in lowercase to make it easy to differentiate.

Once we subclass our composite class, it gets a little more complex. A single record can describe the new class, even though it has the button as a member object. The definition of the member object is inherited from the parent class. This, of course, introduces some difficulties when changing properties or adding source code (pseudo subclassing), since we don't have a record in which to store these properties. The only alternative is to store this information with the container record. In this case, we have to identify the object the property or method belongs to.

The Method field from above would look like this in a subclass:

PROCEDURE Command1.Click

wait window "Click"

ENDPROC

PROCEDURE Command1.Destroy

wait window "Destroy"

ENDPROC

The same is true for the properties. Here is the Properties field of the container record:

DoCreate = .T.

Name = "test2"

Command1.Name = "Command1"

I should mention some exceptions and special cases, which are all related to special types of container classes and objects. PageFrames are a perfect example. Even though a PageFrame is a combination of multiple objects (the PageFrame itself as well as each Page), it is stored as one record in the VCX. FoxPro simply knows the number of page objects because the PageFrame has a PageCount property. This has a couple of disadvantages one is that Visual FoxPro always uses the Page base class to add new pages. Special page classes can only be added manually outside the Visual Class Editor. The same is true for other containers, such as CommandGroups and OptionGroups.

You could explore the previous example even further by adding subclasses and additional member objects, but you wouldn't be learning anything new. The class definitions would grow larger and more complex, but they would still follow the rules discussed above.

Knowing about the VCX file is important for various reasons. This is true for all programmers, not only for third-party tool providers and other people who might be interested in writing Class Browser add-ins. Class libraries can be damaged due to various reasons when this happens, you can lose months of work. But often a library can be fixed easily if you know about the VCX structure. It often happens that there is a problem when saving a class the old copy of the class might already be deleted but the new version is not yet saved. It appears that the class simply disappeared, but it is still there, marked as deleted. If you know about the VCX structure you can simply open the library and recover at least an old version of your class.

Sometimes you might want to do a large number of similar tasks in your class libraries. Let's say you discover that you used the wrong parent class for a whole set of classes. Redefining every single one of them in the Class Browser can be cumbersome. It is a lot easier to open the VCX and change one or two fields in all influenced records, using a REPLACE ALL command with a FOR condition.

Compiling a class library

When you modify code and close a code snippet of a visual class, Visual FoxPro compiles that code right away and stores it in the ObjCode field of the VCX, while the source code gets stored in the Methods field. Those two fields need to be synchronized at all times. When you modify the Methods field directly, opening the VCX like a DBF, you need to make sure that those changes get compiled. Otherwise you will find the funniest results when modifying the class the next time, such as code from other snippets appearing in wrong methods, or old code reappearing and the like. To compile the changes, use the COMPILE CLASSLIB command, like so:

COMPILE CLASSLIB MyClassLib.vcx

This works fine when you have full control over the library, but you need to be careful if you manipulate the source code using a Class Browser add-in. Compiling the class usually isn't possible because the browser is using the file. For this reason you need to close the library, compile it, and reopen it.

Cleaning up class libraries

It is essential to clean up your class libraries. They tend to grow huge, even though their real contents might be tiny. This is due to the fact that every time you modify a class, Visual FoxPro marks the old records in the VCX as deleted and adds new records at the bottom.

Cleaning up a class library is simple. You can open the VCX exclusively and do a simple PACK. This works well in most scenarios. However, I recommend using the Cleanup feature of the Class Browser (see above).

How to protect your source code in a VCX

The source code for all methods of a class is stored in the Methods field of the VCX. When this code is modified, Visual FoxPro compiles it right away and stores the compiled version in the Objcode field. This is the only version of the code that Visual FoxPro needs to instantiate the class and execute its methods. So when you want to give away a VCX library without giving away your source code, you can simply delete the contents of the Methods field, but make sure you do this on a copy of the original library. Otherwise you won't be able to modify the classes in this library anymore.



Advanced Object Oriented Programming with Visual FoxPro 6. 0
Advanced Object Oriented Programming with Visual FoxPro 6.0
ISBN: 0965509389
EAN: 2147483647
Year: 1998
Pages: 113
Authors: Markus Egger

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net