PowerBASIC Information Center Mini-Tutorial

NOTE: As of 28 Jan 2009 I'm updating this page to be consistent with the rest of my tutorial pages. Check back in a day or so for the final result.

Speakers know the advice of "Tell them what you're going to tell them ...", which is what this very short mini-tutorial does. It's a preview of the full PBWin tutorial provided at this site, with all the fat (and some of the meat) cut out.

It's an introduction for newbies to get a feel for PowerBASIC in one reading, although some sections may not make much sense until you've read the corresponding tutorial. And for those of you coming back to PowerBASIC after an absence, it's a reminder of what PowerBASIC offers and perhaps what you forgot.

PowerBASIC Program Overview
A PowerBASIC program starts by executing a function called PBMain. The program ends when the last line of code in PBMain is executed.

Generally, the last line of code in PBMain modally displays an application's main window. When the window is closed, the PBMain function ends and the PowerBASIC application closes. While the main window is open, the program is free to respond to events, such as button presses, etc.

In PowerBASIC, windows are called dialogs.

A Simple Program
Just to get you started, here's a quick look at a traditional "Hello World" program. In this case, no main window is created. Execution starts are the PBMain function but the only line of code is a simply MsgBox which pops up a message.

   #COMPILE EXE   'directs compiler to create EXE
   FUNCTION PBMAIN () AS LONG
       MSGBOX "Hello World"
   END FUNCTION

A Less Simple Program
Hello World! is pretty boring. So here's a simple program that creates a main Dialog with a single button.

The program starts execution in the PBMain function, creating a dialog and a button. When the button is pressed the Callback Function responds by closing the dialog, which was opened modally. With the dialog closed, PBMain continues executing but there are no more lines left in PBMain so the PowerBASIC program ends.

   #COMPILE EXE
   Function PBMain() AS Long
      Dim hDlg AS DWORD, hCtl AS DWORD
      Dialog NEW 0, "Caption",300,300,200,200, %WS_SYSMENU,0 TO hDlg
      Control Add Button, hDlg, 2, "Cancel", 100, 100, 40, 20
      Dialog Show Modal hDlg CALL DlgProc TO Result&
   End Function

   CallBack Function DlgProc() AS Long
      Select Case CB.MSG
         Case %WM_COMMAND
            If CB.CTLMSG = %BN_CLICKED Then
               DIALOG END CB.HNDL, 1
               FUNCTION = 1
            End If
      End Select
   End Function

These statements are covered in detail in the full tutorial.

A Simple DLL
PowerBASIC can also create libraries of functions, called DLLs (dynamic link libraries). Here's a quick look at a simple one-function DLL.

   #COMPILE DLL   'directs compiler to create DLL
   FUNCTION RandomAdd ALIAS "RandomAdd" (BYVAL x AS SINGLE) EXPORT AS LONG
      RandomAdd = x + RND     'adds random amount to x
   END FUNCTION

The exported function 'RandomAdd' is defined as simply adding a random amount to the value of variable argument. The result is returned to the calling program.

The PowerBASIC compiler would use this code to create a *.dll file. The file could be reference by other program to gain access to the RandomAdd function.

DLLs typically contain many functions, particularly those which might be useful in several applications. Applications can simultaneously share the function available in DLLs.

PowerBASIC DLLs can be used by applications, regardless of the language the application was written in.

PowerBASIC IDE
PowerBASIC programs are text files created using the PowerBASIC IDE (pbedit.exe). The IDE acts as both a source code editor and a source code compiler. It generates standard Windows EXEs and DLLs. The IDE additionally provides tools which automate or simplify source code creation/editing.

PBMain - PowerBASIC Program Starting Point
Source code for a PowerBASIC program can be contained in one or more files. As noted above, execution of the programs starts with the PBMain function. Many of the files can contain a PBMain function, but execution of the program will begin with the PBMain in the source code files which has been designated as the Primary Source File. When a PowerBASIC program is contained within a single file (usually with a .bas extension), that file is automatically designated as the Primary Source File.

The PowerBASIC IDE automatically includes an empty PBMain function when creating any new source code file. A user places code inside the PBMain function, as well as adding any other functions needed to create the application.

When the PBMain End Function statement is reached, the PowerBASIC program will end.

