5.4.1 Creating catalogs

Creating catalogs

To fully understand the power of the Component Gallery, you have to create a catalog by yourself. I'll guide you through this process step by step. As an example, I'll use Visual GenRepoX, a public-domain tool I wrote to extend the functionality of the Visual FoxPro report writer. This tool is included with the Developer's Download Files at www.hentzenwerke.com, and future updates will be available from my Web site, www.eps-software.com. One problem with GenRepoX is that it has no real interface because everything happens programmatically. For this reason, many people have trouble getting started. The Component Gallery can help guide you through the tool. Not only is this an easy way for GenRepoX newcomers to learn, but it also allows experts to explore the whole GenRepoX functionality.

The first step is to create a new catalog file. Simply open the Component Gallery's Options dialog, click the Catalogs tab (page 2) and click New. Next, specify a file name (catalogs are regular DBF files), and voila . . . you're done.

The new catalog's name is the file name you specified. Typically you'll want to specify a descriptive and informative name. You can change the name by renaming the catalog item or modifying the item's properties (see Figure 22).

Figure 22. Folder properties of the topmost node of the new catalog.

The variety of options in each property sheet is discussed below. For now, we are only interested in changing some options in the General tab. Here we can change the name, the description and the picture for the catalog. Note that the caption of the dialog is "Folder Properties", even though we are looking at the catalog properties. I'm told this is by design. However, note that this property dialog is essentially different from the property dialogs of the subfolders.

The next step is to create a couple of folders in the catalog. I would like to have folders for the Classes and Programs belonging to Visual GenRepoX, a folder for Documentation, another for Samples, yet another for the GenRepoX Wizards, and finally a folder that allows the user to browse the Web (EPS on the Web). To create a new folder, right-click the Details panel, select New Item, and then select Folder (see Figure 23). All folders listed above are relatively simple to create. You only have to change their captions, descriptions and icons.

Figure 23. Creating a new folder.

Now let's add some items to the folders, starting with Classes and Programs. Figure 24 shows the desired contents of this folder. Basically, this is a summary view of the most important Visual GenRepoX components, which are GenRepoX.prg, an object wrapper for regular Visual FoxPro reports, a subclass of this report wrapper that contains all GenRepoX functionality, and a driver base class, which can be subclassed to create new drivers. There is another folder for existing drivers. Creating these items is straightforward. Right-click in the Details panel and select the kind of item you want to create.

This first folder already demonstrates some of the strengths of the Component Gallery. The created folder provides an overview of the most important Visual GenRepoX components. Without the Component Gallery, you'd have to search through the Visual GenRepoX class library where you'd find a dozen classes, two-thirds of which cannot be used or modified by the user. Then you'd have to find the GenRepoX.prg, which is somewhere on the hard drive. Finally, there are several class libraries with various drivers. Using the Component Gallery is a lot easier. The created catalog shows only the important items, and all of them are in one place. But not only does the Component Gallery show all those items, it also allows you to work with them. The gallery is aware of the different kinds of items it shows, and automatically provides appropriate actions for those items when the user double-clicks or right-clicks on the item. If you go back to Figure 23, you'll see a list of items the Component Gallery is aware of. You can extend this list with your own items if you're missing one. I'll demonstrate this later, using the example of a special GenRepoX report.

Figure 24. The contents of the Classes and Programs folder.

Dynamic folders

So far you've created only simple folders by adding items manually, but the Component Gallery also allows special kinds of folders, called dynamic folders. These folders can be direct links to a directory on the hard drive (see Figure 25), or even to a location on the Internet (see Figure 26).

When using dynamic folders to point to a directory on the hard drive, Windows Explorer is utilized to display the contents of the folder inside the Component Gallery.

Figure 25. A dynamic folder pointing to C:\My Documents.

Figure 26. A dynamic folder pointing to the Internet.

To create a dynamic folder, you simply set the Dynamic Folder property in the Node tab of the folder's Properties dialog (see Figure 27). You can specify an Internet address (such as http://www.eps-software.com) or a directory on your hard drive (such as C:\My Documents).

Figure 27. Creating a dynamic folder.

Now you also know how I created the links to the EPS Web page. I simply created dynamic folders that show the contents of my Web site. There is another way to do this: Instead of a dynamic folder, you could create a Web item. The difference is that dynamic folders are displayed in the Component Gallery, while Web items open an instance of Internet Explorer to display the desired Web page.

Creating links

Typically, a catalog shows the same item in more than one node. An example would be the Checkbox driver in the Visual GenRepoX catalog. (This example ships with Visual GenRepoX 3.0 in the Samples folder.) This is a useful driver, so it should also be in the Drivers folder. Creating the item twice wouldn't be a good solution because this would make the catalog hard to maintain. The better way is to create a link. To do this, first create the item for the Checkbox driver in the Drivers folder. Then right-click the item and select Create Link. The link is created in the current folder and looks just like the original item. The only hint that the item is a link is its name. Also, when you look in the Properties dialog of this new item (the linked one), all properties but the name are read-only.

You can now drag and drop the link into any folder you want.

Understanding item types

The strength of the Component Gallery is its flexibility, which is based on the great variety of different items the gallery can handle. The default list of items already handles the most important item types. However, you might want to introduce your own items. A good example is the Visual GenRepoX catalog created above. Even though Visual GenRepoX reports are regular FoxPro reports, they have to be executed slightly differently in order to allow GenRepoX to handle things differently and to extend the report writer's functionality. For this reason, you have to create a special item type that has the ability to execute those special reports. Later I'll explain how to do that, but before you can create our own items, you should understand how the Component Gallery handles item types.

