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.

Top

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.

 

 


Top

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:

  • $label_p1_1 - Refers to a label on tab page 1 first label
  • $label_p1_2 - Refers to a label on tab page 1 second label
  • $button_p3_1 - Refers to a button on tab page 3 first button
  • $button_p3_2 - Refers to a button on tab page 3 second button
  • $editbox_p2_2 - Refers to a edit box on tab page 2 second edit box

 

IDs:

  • Labels start at 100
  • Push buttons start at 200
  • EditBox start at 300
  • Main Tab starts at 9000
  • A Tab page starts at 1000 next page 2000 etc

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.

Top

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.

Top

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


Functionality

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.

Top

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);
}
?>

 


Script:

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.


In this example, the structure of the script is the important part. It’s a working script that we can change into a working template.

Top

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.

Top