PowerBASIC for Windows |
|
Learn how to use comboboxes. In this example we will build a program that copies text from a combobox to a textbox and can also copy text from a textbox to a combobox. When copying text to the combobox we will test if the text is already in the combobox and if it is then display that the text is already in the combobox. |
Working with ComboBoxes,
TextBoxes, and Buttons
- 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 code is 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 |

- Insert %USEMACROS = 1
on the line following #DIM ALL
as preparation
for next step.
- Insert #INCLUDE "WIN32API.INC"
on the next line. 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.
- Now we will insert the constants used as unique identifiers for each
control displayed on the main dialog. Insert the following lines after
the #INCLUDE "WIN32API.INC" line:
%ID_COMBOBOX = 1000
%ID_TEXTBOX = 1001
%ID_COPYBTN1 = 1002
%ID_COPYBTN2 = 1003
%ID_CLOSEBTN = 1004
- Insert DECLARE CALLBACK
FUNCTION DialogProc()
on the line following the constants that were inserted in Step
#4. This
explicitly declares the callback function that will be used
with the programs
dialog. the callback function will handle all Windows messages
and events
for the dialog. For more information on the DECLARE statement
and callbacks's see the PBWin Help file.
- Insert DECLARE SUB
AddDataToComboBox(hdlg
AS DWORD)
after the line inserted in Step #5. This expicity declares the
subroutine
that will be used to fill the combobox with data.

Creating The
User Interface
- Now we will insert the code that creates and displays the
programs dialog.
This is inserted in the PBMAIN function.
The PBMAIN function is called by Windows to begin
running an application.
Insert LOCAL hDlg AS
DWORD
on the line after FUNCTION PBMAIN, 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.
- Insert DIALOG NEW 0, "Combobox
Tutorial",,, 220, 90, %WS_CAPTION OR
%WS_SYSMENU, 0 TO hDlg
on the line after the line inserted in Step #7. This line of code will
create a complete dialog that is 220 Dialog Units wide and 90 Dialog
Units high. The %WS_CAPTION style tells the compiler that we
want a caption
displayed on this dialog and the %WS_SYSMENU style tells
windows to place
a close button "X" at the top right corner of the dialog . See PBWin
Help for more detailed explanations of all DIALOG
NEW parameters.
- Insert CONTROL ADD COMBOBOX, hDlg, %ID_COMBOBOX, , 0,
0, 100, 80,%CBS_DROPDOWNLIST OR %WS_VSCROLL
on the line following the DIALOG NEW
statement.
This inserts a combobox control on the dialog at the client location of
0, 0 (or the upper left corner) with the width of 100 dialog units and
a height of 80 dialog units. The Height of the combobox
includes the height
of the listbox portion also. The %CBS_DROPDOWNLIST style
tells windows
that the combobox cannot be edited by the user. The
%WS_VSCROLL style causes
a scrollbar to be placed in the listbox portion of the combobox.
- Insert CONTROL
ADD TEXTBOX, hDlg, %ID_TEXTBOX,
"", 120, 0,
100, 12
on the next line. This inserts a textbox control on the dialog
at the X coordinate
of 120 and the Y coordinate of 0, with a width of 100 dialog units and a
height of 12 dialog units.
- Insert CONTROL
ADD BUTTON, hDlg, %ID_COPYBTN1, "Copy ->",
65, 20, 35,
15
on the next line. This inserts a button with the caption of Copy-> onto
the dialog. The button will be placed on the dialog at the
X coordinate
of 65 and a Y coordinate of 20, with a width of 35 dialog units
and a height
of 15 dialog units. This button copies the selected combobox item to the
textbox.
- Insert CONTROL
ADD BUTTON, hDlg, %ID_COPYBTN2, "<- Copy", 120, 20,
35, 15
on the next line. This inserts a button with the caption of <-Copy onto
the dialog. The button will be placed on the dialog at the X coordinate of
120 and a Y coordinate of 20, with a width of 35 dialog units and a height
of 15 dialog units. This button copies the contents of the
textbox into the
combox.
- Insert CONTROL
ADD BUTTON, hDlg, %ID_CLOSEBTN, "Close", 93,
60, 35,
15
on the next line. This inserts a button with the caption of Close onto the
dialog. Th button will be places on the dialog at the X coordinate of 93
and a Y coordinate of 60, with a width of 35 dialog units and a height of
15 dialog units. This button closes the dialog.
- Insert DIALOG
SHOW MODAL hDlg CALL DialogProc
on the next line. This displays the dialog on the screen and tells windows
to route all dialog messages to the DialogProc callback function. For more
information on callback functions see the PBWin Help file.