How item types are handled

For every item displayed in the listview or treeview panel of the Component Gallery, the gallery internally instantiates another object representing the item's behavior. This object is responsible for managing the user interaction and for triggering and executing possible actions. For each item type, the Component Gallery uses a different class. These classes are stored in Vfpglry.vcx, located in the Home()+ '\gallery' directory. The source code for these classes, as well as the source code for a generic item class (which is the parent class of all other items), ship with Visual FoxPro. You can modify these items, or better yet, subclass them to provide your own functionality.

When you add an item to a catalog, you first select the item type, which also predefines the class the gallery is supposed to use. You can change this setting in the Node tab of the item's properties (see Figure 28). This way you could set up another item type that the gallery supports but that isn't exposed through the standard interface (see below), or you could invoke your own classes if you want different or new behavior (see below).

Figure 28. Specifying a class for the item behavior object.

When you double-click, right-click or drag and drop an item, the call is passed on to the underlying behavior object, which then decides what to do. This includes standard behavior like modifying or executing an item, as well as defining the right-click menu and executing complex tasks such as invoking wizards and the like. Many standard items share behavior that is coded in a shared behavioral object. You can call this object rather than executing actions directly in each individual object. You can also reference and use this object in your own behavioral objects (see below).

Standard items

The Component Gallery supports a number of standard items, only a handful of which are exposed through the interface. Table 3 lists all items stored in the Vfpglry.vcx and the _gallery.vcx class libraries. You can use these items in different ways: You can specify the class name in the Properties dialog of each item (Figure 28), you can add new item types to the standard interface (see below), and you can subclass the existing items to create new behavior.

Table 3. Standard items that ship with Visual FoxPro 6.0.

Item class

Class library

Parent class

Description

_activexfolder

Vfpglry.vcx

_folder

Used for folders only. A folder based on this item type automatically displays all ActiveX controls installed on the system.

_activexitem

Vfpglry.vcx

_item

Used for ActiveX items, including ActiveX controls (OCX) as well as other COM servers (EXE/DLL).

_catalogitem

Vfpglry.vcx

_item

Allows you to link to other catalogs.

_classitem

Vfpglry.vcx

_item

Used for every Visual FoxPro class item. The class can be stored in a VCX or a PRG.

_dataitem

Vfpglry.vcx

_item

Used for any Visual FoxPro data source, including database containers (DBC), tables (DBF), and all kinds of views.

Table 3, continued

_fileitem

Vfpglry.vcx

_item

Every file can be managed through the Component Gallery using this item type. The Component Gallery reads the registry for more information about each particular item type and how to handle it.

_folder

_gallery.vcx

_item

A generic folder item. Subclass this class when you want to create your own folder class.

_formitem

Vfpglry.vcx

_item

Handles Visual FoxPro forms (SCX).

_imageitem

Vfpglry.vcx

_fileitem

A special kind of file item that handles all kinds of image files.

_item

_gallery.vcx

_item

All other item classes are subclassed from this class. Use this class as a parent class when you want to create your own item behavior classes.

_menuitem

Vfpglry.vcx

_item

Manages Visual FoxPro menus (MNX).

_node

_gallery.vcx

_item

Generic class used as a base for all kinds of items and folders.

_programitem

Vfpglry.vcx

_item

Handles all kinds of Visual FoxPro program files such as PRGs and header files (H).

_projectitem

Vfpglry.vcx

_item

Used to manage Visual FoxPro projects.

_reportitem

Vfpglry.vcx

_item

Used to manage Visual FoxPro labels (LBX) and reports (FRX).

_sampleitem

Vfpglry.vcx

_item

Can be used to run executable Visual FoxPro files such as EXEs, APPs, FXPs, PRGs, SCXs, FRXs and more.

_shareditem

Vfpglry.vcx

_item

Has some generic behavior that is called from various other items.

_sounditem

Vfpglry.vcx

_fileitem

A special kind of file item that handles sound files in WAV or RMI format.

_templateitem

Vfpglry.vcx

_item

Used to execute wizards.

_urlitem

Vfpglry.vcx

_item

Handles the navigation to all kinds of Web addresses that Internet Explorer can handle. This includes Web sites, HTML documents, Visual FoxPro active documents, Active Server Pages and more. The URL can be on the World Wide Web as well an on an intranet environment and even on your local hard drive. The URL also can be a directory name. In this case the result is a Windows Explorer-like view.

_videoitem

Vfpglry.vcx

_fileitem

A special kind of file item that handles video clips in AVI format.

It is important to understand three basic item classes, which are _node, _item, and _folder. The _node class is the most basic and defines the common behavior of all kinds of items, whether items or folders. The _item class is a subclass of _node, and the _folder class is a subclass of _item. Tables 4 and 5 explain the _node class.

 

Table 4. Properties of the _node class.

Property

Description

_cVersion

Contains some version information.

AItemIndexes[x]

If the item is a folder, this array contains the indexes of all sub-items. There is a collection of items in the gallery. You can use the indexes in this array to reference all the active items.

Builder

Used at design time only. It can define builders and extended builders (BuilderD) to be used with this item.

BuilderX

Used at design time only. It can define builders and extended builders (BuilderD) to be used with this item.

cAlias

Alias of the catalog cursor for an item or folder.

cCatalog

The file name of the current catalog.

cCatalogpath

Full path of the current catalog.

cClass

Default class used for all sub-items.

cClasslib

Class library that contains the definition of the current class.

cClassname

Class used for the current item.

cClick

Allows you to define an alternative method that handles the Click event. To redirect the call to a Test() method, set this property to oTHIS.Test().

cComment

