WinBinder scratchpad (miscellaneous notes)

NOTE: These are rough notes. They will be moved from here sooner or later.


Running WinBinder — some notes (must be reviewed — must give credit where appropriate)

Associating the PHPW extension with WinBinder

To run WinBinder scripts for Windows Explorer, you have to associate .phpw files with php-win.exe. You can accomplish this in several ways.

Option 1. If you use the WinBinder installer, this will be done automatically for you.

Option 2. To manually associate the .phpw extension to php-win.exe:

  1. In Explorer, go to Tools - Folder options and select the File Types tab.
  2. Press New.
  3. From there, you probably have to browse for the php-win.exe file
  4. Then you have the option of always using that program for .phpw files. Check it.

In Windows 2000 or Windows XP, you can right-click on the .phpw file and select "Open With...". In some cases, you might need to hold down Shift for the "Open With..." to appear.

To associate the phpw extension with WinBinder: In Windows Explorer, go to Tools / Folder options, then select the File types tab. Click New. This will open a small dialog. Type phpw, then click OK. A new item will show up on the list box. The click the Advanced button. This will open a new dialog box. Click New. Another dialog shows up. In the Action field, type open. In the Application field, type (or navigate to) the path to php-win.exe, followed by "%1" (with quotes). Example:

C:\WinBinder\PHP\PHP5\php-win.exe "%1"

Click OK to close the dialog, then OK, then Close. Now you may execute a PHPW script just by double-clicking it.

Option 3. You can also create a FILENAME.REG file to do this for you:

  1. Create a text file with Notepad or whatever
  2. Give it a .reg extension
  3. Place the following lines in it:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.phpw]
@="phpw_auto_file"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file]
@="PHP Winbinder App"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell]
@="open"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell\open]
@="Run Winbinder App"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell\open\command]
@="\"C:\\PHP\\WinBinder\\PHP\\PHP4\\php-win.exe\" \"%1\""

Be sure to change the line C:\\PHP\\WinBinder\\PHP....  to the path where you have your php-win.exe.   Also take note of the extra \'s... just like when you have to escape slashes and quotes (a la addslashes()) in PHP.  You only use it on the @="" bits, not in the parts between the []'s.

Another note, You see the words "open" appear in there?  If you copy all those lines and change "open" to "edit" or something you can create a new right-click option for your files.

The @="open" on the ones ending in \shell needs to match the shell\open  (that is, if you had @="edit" you'd then need a corresponding shell\edit)

And the @="Run Winbinder App" on the shell\open is the text that appears in the right-click menu for PHPW files.

Example... to add "Edit PHPW With Notepad" you'd add the following lines to what's already above (at the end probably):

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell\edit]
@="Edit Winbinder App with Notepad"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell\edit\command]
@="%SystemRoot%\\system32\\NOTEPAD.EXE\" \"%1\"

And if you wanted to make this "edit with notepad" the default double-click action, you'd change the one entry above to be the following:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\phpw_auto_file\shell]
@="edit"

Now you will see "Edit Winbinder App with Notepad" appear in bold on the right-click menu.

Once you get everything in your .REG file, just double click on it and it'll ask you if you want to add these lines to your registry.

These changes will happen immediately when you edit the registry with regedit or will happen as soon as you click "yes" after double-clicking on the .REG file you created with this stuff in it.

DISCLAIMER!!:  This alters your registry.  If you do it exactly as I've stated, it won't hurt anything.  But if you change it (particularly the parts between the []'s) it could overwrite important system data (although it'd take a fluke to hit something critical I think..so the chances are still relatively low).  If this worries you or you're not sure what this is all about, don't do it.  Stick with the OPEN WITH thing on the right-click or shift-right-click menu.  It does effectively the same thing but only lets you set the default double-click action, not alternate edit/open/etc. actions.

Running WinBinder without a console (DOS) window


Minimum structure for distribution:

	D:
	+------ phpcode
	|       +------ include
	|       |       *.php
	|       |       +------ db (if you use the database wrapper functions)
	|       |               *.php
	|       +------ resources
	|               *.bmp
	|               *.ico
	+------ bin
        	+------ php4
    					*.*
    				     +------ ext
  		    					*.dll


Calling a script from a batch (.bat) file

I use a .bat file with the following:

@echo off
..\..\..\php\php-win.exe interface.phpw %1 %2 %3 %4 %5 %6 %7 %8 %9 %10

