Directives
Updated: Apr 2, 2006

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

  ==$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. 

  ==$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.


$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"


$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.


$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 '\"'.


$FASTFOR ON | OFF (autodetected and directive ignored)


$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.

  Overview. 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.  Only advanced coders need $GUIOBJ, mainly when
  DIM/CREATE of FORM objects is done in an .obj module.


$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 cannot be nested.
  Such files can have any extension, although ".inc" is often used.

  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.


$OPTIMIZE

  Second-pass optimization **


$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.


$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.


$XPSTYLE

  Same as $RESOURCE 1 as "HotBasic.manifest".  Please see $RESOURCE.


**  Planned future additions

+ Penthouse (registered) version

Copyright 2003-2006 James J Keene PhD
Original Publication: Oct 9, 2003
