PHP WinBinder: Tab Control
|
UniServer 5-Nano PHP WinBinder. |
Tab Control
When applications become too visually large, it's better to split the functionality into logical sections and use a tab control to access each section.
This page covers creating a Windows application based only on the tab control and controls placed on the tabbed pages. The techniques used are applicable to larger applications where a tab control is part of a larger application.
Control Creation
Creating a tab control and adding controls to each tab requires the use of all parameters that can be passed to the create control function.
For reference, the parameters are shown below:
handle = wb_create_control(parent,ctlclass,caption,xpos,ypos,width,height,id,style,parm,ntab) |
Parameters
parent | is a handle to the WinBinder object that is the parent window. |
ctlclass | is the class of the control or object to be created. Click here for a list of the available control classes. |
caption | is either a string with the caption of the control, an array of captions, or an array of arrays with information, depending on the control class. |
xpos, | ypos, width and height describe the position and dimensions of the control when required. |
id | is an integer that identifies the control. It must be unique if the control is to be processed by a callback function. |
style | contains the style flags. |
param | is an optional integer value that depends on the control class. |
ntab | is the index of the tab page that the control is to be inserted on, if any. |
Tabs
To create a tab application, start with a blank canvas (use example1 as a template) and follow this sequence:
- Create a tab area, position and size as required.
- Add individual tabs as required
- Add controls to each tab
Note: Individual tabs have a numerical index, first tab starts at 0.
Main Tab Area
The main tab area is created using this function. //Create main tab area $tab = wb_create_control($mainwin, TabControl, 0, 5, 5, 305, 200, 9000); We are assigning a TabControl (area) to the main window ($mainwin) The handle returned is saved in variable $tab (parent) |
|
Add individual tabs
Add individual tabs to main tab area using function wb_create_items(parent handle, "caption"). //Create Tab 0 - Page 1 wb_create_items($tab, "Page1"); //Create Tab 1 - Page 2 wb_create_items($tab, "Page2"); //Create Tab 2 - Page 3 wb_create_items($tab, "Page3); Note 1: Replace Page1, Page2 and Page3 with your real tab headings. Note 2: Tab indexes start from zero. Each tab added increments this index. |
|
Handles and IDs
Everyone has his or her own personal preference regarding programming style. I like to define handles to variables with a name that reflects the tab page and allocate ID’s to match tab page and control type.
Handle variables:
|
|
IDs:
|
Hence to create first label on tab page 2:
Handle variable $label_p2_1 with an ID (2000+100) 2100
Note 1: The above is just a guide. However what is written in stone is that all variables and IDs must be unique.
Note 2: Although assigning handles to variables appears a logical way to proceed, code becomes difficult to maintain. Similarly using pure IDs makes it difficult to change code. We'll address these issues a bit later.
Adding controls to tabs
We currently have three tabs. To each of these we will add two labels, three buttons and a EditBox. This will allow you to easily see the differences.
//Create Tab 0 - Page 1 wb_create_items($tab, "Page1"); $label_p1_1 = wb_create_control($tab, Label, "Test label A", 10, 14, 112, 20, 1100, 0, 0, 0); $label_p1_2 = wb_create_control($tab, Label, "Test label B", 10, 34, 112, 20, 1101, 0, 0, 0); $editbox_p1_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 1301, 0, 0, 0); wb_create_control($tab, PushButton, "Button A", 10, 90, 80, 22, 1201, 0, 0, 0); wb_create_control($tab, PushButton, "Button B", 100, 90, 80, 22, 1202, 0, 0, 0); wb_create_control($tab, PushButton, "Button C", 190, 90, 80, 22, 1203, 0, 0, 0); //Create Tab 1 - Page 2 wb_create_items($tab, "Page2"); $label_p2_1 = wb_create_control($tab, Label, "Test label C", 10, 14, 112, 20, 2100, 0, 0, 1); $label_p2_2 = wb_create_control($tab, Label, "Test label D", 10, 34, 112, 20, 2101, 0, 0, 1); $editbox_p2_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 2301, 0, 0, 1); wb_create_control($tab, PushButton, "Button D", 10, 90, 80, 22, 2201, 0, 0, 1); wb_create_control($tab, PushButton, "Button E", 100, 90, 80, 22, 2202, 0, 0, 1); wb_create_control($tab, PushButton, "Button F", 190, 90, 80, 22, 2203, 0, 0, 1); //Create Tab 2 - Page 3 wb_create_items($tab, "Page3"); $label_p3_1 = wb_create_control($tab, Label, "Test label E", 10, 14, 112, 20, 3100, 0, 0, 2); $label_p3_2 = wb_create_control($tab, Label, "Test label F", 10, 34, 112, 20, 3101, 0, 0, 2); $editbox_p3_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 3301, 0, 0, 2); wb_create_control($tab, PushButton, "Button G", 10, 90, 80, 22, 3201, 0, 0, 2); wb_create_control($tab, PushButton, "Button H", 100, 90, 80, 22, 3202, 0, 0, 2); wb_create_control($tab, PushButton, "Button I", 190, 90, 80, 22, 3203, 0, 0, 2); |
|
The far right digit assigns a control to that tab number (remember, tabs are indexed starting at 0) Fourth number from right is a controls ID. This must be unique. It follows the convention outlined above. For labels and edit boxes, their handle is captured in a variable following the convention. |
The above produces the following:
Currently there is no functionality, hence pressing a button has no effect.
Interaction
function process_main($window, $id) { switch($id) { //== Page 1 case 1201: // Button A global $label_p1_1, $label_p1_2, $editbox_p1_1; wb_set_text($label_p1_1,"12345"); wb_set_text($label_p1_2,"67890"); break; case 1202: // Button B global $label_p1_1, $label_p1_2, $editbox_p1_1; wb_set_text($label_p1_1,"67890"); wb_set_text($label_p1_2,"12345"); break; case 1203: // Button C global $label_p1_1, $label_p1_2, $editbox_p1_1; $text1 = wb_get_text($editbox_p1_1); wb_set_text($label_p1_1,"Page 1 ".$text1); wb_set_text($label_p1_2,"Page 1 ".$text1); break; //== Page 2 case 2201: // Button D button_D(); break; case 2202: // Button E button_E(); break; case 2203: // Button F button_F(); break; //== Page 3 case 3201: // Button G wb_message_box($window, "Page 3.","BUTTON G"); break; case 3202: // Button H wb_message_box($window, "Page 3.","BUTTON H"); break; case 3203: // Button I wb_message_box($window, "Page 3.","BUTTON I"); break; case IDCLOSE: // Constant IDCLOSE (8) predefined wb_destroy_window($window); // Destroy the window break; } } |
Adding functionality is again performed using the handler function. It is split into three sections corresponding to each page. Each push button is processed by the switch statement individual pushbuttons are identified using a case statement who’s value corresponds to a buttons ID. Page 1 buttons directly run code. Individual segments of code can become long and difficult to read. Page 2 button processing is a possible solution to this. Page 2 buttons call a function to perform the processing. This reduces size of the handler function making it easier to read. Page 3 buttons show examples of pop-up that may be useful in a working script. |
Test 4 Script
<?php Include "../php/include/winbinder.php"; // Location Of Winbinder Library //=== 1) Create main window --------------------------------------------------- $mainwin = wb_create_window(NULL, AppWindow, "Test 4", 320, 240); //=== 2) Create controls for the main window ---------------------------------- //Create main tab area $tab = wb_create_control($mainwin, TabControl, 0, 5, 5, 305, 200, 9000); //Create Tab 0 - Page 1 wb_create_items($tab, "Page1"); $label_p1_1 = wb_create_control($tab, Label, "Test label A", 10, 14, 112, 20, 1100, 0, 0, 0); $label_p1_2 = wb_create_control($tab, Label, "Test label B", 10, 34, 112, 20, 1101, 0, 0, 0); $editbox_p1_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 1301, 0, 0, 0); wb_create_control($tab, PushButton, "Button A", 10, 90, 80, 22, 1201, 0, 0, 0); wb_create_control($tab, PushButton, "Button B", 100, 90, 80, 22, 1202, 0, 0, 0); wb_create_control($tab, PushButton, "Button C", 190, 90, 80, 22, 1203, 0, 0, 0); //Create Tab 1 - Page 2 wb_create_items($tab, "Page2"); $label_p2_1 = wb_create_control($tab, Label, "Test label C", 10, 14, 112, 20, 2100, 0, 0, 1); $label_p2_2 = wb_create_control($tab, Label, "Test label D", 10, 34, 112, 20, 2101, 0, 0, 1); $editbox_p2_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 2301, 0, 0, 1); wb_create_control($tab, PushButton, "Button D", 10, 90, 80, 22, 2201, 0, 0, 1); wb_create_control($tab, PushButton, "Button E", 100, 90, 80, 22, 2202, 0, 0, 1); wb_create_control($tab, PushButton, "Button F", 190, 90, 80, 22, 2203, 0, 0, 1); //Create Tab 2 - Page 3 wb_create_items($tab, "Page3"); $label_p3_1 = wb_create_control($tab, Label, "Test label E", 10, 14, 112, 20, 3100, 0, 0, 2); $label_p3_2 = wb_create_control($tab, Label, "Test label F", 10, 34, 112, 20, 3101, 0, 0, 2); $editbox_p3_1 = wb_create_control($tab, EditBox, "", 10, 54, 112, 20, 3301, 0, 0, 2); wb_create_control($tab, PushButton, "Button G", 10, 90, 80, 22, 3201, 0, 0, 2); wb_create_control($tab, PushButton, "Button H", 100, 90, 80, 22, 3202, 0, 0, 2); wb_create_control($tab, PushButton, "Button I", 190, 90, 80, 22, 3203, 0, 0, 2); //=== 3) Assign handler function to the main window -------------------------- wb_set_handler($mainwin, "process_main"); //=== 5) Enter application loop ----------------------------------------------- wb_main_loop(); //=== 4) Handler Function ----------------------------------------------------- function process_main($window, $id) { switch($id) { //== Page 1 case 1201: // Button A global $label_p1_1, $label_p1_2, $editbox_p1_1; wb_set_text($label_p1_1,"12345"); wb_set_text($label_p1_2,"67890"); break; case 1202: // Button B global $label_p1_1, $label_p1_2, $editbox_p1_1; wb_set_text($label_p1_1,"67890"); wb_set_text($label_p1_2,"12345"); break; case 1203: // Button C global $label_p1_1, $label_p1_2, $editbox_p1_1; $text1 = wb_get_text($editbox_p1_1); wb_set_text($label_p1_1,"Page 1 ".$text1); wb_set_text($label_p1_2,"Page 1 ".$text1); break; //== Page 2 case 2201: // Button D button_D(); break; case 2202: // Button E button_E(); break; case 2203: // Button F button_F(); break; //== Page 3 case 3201: // Button G wb_message_box($window, "Page 3.","BUTTON G", WBC_INFO); break; case 3202: // Button H wb_message_box($window, "Page 3.","BUTTON H", WBC_QUESTION); break; case 3203: // Button I wb_message_box($window, "Page 3.","BUTTON I", WBC_YESNO); break; case IDCLOSE: // Constant IDCLOSE (8) predefined wb_destroy_window($window); // Destroy the window break; } } function button_D(){ global $label_p2_1, $label_p2_2, $editbox_p2_1; wb_set_text($label_p2_1,"xxxx"); wb_set_text($label_p2_2,"yyyy"); } function button_E(){ global $label_p2_1, $label_p2_2, $editbox_p2_1; wb_set_text($label_p2_1,"yyyy"); wb_set_text($label_p2_2,"xxxx"); } function button_F(){ global $label_p2_1, $label_p2_2, $editbox_p2_1; $text1 = wb_get_text($editbox_p2_1); wb_set_text($label_p2_1,"Page 2 ".$text1); wb_set_text($label_p2_2,"Page 2 ".$text1); } ?> |
|
test_4.phpw Run: Navigate to folder UniServer\plugins\winbinder\examples Double click on test_4.bat
I mentioned code maintainability above. Each use of a handle variable in a function requires that it be declared as a global. This just adds to the bloat and makes code a little more difficult to read and is to be avoided. Using raw ID numbers means if you decide to change the numbering order, you need to change all occurrences. On a single script this is probably not to difficult, but if this is over several scripts, it can be a pain. The above problems are resolved on the next page.
|
Summary
The tab control is an excellent choice for producing windows applications. It allows you to have separate functionality on individual pages (tabs). Using the tab control, although a little more complex to configurem is well worth the effort.
Even though this is a working script, we want to modify it to a working template for a real application. The next page shows how to resolve the issues that were highlighted.