Logo

Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.

ProjectHook

This is the base class for project hooks, which define objects you can attach to a project to let you make things happen while you’re working with the project. Every time a project opens, it has the opportunity to create and attach a project hook.

While project hooks have all the usual properties and methods, like Name, Parent, Tag, ReadMethod, and so forth, everything really interesting about project hooks happens in their event methods.

Event

Purpose

Activate

Fires when the project gets focus. Not as useful as we'd like because it doesn't fire while the project is docked.

AfterBuild

Fires when a project's Build method has completed.

BeforeBuild

Fires when a project's Build method is called (whether it's called through the interface or programmatically). Allows you to both make sure certain things happen before the build and change the nature of the build by changing the parameters passed to Build. NODEFAULT halts the build process.

Deactivate

Fires when the project loses focus. Not as useful as we'd like because it doesn't fire while the project is docked.

Destroy

Fires when the project is closed. Lets you turn out the lights as you leave. (Destroy also fires if you release the project hook without closing the project, of course.)

Init

Fires when the project is opened. Lets you do things on the way in. One good thing to do here is give the project hook a reference to the project. (Of course, Init fires if you instantiate a project hook without having it attached to a project, too.) One caution here: The ProjectHook instantiates early in the life of the project, so some project methods (like the source code control CheckIn() and CheckOut()) will not work in the ProjectHook.Init method.

QueryAddFile

Fires when a file is added to the project. Can prevent the file from being added.

QueryModifyFile

Fires when any file in the project is opened for modification (before the appropriate editor opens). Can prevent the editor from opening.

QueryNewFile

Fires when the user chooses to create a new file (before the appropriate editor opens). Can prevent the file from being created.

QueryRemoveFile

Fires when any file is removed from the project. Can prevent the removal of a file.

QueryRunFile

Fires when any file in the project is executed. For reports, read "previewed" for "executed." Can prevent the execution of a file.

Most of these events fire in response to a particular method of the Project COM object. What’s most cool is that they fire no matter how that method got called. In VFP 7, three events that don’t directly correspond to the Project’s method were added: Activate, Deactivate and QueryNewFile.

Project hooks have methods for the "drop" part of OLE drag and drop, and they fire when something is dragged or dropped over the files portion of the project (that is, the white central area, not the gray borders). We can imagine some pretty cool project hooks that let you do additional processing when files are added to the project by drag and drop.

Except for AfterBuild, these methods all have the power to prevent the specified Project method from actually executing—issue NoDefault to do so.

Although you can create project hooks in code (rather than visual) classes, and instantiate and attach those project hooks to open projects, there's no way to make a code class the default project hook for a project. When you try to set ProjectHookLibrary to a PRG, VFP yells at you. You can also run into nasty problems if you have the PRG open while a project is using a class defined within. Since there are no benefits to defining them in code, we suggest you stick with VCX's for project hooks.

Example


* This simple project hook class simply provides you with
* feedback as you work.
* Set the Include file for the class as FoxPro.H (in the main
* VFP directory) to get access to the project constants used
* in BeforeBuild.
DEFINE CLASS prjShowMe AS projecthook

   Name = "prjShowMe"

   *-- A pointer to the project associated with this project
   *-- hook.
   oProject = .NULL.

   PROCEDURE AfterBuild
      LPARAMETERS nError
      WAIT WINDOW "Finished building project"
   ENDPROC

   PROCEDURE BeforeBuild

      LPARAMETERS cOutputName, nBuildAction, lRebuildAll, ;
                  lShowErrors, lBuildNewGuids
      LOCAL cBuildType
      DO CASE
      CASE nBuildAction = BUILDACTION_REBUILD && 1
         cBuildType = "rebuild project"
      CASE nBuildAction = BUILDACTION_BUILDAPP && 2
         cBuildType = "build APP"
      CASE nBuildAction = BUILDACTION_BUILDEXE && 3
         cBuildType = "build EXE"
      CASE nBuildAction = BUILDACTION_BUILDDLL && 4
         cBuildType = "build DLL"
      ENDCASE

      WAIT WINDOW "About to " + cBuildType + " " + ;
                  cOutputName NOWAIT
   ENDPROC

   PROCEDURE QueryRunFile
      LPARAMETERS oFile
      WAIT WINDOW "Running file "+oFile.Name NOWAIT
   ENDPROC

   PROCEDURE QueryRemoveFile
      LPARAMETERS oFile, cClassName, lDeleteFile

      LOCAL cDelete
      IF lDeleteFile
         cDelete = "Deleting"
      ELSE
         cDelete = "Removing"
      ENDIF

      IF EMPTY(cClassName)
         WAIT WINDOW cDelete + " file " + oFile.Name NOWAIT
      ELSE
         WAIT WINDOW "Removing class " + cClassName + ;
                     " from " + oFile.Name NOWAIT
      ENDIF
   ENDPROC

   PROCEDURE QueryModifyFile
      LPARAMETERS oFile, cClassName

      IF EMPTY(cClassName)
         WAIT WINDOW "Modifying file " + oFile.Name NOWAIT
      ELSE
         WAIT WINDOW "Modifying class " + cClassName + ;
                     " of " + oFile.Name NOWAIT
      ENDIF
   ENDPROC

   PROCEDURE QueryNewFile
     LPARAMETERS cFileType
     WAIT WINDOW "Creating a new file of type " ;
                 + cFileType NOWAIT
   ENDPROC

   PROCEDURE QueryAddFile
      LPARAMETERS cFileName
      WAIT WINDOW "Adding file "+cFileName NOWAIT
   ENDPROC

   PROCEDURE Init
      WAIT WINDOW "Opening project" NOWAIT
      IF VARTYPE(_VFP.ActiveProject )= "O"
        This.oProject = _VFP.ActiveProject
      ENDIF
   ENDPROC

   PROCEDURE Destroy
      WAIT WINDOW "Closing project" NOWAIT
   ENDPROC

   PROCEDURE Activate
      WAIT WINDOW "Activating project" ;
                  + This.oProject.Name NOWAIT
   ENDPROC

   PROCEDURE Deactivate
      WAIT WINDOW "Deactivating project" ;
                  + This.oProject.Name NOWAIT
   ENDPROC

ENDDEFINE

See Also

Activate, AfterBuild, BeforeBuild, Deactivate, Destroy, Init, NoDefault, OLE drag and drop, OLEDragDrop, OLEDragOver, OLEGiveFeedback, Project, ProjectHook Property, ProjectHookClass, ProjectHookLibrary, QueryAddFile, QueryModifyFile, QueryNewFile, QueryRemoveFile, QueryRunFile