Directives Updated: Oct 24, 2008 HotBasic statements determine program actions at run-time. Directives affect how your source code is compiled at compile-time. For example, you may use $DEFINE to create variables used only at compile-time to substitute text in source code or with $IFDEF and $IFNDEF, to control which code is compiled. $APPTYPE CGI + | CONSOLE | DLL + | GUI + | OBJ + Default is GUI 'Hint: CGI programs do not maintain a visible window $APPTYPE CGI SLEEP 5 SHOWMESSAGE "No visible window" SLEEP 5 SHOWMESSAGE "Warning: Application with invisible window running" All $AppTypes except CONSOLE link with subsystem: WINDOWS. For $AppType GUI: Case-sensitive, pre-dimensioned read/write variables include: hWnd uMsg wParam lParam nCode HotBasic adds the $APPTYPE (CGI, CONSOLE, etc) to the compile-time $DEFINE list, so conditional code blocks can be defined. E.g., $IFDEF GUI 'code for GUI apps only $ENDIF ==$APPTYPE DLL and OBJ For $APPTYPE DLL and OBJ, source code generally consists of STD procedures which are Public and may be called from other modules, including the main program. All non-STD procedures (DECLARE without STD and GOSUB) are Private, callable only from other procedures in the module. Statements DECLARE ... LIB "xyz" where xyz is a .dll, and DIM of any array must be inside a procedure code block, since executable code is generated. Within such a procedure, these statements and others should be in a RUNONCE code block, since it is necessary only once in a module to DIM an array or to load a .dll library and set up the declared procedure's address. Outside of procedure code blocks, you cannot DIM any array, but you can DIM as globals and within procedures, use the following qualified types: BYTE, WORD, DWORD, SHORT, INTEGER, LONG, INT64, SINGLE, DOUBLE, REAL10, VARIANT, COMPORT, DATE, FILE, RECT, REGISTRY, SQLDATA, SQLITE, TIMER and UDT's (user defined types). DIM/CREATE of other qualified types or of an array generates executable code and those statements should be in a RUNONCE code block inside a procedure. On Linux, the Windows file extensions .obj and .dll are .o and .so respectively. ==$APPTYPE DLL only For a DLL, only STD procedures are exported (Public). Source code for a DLL (1) starts in a procedure which is run by the OS when the .dll is loaded and (2) ends with a required END statement. Microsoft states that code in this "OnLoad" procedure may be used for general initialization statements and may call only API's in kernel32.dll, with certain exceptions such as LoadLibrary and REGISTRY Object code). [Note that only native HotBasic statements that generate such API calls can be used, since you cannot DECLARE other functions in kernel32.dll before the END statement.] Before the END statement, you can DIM and use qualified types listed above, DIM arrays and do math and many other activities, and these quantities will also be globals which the DLL's procedures may access. Please see Statements > Procedures for more details. $ARRAYPOS ON | OFF For each read/write of an array element, ON causes (1) update of the array .Position property and (2) run-time error checking for out-of-bounds subscripts. $ARRAYPOS ON is useful in program development stages. OFF (default) skips these two items and is therefore faster. $ARRAYPOS can be switched ON or OFF at any time in source code. $DEFINE symbol1 [symbol2] Defines symbol1. $DEFINE MySymbol Comma-delimited symbol lists may be used. $DEFINE W95, GUI, NOPRINTER IF no comma and symbol2 is present, symbol1 and symbol2 are also added to the $MACRO lists for text substitution. $DEFINE and $MACRO can be used to define constants. Since text replacement is used, constant names (symbol1 above) should not be embedded in other names. Examples: $DEFINE WM_COMMAND &H111 $DEFINE fmCreate 65535 $DEFINE BitMask1 24 A symbol may be redefined: $DEFINE Button Button1 'code where "Button" is changed to "Button1" $DEFINE Button Button2 'code where "Button" is changed to "Button2" A common pitfall of $DEFINE which invokes text-replacement in source code before compile is embedding text-to-replace A in text-to-replace B. You probably have experienced this issue using text replacement in an editor. $DUPARGERR ON | OFF Disallow (ON) or allow (OFF) SUB and FUNCTION argument name duplicates in DECLARE statements (OFF is default). In sets of procedures, often it is most convenient to be able to use the same name for an argument in many declare statements. E.g., if "lpOBJ" (long pointer to OBJ) is used repeatedly, one does not have to invent a new name with each usage and the same varible (lpOBJ) is used over and over, saving some RAM and some typing. On the other hand, nested calls to such procedures using the same argument name will overwrite that variable, which is relevant if the previous value is needed after the call to a procedure using the same argument name. With $DUPARGERR ON, these duplicate usages will be flagged as errors which may help discover such dependencies. Since ON can be a drastic measure, this directive features the ability to turn the feature ON and OFF for separate blocks of DECLARE statements. $DUPPROCERR ON | OFF ON is default and provides ERROR messages whenever a user name for a procedure in a declare statement duplicates *any other* user symbol name in your code. OFF will suppress (1) ERROR check and (2) compile of DECLARE/CDECL statements with the LIB keyword if the procedure name duplicates *any other* user symbol name in your code. The $DUPPROCERR directive was introduced to handle situations where multiple source code files -- main program, $INCLUDE files, perhaps written by different authors, may have duplicate declare statements for LIB module procedures such as API's. With $DUPPROCERR OFF, when a duplicate declare is found, compile will continue without ERROR and the duplicate declare statement will be skipped. It is suggested to wrap blocks of DECLARE/CDECL statements which might contain duplicates of prior code in $DUPPROCERR OFF/ON directives, rather than inserting a single $DUPPROCERR OFF directive in your main program. $EQUALPREC ON | OFF When ON, (*, /, \) and (+, -) are evaluated with equal operator precedence. Default is OFF. Please see Switches and Operators. $ESCAPECHARS ON | OFF Supported escape sequences are: \a BEEP like CHR$(7) \b Backspace \f Form feed \n Carriage return and line feed like CRLF \r Carriage return \t Tab \v Line feed \\ Translates to a single \ character \" Translates to a single " character \### Binary byte value, ### is 000 to 255; e.g., \013 same as \r \xHH Binary byte value, xHH is x00 to xFF with HH as a hex string OFF is default. Every string is processed for escape characters each time it is assigned to a variable or printed. This can slow program execution. Thus, set $ESCAPECHARS ON and OFF as needed, so control is maintained on the when and where escape characters will be processed. Please see hotesc.bas for a working example and an illustration of what can happen if the same string is processed twice for escape characters. Namely, if a first processing turns "\\" into "\", then a second processing will turn "\..." (... are the next three characters) into a single (probably unwanted) character via the \### sequence. In other words, the processor does not stop and say, "Hey, did the coder really want to do this?" Escape characters are a pre-PC convention and can be very troublesome. However, used with care, some neat things can be done. For one thing, the binary value escape sequences can be used to create binary strings, even including null bytes, for any number of purposes. Since ':' is a statement delimiter in source code, a quoted string containing a ':' should not contain the '\"' escape sequence. Use the equivalent '\x22' instead of '\"'. $GTKFORM FIXED | VBOX | HBOX This Linux-only directive for GTK-mode GUI applications specifies the container used by subsequently created FORMS. The default is FIXED. For multi-FORM applications, $GTKFORM may be used more than once to change the container for additional forms. $GUIOBJ n where n is an immediate value integer, not a variable. $GUIOBJ allocates (or deallocates) n run-time FORM object table slots -- 4 bytes for each object. In the main program, HotBasic has full accounting for all DIM/CREATE of FORM objects and the total number is stated in the compiler output results. However, with DIM/CREATE of FORM objects in .obj modules ($APPTYPE OBJ), this directive is used to increment this total for the linked .exe. $GUIOBJ 10 'add 10 slots to run-time FORM object table $GUIOBJ may by used repeatedly only in the main program module to create a "running total" of the size adjustment of the table. Generally, $GUIOBJ would only be used when linking .obj modules which contain code to DIM/CREATE FORM objects. On the other hand, HotBasic allocates 64 table slots for each FORM array in the main program. If you use only ten of them, then you could write $GUIOBJ -54 'saves 54 x 4 = 216 bytes of data space in .exe. The space saved may be viewed as trivial; so use carefully: Extra table space is not problematic; too little can cause overwriting of other data or crashes. If you are using arrays of FORM objects, $GUIOBJ may be used to increase the number of table slots. Since for each such array, HotBasic allocates 64 slots, the running total available would be 64 x number of arrays. As long as the total number of array elements actually used is less than this total, the $GUIOBJ directive is not needed. Otherwise, $GUIOBJ x 'x = actually used - total available Only advanced coders need $GUIOBJ, mainly when DIM/CREATE of FORM objects is done in an .obj module to be linked into your main program (which may be $APPTYPE GUI or $APPTYPE DLL, where GUI forms may also be created). $IFDEF symbol | $IFNDEF symbol {statements} [$ELSE {statements}] $ENDIF Example: $IFDEF AGP 'code alternative 1 $ELSE 'code alternative 2 $ENDIF $INCLUDE "filename"; filename can include a path. $INCLUDE files can be inserted at any time and can be nested to nine levels, where an included file itself contains $INCLUDE directive(s). Any selection of source code may be placed in an $INCLUDE file, perhaps to avoid editing of long source files. There is no logical restriction in segmenting code into $INCLUDE files. The compiler simply processes the included code in sequence as $INCLUDE directives are found at any line in source code. Such files can have any extension, although ".inc" is often used. Please note that HotBasic fully compiles included files. In contrast, some compilers treat such files as a last resort to find undefined symbols. Therefore, do not include long reference files such as a "windows.inc", etc -- the whole thing will be compiled! For RapidQ users, please see HotBasic Tips regarding "RapidQ.inc". Use of RapidQ.inc produces a Warning ErrorLevel. $MACRO symbol1 symbol2 Substitutes symbol2 for symbol1 in source code lines. DATA statements are not processed for $MACRO entries. Hint: space characters can be used in quoted strings. $MACRO " (" ( 'removes space before ( if any $MACRO " divided by " / $MACRO PopupText ShowMessage $MACRO INT16 SHORT $MACRO #DEFINE $DEFINE $MACRO "!=" <> For $DEFINE and $MACRO, avoid embedding symbol1 text in other symbol1 text. For coders familiar with "macros" that may contain multiple lines of code and even arguments, in HotBasic, this is called a SUB or GOSUB procedure, which does exactly that and in most cases, more efficiently. $OPTIMIZE Used as first line of main program to compile with the -O switch option. Requires file in the HotBasic directory named hotoptim.exe or hotoptim.bat. $OPTION DATA If used at all, this option is only for $APPTYPE OBJ and only to compile .obj modules for use with non-HotBasic main programs. $OPTION DATA causes the compiler to dimension variables used internally by the HotBasic coding system and is therefore necessary for code within the .obj module to function properly if the .obj is ported to another development environment, say, where the main program is in another language. Conversely, if you intend to use the .obj to link with a HotBasic main program, this option should not be used, because it would cause repeat definitions of internal variables and provoke linker errors. $OPTION DIM type; type is a valid numerical type; e.g., $OPTION DIM LONG Causes CONST statements and $TYPECHECK OFF dimensioning to default to the numeric type specified. This is especially useful for CONST statements which default to DOUBLE unless modified by this directive, which can be used repeatedly to specify default dimension type. $OPTION EXPLICIT; same as $TYPECHECK ON $OPTION ICON "filename"; specifies .ico resource; please see $RESOURCE $RESOURCE symbol As "filename"; e.g., $RESOURCE hot_ico As "HotBasic.ico" Filenames with .bmp, .cur, .dlg, .ico and .wav are specifically stored as BITMAP, CURSOR, DIALOG, ICON and WAVE resources respectively, because Windows uses special procedures to access them. Others are stored as RCDATA resources, which guarantees an exact binary image is extracted. The first .ico resource, if more than one, is used as application icon in CONSOLE programs and is displayed by Microsoft explorer.exe listings. App.Icon and MyForm.Icon statements may name application .ico files. But the .Icon statement for FORM child objects always refers to a resource. In the EXTRACTRESOURCE statement and .EXTRACTRES method, the RESOURCE() keyword works but is not necessary. For example, with $RESOURCE my_wav AS "my.wav" one could just write ExtractResource("my_wav","my_wav.tmp") which is more intuitive than using an index n with RESOURCE(n) If RESOURCE(n) is used to denote the resource, the RESOURCECOUNT numeric function may be used to limit the upper value of index n, else a fatal run-time error occurs. .bmp and .ico files as resources may be used in the application as BITMAP and ICON objects. .bmp and .ico files as resources for EXTRACTRESOURCE or the .ExtractRes method should be renamed (e.g., .bm_ and .ic_) to ensure that the extracted resource is an exact copy of the original file. $RESOURCE icon1 as "icon1.ico" 'use as application icon $RESOURCE icon2 as "icon2.ic_" 'use to extract exact binary copy If a .manifest file like HotBasic.manifest is used as $RESOURCE, there is not visible effect of pre-XP machines, but XP-style display occurs on XP machines. In short, the same distribution executable will look different depending on Windows OS version and configuration. E.g., $RESOURCE 1 As "HotBasic.manifest" $SYMBOLTABLE ON | OFF ON prints application Symbol Table; OFF is default. $TYPECHECK ON | OFF ON triggers error on un-dimensioned symbol (recommended). OFF is default. With $TYPECHECK OFF, the slightest typing error in source code may result in unexpected dimensioning of a "new" variable, which can cause great pain in debugging. If ON, typing errors are flagged as "unknown symbols" which are easily corrected. $UNDEF symbol[, symbol[, etc]] Removes symbol from defined list. $UNDEF Button, AGP If the undefined symbol equals "symbol1" in the $DEFINE/$MACRO lists, that pair of symbols is also deleted. This feature is convenient to limit text substitution to a limited set of statements. $UPPERCASE ON ON forces all user symbols to upper case (like RapidQ). OFF is default where case-sensitive matching is used for symbols. IF OFF, variable k <> K and MyVar <> myvar <> MYVAR, etc. Unlike RapidQ, at present, this may prevent compilation of API code since API function names are case-sensitive. Once ON, cannot be turned off during compilation. $X11 The $X11 directive placed near top of source code acts the same as the -x switch to compile for Linux with X11-mode GUI (default is GTK-mode). $X11 adds X11 to the $DEFINE list so $IFDEF X11 may be used for conditional compile of code. For code to be compiled for either Windows or Linux, $X11 is ignored in Windows compile. $XPSTYLE Same as $RESOURCE 1 as "HotBasic.manifest". Please see $RESOURCE. + Penthouse (registered) version Copyright 2003-2008 James J Keene PhD Original Publication: Oct 9, 2003