The Callback Function
| A callback function is a function you write and is called by Windows whenever an event occurs. Events such as when a button is
clicked, when the dialog is displayed or closed, when the mouse moves, etc.
are all sent as messages to callback function. |
- After
the PBMAIN's END FUNCTION
statement insert CALLBACK
FUNCTION DialogProc()
This is the start of the dialogs callback function that will
handle all Windows
messages.
- Insert SELECT
CASE AS LONG CBMSG
on the line following CALLBACK
FUNCTION DialogProc(). CBMSG
is the numerical message sent to the callback function.
- On
the next line insert CASE
%WM_INITDIALOG
to allow the program to respond to the message %WM_INITDIALOG.
The %WM_INITDIALOG
message is sent the dialog's callback procedure immediately
before the dialog
is displayed. Typically this is where initialization tasks are
carried out.
- Insert
AddDataToComboBox(CBHNDL)
on the next line. This calls the AddToComboBox subroutine with CBHNDL as
a parameter. CBHNDL is the handle of the dialog that received
the message.
- On
the next line insert CASE %WM_COMMAND
to allow the program to respong to %WM_COMMAND messages. The %WM_COMMAND
message is sent when the user selects an item from a menu, when a control
sends a notification message (such as a button click).
- Insert SELECT
CASE AS LONG CBCTL
on the line following CASE %WM_COMMAND.
CBCTL is the unique identifier for the control that is sending
the message.
- Insert LOCAL
txt AS STRING
on the next line to declare a local
string variable.
- Insert CASE
%ID_COPYBTN1
on the next line. This will catch all %WM_COMMAND messages for the control
who's identifier is %ID_COPYBTN1.
- Insert IF
CBCTLMSG = %BN_CLICKED THEN
on the next line. CBCTLMSG is the numeric value of the
notification message
sent from the control. %BN_CLICKED is the notification message sent
when the user clicks a button. This occurs when the user clicks
the Copy-> button.
- On
the following line insert COMBOBOX GET
TEXT CBHNDL,
%ID_COMBOBOX TO txt
This will get the selected text from the combobox whose
identifier is %ID_COMBOBOX
and is located on the dialog with a handle of CBHNDL and place it in the
string variable txt.
- On
the next line insert CONTROL SET TEXT
CBHNDL,
%ID_TEXTBOX, txt
This will copy the contents of the string variable txt into the
control who's
identifier is %ID_TEXTBOX and is located on the dialog with a
handle of CBHNDL.
- Insert END
IF
on the next line.

