Variables and Types Updated: July 28, 2012 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: hbTrap 'Address of exception handling routine for run-time errors. hbError 'Run-time error code readable in hbTrap exception handler. If hbTrap = zero (default), run-time errors terminate the application. If hbTrap = CODEPTR(my_run-time_error_handler), then instead of application termination, your handler code is run. Please see more detail in the "Error Levels and Run-Time Errors" section. hbConsole 'TRUE after SHOWCONSOLE execution; FALSE after FREECONSOLE. 'IF hbConsole THEN PRINT "Something" 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-2012 James J Keene PhD Original Publication: Oct 9, 2003