Comment as stored in the catalog.

cDblclick

Allows you to define an alternative method that handles the double-click event.

cDesc

Item description.

cDragdrop

Allows you to define an alternative method that handles the DragDrop event.

cDragdrop2

Allows to define an alternative method that handles the Drop event of the class icon onto some target object.

cFilename

Name of the currently referenced file.

cFolderpicture

Bitmap or icon used for the current folder (if the item is a folder).

cId

Unique ID that identifies the catalog and the item.

cId2

Catalog ID.

cItemclass

Class used for the behavior object.

cItemclasslibrary

Class library containing the class for the behavior object.

cItemtpdesc

Alternative item types for certain files (redirect).

cItemtype

Display name of the current item type.

cKeypress

Allows you to define an alternative method to handle the KeyPress event.

cKeywords

Keywords that identify the current item.

cLink

Optional ID that links the current item to another item.

cObjecttype

Item type.

cOledragdrop

Allows you to define an alternative method to handle the OLEDragDrop event.

cOledragover

Allows you to define an alternative method to handle the OLEDragOver event.

cParent

String that describes the parent object (folder).

cPicture

Item image (icon or bitmap).

cProperties

Property settings specified in the scripts.

cRightclick

Allows you to define an alternative method to handle the right-click event.

cScript

Script source of the current item.

cScriptmethod

Internal.

cSourcealias

Alias of the table that defines the current item.

Table 4, continued

Property

Description

cSourcecatalog

File name and path of the current catalog.

cSourcecatalogpath

Path of the current catalog.

cStatusbartext

Text displayed in the status bar.

cTarget

Internal.

cText

Item text.

cTooltiptext

The item's tooltip text.

cType

Specifies whether the current node is an item or a folder.

cTypedesc

Specifies the type description text for all child items/folders of a folder.

cUser

Specifies the user text for an item/folder (unused by the gallery).

cViews

Specifies the views list for an item/folder.

enabled

Indicates whether the item is enabled (.T./.F.).

lCatalog

Indicates whether the current item is a catalog.

lDeleted

Indicates whether the current item has been deleted.

lDynamic

Indicates whether the current item is a dynamic folder.

lFolder

Indicates whether the current item is a folder.

lFolderitem

Indicates whether the current item is a folder item.

lFullpath

Specifies if various file name properties for an item/folder are automatically full pathed.

lGetfileaddress

Specifies if the file name is a file addresss.

lObject

Specifies if the current item is type OBJECT.

lRelease

Specifies that the item's Release method has been executed.

lRuncodemode

Specifies that the item is currently in the RunCode() method mode.

lScriptmode

Specifies that the item is currently in the RunScript() method mode.

lView

Specifies that the item is type VIEW.

nIndex

Index of this item.

nItemcount

Number of sub-items.

nItemindex

Specifies the item index of the item in the TreeView/ListView object.

nNodeindex

Specifies the node index of the item in the TreeView/ListView object.

nRecno

Absolute record number in the current catalog table.

nSourcerecno

Internally assigned record n umber (stored as regular data in the catalog table).

oAction

Reference to an object that is delegated to for all actions such as Click, DblClick, etc. You can hook a custom object that has these methods to oAction of an item, and the events for that item will be delegated to the oAction object.

oControl

Specifies the TreeView or ListView parent object of the item node object.

oFolder

Reference to the folder this item belongs to.

oHost

Reference to the Component Gallery.

oLink

If the object is a link, this is a reference to the real item.

oNode

Reference to the TreeView or ListView node object for the item.

oObject

Object reference to a VFP object used for objects of type OBJECT.

oParent

Reference to the parent object (parent folder).

oRecord

Specifies the SCATTER NAME object from the catalog cursor table record for the item.

Table 4, continued

Property

Description

oShortcutmenu

Reference to the shortcut menu definition.

oSource

Specifies an object source reference during a drag-and-drop operation.

oTarget

Specifies an object target reference during a drag-and-drop operation.

tUpdated

Date and time when the item was last updated.

visible

Specifies whether the current item is visible.

vResult

Used internally by the gallery for returning variant return values from method calls.

Table 5. Methods of the _node class.

Method

Parameters

Description

Click

 

Method that handles click events.

DblClick

 

Method that handles double-click events.

DragDrop

oSource, nXCoord, nYCoord

Method that handles drag-and-drop events.

DragDrop2

oSource, nXCoord, nYCoord

Method that handles the target drop event from dragging the class icon to a target.

FullPath

tcFileName, lcNewFileName

Returns a full path of a file name relative to the item's catalog folder location.

GetFile

tcFileExt, tlAutoExtDialog

Returns a file name from a user dialog.

GetFileAddress

TlNoShellExecute, tcFileExt

Returns a URL from a user dialog.

InitProperties

 

Internal.

KeyPress

nKeyCode, nShiftAltCtrl

Method that handles keypress events.

NewInstance

 

Returns a new instance of an object based on the same class of the object (new _Item, new _Folder).

Properties

 

Can be called to programmatically display the property sheet.

ReadProperties

 

Reads the properties from the catalog Properties memo field into the cProperties property and sets the relative properties.

Refresh

 

Handles refresh events.

RefreshFolderPicture

 

Refreshes the folder image.

RefreshPicture

 

Refreshes the item's image.

Release

 

Handles release events.

ReleaseObjects

 

Releases all object references for a node object.

Remove

tlConfirm, tlNoRefresh

Handles remove events.

RightClick

 

Handles right-click events.

RunCode

TcCode

Executes a code snippet.

RunScript

TvItem

Executes a Visual FoxPro script.

ScriptHook

TcProgram

