PowerBASIC

From Bauman National Library
This page was last modified on 8 June 2016, at 19:35.
PowerBASIC
Developer Robert "Bob" Zale (b. 1945, d. 2012)
First appeared 1989; 34 years ago (1989)
Website powerbasic.com
Influenced by
Turbo Basic

Powerbasic is a powerfull professional development tool. It comes in two versions: the console compiler and the GUI compiler. The language offers all the elements to design and create professional products. It creates stand alone EXEs or DLLs. EXEs are among the smallest (starting from 7,5Kb): source code is compiled into native machine code. PowerBasic may gain access to the entire Windows API. The programmer may build software starting from console utilities without user interface, to complete GUIs or server to client CGIs. DLLs can be used by programs written in any other language that supports 32-bit Windows DLLs. The language has hundreds of functions and statements, and 29 controls. Beyond all standard programming functions, PowerBasic supports: COM automation, built-in 32-bit inline assembly with 80486 and Pentium opcodes, true 32-bit code pointers, client/Server Network Communications and multi-thread application support, 80-bit extended-precision math, up to 2 Gb of memory may be allocated for arrays and dynamic strings. PowerBasic offers a well thinked IDE with a source-level integrated debugger. Unfortunately the GUI editor is sold separately. Coding in PowerBasic is quite simple. Using the language for simple tasks may remember old fashion easy and amusing QuickBasic programming as the syntax and most of the functions and statements rensemble QB. On the other hand if you start a more advance project at the beginning this could be a little misleading, but actually the learning curve is quite smooth. The Help is well done and complete. One of the major advantages of Powerbasic is that's a mature language and has a great number of developers which created a large community where you can find every kind of help and source code.

History

The first version of the DOS compiler was published as BASIC/Z, the very first interactive compiler for CP/M and MDOS. Later it was extended to MS-DOS/PC DOS and in 1987 Borland distributed it as Turbo Basic. PowerBASIC, founded by the developer of the compiler, took over development and distribution in 1989, calling it PowerBASIC and later PBDOS.

PowerBASIC went on to develop Basic compilers for Windows, first PBWIN — their flagship product — then PBCC, described below.

On November 6, 2012, Robert Zale, the creator of PowerBASIC, died. For a time, it was assumed that the company might cease operations. His wife, Mrs. Vivian Zale, posted on 8 March 2014 to the PowerBASIC forums a statement that the company would continue in operation. On 10 May, 2015, Mrs. Zale announced that work was continuing on new versions of PowerBASIC compilers.

Native code compiling

Most programmers today are familiar with either dot.net programming languages or scripting languages (ie. HTML5, Javascript, etc.). In the Windows world, dot.net currently “rules the roost” for many while old fashioned WIN32 programming has gone by the wayside. Native coding for Windows programmers means coding directly to the WIN32 API. Why would anyone want to do that, one may ask ? One word “Performance” ! To better appreciate how native coding affects performance, watch Herb Sutter’s talk “Why C++ ?” on Microsofts Channel 9. No matter what programming language you currently use, his talk about C++ is a must watch video. Simply put, native coding directly to the operating system produces the best performance possible.

Dot.net is a framework between the operating system and ones application, a middleman one could say. So would not talking directly to the operating system provide better performance ? Actually it does. But who cares about performance anymore, since computers are so much faster today ? Todays small Windows tablets for one require high performance applications since they usually have minimal hardware. Developers of performance critical apps, like graphic editors, look for every bit of performance they can get. Embedded programmers also may want high performance apps so they can use minimal hardware.

Simple example

In just four lines you can write a PowerBASIC program. Just place the following lines of code into a file, open it in the IDE, and press the Compile/Execute button. A popup window will be displayed with the words "Hello World". Clicking the OK button will end the program.

 #COMPILE EXE
   Function PBMain() as Long
      MsgBox "Hello World"
   End Function