- Insert CASE
%ID_COPYBTN2
on the line following END IF. This
will catch all %WM_COMMAND messages for the control who's
identifier is %ID_COPYBTN2.
- Insert LOCAL InComboBox AS LONG
on the next line, to create a new long integer variable
called InComboBox.
- On
the next line insert IF CBCTLMSG
= %BN_CLICKED THEN
CBCTLMSG is the numeric value of the notification message sent from
the control. %BN_CLICKED is the notification message sent when the
user clicks a button. This occurs when the user clicks the
<-Copy button.
- Insert CONTROL
GET TEXT CBHNDL, %ID_TEXTBOX TO txt
on the next line. This will retrieve the
text that is currently in the control who's identifier is
%ID_TEXTBOX located
on the dialog with a handle of CBHNDL and place it in the string variable
txt.
- Insert CONTROL
SEND CBHNDL, %ID_COMBOBOX, %CB_FINDSTRINGEXACT, -1,
STRPTR(txt) TO InComboBox.
on the next line. This is probably the most complex line of code in this
example, it checks to see if a string is already in a combobox.
The CONTROL
SEND function sends a message to a window or windows. In this case we are
sending the message to the control that is located on the dialog with the
handle of CBHNDL and has the identifier of %ID_COMBOBOX. The
%CB_FINDSTRINGEXACT
message instructs windows to find the first string in the
combobox that exactly
matches the string in the last parameter of the CONTROL SEND function. The
-1 tells the CONTROL SEND function to search the entire combobox starting
at the first entry. The last parameter of STRPTR(txt) is a string pointer
of the text to search to combobox for. CONTROL SEND function returns the
zero-based index of the matching item and stores this value in
the InComboBox
variable. If the string is not found in the combobox then the
function returns
%CB_ERR
- On
the next line insert IF
InComboBox = %CB_ERR THEN
to test if the variable InComboBox contains the numeric
value of %CB_ERR.
- On
the following line insert COMBOBOX ADD
CBHNDL, %ID_COMBOBOX,
txt
This will add the contents of the string variable txt into the
combobox that
has the identifier %ID_COMBOBOX and is located on the dialog that has the
handle of CBHNDL.
- Insert ELSE
after the line COMBOBOX ADD
CBHNDL, %ID_COMBOBOX, txt
- Insert ?
"That item is already in the Combobox"
on the next line. This will display a message box telling the
customer that
the text in the TEXTBOX is already in the COMBOBOX.
- On
the next line insert END IF
to end the IF statement that tested to if the TEXTBOX
text was already
in the COMBOBOX.
- Insert END
IF
on the next line to end the IF statement that tested if
the <-COPY
button was clicked.

- Insert CASE %ID_CLOSEBTN
on the line following the END IF statement entered in the last step. This
will catch all %WM_COMMAND messages for the control who's identifier is
%ID_CLOSEBTN.
- Insert IF CBCTLMSG = %BN_CLICKED THEN
DIALOG END CBHNDL
on the next line. CBCTLMSG is the numeric value of the notification
message sent from the control. %BN_CLICKED is the
notification message
sent when the user clicks a button. This occurs when the user clicks the
Close button.
- Insert END
SELECT
on the next line to end the SELECT CASE AS
LONG CBCTL statement entered in Step #20.
- Insert END
SELECT
on the next line to end the SELECT CASE AS
LONG CBMSG statement entered in Step #16.
- On
the next line insert END FUNCTION
to end CALLBACK FUNCTION
DialogProc() statement
entered in Step #7

Create the Subroutine that
initializes the COMBOBOX with data
- Insert SUB AddDataToComboBox(hdlg AS DWORD)
on the line following the END FUNCTION
statement. This creates a new subroutine called
AddDataToComboBox
and accepts a double-word parameter of hdlg.
- Insert LOCAL
i AS LONG
on the next line to declare a new long integer variable
called i.
- On
the following line insert FOR i
= 1 TO 10
to define a loop that increments the long integer variable i starting at
1 and ending at 10.
- Insert COMBOBOX
ADD hdlg, %ID_COMBOBOX, "Combobox data
#"+STR$(i)
on the line following the FOR i = 1 TO 10 statement. This will append text to
the combobox
who's identifier is %ID_COMBOBOX and is located on the dialog
with the handle
of hdlg.
- Insert NEXT i
on the next line to define the end of the FOR i
= 1 TO 10 loop inserted in Step #45.
- Insert COMBOBOX
SELECT hdlg, %ID_COMBOBOX, 1
on the next line. This will select the first item in the COMBOBOX with the
identifier of %ID_COMBOBOX located on the dialog with the handle
of hdlg.
- On
the next line insert END SUB
to define the end of the subroutine created in Step #43.

