PHP WinBinder: Alternative control 3

From The Uniform Server Wiki
Revision as of 18:37, 2 February 2010 by BobS (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search


UniServer 5-Nano
PHP WinBinder.

Alternative control part 3

This page is a continuation of the alternative control. It covers adding functionality to the following buttons: Logs, Edit and Test. Each of these buttons needs to access several files. One solution is to use pop-up windows containing additional buttons to access the appropriate files. This is far from ideal and would be extremely messy.

A more appropriate solution would be to use dropdown menus. WinBinder makes this task extremely easy. The advantage of using this solution is that the application remains compact, requires minimal changes and offers expandability.


Adding a menu control is easy. It forces a menu across the top of your application. All you need to do is re-size your application to fit.

From my point of view, it carries baggage that is not required, such as:

  • keyboard short cuts, which I never use.
  • Images to the side of a menu item! This is supposed to be intuitive, but I never had a clue what most of them do.

Yep! I like lean and clean.

Please remember this is not a commercial product. A menu item must be useful.

// Create main menu
$mainmenu = wb_create_control($mainwin, Menu, array( 
       array(ID_NEW,     "&New\tCtrl+N",     "", PATH_RES . "menu_new.bmp",  "Ctrl+N"),
       array(ID_OPEN,    "&Open...\tCtrl+O", "", PATH_RES . "menu_open.bmp", "Ctrl+O"),
       null,             // separator                      
       array(ID_SAVE,    "&Save\tCtrl+S",    "", PATH_RES . "menu_save.bmp", "Ctrl+S"),
       array(ID_SAVEAS,  "Save &As..."),
       null,             // separator
       array(IDCLOSE,    "E&xit\tAlt+F4",    "", PATH_RES . "menu_exit.bmp"),
       array(ID_HELP,    "&Help topics\tF1", "", PATH_RES . "menu_help.bmp",  "F1"),
       null,             // separator
       array(ID_WEBSITE, "&Web site"),
       null,             // separator
       array(ID_ABOUT,   "About...")

In WinBinder most parameters are optional, hence the code can be reduced to this

Absolutely no baggage; just clean drop down menus.

This really is an elegant structure and easy to use.

  • Define any ID used, remembering that it must be unique
  • Add menu text to be displayed to a user

That’s it!

Click a menu item and its ID is sent to the handler function for processing.

// Create main menu
$mainmenu = wb_create_control($mainwin, Menu, array( 
       array(ID_NEW,     "New"),
       array(ID_OPEN,    "Open"),
       null,             // separator                      
       array(ID_SAVE,    "Save"),
       array(ID_SAVEAS,  "Save As..."),
       null,             // separator
       array(IDCLOSE,    "Exit"),
       array(ID_HELP,    "Help1"),
       null,             // separator
       array(ID_WEBSITE, "Web site"),
       null,             // separator
       array(ID_ABOUT,   "About...")

Our new UniController has a common set of buttons that are specific to the servers. They are interlocked providing an easy to use interface which prevents a user killing the servers.

The drop down menu now allows a user to access lower levels of the server and, for example, change the ports with ease. To implement this, a menu item can open another window to make appropriate changes.

The main point is that a simple change to a menu offers real expandability.


Menu - Example

Example: test_7.phpw

The applications main buttons are generally all that is required to run the servers.

Using a drop down menu allows various aspects of the server to be accessed. A few possibilities are viewing log files, putting servers on-line and setting passwords.

To the right are additional items that you may wish to include. A semi-working menu can be found in example test_7.phpw. To see this in action, run test_7.bat.


Adding appropriate code in the handler function activates menu items.


Most menu items use similar code. I have included code that is unique for a particular task. This introduces more WinBinder features not previously covered.


  • Local requires displaying a web page on the local server in a user's default browser
  • View and Edit requires running a user's default text editor.
  • Directly changing a server variable requires a pop-up menu.
  • MySQL password restore requires running a batch file. In addition, you require verification from a user that what they called for is what they really intend to do.

Each of these tasks are covered in the next section, including working example code.

Function: - wb_exec

The example code uses this versatile function (lifted from manual):

bool wb_exec (string command [, string param])

Opens or executes a command. The string passed to this function can be one of the following:

  • A WinBinder script.
  • An executable file.
  • A non-executable file associated with an application.
  • A folder name. Passing a null or empty string opens the current folder.
  • A help file or help file topic.
  • An URL, e-mail, newsgroup, or another Internet client application.
// Create main menu
$mainmenu = wb_create_control($mainwin, Menu, array( 
       array(IDCLOSE,    "Exit"),
       array(ID_ROOT,    "Root WWW"),
       array(ID_ROOTSSL, "Root SSL"),

       array(ID_APACHECNF,            "Apache config httpd.conf"),
       array(ID_APACHESSLCNF,         "pache ssl config ssl.conf"),
       null,                            // separator
       array(ID_MYSQLINI,             "MySQL my.ini"),
       null,                           // separator
       array(ID_PHPINI,               "PHP php.ini"),
       array(ID_PHPINICLI,            "PHP php-cli.ini "),
       array(ID_PHPINIPRODUCTION,     "PHP production ini "),
       array(ID_PHPINIDEVELOPMENT,    "PHP development ini"),
       null,                           // separator
       array(ID_PHPSWITCHPRODUCTION,  "PHP switch to production"),
       array(ID_PHPSWITCHDEVELOPMENT, "PHP switch to development"),

       array(ID_APACHE_ER,   "Apache Error Log"),
       array(ID_APACHE_ACC,  "Apache Access Log"),
       null,                 // separator
       array(ID_MYSQL_ER,    "MySQL Error Log"),

       array(ID_WWWROOTHTACCESS,  "Root www .htaccess"),
       array(ID_WWWROOTPASSWORD,  "Root www name password"),
       null,                      // separator
       array(ID_SSLROOTHTACCESS,  "Root ssl .htaccess"),
       array(ID_SSLROOTPASSWORD,  "Root ssl name password"),
       null,                      // separator
       array(ID_APANELHTACCESS,   "Apanel .htaccess"),
       array(ID_APANELPASSWORD,   "Apanel name password"),
       null,                      // separator
       array(ID_SETMYSQLPASSWORD, "Set MySQL Password"),
       array(ID_RESTOREMYSQLPASS, "Restore MySQL Password"),

       array(ID_HELP,    "Help topics"),
       null,             // separator
       array(ID_WEBSITE, "&Web site"),
       null,             // separator
       array(ID_ABOUT,   "About...")


Function: - wb_exec()

This function is used extensively in processing menu items. Three uses are shown below.

Display a local web page

To display a local web page, use the following format:


For example, to display index page use:


For our application, the above is too specific.

An index page can use one of several file extensions, so we do not want to specify an index page. We'll let Apache choose one from the list defined in its configuration file:

DirectoryIndex index.html index.shtml index.html.var index.htm index.php3 index.php index.cgi

A user can change the Apache port. This needs to be read from the configuration file and included in the Internet address, so the following format is required:



To display the root www index page requires the following handler code:

The Apache port is read from the configuration file. If the value is 80 (standard), there is no need to include this in the address; all browsers understand and assume port 80.

However, if it is included, the code can be reduced to this:

case ID_ROOT: // Server root WWW
 $apache_port = get_apache_port();       


case ID_ROOT: // Server root WWW

  $apache_port = get_apache_port();              // Get actual port
  if($apache_port == 80){                        // Standard port no change
    $text='http://localhost/';                   // Use as is
  else{                                          // Non standard hence
    $text='http://:'.$apache_port.'/localhost/'; // hence add port
  wb_exec($text);                                // Open page in browser


Edit or display text files

To edit or display the content of a text file, we use Windows notepad. This is contained somewhere on the system path.

To obtain the full path to this file, use function wb_find_file(). It looks in the Windows and System directories. The path is required by function wb_exec(). This function also allows you to pass a parameter to a file.

The handler code for viewing the Apache error.log file is shown below.

  case ID_APACHE_ER:                                                     // Apache Error log
    if (file_exists("$us_apache/logs/error.log")) {                      // Does file exist
      wb_exec(wb_find_file("notepad.exe"),"$us_apache/logs/error.log" ); // View Apache error log

Note 1: The variable $us_apache must be declared as local at the top of the handler function. ($us_apache is a UniServer core variable)

Note 2: A user may have deleted the file (can become large; generally a good idea to delete), so we must check for existence, otherwise an error is generated.

Run another WinBinder application

Change MySQL password requires user input. Our current application has been purposefully made minimal, therefore there are no input fields. A solution is to use a second WinBinder application that is run from the dropdown menu.

From the examples folder I copied and renamed file test_1.phpw to test7b.phpw and placed it in folder alt_con_1. This application would contain an input field and code to change the MySQL port. It is used here to demonstrate how to run a second application from our main application.

Again we use function wb_exec(). I have reworded the parameters it takes.

wb_exec("complete_path_of_program_to_run","pass_any_parameters" ); 
  • The first parameter can be either an absolute path (C:/path/prog.exe) or a relative path (../../path/prog.exe)
    ../../path/prog.exe This means from the current working folder move up two folder levels and down into folder prog and run prog.exe
  • The second parameter provides a list of parameters that are passed to prog.exe. Each parameter passed must be separated by a space.


We want to run our second application test7b.phpw with program php-win.exe (php-win.exe hides the command window).

PHP will use a default configuration, hence the need to force it to use php-wb.ini

An optional parameter or parameters can be passed to the script test7b.phpw

Putting all this together, the line of code looks like this:

wb_exec("..\php\php-win.exe", "-c ..\php\php-wb.ini test_7b.phpw 23456"); // Run second window app. 

The full handler code looks like this:

 case ID_SETMYSQLPASSWORD: // Set MySQL Password
  wb_exec("..\php\php-win.exe", "-c ..\php\php-wb.ini test_7b.phpw 23456"); // Run second window app. 

Are you sure WBC_YESNO

There are situations requiring confirmation from a user, for example, overwriting critical data in a file.

A very easy way to obtain this information is to use a message box with style WBC_YESNO.

The pop-up box contains two buttons: “YES” and “NO”. Clicking yes returns TRUE and click “NO” returns FALSE.

The handler for restore MySQL password uses this code shown below:

case ID_RESTOREMYSQLPASS: // Restore MySQL Password
  $text ="Are you sure?\nYou want to restore\nthe MySQL password.";
  if(wb_message_box($window, $text, "MySQL Password Restore", WBC_YESNO)){ 
    wb_exec('..\..\..\unicon\restore_mysql_password\Run_restore.bat'); // Run MySQL password restore batch file. 

An "if" tests the returned value. Pressing the YES button returns true and the restore batch file is run.


User feedback

For any number of reasons the servers may take a relatively long time to either start or stop. If the indicators (red or green) remain static for this period it gives a user the impression that something is wrong.

A progress bar could be used, however the layout does not justify using one. An alternative is to use another indicator with a different colour linked to the main timer. This indicator flashes, providing a user with feedback. When the main indicators change, it is turned off.

There are two images: blue and blank. These are created as follows:

File test_7.phpw

Add this line to the end of Common variables section (top of page)

$flash                   = FALSE; // progress indicator off

Add this section to end of //-- Create indicators

 //flashing indicator
 $frame = wb_create_control($mainwin, Frame, "", 215, 109, 20, 12, ID_F_BLANK, WBC_IMAGE); // progress off
 wb_set_image($frame,  'blank.bmp', NOCOLOR);
 $frame = wb_create_control($mainwin, Frame, "", 215, 109, 20, 12, ID_F_BLUE, WBC_IMAGE); // progress on
 wb_set_image($frame,  'blue.bmp', NOCOLOR);

Finally, add this to the end of main_timer() function:

 //Progress indicator

 if( $Start_timer_Apache_run | $Start_timer_Apache_stop | $Start_timer_MySQL_run |$Start_timer_MySQL_stop){

     progress_indicator_on(TRUE);   // On
     $flash = FALSE;                // Invert flash
     progress_indicator_on(FALSE); // Off
     $flash = TRUE;                // Invert flash

     progress_indicator_on(FALSE); // Off
     $flash = FALSE;               // Initial    



To see this code in action, run test_7.bat (code contained in test_7.phpw).

Run Uniform Server; start and stop each server; observe the button and indicator states.

Start and stop both servers; again observe the button and indicator states.

Try the menu (only a minimum number of items work).

After testing, close both Servers and the application script.



Essentially that completes the alternative control. There is a remaining issue.

You will have noticed a button named refresh. This serves no real purpose other than to update buttons and indicators (by running function main_init) after restoring the application using the tray icon.

A solution is provided on the next page that removes the need for this button.