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
