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 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).
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
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
Arithmetic + - * / \ ^ MOD ISFALSE ISTRUE Boolean and or not xor eqv imp Relational = <> >< < > <= =< >= => String + (concatenation) & (concatenation) Compound += -= *= /= \= &= AND= OR= EQV= IMP= MOD=
0 is FALSE, non-zero is TRUE expressions return -1 (TRUE) or 0 (FALSE)
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
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 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
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
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
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
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.