As noted before, calling a MODAL window is one way of allowing the program to remain active. Another approach is to create a loop that cycles repeatedly until a user presses an appropriate key to end the loop.

Multiple Source Code Files
Source code for a PB program may be contained in one or more text files. The #INCLUDE statement is used to direct the compiler to include the source code from files other than the Primary Source File. This allows large amounts of source code to be broken into smaller, more manageable files.

An included file may also have #INCLUDE statements. PowerBASIC supports up to to six levels of depth of included files.

PowerBASIC DDT and the Graphical User Interface (GUI)
Programming languages such as those in Visual Studio, allow a user to create an application's user interface (windows, controls, toolbars, etc.) by drawing the components with the mouse. Standard PowerBASIC has no such GUI builder.

Instead a PowerBASIC programmer creates the components of a GUI by writing source code statements which define and display the GUI elements. PowerBASIC uses the term DDT, Dynamic Dialog Tools, to refer to the collective set of code statements that can be used to create the elements of a user interface.

The most common means of creating graphical elements within a PowerBASIC program is to use the "DIALOG" (to create windows) and "CONTROL" (to create child controls in the windows) programming statements. There are 22 specific controls (buttons, checkboxes, listboxes, etc.) for which specific PowerBASIC support is provided.

A separate product from the PowerBASIC company, PowerBASIC Forms, is available which provides drag and drop GUI creation capabilities. Third-party IDE tools are also available which provide the ability to create a user interface using the mouse.

Many PowerBASIC programmers find that writing source code to create GUI elements is completely acceptable and do not use the mouse-driven GUI creation tools.

Managing GUI Elements - The CallBack Function
The GUI elements of an application - dialogs and their child controls - are all windows, which the Windows OS manages. When an event occurs, such as a mouse click by a user, Windows sends a message to the window (dialog or control) where the event occurred.

When a dialog or control is created in PowerBASIC, the PowerBASIC function, that will handle Windows messages is declared. These special functions are referred to as CallBack Functions. A single dialog-level callback function can be used to handle all messages - to a dialog or to its child controls. Or, a separate callback function can be defined for each child control.

Messages can also be originated within a PowerBASIC program to send a message to another dialog/control within the PowerBASIC program, or even to a dialog/control within another application.

An example of a callback function was provided earlier, as part of the section "A Less Simple Program".

Accessing Message Values
Within a CallBack function, PowerBASIC provides special functions to access the content of the Windows message, which consists of 4 values: hWnd, msg, wParam, and lParam .

The CB callback functions cb.hndl, cb.msg, cb.wparam, and cb.lparam can be used to retreive the corresponding Windows message components. Other CB callback functions are also available.

Understanding and using callback functions is one of the most fundamental aspects of PowerBASIC programming. Because all responses to user events occur within callback functions, a PowerBASIC programmer must be familiar with the various messages which a program can receive.

For example, notificaton of a button click is returned by the cb.ctlmsg function. When a callback function received that value, an application code would respond (as in the example above, with the text for a cb.ctlmsg value of %BN_CLICKED).

Formatting Syntax
When writing PowerBASIC code, here are basic formatting rules.

     no line ending                print "Hello"
     multi-statements per line	   print "hello" : print "goodbye"
     split lines                   print _   'space precedes underscore
                                   "Hello" 
     line numbers                  100 print "hello"
     labels allowed                LabelName:  'colon used, no code allowed
     use code from ext file        #Include "extrasourcecode.txt"  
     double quotes for strings     print "Hello"
     case-insensitive              A=5  is same as   a=5
     variable declaration          use #Dim All, otherwise is optional
     

Code Syntax
Here are lines of code, with features pointed out.

     Dim A as String           ' variable declaration
     Dim B as Long, b as long  ' invalid - B and b are same variable
     Dim A, B as Long          ' without specifier, A is Single
     Dim a$                    ' $ is string type specifier
     Dim MyArray()             ' undimensioned, resize later with REDIM
     Dim N$, N%                ' N$, N% are different variables
     REM ...                   ' any line staring with REM is a comment
     y = 4  'comment here too  ' any text after a ' is also a comment
     a$ = "Hello"              ' assignment of string to variable a$.
     x = 5.23                  ' no end-of-line character required
     a$ = _                    ' underscore to break up long line
             "Goodbye"         ' 2nd line of a 2-line code
     Dim a(5)                  ' simple 6 element array (0-based)
     Dim a(5 to 9)             ' alternate way to state array bounds
     x = sin(10)               ' parentheses must enclose arguments   
     Sub MyS ()                ' declaration of Sub, no arguments
     Sub MyS (x as long)       ' declaration of Sub, one argument
     MyS x                     ' parentheses optional to use Sub

