Variables and Types
Updated: Sep 8, 2009

In coding jargon, a "qualified type" is a symbol which the compiler understands
as an item it can dimension.  "Dimension" just means the compiler allocates
memory space for the item and gives it the name used in the source code.

  DIM MyVar As INTEGER

sets aside 4 bytes of memory named with user symbol MyVar.  Compiler Symbol
Table output lists all dimensioned variables, types and objects.


Qualified Types -- Variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TYPE   SUFFIX BYTES  CATEGORY SIGNED   
BYTE     ?     1     integer   No    0 to 255
WORD     ??    2     integer   No    0 to 65535
DWORD    ???   4     integer   No    [often pointer or larger + integer]
SHORT    %     2     integer   Yes   -32768 to 32767
INTEGER  &     4     integer   Yes   -2147483648 to 2147483647
LONG     &     4     integer   Yes   [LONG is an alias for INTEGER]
INT64          8     integer   Yes   64-bit integer
SINGLE   !     4     floating  Yes   [aka REAL4]
DOUBLE   #     8     floating  Yes   [aka REAL8]
REAL10        10     floating  Yes
VARIANT       16     varies    --    [see usage in variant.bas]
STRING   $    Varies string    N.A.  [is an "Object" in HotBasic]

The suffix may be used with $TYPECHECK OFF (not recommended) so i& and c$ are
implicitly dimensioned as LONG and STRING respectively.

Use of a variable suffix does not change the need to specify Type for DECLARE
statement arguments and affects destination, not source, variables.

You probably know well that memory just contains bits -- 0 or 1.  The types
above help the coder to track what source code is doing and tell the compiler
how to handle the data, such as when one type is assigned to another type,
e.g., MyWordVar = MyReal4Var.  The hottypes.bas program shows exactly how
assignments are done.

This list of types is long enough to do any job and not so long that you have
to read long manuals to understand source coding.


Qualified Types -- Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~
Objects used without DIM statements are

  APPLICATION, CLIPBOARD, CONSOLE, FILEREC, FPU, MOUSE, PRINTER +,
  PROPERTIES +, SCREEN, VERSION

Objects which may be dimensioned are

  BITMAP +, COMPORT +, DATE, FILE, LIST, MEMORY, NODE, RECT, REGISTRY,
  SOCKET, SQLDATA, SQLITE, STRING, TIMER, VARIANT

with GUI (+) objects

  BUTTON, CANVAS, CHECKBOX, COLORDIALOG, COMBOBOX, DATETIME, EDIT,
  FILELISTBOX, FINDDIALOG, FONT, FONTDIALOG, FORM, GAUGE, GRID, GROUPBOX,
  HEADER, IMAGE, LABEL, LISTBOX, LISTVIEW, MAINMENU, MENUITEM, OPENDIALOG,
  PAGEDIALOG, PANEL, POPUPMENU, PRINTDIALOG, RADIOBUTTON, REPLACEDIALOG,
  RICHEDIT, RICHEDIT2, SAVEDIALOG, SCROLLBAR, SPLASH, STATUSBAR, SYSTRAY,
  TABCONTROL, TOOLBAR, TRACKBAR, TREEVIEW, UPDOWN

and properties, methods and events for each are described in a section of these
notes.

Please note that STRING is an object in HotBasic and all the properties and
methods of the MEMORY and LIST objects apply to an ordinary STRING.  However,
strings as items in a STRING array or in a TYPE/OBJECT are fixed-length
buffers, not STRING objects themselves.

Object dimension example:

  DIM F As FILE, M As MEMORY
  F.OPEN("myfile.txt",2): M.LoadFromFile("myfile.ini")

User code may name (dimension) a number of objects for each of the above object
types.  For example, i, j and k may all be dimensioned As LONG.


Qualified Types -- User-Defined Types (UDT) and Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
What if you don't see above what you need?  Just define your own type.
arrayudt.bas, construc.bas, hotudt.bas and typebyte.bas in HotTrial show
examples.

