PHP WinBinder: Alternative control 3: Difference between revisions
(New page: {{Nav 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 T...) |
(Proofreading and grammatical changes; some minor reformatting) |
||
Line 2: | Line 2: | ||
'''''Alternative control part 3''''' | '''''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. | 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. | 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. | ||
== Menu == | == Menu == | ||
Line 10: | Line 10: | ||
|-valign="top" | |-valign="top" | ||
| | | | ||
Adding a menu control is easy | 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. | All you need to do is re-size your application to fit. | ||
From my point of view it carries baggage that is not required, keyboard short cuts never use | 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! | *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. | Yep! I like lean and clean. | ||
Please remember this is not a commercial product | Please remember this is not a commercial product. A menu item must be useful. | ||
| | | | ||
Line 45: | Line 44: | ||
|-valign="top" | |-valign="top" | ||
| | | | ||
<br />In WinBinder most parameters are optional hence the code can be reduced to this | <br />In WinBinder most parameters are optional, hence the code can be reduced to this | ||
Absolutely no baggage; just clean drop down menus. | Absolutely no baggage; just clean drop down menus. | ||
This really is an elegant structure and easy to use. | |||
* Define any ID used, | * Define any ID used, remembering that it must be unique | ||
* Add menu text to be displayed to a user | * Add menu text to be displayed to a user | ||
Click a menu item and | That’s it! | ||
Click a menu item and its ID is sent to the handler function for processing. | |||
| | | | ||
<pre> | <pre> | ||
Line 78: | Line 78: | ||
</pre> | </pre> | ||
|} | |} | ||
Our new UniController has a common set of buttons that are specific to the servers. They are interlocked providing an easy to use interface | 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 change | 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. | |||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' | ||
== Menu - Example== | == Menu - Example== | ||
{| | {| | ||
Line 95: | Line 94: | ||
The applications main buttons are generally all that is required to run the servers. | 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 | 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'''. | ||
'''''Activation'':''' | '''''Activation'':''' | ||
Line 105: | Line 104: | ||
'''''Unique'':''' | '''''Unique'':''' | ||
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. | 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. | ||
'''''Tasks'':''' | '''''Tasks'':''' | ||
* Local requires displaying a web page on the local server in a | * Local requires displaying a web page on the local server in a user's default browser | ||
* View and Edit requires running a | * View and Edit requires running a user's default text editor. | ||
* Directly changing a server variable requires a pop-up menu | * Directly changing a server variable requires a pop-up menu. | ||
* MySQL password restore requires running a batch file. In addition you require | * 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 | Each of these tasks are covered in the next section, including working example code. | ||
'''''Function'': - wb_exec''' | '''''Function'': - wb_exec''' | ||
Line 190: | Line 189: | ||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' | ||
== Function'': - wb_exec() == | == Function'': - wb_exec() == | ||
This function is used extensively in processing menu items | This function is used extensively in processing menu items. Three uses are shown below. | ||
=== Display a local web page === | === Display a local web page === | ||
To display a local web page use the following format: | To display a local web page, use the following format: | ||
<pre> | <pre> | ||
wb_exec("http://localhost/path_to_page"); | wb_exec("http://localhost/path_to_page"); | ||
</pre> | </pre> | ||
For example to display index page use | For example, to display index page use: | ||
<pre> | <pre> | ||
wb_exec("http://localhost/index.php"); | wb_exec("http://localhost/index.php"); | ||
</pre> | </pre> | ||
For our application the above is too specific. | For our application, the above is too specific. | ||
An index page can use one of several file extensions | 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.pl index.cgi | DirectoryIndex index.html index.shtml index.html.var index.htm index.php3 index.php index.pl index.cgi | ||
A user can change the Apache port | 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: | ||
<pre> | <pre> | ||
wb_exec("http://localhost:port_number/"); | wb_exec("http://localhost:port_number/"); | ||
Line 220: | Line 217: | ||
To display the root www index page requires the following handler code: | 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. | 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 included the code can be reduced to this | However, if it is included, the code can be reduced to this: | ||
<pre> | <pre> | ||
case ID_ROOT: // Server root WWW | case ID_ROOT: // Server root WWW | ||
Line 249: | Line 246: | ||
</pre> | </pre> | ||
|} | |} | ||
=== Edit or display text files === | === Edit or display text files === | ||
To edit or display the content of a text file we use Windows '''notepad''' | 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()''' | 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 Apache error.log file is shown below. | The handler code for viewing the Apache error.log file is shown below. | ||
<pre> | <pre> | ||
//--Logs | //--Logs | ||
Line 266: | Line 261: | ||
break; | break; | ||
</pre> | </pre> | ||
'''''Note 1'':''' The variable '''$us_apache''' must be | '''''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) | '''''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 === | === Run another WinBinder application === | ||
Change MySQL password requires user input. Our current application has been purposefully made minimal | 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 | 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. | Again we use function wb_exec(). I have reworded the parameters it takes. | ||
<pre> | <pre> | ||
wb_exec("complete_path_of_program_to_run" | wb_exec("complete_path_of_program_to_run","pass_any_parameters" ); | ||
</pre> | </pre> | ||
* The first parameter can be either an absolute path (C:/path/prog.exe) or a relative path (../../path/prog.exe)<br />'''../../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 first parameter can be either an absolute path (C:/path/prog.exe) or a relative path (../../path/prog.exe)<br />'''../../path/prog.exe''' This means from the current working folder move up two folder levels and down into folder prog and run prog.exe | ||
Line 288: | Line 282: | ||
We want to run our second application '''test7b.phpw''' with program '''php-win.exe''' (php-win.exe hides the command window). | 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 | 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''' | An optional parameter or parameters can be passed to the script '''test7b.phpw''' | ||
Putting all this together the line of code looks like this: | Putting all this together, the line of code looks like this: | ||
<pre> | <pre> | ||
wb_exec("..\php\php-win.exe", "-c ..\php\php-wb.ini test_7b.phpw 23456"); // Run second window app. | wb_exec("..\php\php-win.exe", "-c ..\php\php-wb.ini test_7b.phpw 23456"); // Run second window app. | ||
Line 302: | Line 296: | ||
break; | break; | ||
</pre> | </pre> | ||
=== Are you sure WBC_YESNO === | === Are you sure WBC_YESNO === | ||
There are situations requiring confirmation from a user for example overwriting critical data in a file. | 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. | 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” | 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: | The handler for restore MySQL password uses this code shown below: | ||
Line 319: | Line 313: | ||
break; | break; | ||
</pre> | </pre> | ||
An "if" tests the returned value. Pressing YES button returns true and the restore batch file is run. | An "if" tests the returned value. Pressing the YES button returns true and the restore batch file is run. | ||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' | ||
== User feedback == | == 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 something is wrong. | 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 | 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 | 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: | There are two images blue and blank. These are created as follows: | ||
Line 369: | Line 362: | ||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' | ||
== Test == | == Test == | ||
To see this code in action run '''test_7.bat''' (code contained in test_7.phpw) | To see this code in action, run '''test_7.bat''' (code contained in test_7.phpw). | ||
Run Uniform Server | Run Uniform Server; start and stop each server; observe the button and indicator states. | ||
Start and stop both servers again observe 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) | Try the menu (only a minimum number of items work). | ||
After testing close both Servers and application script. | After testing, close both Servers and the application script. | ||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' | ||
== Summary == | == Summary == | ||
Essentially that completes the alternative control | Essentially that completes the alternative control. There is a remaining issue. | ||
You will have noticed a button named refresh | You will have noticed a button named refresh. This serves no real purpose other than to update buttons and indicators (runs function main_init ) after restoring the application using the tray icon. | ||
A solution is provided on the [[PHP WinBinder: Alternative control 4 | '''next page''']] that removes the need for this button | A solution is provided on the [[PHP WinBinder: Alternative control 4 | '''next page''']] that removes the need for this button. | ||
'''''[[#top | Top]]''''' | '''''[[#top | Top]]''''' |
Revision as of 19:33, 30 January 2010
|
|
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.
Menu
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:
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( "&File", 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"), "&Help", 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...") )); |
Absolutely no baggage; just clean drop down menus. This really is an elegant structure and easy to use.
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( "File", array(ID_NEW, "New"), array(ID_OPEN, "Open"), null, // separator array(ID_SAVE, "Save"), array(ID_SAVEAS, "Save As..."), null, // separator array(IDCLOSE, "Exit"), "Help", 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
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. Activation: Adding appropriate code in the handler function activates menu items. Unique: 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.
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:
|
// Create main menu $mainmenu = wb_create_control($mainwin, Menu, array( "File", array(IDCLOSE, "Exit"), "Local", array(ID_ROOT, "Root WWW"), array(ID_ROOTSSL, "Root SSL"), "Edit", 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"), "Logs", array(ID_APACHE_ER, "Apache Error Log"), array(ID_APACHE_ACC, "Apache Access Log"), null, // separator array(ID_MYSQL_ER, "MySQL Error Log"), "Passwords", 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"), "Help", 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:
wb_exec("http://localhost/path_to_page");
For example, to display index page use:
wb_exec("http://localhost/index.php");
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.pl 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:
wb_exec("http://localhost:port_number/");
ROOT WWW:
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(); $text='http://:'.$apache_port.'/localhost/'; wb_exec($text); break; |
|
//--Local 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 break; |
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.
//--Logs 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 } break;
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.
Requirement:
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. break;
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. } break;
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){ if($flash){ progress_indicator_on(TRUE); // On $flash = FALSE; // Invert flash } else{ progress_indicator_on(FALSE); // Off $flash = TRUE; // Invert flash } } else{ progress_indicator_on(FALSE); // Off $flash = FALSE; // Initial }
Test
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.
Summary
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 (runs 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.