Programs in PowerBASIC start execution in the PBMain function, which is the only function this simple program includes. Once the message box OK button is pressed the PBMain function ends, which also ends the PowerBASIC program.

One more example

This slightly expanded example provides a better feel for what a complete PowerBASIC program is all about. In this example, a single window is created which contains a single button.

Unlike code created using the drag and drop capabilities of a Visual Basic program, the interface-defining PowerBASIC code is written manually. Event code (such as responding to a button click) is also written manually.

A companion product, PowerBASIC Forms, is available which supports VB-like drag and drop creation of the graphical user interface.

Here's the entire program, consisting of just 11 lines of code. Just place this text into a file, open it in the IDE, and press the Compile/Execute button. The program consists of a window containing a single button. When the button is pressed the program ends.

 #Compile Exe
   #Include "Win32API.inc"

   Function PBMain() As Long
      Dim hDlg As Dword, hCtl As Dword
      Dialog New 0, "PowerBASIC",300,300,100,75, %WS_SysMenu,0 To hDlg
      Control Add Button, hDlg, 2, "Cancel", 25, 15, 40, 20
      Dialog Show Modal hDlg Call DlgProc To Result&
   End Function

   CallBack Function DlgProc() As Long
      If CbMsg = %WM_Command Then Dialog End CbHndl, 0
   End Function

Example of window creating

In this example, I will create a window (Dialog) with some controls on it and some menus:

#COMPILE EXE
#REGISTER NONE
#DIM ALL        '  This is helpful to prevent errors in coding
#INCLUDE "win32api.inc"     ' Win 32 API include file !
' ----------------------------------------------------------
' ----------------------------------------------------------
%Form1_FILE                                     = 500
' ----------------------------------------------------------
%Form1_NEWFILE                                  = 505
%Form1_OPENFILE                                 = 510
%Form1_SAVEFILE                                 = 515
%Form1_SAVEAS                                   = 520
%Form1_SEPARATOR_525                            = 525
%Form1_EXIT                                     = 530
' ----------------------------------------------------------
%Form1_EDIT                                     = 600
' ----------------------------------------------------------
%Form1_CUT                                      = 605
%Form1_COPY                                     = 610
%Form1_PASTE                                    = 615
' ----------------------------------------------------------
%Form1_HELP                                     = 700
' ----------------------------------------------------------
%Form1_HELP1                                    = 705
%FORM1_LABEL1             = 100
%FORM1_BUTTON1            = 105
%FORM1_CHECK1             = 110
%FORM1_LISTBOX1           = 115
%FORM1_COMBOBOX1          = 120
' --------------------------------------------------
DECLARE SUB CreateDialog_Form1(BYVAL hParent&)
DECLARE CALLBACK FUNCTION Form1_DlgProc
' --------------------------------------------------
DECLARE SUB Form1_NEWFILE_Select()
DECLARE SUB Form1_OPENFILE_Select()
DECLARE SUB Form1_SAVEFILE_Select()
DECLARE SUB Form1_SAVEAS_Select()
DECLARE SUB Form1_EXIT_Select()
DECLARE SUB Form1_CUT_Select()
DECLARE SUB Form1_COPY_Select()
DECLARE SUB Form1_PASTE_Select()
DECLARE SUB Form1_HELP1_Select()
DECLARE CALLBACK FUNCTION CBF_FORM1_BUTTON1()
DECLARE CALLBACK FUNCTION CBF_FORM1_CHECK1()
DECLARE CALLBACK FUNCTION CBF_FORM1_LISTBOX1()
DECLARE CALLBACK FUNCTION CBF_FORM1_COMBOBOX1()
' --------------------------------------------------
GLOBAL App_CurrentDlg AS DWORD
GLOBAL hForm1&    ' Dialog handle
GLOBAL hForm1_Menu0&  ' Global Handles for menus
GLOBAL hForm1_Menu1&
GLOBAL hForm1_Menu2&
GLOBAL hForm1_Menu3&
' *************************************************************
'                   Application Entrance
' *************************************************************
FUNCTION PBMAIN ()AS LONG
    LOCAL Count&
    CreateDialog_Form1 0
    ' Dialogs Handle in variable - hForm1&
    DIALOG SHOW MODELESS hForm1& , CALL Form1_DlgProc
    DO
        DIALOG DOEVENTS TO Count&
    LOOP UNTIL Count&=0