It is a one-two process: (1) TYPE statement block defines the type and
(2) DIM statement names instances or arrays of the UDT for use in code.

OBJECT is an alias for TYPE.  Please see Objects > Custom Objects for
constructor syntax in UDT structures and for EXTENDS syntax, used to add
properties, methods and/or functions to native HotBasic Objects listed above.

  TYPE INVENTORY
    description as string*64
    supplier as string
    part as long
    'etc
  END INVENTORY

The *n syntax above specifies its ram allocation -- 64 bytes.  If *n syntax is
omitted as for "supplier" above, the default length is 256 bytes.

For "As STRING" UDT items, HotBasic will never allow a UDT buffer overflow
when writing a text string to the item.  If your source data string is too
long, it is truncated.

UDT "properties" are all read/write items.

With Custom Object syntax, "As SUB" and "As FUNCTION" represent additional
qualified types for new Object methods and functions respectively.


UDT -- Constructor Syntax
~~~~~~~~~~~~~~~~~~~~~~~~~
Any TYPE/OBJECT (UDT) may be defined with default values with simple
constructor syntax.  Both numeric and string OBJECT/TYPE items may be assigned
default values.

Constructor syntax is similar to that used in DEF... dimensioning statements
for variables (DEFINT, DEFSTR, etc).  See construc.bas in HotTrial.

One simply appends " = value" to the OBJECT/TYPE item line.  The value must be
an "immediate" or "literal" value -- that is, a number for numeric items or a
quoted string for string items in your OBJECT/TYPE code block.  The value
cannot be a variable or expression, which can, however, be used in an
OBJECT/TYPE initialization SUB.

For numeric items, the value should match the item type (floating vs
non-floating).  "MyFloat as double = 1.5" and "MyInt as integer = 10" meet
this requirement.  A hex value such as &HA000 may be used.

For string items, consider the optional "* n" syntax where n is a literal
integer for maximum string length, exactly as done in DIM of string arrays.
If "* n" syntax is omitted, n defaults to 256.

The quoted string is truncated if longer than the item size.  With

  MyText As STRING*12 = "HotBabe Hello"

"HotBabe Hello" is truncated and the default .MyText item will be
"HotBabe Hell" -- something nobody wants!

At run-time all string assignments to OBJECT/TYPE string items are similarly
truncated if necessary to avoid buffer overflows.

  MyUDT.MyText = s$

is always logically the same as

  MyUDT.MyText = left$(s$,n) 'where n is maximum item size


UDT -- Property Set and Get +
~~~~~~~~~~~~~~~~~~~~~~~~~~~
You may run code on write (property set) or on read (property get) of TYPE/
OBJECT members.

PROPERTY SET syntax runs code on value assignment to a TYPE/OBJECT member
if a SUB exists named {upper-case TYPE}{member}_Set.  For example, for instance
x of object ABC, if code contains x.Rating = 10, then if SUB ABCRating_Set
exists, it is run.

PROPERTY GET syntax runs code on read of a TYPE/OBJECT member if a FUNCTION
exists named {upper-case TYPE}{member}_Get.  For example, for instance x of
object ABC, if code contains y = x.Rating, then if FUNCTION ABCRating_Get
exists, it is run.


UDT -- Type Nesting
~~~~~~~~~~~~~~~~~~~
Nested types are often seen in reference material and source code:

  '====nesttype.bas
  $APPTYPE CONSOLE: $TYPECHECK ON

  TYPE POINT
    x as long = 10  'Constructor syntax
    y as long = 20
  END POINT

  TYPE LINE
    pt1 as POINT  'POINT type as member of LINE type
    pt2 as POINT
  END LINE

  dim A as line

  PRINT "Show Constructors are inherited:"
  print A.pt1.x; tab; A.pt1.y
  print A.pt2.x; tab; A.pt2.y

  PRINT "Write and read each LINE member:"
  A.pt1.x = zero: A.pt1.y = zero
  A.pt2.x = 100:  A.pt2.y = 100
  print A.pt1.x; tab; A.pt1.y
  print A.pt2.x; tab; A.pt2.y

  PAUSE
  '====nesttype.bas