Saving, Compiling and Running the Tutorial
- From
the PB/Win IDE menu select File | Save File AsŠ and select a directory and
filename to save this tutorial in.
- From
the PB/Win IDE menu select Run | Compile and Execute
This will create and executable (.EXE) file from the IDE's code and then
run the executable file . The results of the compile will be displayed in
the output pane located at the bottom of the IDE window. If you
receive any
errors double check that you typed everything in correctly then try this
step again.
The Result
When the tutorial's exectuable launches it should look like:

Note: Different versions of Windows display dialogs and
controls differently.
The Code
#COMPILE EXE
#DIM ALL
%USEMACROS = 1
#INCLUDE "WIN32API.INC"
%ID_COMBOBOX = 1000
%ID_TEXTBOX = 1001
%ID_COPYBTN1 = 1002
%ID_COPYBTN2 = 1003
%ID_CLOSEBTN = 1004
DECLARE
CALLBACK FUNCTION DialogProc()
DECLARE
SUB AddDataToComboBox(hdlg
AS DWORD)
FUNCTION
PBMAIN () AS LONG
LOCAL hDlg
AS DWORD
DIALOG
NEW 0, "Combobox
Tutorial",,, 220, 90, %WS_CAPTION OR %WS_SYSMENU,
0 TO hDlg
CONTROL
ADD COMBOBOX,
hDlg, %ID_COMBOBOX, , 0,0,100,80,%CBS_DROPDOWNLIST OR %WS_VSCROLL
CONTROL
ADD TEXTBOX,
hDlg, %ID_TEXTBOX, "", 120, 0, 100,12
CONTROL
ADD BUTTON,
hDlg, %ID_COPYBTN1, "Copy ->", 65, 20, 35, 15
CONTROL
ADD BUTTON,
hDlg, %ID_COPYBTN2, "<- Copy", 120, 20, 35, 15
CONTROL
ADD BUTTON,hDlg,
%ID_CLOSEBTN, "Close", 93, 60,
35, 15
DIALOG SHOW
MODAL hDlg CALL DialogProc
END FUNCTION
CALLBACK
FUNCTION DialogProc()
SELECT
CASE AS LONG
CBMSG
CASE %WM_INITDIALOG
AddDataToComboBox(CBHNDL)
CASE %WM_COMMAND
SELECT CASE AS LONG CBCTL
LOCAL txt AS
STRING
CASE %ID_COPYBTN1
IF CBCTLMSG = %BN_CLICKED THEN
COMBOBOX GET TEXT CBHNDL, %ID_COMBOBOX TO txt
CONTROL SET TEXT CBHNDL, %ID_TEXTBOX, txt
END IF
CASE %ID_COPYBTN2
IF CBCTLMSG = %BN_CLICKED THEN
LOCAL InComboBox AS LONG
CONTROL
GET TEXT CBHNDL, %ID_TEXTBOX TO txt
CONTROL
SEND CBHNDL, %ID_COMBOBOX, %CB_FINDSTRINGEXACT,
-1, STRPTR(txt) TO InComboBox
IF InComboBox = %CB_ERR THEN
COMBOBOX
ADD CBHNDL, %ID_COMBOBOX, txt
ELSE
? "That
item is already in the Combobox"
END IF
END IF
CASE %ID_CLOSEBTN
IF
CBCTLMSG = %BN_CLICKED THEN DIALOG END
CBHNDL
END
SELECT
END
SELECT
END FUNCTION
SUB
AddDataToComboBox(hdlg AS DWORD)
LOCAL i AS
LONG
FOR i = 1 TO 10
COMBOBOX
ADD hdlg, %ID_COMBOBOX, "Combobox data
#"+STR$(i)
NEXT i
COMBOBOX SELECT hdlg,
%ID_COMBOBOX, 1
END SUB
|
|