.

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

  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 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



  2. Insert %USEMACROS = 1
    on the line following #DIM ALL as preparation for next step.

  3. 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.

  4. 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:

  5. %ID_COMBOBOX = 1000
    %ID_TEXTBOX  = 1001
    %ID_COPYBTN1 = 1002
    %ID_COPYBTN2 = 1003
    %ID_CLOSEBTN = 1004

  1. 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.

  2. 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

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  8. 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.

  9. 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.

  10. 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.



  11. 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.

  12. 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.

  13. Insert SELECT CASE AS LONG CBMSG
    on the line following CALLBACK FUNCTION DialogProc().  CBMSG is the numerical message sent to the callback function.

  14. 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.

  15. 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.

  16. 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).

  17. 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.

  18. Insert LOCAL txt AS STRING
    on the next line to declare a local string variable.

  19. Insert CASE %ID_COPYBTN1
    on the next line. This will catch all %WM_COMMAND messages for the control who's identifier is %ID_COPYBTN1.

  20. 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.

  21. 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.

  22. 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.

  23. Insert END IF
    on the next line.




  24. 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.

  25. Insert LOCAL InComboBox AS LONG
    on the next line, to create a new long integer variable called InComboBox.

  26. 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.

  27. 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.

  28. 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

  29. On the next line insert IF InComboBox = %CB_ERR THEN
    to test if the variable InComboBox contains the numeric value of %CB_ERR.

  30. 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.

  31. Insert ELSE
    after the line COMBOBOX ADD CBHNDL, %ID_COMBOBOX, txt

  32. 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.

  33. On the next line insert END IF
    to end the IF statement that tested to if the TEXTBOX text was already in the COMBOBOX.

  34. Insert END IF
    on the next line to end the IF statement that tested if the <-COPY button was clicked.


  35. 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.

  36.  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.

  37. Insert END SELECT
    on the next line to end the SELECT CASE AS LONG CBCTL statement entered in Step #20.

  38. Insert END SELECT
    on the next line to end the SELECT CASE AS LONG CBMSG statement entered in Step #16.

  39. On the next line insert END FUNCTION
    to end CALLBACK FUNCTION DialogProc() statement entered in Step #7




  40. Create the Subroutine that initializes the COMBOBOX with data

  41. 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.

  42. Insert LOCAL i AS LONG
    on the next line to declare a new long integer variable called i.

  43. 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.

  44. 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.

  45. Insert NEXT i
    on the next line to define the end of the FOR i = 1 TO 10 loop inserted in Step #45.

  46. 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.

  47. On the next line insert END SUB
    to define the end of the subroutine created in Step  #43.




  48. Saving, Compiling and Running the Tutorial

  49. From the PB/Win IDE menu select File | Save File AsŠ and select a directory and filename to save this tutorial in.

  50. 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


Jump to top Return to index

. .