Notice the naming convention for members of instance A, where A.pt1.x is the 
x member of the pt1 member of A.

For Custom Object nesting, "As SUB" and "As FUNCTION" members retain their
original name, since these user names must match declared SUB or FUNCTION user
names elsewhere in source code. 

The disadvantage of "automated" nesting of types and generation of member names
may be clear from the nesttype.bas example above.  First, the generated names
are longer which may help reading and understanding code, but more keystrokes
are required when writing code.  Second, the original names of the child
type's members are lost.  This may be unacceptable for Custom Objects since
methods code may reference the original names.

LINE instance A above is in fact a contiguous ram area, just like POINT.  And
"manual" nesting intuitively parallels the underlying data structure we are
creating.  Thus, we cut and paste to write LINE in a usable form:

  TYPE LINE
    x1 as long  'was .pt1.x
    y1 as long
    x2 as long  'was .pt2.x
    y2 as long
    'etc
  END LINE

  DIM A as LINE

and we write

  A.x1 = x  'and so forth

Above we chose more suitable names for the POINT members.  In short, with such
code, the POINT structure is not used at all -- except as a reference.


UDT -- Arrays as Type Member
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HotBasic does not (yet) have arrays as elements inside a UDT.  Many methods
may be used.  Here is a simple method using BYREF():

  TYPE HasArrays
    array1 as string*400
    array2 as string*800
    'etc
  END HasArrays

  DIM MyData As HasArrays, i As LONG, x As LONG

MyData.array1 has ram for 100 4-byte values.  To read 0-based value i:

  x = BYREF(@MyData.array1 + i * 4)  'x may be INTEGER or SINGLE

Reverse the above to write value i:

  BYREF(@MyData.array1 + i * 4) = x

Another approach is to

(1) dimension "scatch" ARRAYs with 1 to 5 subscripts,
(2) MEMCPY your UDT string into the ARRAY,
(3) do your data processing using conventional array subscripting and
(4) if necessary, MEMCPY back to UDT.


Internal Variables +
~~~~~~~~~~~~~~~~~~
Case-sensitive, pre-dimesioned read/write variables include:

==For $AppType GUI:

  hWnd, uMsg, wParam, lParam, nCode (notify code)

are message information defined upon entry into an event routine.

For .OnDialog procedures (please see DIALOGS):

  hDlg, mDlg, wDlg, lDlg  'message information

For .OnPaint procedures and in .BeginPaint/.EndPaint or .GetDC/.ReleaseDC
code blocks,

  hbDC     'Device context handle

Additional GUI internal variables are:

  hbFont   'Handle of default font assigned to GUI objects.
           'Please see FONT Object for def_font.bas demo of usage.

  hbForm   'Handle of application's main FORM (the one defined first!)

  hbParent 'Handle of last defined FORM

  hbLoop   'CODEPTR() to user procedure called for any message/event

If non-zero, hbLoop allows users to trap any message processed by the
application.  E.g., hbLoop = CODEPTR(MyEvents)

  hbMsg    'Address of MSG structure associated with hbLoop event

defined before entry into a user hbLoop event procedure.  This Windows' MSG
structure contains hWnd, uMsg, etc, above and more!

When .ShowHint is used,

  hbHint   'Handle of ToolTip object used to create and show hints

==For any $AppType:

For SUB and FUNCTION procedures defined in Custom Objects:

  hbObj     'Address of calling Object/Type structure

  hbHnd     'Handle of extended FORM object, if applicable
            'or address of extended non-FORM object

  hbArgs    'Pointer to variant array of input parameters
            'for Custom Object Invoke, Method, GetNum, GetStr or GetVariant

When the .Item() or FIELD$ functions are used,

  hbItem    'Address of retrieved item or field in the LIST, MEMORY or STRING

When the LPRINT statement is used,

  hbPrinter 'Handle of printer port created, typically lpt1:


+  Penthouse (Registered) version

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