END FUNCTION
' *************************************************************
'                    Application Dialogs
' *************************************************************
SUB CreateDialog_Form1(BYVAL hParent&)
    LOCAL Style&, ExStyle&
    LOCAL N&, CT&        '  Variables used for Reading Data in Arrays for Listbox and Combobox
    Style& = %WS_POPUP OR %DS_MODALFRAME OR %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU OR %DS_CENTER
    ExStyle& = 0
    DIALOG NEW hParent&, "Your Dialog", , , 280,  200, Style&, ExStyle&, TO hForm1&
    ' ---------------------------
    MENU NEW BAR TO hForm1_Menu0&
    ' ---------------------------
    ' ---------------------------
    MENU NEW POPUP TO hForm1_Menu1&
    MENU ADD POPUP, hForm1_Menu0& ,"&File", hForm1_Menu1&, %MF_ENABLED
    ' ---------------------------
    MENU ADD STRING, hForm1_Menu1&, "&New File",  %Form1_NEWFILE, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu1&, "&Open File",  %Form1_OPENFILE, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu1&, "&Save File",  %Form1_SAVEFILE, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu1&, "Save File &As",  %Form1_SAVEAS, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu1&, "-",  %Form1_SEPARATOR_525, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu1&, "E&xit",  %Form1_EXIT, %MF_ENABLED
    ' ---------------------------
    MENU NEW POPUP TO hForm1_Menu2&
    MENU ADD POPUP, hForm1_Menu0& ,"&Edit", hForm1_Menu2&, %MF_ENABLED
    ' ---------------------------
    MENU ADD STRING, hForm1_Menu2&, "Cu&t",  %Form1_CUT, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu2&, "&Copy",  %Form1_COPY, %MF_ENABLED
    MENU ADD STRING, hForm1_Menu2&, "&Paste",  %Form1_PASTE, %MF_ENABLED
    ' ---------------------------
    MENU NEW POPUP TO hForm1_Menu3&
    MENU ADD POPUP, hForm1_Menu0& ,"&Help", hForm1_Menu3&, %MF_ENABLED
    ' ---------------------------
    MENU ADD STRING, hForm1_Menu3&, "&Contents",  %Form1_HELP1, %MF_ENABLED
    MENU ATTACH hForm1_Menu0&, hForm1&
    CONTROL ADD LABEL, hForm1&,  %FORM1_LABEL1,  "Label  1", 28, 136, 216, 32, _
        %WS_CHILD OR %WS_VISIBLE OR %SS_CENTER OR %WS_BORDER, 0
    CONTROL ADD "Button", hForm1&,  %FORM1_BUTTON1,  "Button  1", 12, 8, 80, 24, _
        %WS_CHILD OR %WS_VISIBLE OR %BS_PUSHBUTTON OR %WS_TABSTOP, 0 CALL CBF_FORM1_BUTTON1
    CONTROL ADD CHECKBOX, hForm1&,  %FORM1_CHECK1,  "Check  1", 12, 40, 92, 24, _
        %WS_CHILD OR %WS_VISIBLE OR %BS_AUTOCHECKBOX OR %WS_TABSTOP, 0 CALL CBF_FORM1_CHECK1
    ' - - - - - - - - - - - - - - - - - - - - - - - - -
    DIM LISTBOX1_List(4) AS LOCAL STRING
    DATA "Item 1","Item 2","Item 3","Item 4","Item 5"
    FOR N&=0 TO 4
        CT&=CT&+1
        LISTBOX1_List(N&)=READ$(CT&)
    NEXT N&
    ' - - - - - - - - - - - - - - - - - - - - - - - - -
    CONTROL ADD LISTBOX, hForm1&,  %FORM1_LISTBOX1, LISTBOX1_List(), 12, 72, 108, 48, _
        %WS_CHILD OR %WS_VISIBLE OR %LBS_NOTIFY OR %LBS_SORT OR %LBS_NOINTEGRALHEIGHT OR %WS_VSCROLL OR %WS_TABSTOP, _
        %WS_EX_CLIENTEDGE CALL CBF_FORM1_LISTBOX1
    ' - - - - - - - - - - - - - - - - - - - - - - - - -
    DIM COMBOBOX1_List(4) AS LOCAL STRING
    DATA "Item 1","Item 2","Item 3","Item 4","Item 5"
    FOR N&=0 TO 4
        CT&=CT&+1
        COMBOBOX1_List(N&)=READ$(CT&)
    NEXT N&
    ' - - - - - - - - - - - - - - - - - - - - - - - - -
    CONTROL ADD COMBOBOX, hForm1&,  %FORM1_COMBOBOX1, COMBOBOX1_List(), 136, 16, 112, 52, _
        %WS_CHILD OR %WS_VISIBLE OR %CBS_DROPDOWNLIST OR %CBS_SORT OR %WS_VSCROLL OR %CBS_NOINTEGRALHEIGHT OR %WS_TABSTOP, _
        %WS_EX_CLIENTEDGE CALL CBF_FORM1_COMBOBOX1