Operators

     Arithmetic             +  -  *  /  \  ^  MOD  ISFALSE  ISTRUE
     Boolean                and  or   not   xor   eqv   imp
     Relational             =  <>  ><  <  >  <=  =<  >=  =>
     String                 +  (concatenation)
                            &  (concatenation)
     Compound               +=  -=  *=  /=  \=  &=  
                            AND=  OR=   EQV=   IMP=   MOD=
     

TRUE/FALSE

     0 is FALSE,  non-zero is TRUE
     expressions return -1 (TRUE) or 0 (FALSE)
     

Data Types

    Commonly used (with type specifier):
    * integer            a%        * variable-length string   a$
    * long integer       a&        * fixed-length string      a$
    * single-precision   a!        * double-word              a???
    * double-precision   a#        * variant                  none
    * pointer            none
     	
    Less commonly used:
    * bit                          * field string
    * byte                         * asciiz string
    * word                         * guid
    * extended-precision           * iautomation
    * quad-integer                 * idispatch
    * currency                     * iunknown
    * extended-currency   
    

Numerical Base Notation

    &H                is hex
    &O  or  &Q  or &  is octal
    &B                is binary
    

Pointer

    varible defined as a pointer    DIM X as Integer Pointer
                                    DIM R as Single PTR

    reference value at PTR addres   i = @X    # 1 level of indirection
                                    i = @@X   # 2 levels of indirection
    

UDT - User Defined Type

    Type MyVar
       i as integer
       A(5) as long        # element can be an array (1 or 2 dimensions)
       b as single
       s(5) as string * 5  # must be fixed-length strings
    End Type
    Dim X as MyVar
    

Arrays

    arrays are zero-based   
    Dim A(5)       6 elements, smallest index = 0
    Dim A(1 to 5)  5 elements, smallest index = 1
    Dim A(5,5)     multi-dimensional array
    Global A()     must define without (), then DIM/REDIM locally
    

Equates
PowerBASIC calls constants equates. Equates have global scope and must be defined outside procedures.

    precede numeric equates with %      %X = 2
    precede string  equates with $      $X = "hello"
    equates made from other equates     %K = %i + %j
    

Variable Scope
Procedures include sub/function/property/method/macro.

     * Local Scope   Dim, ReDim, Local, Static, Instance 
     * Global Scope  Global, Threaded 

     local       declared within procedure
     static      same as local, but value retained between calls
     global      accessible anywhere, delcared outside procedures
     threaded    access anywhere, unique copy for each thread
     instance    access anywhere in a class, unique copy for each object
     

Flow Control

     if (expression) then
        ... statements
     elsif (expression) then
        ... statements
     else 
        ... statements
     end if


     do while|until (expression)
        ... statements
     loop while|until (expression)


     select case (expression)
        case > b
           ... statements
        case 7
           ... statements
        case 5 to 9
           ... statements
        case 1,4
           ... statements
        case 3 to 7, 12
           ... statements
        case else
           ... statements
     end select     


     While (expression)
        ... statements
     Wend

     
     for i = 0 to 10 Step 2
        ... statements
     next i


     var = switch (expr, val1, val2, var3, ...)
     var = choose (index, val1, val2, var3, ...)
     var = IIF (expr, TruePart, FalsePart)
     var = Max (val1, val2, var3, ...)
     var = Min (val1, val2, var3, ...)


     Loop redirection:   exit, iterate 

     Exit for, function, if, do, macro, method, property, select, sub, try
     

Procedures
Both functions and subroutines are supported. Class property and methods are procedures, as are macros.

     Function Test() As Long
          MSGBox "hello function"
          Function = 2   
     End Function

     Sub Test() 
         MSGBox "hello sub"
     End Sub
     

