With external procedures, such as those found in DLL files, an explicit declaration statement is required. The declaration defines the file where the procedure is found, the procedure name, all arguments required to call the procedure, and other information needed to use the external procedure.
Here is a summary of the PowerBASIC functions used to declare variables and procedures. The first four categories provide functions to declare program variables. The next two cover internal and external procedures, respectively.
| Dim, Local, Static |
| Global, Threaded |
| Instance |
| ReDim |
| Sub, Function, Macro, Method, Property |
| Declare |
Variable Declarations
PowerBASIC variables can be used simply by placing them in the source
code. It is also possible to force declaration of variables by
using the #DIM ALL compiler directive.
Use of #DIM ALL is considered good programming practice because it avoids potential execution issues which are difficult to find and correct. Most programmers use the directive.
Syntax and examples of the variable declaration functions are discussed next.
DIM var As type DIM var As Scope type DIM var As Scope type POINTER DIM var As Scope type POINTER At address
var is replaced with the variable name and may include a PowerBASIC type suffix. If a type suffix is used, the As type cannot be used. Note that PowerBASIC has no default data type that is assumed. Either a data type suffix or a type keyword must be in a variable declaration.
Scope is optional, and can be any of GLOBAL, INSTANCE, LOCAL, STATIC, or THREADED. Type is any of the PowerBASIC data types. POINTER is optional and is synonymous with PTR. The address, which applies only to array variables, is also optional.
When applied to array variables, "var" can be replaced with either "var()" or "var(subscripts)". When declared without subscripts, an array must be redimensioned with REDIM as discussed below.
Arrays may also be placed at a specific address in memory. See the PowerBASIC Help file for more details and discussion on when to use the feature.
And here are several examples.
DIM s As String DIM s$ DIM x As Single DIM myArray(5) As String DIM myArray(1 to 5) As String DIM myArray(5,5) As Integer
Here are the various ways a REDIM statement can be written.
REDIM array() REDIM array(subscripts) REDIM PRESERVE (subscritps) REDIM PRESERVE array(subscripts) As type REDIM array(subscripts) As type At address REDIM [PRESERVE] array[(subscripts)] [AS type] [AT address] [, ...]
var is replaced with the variable name and may include a PowerBASIC type suffix. If a type suffix is used, the As type cannot be used.
Scope is optional, and can be any of GLOBAL, INSTANCE, LOCAL, STATIC, or THREADED. Type is any of the PowerBASIC data types. POINTER is optional and is synonymous with PTR. The address, which applies only to array variables, is also optional. PRESERVE is optional, but when included any pre-existing values of the variables are kept. Without PRESERVE, REDIM resets all variable values.
When applied to array variables, "var" can be replaced with either "var()" or "var(subscripts)". When declared without subscripts, an array must be redimensioned with REDIM before elements can be accessed.
And here are several examples.
REDIM A(5) 'index 0 to 5, 6 elements REDIM A(1 to 10) 'index 1 to 10, 10 elements REDIM A(4,6) '5x7 array, 35 elements REDIM A() 'must REDIM again before using REDIM A(5) 'resets all array elements REDIM PRESERVE A(8) 'saves existing array values
Arrays may also be placed at a specific address in memory. See the PowerBASIC Help file for more details and discussion on when to use the feature.
Here are the two formats for using these variable declaration statements.
LOCAL var1 As type, var2 As type LOCAL var1, var2 As type
Both examples apply to LOCAL, STATIC, GLOBAL, THREADED, and INSTANCE declaration statements.
The first format lists variable/type pairs. The second lists multiple variables followed by a type. Note that in the second format the type applies to the entire list of variables. This is different than several other languages, where without an explicit type a variable is assigned a default type.
And here are several examples.
LOCAL a$ 'single variable LOCAL a As String 'single variable LOCAL d,e,f As Integer 'multiple variables LOCAL s As String, i As Integer 'multiple variables LOCAL a() As Long 'array, without bounds LOCAL a(5) As Long 'array, with bounds
Finally, here is an example showing where each of the various variable declaration statements can be used in a PowerBASIC program. Note that the PowerBASIC compiler allows the CLASS/Sub/Function code blocks to be placed before or after the PBMain() function.
#COMPILE EXE GLOBAL/THREADED ... 'global declarations Function PBMain() As Long DIM/REDIM/LOCAL/STATIC ... 'local declarations End Function CLASS myClass INSTANCE 'local declarations INTERFACE myInterface METHOD myMethod DIM/REDIM/LOCAL/STATIC... 'local declarations END METHOD PROPERTY myProperty DIM/REDIM/LOCAL/STATIC... 'local declarations END PROPERTY END INTERFACE END CLASS SUB mySub() DIM/REDIM/LOCAL/STATIC ... 'local declarations END SUB FUNCTION myFunction() DIM/REDIM/LOCAL/STATIC ... 'local declarations END SUB
Note also that while the code that defines a CLASS is placed outside all procedures, object variable definition occurs in the same locations as all other variable types.
Internal Procedure Declaration
PowerBASIC supports several types of internal procedures, including
Sub, Function, Method, Property and Macro.
Sub/Function/Macro procedures are used within a standard PowerBASIC application. Method/Property functions are used exclusively within an object.
A procedure is created by simply writing the code and enclosing it with the procedure statements. Sub..End Sub/Function..End Function/Macro..End Macro/Method..End Method/Property..End Property.
Sub/Function/Macro procedures are discussed in the tutorial section on procedures, but here are a couple of early examples.
In all of these examples, the information needed to create the procedure declaration is taken from the source code by the compiler, making it unnecessary for the programmer to explicitly declare the procedures.
Sub Hello(m$) Msgbox m$ End Sub Function Hello(m$) as Long Msgbox m$ Function = 0 End Function MACRO Pi = 3.141592654 MACRO Degree2Radian(deg) = (deg * 0.0174533) MACRO Radian2Degree(rad) = (rad * 57.29578)
Method and Property procedures are dicussed in the tutorial section on objects, but here are a couple of early examples.
Method (m$) as Long Method = val(m$) * 2 End Method Property (m$) as Long Property = val(m$) * 2 End Property
External Procedure Declaration
PowerBASIC is able to use (compiled) procedures stored in external files.
To do so, an explicit DECLARE statement is required in the PowerBASIC
source code file referencing the external file and the information needed
to access its stored procedures.
The use of the DECLARE statement is covered in the tutorial section on API, but here are a couple of early examples.
DECLARE FUNCTION WinBeep LIB "KERNEL32.DLL" ALIAS "Beep" _ (BYVAL dwFreq AS DWORD, BYVAL dwDuration AS DWORD) AS LONG DECLARE FUNCTION GetTickCount LIB "KERNEL32.DLL" _ ALIAS "GetTickCount" () AS DWORD
To make it easier for PowerBASIC programmers to use standard Windows DLLs, a file named Win32API.inc is installed with PowerBASIC. It lists the declaration statements for a large number of Windows DLL procedures, which are called API. To use the file, simply place the following include statement in the application source code.
#INCLUDE "WIN32API.INC" ' Win32 declares and equates
If you have any suggestions or corrections, please let me know.