ProjectHooks are a new base class introduced in Visual FoxPro 6.0 that let us intercept some of the events that occur while we are working with the Project Manager. The Project Object is an object interface to an open project, allow developers to manipulate the project properties and drill down into the project contents easily. In this session, we'll examine these powerful new tools.
With the new Project object, a new interface introduced in Visual FoxPro 6.0, Microsoft has exposed some of the internal events and properties controlled by the Project Manager. These new interfaces give us the ability to manipulate the contents of a Project without resorting to open the project file as a table, and make easier to read and easier to comment code. In addition, in combination with the ProjectHook object discussed below, new tools for design work can be easily developed.
The Project Object is an item in a Projects collection, and it in turn can have a Files collection representing the projects contents. An illustration of this is shown in Figure 1.
The Project Object is exposed as a member of the Projects collection, a new attribute of the Application object. The Projects collection has a Count property to tell you the number of open projects, and an Item method to point to an individual project. The Application object also has an ActiveProject property that points to the currently active project. Unfortunately, if no project is open, trying to access the ActiveProject property returns an OLE error, so always check that Application.Projects.Count is greater than zero before attempting to access ActiveProject.
Each Project object will display properties and methods similar to the interface it presents within the Project Manager. Five methods can be called: Build, Cleanup, Close, Refresh and SetMain, all of which have pretty obvious behaviors. Properties available at the project level are those that are visible within the Project Manager through the Project Info menu options or within the "Version" dialog when building an EXE or DLL.
Each Project object can have a related ProjectHook object, as described below, and will contain two collections, Files and Servers. Like the Project collection itself, Files and Servers each has a Count property and an Item method for iterating the contents.
The Files collection contains individual File objects that represent the files assembled in the project. Each file will display the attributes that can be manipulated through the Project Manager interface: Name, Description, FileClassLibrary, and so forth.
So, the Project class can be iterated through in a number of ways – an excellent place for an Iterator class – as the example below shows:
* Program....: DUMPPJX.PRG
* Version....: 1.0
* Author.....: Ted Roche
* Date.......: May 17, 1998
* Notice.....: Copyright © 1998 Ted Roche, All Rights Reserved.
* Compiler...: Visual FoxPro 06.00.8093.00 for Windows
* Abstract...: Iterate through a Project object
IF _VFP.PROJECTS.COUNT = 0
WAIT WINDOW "No Projects open"
LOCAL m.i && counter
LOCAL loProject && pointer to project object
loProject = _VFP.ActiveProject
? " *** Project ***"
? "Name: " + .name
? "Main File: " + .MainFile
? "Last Built: " + TRANSFORM(.BuildDateTime)
ENDWITH && loProject
IF loProject.Files.Count = 0
? "Project has no files"
? " *** Files *** "
FOR m.i = 1 TO loProject.Files.Count
? "Filename: " + loProject.Files(m.i).Name
ENDFOR &&* m.i = 1 TO loProject.Files.Count
IF loProject.Servers.Count = 0
? "Project has no servers"
? " *** Servers *** "
FOR m.i = 1 TO loProject.Servers.Count
? "Filename: " + loProject.Servers(m.i).Name
ENDFOR &&* m.i = 1 TO loProject.Servers.Count
The figures 2 through 5 show the hierarchy of the Project, Files and Server objects, and their methods and properties:
Nearly anything that can be done with the Project Manager can now be done by using the project objects. In fact, a new clause, NOSHOW, was added to the MODIFY PROJECT command specifically because the Project object could be used to manipulate the project, so the Project Manager interface might not need to be displayed at all!
The projecthook object, new to Visual FoxPro 6.0, allows us to define an object that is instantiated when our projects are opened automatically. The object can intercept most of the interaction the developer has with the Project, and can be used for many project-related functions.
A ProjectHook is defined within a class library and attached to the project via the Project Info dialog. Alternatively, a global ProjectHook class can be defined in the Tools|Options dialog. When the project is next opened, the specified class library is searched and the defined class is instantiated.
The ProjectHook is a new Visual FoxPro base class, and has the usual properties shared by most VFP objects: Name, Class, BaseClass, ParentClass, Tag. In addition, it has OLE events to support drag and drop – but drag and drop on the Project Manager, not on the invisible ProjectHook. Other events include:
AfterBuild: fires after a build is complete
BeforeBuild: before the build action starts, a hook to give the developer a chance to change the way the build takes place, record some information, or even abort the build process.
QueryAddFile: fires just before a file is added to the project. Again, the developer has control of the result, including rejecting the add.
QueryModifyFile, QueryRemoveFile, QueryRunFile – like the function above, each gives the developer information on the specific action taking place, and allows the developer to reject the action by issuing NODEFAULT.
Just as important as these special events may be the simple events of Init and Destroy that allow you to run special code each time a project is loaded or closed. For example, the Init would be an ideal place to set the initial configuration or load an add-on toolbar. The Destroy is the appropriate place to close any opened files or toolbars or release any variables needed by the projecthook.
The number of applications of ProjectHooks, with their corresponding Project Objects, in unlimited. Here are some ideas I have heard proposed:
searching within a project, perhaps with "replace" capabilities
One problem with the hooking process as it is used in the project manager is that there is room for only one hook. What if you wanted to add an audit trail projecthook and a commenting projecthook to the same project. You might consider manually switching back and forth each time you needed it, and after a while found that the time to switch was more costly than invoking the function directly. What you need is a tool that can manage the pool of hooks you want to use. Enter ProjectHookX. Written by Toni and Mike Feltman of F1 Technologies (formerly Neon Software) with some suggestions from Doug Hennig and others, ProjectHookX allows you to have multiple ProjectHook objects created and active with a single project. ProjectHookX and its associated documentation is included on the disk.
Ted Roche is a Microsoft Certified Solutions Developer (MCSD) with over twelve years of experience delivering custom FoxPro applications, support and training. He is a five-time winner of Microsoft's Most Valuable Professional (MVP) award and has been a featured speaker at over a dozen professional conferences in the US, Canada and Europe. Ted has contributed to six books on FoxPro. He's has just completed the Hacker's Guide to Visual FoxPro 6.0, available now at most fine bookstores or directly from Hentzenwerke Publishing He is a Contributing Editor and writes portions of the Ask Advisor column in FoxPro Advisor magazine. Contact Ted at email@example.com