And it opens the dos window and the PHP app window, maybe it is because of the batch file? How else can i make the call?

Try it without a batch file, by associating phpw extension to php-win.exe (see ***below***)

And yes.. you're keeping the black DOS screen because you're running a .BAT file.  You might be able to right-click on the .BAT and under Properties set it so that the window doesn't appear, but that's still not a clean way to do what you want to do.

If you still want to make it work on a BAT file, you'll need to use the start batch command before calling the PHP-WIN.

Some like that:

@start ..\..\..\php\php-win.exe interface.phpw %1 %2 %3 %4 %5 %6 %7 %8 %9 %10

The console window will open and close in less than a second when the batch is processed.


Associating values with combo boxes and list boxes

It will be possible to use associative arrays with list boxes and combo boxes, but this is not currently possible. There are some workarounds, though:

1) Pass the position of an item to db_get_id() to obtain its identifier. In this case you must not change the order in which the items appear on your combo / list box.

$val = db_get_id($table, wb_get_selected($combobox));

2) Call wb_get_data() to get the id of an element based on its name. This works well as long as you don't have repeated names among the elements. In this case you can sort the items in the control.

$sel = wb_get_text($combobox);
$data = db_get_data($table, null, "name");
$sel_index = (int)array_search($sel, $data);
$val = db_get_data($table, $sel_index, "id");

3) For each item, append a series of tab characters, then the item id. The id's will be hidden from view but they will be there so you can access them directly (using a simple filter or regular expression). In this case you can sort the items in the control.

4) Use the OO interface. Check out the sample code at OOi_samples/ooi_listboxes.phpw.

If you want to use some of the OOi features, but don't want to convert your entire code, you may temporarily convert your non-ooi objects (like your main window), so you'll be able to use it. Check out the example below:
 

<?
define("wbpath", "../");
require wbpath . "/include/winbinder.php";
require wbpath . "/include/ooi.inc.php";