Functions by Category (built-in functions)

     Numeric-----------------
     * Assignment             let, reset 
     * Powers                 exp, exp2, exp10, sqr 
     * Logarithms             log, log2, log10 
     * Base Conversions       bin$, hex$, oct$ 
     * Random                 rnd, randomize 
     * Modify                 incr, decr 
     * Properties             len, sizeof
     * Integer Result         int, ceil, fix
     * Decimal Place Control  round
     * Multiple Variables     min, max, swap 
     * Sign Operation         abs, sgn 
     * Fraction/Remainder     frac, mod 
     * Value Conversions      val, variant#
     * Pointer                varptr 
     * Trigonometry           sin, cos, tan, atn

     Strings-----------------
     * Assignment             let, reset 
     * Concatenation          join$, build$
     * Case-Conversion        ucase$, lcase$, mcase$
     * Properties             len, sizeof, varptr 
     * Single Character       asc, chr$ 
     * Truncate Strings       left$, right$, remain$, extract$ 
     * Remove Spaces          ltrim$, rtrim$, trim$ 
     * Repetitive Strings     space$, string$, nul$, repeat$ 
     * Value Conversion       val, str$, variant$ 
     * Parsing                parse, parse$, parsecount
     * Number Base            hex$, oct$, bin$
     * Formating              format$, using$, strreverse$
     * Unicode                ucode$, acode$, ucodepage
     * Remove Characters      remove$, retain$, strdelete$
     * Regular Expressions    regexpr, regrepl
     * Pointers               strprt, varptr
     * Find/Replace           mid$, instr, tally$, replace,
                              asc, tab$, verify, strinsert$
     * Justification          lset, rset, lset$, rset$,
                              cset, cset$ 

     Arrays------------------
     * Create/Destroy         parse, erase 
     * Initialize/Set Values  reset, ARRAY assign 
     * Properties             arrayattr, lbound, ubound
     * Add/Delete Elements    ARRAY insert, ARRAY delete 
     * Search/Sort            ARRAY scan, ARRAY sort
     * Matrix                 mat 
     * Implied Bit-Arrays     BIT, BIT CALC 
     * File Operations        FileScan, Line Input#, Print#, GET, PUT 

     Date/Time---------------
     * Current Time           date$, time$
     * Elapsed Time           tix, timer
     * Pause Program          sleep     

     System Calls------------
     * Environment            environ, environ$ 
     * Execute Programs       shell 
     * App Information        command$, EXE 
     * DESKTOP                Get Client, Get Loc, Get Size 
     * WINDOW                 Get ID, Get Parent 
     * Memory Access          peek, peek$, poke, poke$ 
     * GLOBALMEM              alloc, free, lock, size, unlock 
     * CLIPBOARD              Get Text, Set Text, Get Item,
                              Set Item, Reset 

     Keyboard----------------
     * Characters & Strings   GRAPHIC Inkey$, GRAPHIC WaitKey$, 
                              GRAPHIC Line Input 
     * Variables              GRAPHIC Input 
     * Buffer                 GRAPHIC Flush, GRAPHIC InStat 

     Error Trapping----------
     * Most Recent Error Info   erl, erl$, err, errclear, error$ 
     * Generate Error           error 
     * Respond to Errors        On Error, resume, Try/End Try 
     * Monitoring Performance   Trace, Profile, CallStk, 
                                CallStk$, CallStkCount 

     Folders-----------------
     * Create                 mkdir, rmdir 
     * Navigate               chdir, chdrive, 
     * Information            curdir$, dir$, dir$ close, 
                              diskfree, disksize

     Files-------------------
     * Access Control         lock, unlock 
     * File Access            open, close, freefile,
                              filename$, isfile 
     * File Management        kill, name, setEOF 
     * Write To File          write#, print#, flush 
     * Read From File         input#, line input# 
     * Random/Binary Files    get, get$, put, put$, 
                              loc, seek, field 
     * Opened File Info       eof, lof, fileattr, filescan 
     * Closed File Info       getattr, setattr 
     * Utilities              pathname$, pathscan$, filecopy 
     * Program Data           data, read$, datacount 
     

If you have any suggestions for additions to this mini-tutorial, please let me know.