END SUB
' *************************************************************
'                             Dialog Window Procedure
'                             for Form Form1
'                             uses Global Handle - hForm1&
' *************************************************************
CALLBACK FUNCTION Form1_DlgProc
    SELECT CASE CBMSG
        CASE %WM_COMMAND
            ' Process Messages to Controls that have no Callback Function
            ' and Process Messages to Menu Items
            SELECT CASE LOWRD(CBWPARAM)    ' Parse by Ctrl ID #
                CASE  %Form1_NEWFILE                                      ' Popup Menu Item Selected
                    Form1_NEWFILE_Select
                CASE  %Form1_OPENFILE                                     ' Popup Menu Item Selected
                    Form1_OPENFILE_Select
                CASE  %Form1_SAVEFILE                                     ' Popup Menu Item Selected
                    Form1_SAVEFILE_Select
                CASE  %Form1_SAVEAS                                       ' Popup Menu Item Selected
                    Form1_SAVEAS_Select
                CASE  %Form1_EXIT                                         ' Popup Menu Item Selected
                    Form1_EXIT_Select
                CASE  %Form1_CUT                                          ' Popup Menu Item Selected
                    Form1_CUT_Select
                CASE  %Form1_COPY                                         ' Popup Menu Item Selected
                    Form1_COPY_Select
                CASE  %Form1_PASTE                                        ' Popup Menu Item Selected
                    Form1_PASTE_Select
                CASE  %Form1_HELP1                                        ' Popup Menu Item Selected
                    Form1_HELP1_Select
                CASE ELSE
            END SELECT
        CASE %WM_SHOWWINDOW
            IF CBWPARAM THEN
                App_CurrentDlg=CBHNDL
            ELSE
                App_CurrentDlg=0
            END IF
        CASE %WM_ACTIVATE
            IF LOWRD(CBWPARAM)<>0 THEN
                App_CurrentDlg=CBHNDL
            ELSE
                App_CurrentDlg=0
            END IF
        CASE %WM_DESTROY
        CASE ELSE
    END SELECT
    FUNCTION = 0