Specifies a script hook program to be specified when running a script.

SetProperties

TcProperties

Sets properties specified in the cProperties property to their associated values.

WriteProperties

TlUpdateSource, tlAutoAdd

Writes the various item properties to the catalog Properties memo field.

Beyond the basic functionality the _node class provides, the _item class has some specialized behavior for all kinds of items (including folders). You should subclass this class rather than the _node class if you want to create a new item type. Tables 6 and 7 explain this class.

Table 6. Properties of the _item class.

Property

Description

cFormclasslibrary

Specifies the form class library.

cItemtypedesc

Specifies the item type description.

cMethod

Specifies the method to edit when opening the Class Designer for a class item.

cRightclickmenu

Specifies a program to run for the right-click menu event.

lAutosetmenu

Specifies that the code in SetMenu is automatically used to initialize the right-click shortcut menu for an item.

lDefaultmenu

Specifies whether default menu items such as Cut, Copy and Paste should be displayed.

lModify

Specifies whether the current item can be modified from within the Component Gallery.

lNewmenu

Specifies whether the default menu has a "New" item.

lPastemenus

Specifies whether the default menu has a "Paste" item.

lPropertiesmenu

Specifies whether the default menu has a "Properties" item.

lRightclickmenu

Specifies whether the current item has a shortcut menu.

lWebview

Specifies whether the current item requires Internet Explorer to display some dynamic content. If this is the case, the Component Gallery changes significantly. The standard toolbar buttons are replaced by typical browser buttons such as Refresh, Stop Loading, and Back.

Table 7. Methods of the _item class.

Method

Parameters

Description

About

 

Displays an about dialog for an item (optional).

AddDefaultMenu

ToObject

Adds a default shortcut menu to the current item.

AddMenuBar

tcPrompt, tcOnSelection, tcClauses, tnElementNumber, tlMark, tlDisabled, tlBold

Adds a menu bar to an existing shortcut menu.

AddMenuSeparator

TnElementNumber

Adds a menu separator to the existing shortcut menu.

AddPasteMenus

toObject, toMenuObject

Adds Paste menu items to the current shortcut menu.

AddPropertiesMenu

toObject, toMenuObject

Adds the Properties item to the current shortcut menu.

AfterLabelEdit

cancel, newstring

Fires when the user finishes editing a label.

ClearMenu

 

Deletes the current menu definition.

Copy

 

Copies the current object.

CreateLink

 

Creates a link to the current object.

Cut

 

Cuts the current object.

Disable

 

Disables the current object.

Table 7, continued

Method

Parameters

Description

Enable

 

Enables the current object.

Help

 

Activates the help for the current object.

Hide

 

Hides the current object.

Modify

 

Starts the appropriate editor for the current item if the item can be modified.

NewMenu

 

Creates a new shortcut menu.

OLECompleteDrag

oControl, nEffect

Handles the OLECompleteDrag event.

OLEDragDrop

oControl, oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord

Handles the OLEDragDrop event.

OLEDragOver

oControl, oDataObject, nEffect, nButton, nShift, nXCoord, nYCoord, nState

Handles the OLEDragOver event.

OLEGiveFeedBack

oControl, nEffect, defaultcursors

Handles the OLEGiveFeedBack event.

OLESetData

oControl, oDataObject, eFormat

Handles the OLESetData event.

OLEStartDrag

oControl, oDataObject, nEffect

Handles the OLEStartDrag event.

Open

 

Method to open an item (defined at item type level).

Paste

 

Pastes the item that is currently in the clipboard.

PasteLink

 

Pastes the link that is currently in the clipboard.

QuickView

 

Activates the quick view for the current item.

Rename

 

Starts an item-rename operation.

Run

 

Executes items.

SetFocus

 

Handles the SetFocus event.

SetMenu

 

Sets the shortcut menu items for an item.

Show

NStyle

Handles the Show event.

ShowMenu

 

Activates the shortcut menu for the current item.

UpOneLevel

 

Navigates to the parent item (folder).

Folders are special item types. The default folder class is _folder, which is a subclass of the _item class. This class has some highly specialized behavior for folders. Tables 8 and 9 explain these special item types.

Table 8. Properties of the _folder class.

Property

Description

cFolderType

The information stored in this property gives an indication of special folder types, such as dynamic folders that can point to an Internet URL. In this case the value of this property would be "web".

lSearchSubdirectories

Specifies that the dynamic folder will search all subdirectories, which will create a sub-dynamic folder for each subdirectory found. This is optional and might slow down the refreshing of the gallery.

lSortOnCleanup

Specifies whether a folder should be sorted when the user issues a "Cleanup catalog".

Table 9. Methods of the _folder class.

Method

Parameters

Description

Backup

TcFileName

Creates a backup of the selected catalog if the current folder is the main catalog folder.

Cleanup

tlNoRefresh, tlIgnoreErrors

Executes a cleanup of the current catalog. This includes packing the table and reordering items. This method executes only if the current folder is the main catalog folder.

Find

 

Displays the Find dialog.

GetFolderType

 

Gives an indication about special folder types, such as dynamic folders that can reference a URL on the Internet (return value is "web").

InitDBCFolder

 

Initialize the DBC folder of a dynamic project folder.

InitFileFolder

 

Initialize the files of a dynamic folder.

InitFolder

 

Initialize a dynamic folder.

InitPJXFolder

 

Initialize the PJX folder of a dynamic folder.

InitVCXFolder

 

Initialize the VCX folder of a dynamic project folder.

Restore

TcFileName

Restores the current catalog from an earlier created backup. This method executes only if the current folder is the main catalog folder.

Creating new items

