#Define, #UnDef, #If, #ElIf, #Else, #EndIf, #IfDef, #IfNDef, #Include, _Include
Visual FoxPro 3.0 introduced many new concepts to FoxPro programmers, and the ability to manage constants, like the other "real" languages, was a most welcome feature. Visual FoxPro supports the ability to insert defined constants into program, form and class code, as well as the ability to conditionally test and undefine these constants as required.These are not FoxPro commands, but rather preprocessor directives. If you include one of these as a string and attempt to macro-expand it within FoxPro, you get the error message "Syntax error." That's because these commands are not intended to be run by the FoxPro interpreter, but are directed to the preprocessor, which produces the pseudo-object code ("p-code"), which the Visual FoxPro interpreter then runs. To distinguish them from FoxPro commands, we often refer to them as "compiler directives," even though, strictly speaking, FoxPro lacks a true compiler.Here's the inside scoop. Within the development version of FoxPro, source code can be compiled at various times. When saving a method of a form, the code is compiled during the save process. When running a program whose compiled version is older than its source (with SET DEVELOPMENT ON), the source is recompiled. Finally, source is recompiled when you explicitly tell it to—either by selecting Compile from the Program menu or by building a project. When the preprocessor is called into play, it scans the source code for preprocessor directives, all of which begin with the # symbol. If it finds any of these, it performs the action specified by the command. If this command introduces more preprocessor directives (such as #INCLUDEing another file) these directives are completed, too, until all directives have been performed. At that point, FoxPro source code is converted into the p-code the interpreter (and runtime) will be able to run. Let's review the various commands, and see what they can do.
Usage |
#DEFINE cName eExpression #UNDEF cName |
Example |
#DEFINE c_nVERSION_NO "1.23" * The following inserts the literal TTOC() expression * into the source, rather than the date and time. #DEFINE c_tVERSION_BUILT TTOC(DATETIME()) * 1st example: evaluate both outside of quotes. WAIT WINDOW "Version "+ c_nVERSION_NO + ; ", built "+c_tVERSION_BUILT * 2nd example: Constants evaluated inside square brackets. WAIT WINDOW [Version c_nVERSION_NO , built c_tVERSION_BUILT] * 3rd example: Constant substitution doesn't take place * within single or double quotes. WAIT WINDOW 'Version c_nVERSION_NO , built c_tVERSION_BUILT' |
Usage |
#IF eExpression [ #ELIF eExpression ] [ #ELSE ] #ENDIF |
Example |
#IF C_DEBUGGING do DebugLog with Program(), Pcount() #ENDIF * Use the faster VARTYPE() if * compiling under VFP 6 or later. #IF "FOXPRO 06" $ UPPER(VERSION(1)) OR ; "FOXPRO 07" $ UPPER(VERSION(1)) IF VARTYPE(toObject) <> "O" #ELSE IF TYPE("toObject") # "O" or ISNULL(toObject) #ENDIF RETURN .F. ENDIF |
Example |
* #IF "FOXPRO 07" $ UPPER(VERSION(1)) ? "Using the current version." #ELIF "FOXPRO 06" $ UPPER(VERSION(1)) ? "Using an older version." #ELIF "FOXPRO 05" $ UPPER(VERSION(1)) ? "Using a pretty old version." #ELSE ? "Using a really old version! #ENDIF |
Usage |
#IFDEF cConstantName #ENDIF |
Example |
#IFDEF cAuditing && Auditing functions to be included IF cAuditing DO AuditTrail with ... ELSE .... more code #ENDIF |
Usage |
#IFNDEF cConstantName #ENDIF |
Example |
#IFNDEF C_DEBUGGING SET DEVELOPMENT OFF SET TRBETWEEN OFF #ENDIF |
Usage |
#INCLUDE cFileName _INCLUDE = eFileAndPathName |
In VFP version 3.x, compiling a file that #INCLUDE's other files doesn't return any error messages if the #INCLUDEd file is not located or cannot be opened because it is in use. This one trips us up all the time: If you open FoxPro.H to see what they called a constant, and then compile and run a program using that file without closing the editing window, you'll get stupid errors like "Variable 'COLOR_RED' is not found." In VFP 5.0 and later, a dialog appears, informing you the file can't be opened, and generates an ERR file if you choose "Ignore" to continue compiling. Although we at least get an error telling us it's open, we wish having the #INCLUDE file open didn't prevent you from compiling. That's just plain annoying. |
We've mentioned FoxPro.H in a few places throughout the book, and thought we should clue you in on this file. This file contains predefined sets of constants for many of the more difficult-to-remember functions, such as color numbers, low-level file routines, PRTINFO() types, parameters to MessageBox() and so forth. This file is worth browsing and using. We far prefer to see code using these constants, because it's much easier to read and, therefore, to maintain. |
Example |
* STANDARD.H #INCLUDE FOXPRO.H #INCLUDE MyVars.H * Much easier-to-read code #INCLUDE FOXPRO.H IF MESSAGEBOX("Question",; MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2, ; "Title") = IDYES * than: IF MESSAGEBOX("Question", 292, "Title") = 6 && what's 292? 6? _INCLUDE = LOCFILE(HOME()+"FOXPRO.H","H") |
See Also |