END FUNCTION
' *************************************************************
'  Application Callback Functions (or Procedures) for Controls
' *************************************************************
' ------------------------------------------------
SUB Form1_NEWFILE_Select()
END SUB
' ------------------------------------------------
SUB Form1_OPENFILE_Select()
END SUB
' ------------------------------------------------
SUB Form1_SAVEFILE_Select()
END SUB
' ------------------------------------------------
SUB Form1_SAVEAS_Select()
END SUB
' ------------------------------------------------
SUB Form1_EXIT_Select()
END SUB
' ------------------------------------------------
SUB Form1_CUT_Select()
END SUB
' ------------------------------------------------
SUB Form1_COPY_Select()
END SUB
' ------------------------------------------------
SUB Form1_PASTE_Select()
END SUB
' ------------------------------------------------
SUB Form1_HELP1_Select()
END SUB
' ------------------------------------------------
CALLBACK FUNCTION CBF_FORM1_BUTTON1
    IF CBCTLMSG=%BN_CLICKED THEN
    END IF
    IF CBCTLMSG=%BN_SETFOCUS THEN
    END IF
    IF CBCTLMSG=%BN_KILLFOCUS THEN
    END IF
END FUNCTION
' ------------------------------------------------
CALLBACK FUNCTION CBF_FORM1_CHECK1
    IF CBCTLMSG=%BN_CLICKED THEN
    END IF
    IF CBCTLMSG=%BN_SETFOCUS THEN
    END IF
    IF CBCTLMSG=%BN_KILLFOCUS THEN
    END IF
END FUNCTION
' ------------------------------------------------
CALLBACK FUNCTION CBF_FORM1_LISTBOX1
    LOCAL CVal&amp;
    ' Return Current Selection in CVal&amp;
    CONTROL SEND CBHNDL , CBCTL, %LB_GETCURSEL, 0,0 TO CVal&amp;
    IF CBCTLMSG=%LBN_SELCHANGE THEN
    END IF
    IF CBCTLMSG=%LBN_DBLCLK THEN
    END IF
    IF CBCTLMSG=%LBN_SETFOCUS THEN
    END IF
    IF CBCTLMSG=%LBN_KILLFOCUS THEN
    END IF
END FUNCTION
' ------------------------------------------------
CALLBACK FUNCTION CBF_FORM1_COMBOBOX1
    LOCAL CVal&amp;
    ' Return Current Selection in CVal&amp;
    CONTROL SEND CBHNDL , CBCTL, %CB_GETCURSEL, 0,0 TO CVal&amp;
    IF (CBCTLMSG=%CBN_SELCHANGE) OR  (CBCTLMSG=%CBN_EDITCHANGE) OR (CBCTLMSG=%CBN_EDITUPDATE) THEN
    END IF
    IF CBCTLMSG=%CBN_DBLCLK THEN
    END IF
    IF CBCTLMSG=%CBN_SETFOCUS THEN
    END IF
    IF CBCTLMSG=%CBN_KILLFOCUS THEN
    END IF
END FUNCTION

The above example EXE compiles to about 52 Kilobytes . The DDT commands used, simplify some of the API tasks for a Dialog, but you can still see the API style similarity in it though. It uses a Dialog Procedure, just like you do with a pure WIN32 app. Some of the WM_COMMAND notification messages though are parsed out by the DDT embedded runtime code and the calls are automatically forwarded to the CallBack subroutines , so you don’t have to process WM_COMMAND for all control types. The notification codes for WM_COMMAND are pushed into some system Variables (ie. CBCTLMSG) already, so you can test for the notification messages just by using these system variables. Something similar is done with the Dialog procedure with the normal parameters of a dialog procedure pushed to system variables (ie. CBMSG). PowerBasic’s DDT also can do something similar with some WM_NOTIFY notification messages.

DDT just simplifies things a bit, rather than totally shield you from the WIN32 API. You can also integrate the WIN32 API into an application written using the DDT command set.

Third-party support

References

Cite error: Invalid <references> tag; parameter "group" is allowed only.

Use <references />, or <references group="..." />

External links