As an example, I want to use my Visual GenRepoX catalog again. I'd like to add some sample reports to the Samples folder. Of course, those reports aren't regular Visual FoxPro reports. Visual GenRepoX has to be invoked before the report can be previewed. All other report functionality, like modifying a report, is the same as with regular Visual FoxPro reports. For this reason, I simply subclass the _reportitem class. I call the new class cGenRepoXReportItem. The _reportitem class has a Run() method, which is the method that needs to be changed. In fact, I'll get rid of the original behavior altogether and overwrite it with the following code:

** Overwrite the default behavior...

LOCAL lcCommand

lcCommand = ["REPORT FORM "]+Alltrim(THIS.cFileName)+[" PREVIEW]

GenRepoX(lcCommand)

Instead of executing the report directly, I route the call through the GenRepoX wrapper. For simplicity's sake, I call the GenRepoX function instead of the GenRepoX object, even though this would be the proper way now. After all, I want to show you how the Component Gallery works not how to properly invoke GenRepoX.

I can now add a report item and specify this class as an item class. When I right-click such an item and select Preview from the shortcut menu, the new method fires and GenRepoX gets called. Quite simple, isn't it?

The next step is to modify the menu, because we want to give the user a clue that we are doing something different. Here's the code:

 

LPARAMETERS toObject

IF NOT _item::SetMenu(toObject)

RETURN .F.

ENDIF

IF !THIS.oShared.CheckItem(THIS)

RETURN .F.

ENDIF

this.AddMenuBar("Modify","oTHIS.Modify()",,,,,!this.oHost.lRunFileDefault)

this.AddMenuBar("Preview GenRepoX)","oTHIS.Run()",,,,,this.oHost.lRunFileDefault)

First of all, I am executing inherited behavior. Note that I'm not using DoDefault(), but the scope resolution operator. I do this because I don't want to inherit the items defined in the _reportitem class. However, all menu items should be defined generically in the _item class. For this reason, I skip the direct parent class and go one step higher. In the next step, I check whether the current item can be handled by the shared item because I still want to let the shared item handle standard tasks such as modifying the class. You might wonder why I knew I had to do this. Well, I actually didn't. I just looked it up in the _reportitem class and figured it must be there for a reason.

Finally, it's time to add an item to the shortcut menu. I simply used the AddMenuBar() method. The first parameter is the caption. Parameter two defines the action that occurs when the item is selected. When a right-click menu is created, the gallery stores a reference to the active object in a public reference called oTHIS. So with oTHIS.Modify() and oTHIS.Run() we send messages to the current object. And remember that I changed the code in the Run() method. So this is how this method gets called.

The final parameter is a little confusing. It defines whether the added menu item should be displayed in boldface. In the Component Gallery options, the user can specify the default item action (either modify or run). Our menu should show the default action in boldface. So the first thing I have to do is figure out the option setting, which is stored in the gallery itself. I always have a reference to the gallery called oHost. The actual setting is stored in a property called lRunFileDefault. This setting is simply passed to the AddMenuBar() method.

By now you know how to modify behavior and how to set items in the menu. You also know how to link those items to a certain method, so you could easily create new methods and add menu items that call those methods. With this knowledge, you're limited only by your creativity.

Adding item types

By default, the Component Gallery supports only a dozen item types, but you'll often want to add new ones. You might want to add items and change the underlying classes to get different behavior, or maybe create a catalog that deals with non-default behavior, like the Visual GenRepoX catalog. In this case, it is much more comfortable to add new item types.

Adding new item types is done per catalog. You can do it through the Properties dialog of the main catalog node (see Figure 29).

Figure 29. Adding item types.

When creating a new item type, you need to specify an item type name, a class and a class library to be used for the behavior object, and whether the new item is a folder or a regular item. Optionally, you can specify properties and alternative item types (redirect). Items often need certain properties that the user can change, which you can specify in the Properties edit box. In the previous example, we could add a property that allows setting the file name:

Report file name,cFileName

When the user adds a new GenRepoX report item, he can now open the item's properties and see another page that allows him to specify the item name. I'll discuss this topic in more detail later.

We can also specify alternative item classes in the current dialog. Let's say the user incorrectly selects a DOC file as a GenRepoX item. We could redirect this item to a regular file item like so:

DOC=_fileitem

Once a new item type is added, it is available in the right-click menu as well as in the treeview (see Figure 30). But remember that items are defined per catalog. It sometimes gets confusing when you open multiple catalogs and one catalog supports items that are unsupported by the other.

Folder and item properties

Each item and folder in the Component Gallery has a Properties dialog that allows you to modify and customize the behavior, look and feel of each item. For most items, the property sheets will vary in appearance due to the flexibility of each item. I'll give you an overview of the most important items and their different property sheets. I'll also explain how to customize the items and their property sheets.

The property sheets I describe here are advanced property sheets. You can activate advanced property sheets in the Component Gallery's Options dialog (Advanced editing enabled). If you don't activate this feature, the property sheets will have significantly fewer items.

Figure 30. The "GenRepoX Report" item that was defined in the
Visual GenRepoX catalog.

 

Catalog properties

Figure 31 shows the General tab of a sample catalog property sheet. On this tab, you can define the most basic properties such as the catalog name and a short description, as well as an item for the catalog. The catalog's property sheet is a specialized form of a folder property sheet. Take note that the specified name is used for the topmost node as well as for the whole catalog (in the Open dialog, for instance). The General tab allows you to specify two additional properties the item picture and an item description. These settings are used for items within the current catalog that don't have specific icons and descriptions assigned.

On the Node tab of the property sheet (see Figure 32), you can specify some internals for the catalog node. The ID is the automatically created name of the actual node. This property is always read-only. The Class name and Class library properties allow you to specify the class to be used internally (see above). The Item class is a standard class for all items that don't have a defined class. Finally, the Dynamic folder property defines the location of a dynamic folder (see above).

Figure 31. The General tab of the catalog property sheet.

Figure 32. Customizing some internals of the folder using the Node tab.

The Scripts tab is used to maintain scripts and property settings. This topic is discussed below. On the Comments tab, you can add personal comments and modify the contents of the User field of the catalog. Finally, there is the Item Types tab, which is used to add custom item types to a catalog (see above).

 

Folder properties

Folder properties are similar to catalog properties. The major difference is that they do not have an Item Types tab. Also, properties such as the folder name have less impact than the catalog properties because they only define local names.

Item properties

Item property sheets are also similar to folder and catalog property sheets, but they have some additional tabs and omit some generic settings. On the first tab, you can set properties for the name, description and item image. Sub-item images and descriptions can't have properties because items (unlike folders) can't have sub-items.

The first new tab is Views, which allows you to influence how an item is displayed and how it can be found. You can specify a list of keywords, which can then be used in the Search dialog to define dynamic views based on one or more keywords. The View settings are a bit confusing at first, but helpful nevertheless. The Visual FoxPro standard catalog has a good example for View settings. It has a Dialogs folder that contains an About Dialog item. Now let's assume the user wants to use the "Class By Type" view. In this case, the About dialog should be listed as a form. This can be accomplished with the following setting in the Views property:

Class By Type=Forms

The Node tab is a simplified version of the Node tab in the folder and catalog properties. It allows you to specify classes for the current item, but not for sub-items. The Script and Comments tabs are identical to the ones in the folder and catalog properties.

In addition, there typically is one more tab that has some properties specific to the current item. Class items have properties that show the base class, class locations, and so on. URL items have the Web address and so forth. This special property tab can be customized if you create special items that have some properties that need to be set by the user. See below for more information about custom properties.

Creating custom properties

Often you will want your users to set some properties. The GenRepoX example is a perfect example. In the special GenRepoX report item, we overwrote the Run() method to execute a GenRepoX report by calling the GenRepoX method. However, there might be a need to execute a GenRepoX report directly without invoking GenRepoX. People like to do that to see whether a report can still be executed without GenRepoX. For this reason I decided to create a new property called lUseGenRepoX in the cGenRepoXReportItem class. Now I need to register this property with the Component Gallery so it will be displayed in the Properties dialog. I can do this two different ways: One allows the user to remove the definition, and the other is done internally and can't be removed from the property sheet by the user.

First I'll describe the secure way of registering the property, which prevents the user from removing it. To do this, I have to open the catalog like a regular DBF and manually add a record (see below for an explanation of the table structure). The Type field must be "CLASS". The ID is simply a unique value. The next couple of fields remain blank. The TypeDesc has to be "ITEM" because I want to create new properties for an item. It could also be "FOLDER" if I wanted to create folder properties. The magic actually happens in the Properties field. Here's what I added there:

Use GenRepoX to preview,lUseGenRepoX

Copies,nCopies

The first value up to the comma is the text that will be displayed. After the comma, I specify the property name. In this example I created a second property that specifies how many copies should be printed by default. The gallery allows you to specify as many properties as you want, separating them with a carriage return. Note that the properties are of different types the first is logical and the second is numeric. The Component Gallery handles different property types automatically.

Now there is only one thing left to connect this record to a specific class. We do this in the Class and ClassLib fields, where we specify the appropriate name. In this example, the class name would be cGenRepoXReportItem and the library is the name of the VCX file we've chosen to store our class. Figure 33 illustrates our property sheet.

Figure 33. A custom tab in the property sheet.

Properties also can be specified in the Item Type tab of the catalog properties (see above). You simply specify some descriptive text and the name of the property. If the behavior object doesn't have the specified property, the property definition is ignored (unlike in the internal descriptions where this would cause an error). Note that this works only for newly defined items. Properties for internal objects can only be defined low level in the catalog DBF.

Once I allow the user to set certain properties, I can react to them in the Run() method (or other methods) of my special report class like so:

 

LOCAL lcCommand

lcCommand = ["REPORT FORM "]+Alltrim(THIS.cFileName)+[" PREVIEW]

IF THIS.lUseGenRepoX

GenRepoX(lcCommand)

ELSE

&lcCommand

ENDIF

In this example I support only one of the two properties, but I think you get the idea.

Scripting

You might need to customize some properties or some behavior, but if the change is small (or located only at one place) you might not want to create a new class. In this case you can utilize the Component Gallery's scripting capabilities. You can define scripts on the Scripts tab of an item's property sheet (see Figure 34). This tab allows two different types of scripts. One allows setting properties (you guessed it: this is the edit box with the caption "Properties:"), and the other allows creating entire FoxPro functions. Properties are set one by one. You can specify as many property settings as you want, separating them with a carriage return (new line). I could set my lUseGenRepoX property like so:

lUseGenRepoX = .F.

This would set to .F. the behavior's lUseGenRepoX property (which normally defaults to .T.). Without the script, I always had to go to the property sheet to set this property before I printed. You can access every public property of the current behavior object. The gallery simply adds the defined property expression to the object name and evaluates it. Remember that each behavior object also has links to other objects, such as the parent node, the host (which is the Component Gallery itself), and so forth. So you could easily set properties of the Component Gallery like so:

oHost.BackColor = 255

This would set the Component Gallery's back color to red, as soon as the behavior object gets instantiated (which happens as soon as the user looks at a folder that contains the item with the script). This can be very useful to interact with add-ins that you might have created for the gallery (see below).

Properties can also be used to redirect method calls. To use the user-defined Test() method to handle the Click event, you could redirect it like so:

CClick="oTHIS.Test()"

For simple tasks, you can also use a Visual FoxPro script, which is a regular Visual FoxPro function. You can use all kinds of structures, such as IF and CASE statements. The only limitation is that you cannot define sub-structures like other function or class definitions. Unlike regular Visual FoxPro code, scripts are not compiled; instead, they are executed and interpreted line by line, similar to Visual Basic or Java scripts.

Figure 34. A simple script and two redirected method calls.

To call a script, you have to redirect a method call, similar to the last example, but instead of setting a method name you would specify a script call in the properties:

CClick=<>

Because no ID was specified between the brackets, the script specified in the current item is executed. Let's say we want to use the script to set the default to a certain directory every time the user clicks an item. We would create a script similar to the following:

CD "\Program Files\Visual GenRepoX"
MessageBox("Directory changed.")

Figure 34 shows how this is specified in the property sheet. Take note that you can specify only one script in a property sheet. If you wanted to create another script for a different event, you'd have to add another record to the component catalog something you could only do low-level in the DBF file. Additional script records have the type SCRIPT, a unique item ID that will be used to reference the script, and the actual script in the Script field. Let's assume you created a script record with the ID SCRIPT1. You would call this script with the following setting in the properties:

CRightClick=<SCRIPT1>

Take note that redirecting methods overwrites the default behavior assigned to a certain event. The above example redirects the right-click event. This means that the default behavior (like the shortcut menu) is now disabled. Unfortunately, there is no equivalent of DoDefault() in scripts or other redirected methods.

Add-ins

Like the Class Browser, the Component Gallery itself can be customized through add-ins. I explained add-ins in detail in the Class Browser section. However, I'd still like to give you a simple example of a Component Gallery add-in. I would like to add a button to the gallery that scans the current folder for GenRepoX report items and executes all of them. Here is the code that does that:

LPARAMETERS loGallery

loGallery.AddObject("cmdGenRepoX","cPrintReportsButton")

RETURN

DEFINE CLASS cPrintReportsButton AS CommandButton

FontName = "MS Sans Serif"

FontSize = 8

Height = 23

Width = 100

Caption = "GenRepoX Exec."

Visible = .F.

FUNCTION Visible_Assign (llNewVal)

IF Type("llNewVal") = "L" AND llNewVal AND NOT THIS.Visible = llNewVal

* The button is set visible

THIS.Top = THISFORM.chkDetailsView.Top

THIS.Left = THISFORM.chkDetailsView.Left + ;
THISFORM.chkDetailsView.Width + 5

ENDIF

THIS.Visible = llNewVal

ENDFUNC

FUNCTION Click

LOCAL lnCounter

FOR lnCounter = 1 TO ALen(THISFORM.oFolder.aItemIndexes,1)

IF "genrepox" $ ;
THISFORM.aItemList(THISFORM.oFolder.aItemIndexes(lnCounter)).Class

THISFORM.aItemList(THISFORM.oFolder.aItemIndexes(lnCounter)).Run

ENDIF

ENDFOR

ENDFUNC

ENDDEFINE

The code has to be stored in a PRG file. For now, I'll assume you stored it in a file called Grxaddin.prg. You can now run the Component Gallery and register the add-in like so:

_oBrowser.AddIn("GenRepoX Execute","grxaddin.prg","INIT")

Note that the reference to the gallery is still called _oBrowser. That's because the gallery and the browser share underlying architecture as well as the interface. I would like to see a second object reference called _oGallery, but apparently nobody else thought of this before. If you would like such a reference, too, you can create a simple add-in that defines a public variable called _oGallery and turns it into an object reference pointing to _oBrowser. This add-in needs to be called in the Activate event of the gallery.

When the add-in is executed, the new button gets instantiated. However, the button is invisible at first because I don't want it to show up unless a GenRepoX item is displayed. For this reason I have the GenRepoX item activate the button. To do that, I could either code something in the Init() method of the GenRepoX behavior class, or I can create a little script (actually a property setting) that sets the Visible property of the button to .T. This can be done in the property sheet of any GenRepoX item, like so:

oHost.cmdGenRepoX.Visible = .T.

When the button is set visible, an assign method fires and handles the positioning of the button according to other items in the gallery.

When the button is clicked, I iterate through the current items, check if they have "genrepox" in their class names, and if so, I fire the item's Run() method to execute the report. Iterating through the active items is simple. The gallery has an object reference called oFolder, which is a reference to the currently selected folder. This folder object has an array of item numbers that are members of the folder. We can use these numbers to reference items in the gallery's aItemList collection. This collection has a reference to all the behavioral objects the gallery has instantiated so far. Take note that there could be items from other folders as well, because the gallery creates behavior objects as soon as a folder is browsed, but no longer removes them for performance reasons. Once we have a reference to the items in the selected folder, we can check their Class property to see whether the item is related to GenRepoX.

The gallery's object model

The internal object model of the Component Gallery is quite rich. Full documentation of the internal object model is beyond the scope of this book. Please refer to the Visual FoxPro documentation. However, I would still like to give you an overview of the most important references and properties of the Component Gallery (see Table 10). You can access those properties either from add-ins or through the _oBrowser object reference (yes, the reference to the gallery is also _oBrowser, since the two tools share one interface).

Catalog file structure

Component Gallery catalogs are regular Visual FoxPro tables (DBF). Most content in a catalog can be edited through the Component Gallery's interface. However, some data (such as custom property sheets or scripts) have to be defined as low level in the DBF. Also, there are other reasons for editing the file directly: corrupt content, or mass updates that can be done with a REPLACE ALL FOR statement. Table 11 explains the structure of catalog tables.

The Component Gallery has a default catalog Vfpglry.dbf that it opens when the gallery is called from the menu. This catalog has references to catalogs and other items. All items displayed by default are somehow references from the default catalog.

 

Table 10. The most important properties and references of the Component Gallery.

Property/Reference

Description

aFolderlist

Collection of all displayed folders.

aItemlist

Collection of all items the browser displays and has displayed (they are not removed once they are displayed).

cCatalog

Contains the name of the currently selected catalog file.

cDefaultcatalog

Stores the name of the default catalog file.

cDefaultcatalogclasslibrary

Stores the name of the default class library for catalog items.

cDefaultcatalogpath

Contains the name of the default Component Gallery path.

cFolderclass

Default folder class name.

cItemclass

Default item class name.

cViewtype

Currently active view type.

cWebbrowserclass

Class used for dynamic folders (Internet and directories).

cWebbrowserclasslibrary

Class library that stores the class for the Web browser view.

lBrowser

This property is set to .T. if the gallery runs in browser mode. This is important for add-ins.

lFFCbuilderlock

Specifies whether the Fox Foundation Class builder lock is on.

nFoldercount

Number of opened folders.

nFolderlistindex

Index of the currently selected folder.

nItemcount

Number of items.

nItemlistindex

Index of the currently selected item.

oCatalog

Reference to the active catalog.

oFolder

Reference to the current folder.

oItem

Reference to the current item.

oItemshortcutmenu

Reference to the shortcut menu (and the menu settings) of the current item.

 

Table 11. The structure of catalog tables.

Field

Type

Description

Example

Type

C(12)

Specifies the kind of item represented by the current record.

ITEM, FOLDER, CLASS, SCRIPT

ID

C(12)

Unique identifier for each record.

Clireg, _gfr445g5

Parent

Memo

Specifies the parent folder of the current item. Used to build the hierarchical view the gallery uses.

Clireg, _gfr445g5

Link

Memo

Identifier of a linked item. A link identifier is composed of the catalog name and the item ID.

Activex!treeview, genrepox!_dgj8342

Text

Memo

Item name that will be displayed in the listview and the treeview.

About Dialog, Documentation, My Documents

TypeDesc

Memo

Additional description text for each item of a folder. This text is inherited by all child items/folders of a folder.

Double-click these items to execute.

Desc

Memo

The text that will appear in the description area.

This component can be used to

Properties

Memo

Contains all properties that are set in the Script tab of the item property sheet.

cbaseclass=container
lUseGenRepoX = .F.

Table 11, continued

Field

Type

Description

Example

FileName

Memo

The file name where the referenced item is stored. If the item is a class, this field contains the name of the class library. If the item is a URL, it is stored here.

(HOME()+"ffc\_dialogs.vcx")

GenRepoX.vcx

http://www.eps-software.com

Class

Memo

If the referenced item is a class, it is stored here. Note that there needs to be a reference to the library as well, which is stored in the filename field.

_aboutbox

cCheckBoxDriver

Picture

Memo

Picture (icon or bitmap) for non-folder items. If the current record is a folder, this field specifies the standard icon for all sub-items.

File.ico

(HOME()+"gallery\class.ico")

FolderPict

Memo

Picture (icon or bitmap) used for folders. If the item uses the standard icon, this field is empty.

dfldr.ico

(HOME()+"genrepox\grxreport.ico")

Script

Memo

Visual FoxPro script.

cVBRFile = GETFILE("VBR")

cCliReg = oTHIS.cFIleName

IF !FILE(m.cCliReg)

RETURN .F.

ENDIF

IF EMPTY(m.cVBRFile) OR UPPER(JUSTEXT(m.cVBRFile))#"VBR"

RETURN .F.

ENDIF

oTHIS.Runcode([RUN /N &cCliReg. "&cVBRFile." NOLOGO])

ClassLib

Memo

Class library where the class definition for the behavior object is stored.

(HOME()+"gallery\_gallery.ico")

(HOME()+"genrepox\grxreport.ico")

ClassName

Memo

Class used for the behavior object. The ClassLib field specifies the library for that class.

_folder
_activexfolder

ItemClass

Memo

The default class used for all items within a folder. Used only in folder items.

_activexitem

_reportitem

ItemTPDesc

Memo

Contains information about alternate file items for particular file types if the current item is a generic file item.

BMP=_imageitem
ICO=_imageiem
WAV=_sounditem
DBF=_dataitem

Views

Memo

Specifies special settings for certain views.

Class By Type=Forms

Keywords

Memo

Specifies a list of keywords that can be used to identify and search the component.

Class

SRCAlias

Memo

Specifies the source alias of the catalog table the item originated from.

Catalog1

Table 11, continued

Field

Type

Description

Example

SRCRecNo

N(6,0)

Specifies the source record number of the catalog table where the item originated from.

3

Updated

T

Information about the date and time of the last update through the gallery's interfaces. This field is for internal use only.

09/03/1998 11:57:00 AM

Comment

Memo

Can be used to store comments.

Need to finish this

User

Memo

Reserved for user extensions. The Component Gallery does not use this field.

*:EXTENSION

Browser.dbf

As a close relative of the Class Browser, the Component Gallery also uses the browser table to store metadata. In the section about the Class Browser, I described the structure of Browser.dbf (see Table 1). The rules of using Browser.dbf in combination with the Component Gallery are the same as for the Class Browser.



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