PowerBASIC for Windows |
|
Learn to use DDT to create dialogs, callbacks and
controls. We'll build a program with a main dialog and two buttons, OK
and Exit. The current date and time is shown when the OK button
is pressed. The program is closed when the Exit button is pressed. |
|
Build a Windows program using PBWin's built-in Dynamic Dialog Tools (DDT).
1. Press the down arrow on the toolbar button for New and select
"Generic PB program" from the dropdown menu that is shown. A new
document with a template skeleton code will be created, ready for
insertion of some working code.

Some explanation of the template codeis in order:#COMPILE EXE tells the compiler to create an
.EXE program, rather than a DLL #DIM ALL tells
the compiler all variables must be declared before use with DIM, LOCAL, STATIC or
GLOBAL. While this adds a bit of extra work for the programmer,
it helps protect you from simple spelling errors, which can be very difficult to
find. FUNCTION PBMAIN is the program's entry point and END FUNCTION is its exit point.

2. Insert %USEMACROS =1 on the line following
#DIM ALL as preparation for next step.
3. Insert #INCLUDE "WIN32API.INC"
on the line following %USEMACROS =1. This tells the compiler to include the file WIN32API.INC, which contains Equates, Types/Unions, and
declares for many of the Win32API calls provided by Windows itself. The %USEMACROS equate on the line above tells the compiler to use Macros
in WIN32API.INC where possible, which results in a smaller executable file.
4. Insert LOCAL hDlg AS DWORD
on the line after FUNCTION MAIN,
that is, as the first statement inside the Function. We will soon need this
DWORD variable to store the handle of the actual DDT dialog.
5. Insert DIALOG NEW 0, "Caption",,, 220, 140, %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg
on the line after the LOCAL declare. One line of code, and it will create a complete
dialog with a system menu, a caption that says Caption and with the client size of 220 Dialog Units wide, 140 Dialog Units high. The client area is the area
available for controls, that is, the light-gray area under the caption
bar. See PBWin Help for more detailed explanations of all DIALOG NEW parameters.
6. Insert DIALOG SHOW MODAL hDlg
on the line after DIALOG NEW.

7. Compile and Execute (Run) the code. The program is not yet complete,
but can be compiled and run to see how it looks so far.
And here's the result:

Not very useful yet, but it is a complete, stand-alone 32-bit Windows program,
using a resolution independent dialog, Prog2.exe. The total size is only 13,824 bytes (as compiled using
PBWin 8.01). Use the program's system menu to close it, or make sure it
has focus and press Alt+F4 to close it down.
The Callback Procedure
The dialog needs a way to communicate with controls and the system. It needs a callback procedure. That's a function which will become the
central place for messages sent to and from both system and controls.
8. Add a CALLBACK FUNCTION DlgProc with a SELECT CASE filter for messages to the code, and
complete the DIALOG SHOW command in PBMAIN with CALL DlgProc, so it looks
like:

We have now told the dialog to use the DlgProc as central callback
procedure for internal program messages. That's done by adding CALL DlgProc to the
DIALOG SHOW command. Then, we added the actual CallBack Function
DlgProc with a Select Case message filter for some of the most
important messages used in the communication between the system, the
dialog and its child controls. The DlgProc receives a message with
%WM_INITDIALOG value just before the dialog is shown, so this can
often be a good place to initiate variables. The DlgProc
receives %WM_DESTROY when the dialog is about to be destroyed, that is,
at exit, so this is a place to clean up memory, store
settings, etc. The DlgProc receives %WM_COMMAND when controls and menus
are activated, so this is a place where more code will have to be added
as soon as we add some "live" controls. We will not be adding any code
under %WM_INITDIALOG and %WM_DESTROY in this example, but keep them here for later use.
Adding Controls
Windows provides a set of standard controls like Buttons,
Labels, ListBoxes and TextBoxes, etc. Which ones are used depends on the
task. In this case the task involves creating two buttons, so lets add
them to the dialog.
9. Insert the following two CONTROL ADD commands in PBMAIN, between
DIALOG NEW and DIALOG SHOW:
CONTROL ADD BUTTON, hDlg, %IDOK, "&OK", 112, 122, 50, 14 CONTROL ADD BUTTON, hDlg, %IDCANCEL, "E&xit", 166, 122, 50, 14
Two buttons will be created in the lower right corner of the dialog.
The %IDOK and %IDCANCEL control IDs
are actually system-related IDs, already defined in the file WIN32API.INC,
which we included earlier.
The ampersand character (&), when used in string literals, will
append an underline and thereby act as
a keyboard shorcut to the control (sometimes in combination with the
left Alt key) - in this case the letter O for the OK button and the
letter x for the Exit button. Please note that in later systems, like
XP, this standard Windows behavior may be turned off by default and
then has to be activated in the desktop settings for "Effects". Now it's
time to add control handlers for the two buttons to the DlgProc.
10. Insert the following Select Case control filter under %WM_COMMAND
in the DlgProc:
CASE %WM_COMMAND SELECT CASE AS LONG CBCTL CASE %IDOK IF CBCTLMSG = %BN_CLICKED THEN MSGBOX "Current time is: " & TIME$ & $LF & _ "Current date is: " & DATE$, _ %MB_TASKMODAL, _ "Time and Date" END IF
CASE %IDCANCEL IF CBCTLMSG = %BN_CLICKED THEN DIALOG END CBHNDL END IF
END SELECT
%WM_COMMAND is a system equate value, meaning "Window Message -
Command". CBCTL (CallBack Control) is a DDT value relating to a
control's ID and CBCTLMSG (CallBack Control Message) relates to the
notification sent from a control. %BN_CLICKED is a system equate value
for "Button Notification - Clicked", which is sent from a Button to the
dialog when a Button is clicked.
Under %IDOK, which is the OK Button, we have inserted code for a
message box, showing current system time and date on separate lines.
TIME$ returns the current system (computer) time as a text string and
DATE$ returns current system (computer) date. Here the ampersand
(&) character tells the compiler to append the following
string to the text before it (a plus sign (+) can also be used) and $LF
is a built-in PowerBASIC equate with same value as the standard line
feed character in Windows, ASCII 10. The underscore character acts as
line continuation character in PowerBASIC and is used to wrap long code
lines. The MSGBOX is given %MB_TASKMODAL style (MessageBox - Taskmodal)
to make it modal. That is, the user has to close it to be able to
continue. We also give it the caption title "Time and Date".
Under %IDCANCEL, which is the Exit Button, we have inserted code for
closing the dialog via DIALOG END. CBHNDL contains the dialog's window
handle, with same value as hDlg in PBMAIN. There's only
one thing left to do before we compile and run the program again:
11. Change the dialog caption in PBMAIN to for example "Time and Date"
12. Compile and Execute (Run) the code.
The Result
This shows what happens when the OK button is clicked:

A complete, stand-alone 32-bit Windows program, Prog2.exe, with a main
dialog and two buttons, at a total size of only 15,360 bytes (as
compiled using PBWin 8.01).
The Code
Here's the program - Prog2.bas, with additional comments, line feeds and dividers to make the code a bit easier to read and maintain.
'====================================================================== ' Prog2.bas ' Example program for PBWin. '====================================================================== #COMPILE EXE #DIM ALL '------------------------------------------------ %USEMACROS = 1 #INCLUDE "WIN32API.INC"
'====================================================================== FUNCTION PBMAIN () AS LONG '---------------------------------------------------------------------- ' Program entrance '---------------------------------------------------------------------- LOCAL hDlg AS DWORD
DIALOG NEW 0, "Time and Date",,, 220, 140, _ %WS_CAPTION OR %WS_SYSMENU, 0 TO hDlg '------------------------------------------------------------- CONTROL ADD BUTTON, hDlg, %IDOK, "&OK", 112, 122, 50, 14 CONTROL ADD BUTTON, hDlg, %IDCANCEL, "E&xit", 166, 122, 50, 14 '------------------------------------------------------------- DIALOG SHOW MODAL hDlg, CALL DlgProc
END FUNCTION
'====================================================================== CALLBACK FUNCTION DlgProc() AS LONG '---------------------------------------------------------------------- ' Main Dialog procedure '---------------------------------------------------------------------- SELECT CASE AS LONG CBMSG CASE %WM_INITDIALOG ' entry - the dialog is about to be shown CASE %WM_DESTROY ' exit - the dialog is about to be destroyed CASE %WM_COMMAND ' received from a control or menu item, etc.
SELECT CASE AS LONG CBCTL ' which control id is calling? CASE %IDOK ' the OK button or the Enter key IF CBCTLMSG = %BN_CLICKED THEN ' was clicked
' Show a message, telling current time and date MSGBOX "Current time is: " & TIME$ & $LF + _ "Current date is: " & DATE$, _ %MB_TASKMODAL, _ "Time and Date" END IF
CASE %IDCANCEL ' the Exit button or the Escape key IF CBCTLMSG = %BN_CLICKED THEN ' was clicked DIALOG END CBHNDL ' end the program END IF END SELECT
END SELECT
END FUNCTION
|