/**
       Create the main window
**/
$mainwin  = wb_create_window (NULL, AppWindow, "Sample WB
Application", 320, 240);
wb_set_handler($mainwin, "pc_main");

/**
       To create the WbComboBox widget, you'll need an OOi object as
parent window.
**/
$ooi_mainwin = new WbAppWindow($mainwin);

/**
       As you have the OOi Main Window, you can add the 'ComboBox' itself.
       Parameters are:
               $parent ($ooi_mainwin)
               $position_left
               $position_top
               $width
               $height (after drop-downed)
               Array($options)
               $id
               $style
               $lparam
       You may add the options later if you prefer.
**/
$combobox = new WbComboBox($ooi_mainwin, 10, 10, 100, 100);
$combobox->id = 0x100;
$combobox->addOption("br", "Brazil");
$combobox->addOption("us", "United States");
$combobox->addOption("value1", "Text number 1");
$combobox->addOption("who", "Who let the dogs out");

/**
       By using the OOi, you may also sort your combobox, and maintain the values
**/
$combobox->sort();

/**
       So, you want to continue using your non-OOi codes...
**/
wb_create_control($mainwin, Label, "I'm just a label...", 5, 30, 150, 20);

wb_main_loop();

function pc_main($window, $id){
       global $combobox;
       if($id == $combobox->id){
               echo "Combobox hit!\n";
               echo "Selected value: " . $combobox->selectedValue . "\n";
               echo "Selected text:  " . $combobox->selectedDesc  . "\n";
               echo "===================\n";
       }
       if($id == IDCLOSE)
               wb_destroy_window($window);
}
?>
 

When the functionality is implemented in the future you may use an associative array instead:
 

wb_set_text($combobox, array(
  "value1" => "Text 1",
  "value2" => "Text 2",
  "value3" => "Text 3"
 ));

or

wb_set_value($combobox, array(
  "value1" => "Text 1",
  "value2" => "Text 2",
  "value3" => "Text 3"
 ));

In this case, wb_get_value() will return the item value instead of its index as it does today:

$val = wb_get_value($combobox);


Adding new styles to existing controls (for C developers)

WinBinder does not currently allow a horizontal scroll bar in edit controls. However, it is easy to add a custom flag to a controls. In this specific case, create the new flag in wb.h

#define WBC_HSCROLL 0x00008000    // This value is not used

Note that the value above is an unused value. You may reutilize a value, however, which is the recommended practice. First you have to make sure it will not conflict with existing flags. In this example you could safely use 0x00010000 (WBC_CHECKBOXES) instead of 0x00008000 because edit controls with check boxes do not make sense. So the line becomes:

#define WBC_HSCROLL 0x00010000    // This value is being reutilized (preferred practice)

Then add some extra code to verify the flag in file wb_control.c, function wbCreateControl:

case EditBox:                                    // Inside the first 'switch' statement 
    pszClass = "EDIT";    // Existing code
    dwStyle = WS_CHILD | WS_TABSTOP | nVisible; // Existing code
if(BITTEST(dwWBStyle, WBC_HSCROLL))          // <-- insert this line
    dwStyle |= WS_HSCROLL;                    // <-- and this one
    // ....
break; // Existing code 

... and export it as a new PHP constant in phpwb_export.c:
WB_ZEND_CONST(LONG, "WBC_SCROLL", WBC_HSCROLL)

Now you may use the new constant together with WBC_MULTILINE inside your PHP code:

wb_create_control($win, EditBox, "This edit box has a horizontal scroll bar", 20, 20, 160, 70, ID_EDIT, WBC_MULTILINE | WBC_HSCROLL);

A more proper implementation should check if WBC_MULTILINE is also set:

case EditBox:                                           // Inside the first 'switch' statement 
// .... if(BITTEST(dwWBStyle, WBC_MULTILINE)) {
if(BITTEST(dwWBStyle, WBC_READONLY)) dwStyle |= WS_VSCROLL | ES_MULTILINE; else dwStyle |= WS_VSCROLL | ES_MULTILINE | ES_WANTRETURN; if(BITTEST(dwWBStyle, WBC_HSCROLL))          // <-- insert this line
    dwStyle |= WS_HSCROLL;                    // <-- and this one
// .... break;




Compiling the WinBinder manual

Here's the toolset you'll need:


About sounds

Not yet implemented!

I think wb_play_sound() is fine. I agree that wb_play() is too generic, but wb_play_wav() is too specific (more than Windows itself, in fact). The idea is to use the Windows API PlaySound() and MCI functions as the basis for the sound functions. These are fairly high-level functions. We must not forget MIDI files, which are completely different in nature but can be controlled with the same functions.

I'll also create some mechanism to notify the application window when a sound stops.

A "wild" idea: To reduce the number of functions I'd like to use names like wb_load_mm(), wm_play_mm() etc. where "mm" stands for "multimedia", or something like that. Thus we could use the same set of functions to control video, CDs, DVDs, etc. in the future. I don't like the idea of having wb_play_sound(), wb_play_midi(), wb_play_video(), wb_play_cd(), wb_play_dvd() etc. You have probably noticed that I'm obsessively economical with creating new functions. This is a kind of mental disorder caused by being exposed to very high doses of Windows API functions and messages for many years. :)

> One other comment. Why a "destroy sound" function? Why not just a "wb_destroy()" that does a general collection of the object being destroyed, also destroying any child/dependant processes or objects? A basic unset() type thing. Anytime you want to destroy something, you just assign *nothing* to it. I can't think of a reason why sound/media files need their own destroy function. But maybe someone else has a reason (which is cool with me.. if someone has a good reason that I don't see, I'm always willing to listen and learn).

The idea here is to be able to load a sound (or video, or MIDI, or other multimedia type/stream etc.) into memory with wb_load_mm(), play it or do whatever is needed with it (still in memory), then free the memory allocated to it. Because WinBinder is not object-oriented (without the OOi layer), simply setting it to NULL won't do the job. Here: 

$snd = wb_load_mm("test.wav"); // Load a copy of the media file into memory
$length = wb_get_sound_info($snd, "length");
// etc...
wm_play_mm($snd);
wb_destroy_mm($snd); // This will deallocate the memory

The function wb_destroy_mm() would simply call a wbDestroyMM(). This one, in turn, would simply check if the pointer passed to it is valid. If yes, just call eFree() to liberate the memory allocated with wb_load_mm().


Accepting multiple values

Not yet implemented!

Functions that accept multiple values can accept an array of values or a newline-separated string. For example:

//The following examples are equivalent:

wb_set_text($tabctrl, array("First", "Second", "Third"));
wb_set_text($tabctrl, "First\r\nSecond\r\nThird");
wb_set_text($tabctrl, "First\nSecond\nThird");
wb_set_text($tabctrl, "First\rSecond\rThird");

are equivalent and produce the same results. Note that CR/LF, LF, and CR may be used interchangeably to designate a newline.