WinBinder objects

Windows uses handles of type HWND to refer to most GUI objects. Since handles are 32-bit pointers that are unique to each window, it would be tempting to use them as PHP variables to refer to controls. However, this approach is not ideal for the following reasons:

Therefore a WinBinder Object (WBOBJ) structure is defined. All WinBinder windows and controls are of type WBOBJ. The structure contains the window handle (HWND) and other data. Below is a copy of the WBOBJ definition in WB.H:

// WinBinder object (window, control, or menu), stored with SetWindowLong() / GWL_USERDATA

typedef struct _wbo {
    HWND hwnd;                  // Control or window handle
    UINT id;                    // Control identifier
    UINT uClass;                // Object class
    int item;                   // Item index
    int subitem;                // Sub-item index
    DWORD style;                // WinBinder style
    struct _wbo *parent;        // Parent window
    LPTSTR pszCallBackFn;       // Callback function
    LPTSTR pszCallBackObj;      // Object for callback method
    LPARAM lparam;              // User-defined parameter
    LONG lparams[8];            // General-purpose parameter array
    RECT rcTitle;               // Title area
    AREA arMin;                 // Minimum window area
    AREA arMax;                 // Maximum window area
    HBITMAP pbuffer;            // Screen buffer for container windows
} WBOBJ, *PWBOBJ;

The WinBinder functions wb_create_control() and wb_create_window() effectively return a pointer to the window's WBOBJ structure as a long integer. This pointer is also stored (with Window API function SetWindowLong() and GWL_USERDATA) in every window. Therefore it always possible to obtain the HWND from a WBOBJ and vice-versa, for any given window or control.

The first LPARAM type field, lparam, carries the value of the param argument that is passed in functions wb_create_control() and wb_create_window(). The array of LONGs, lparams, is reserved for internal use and can be used to carry additional user information or 32-bit pointers. These additional pointers are accessible only via the wb_peek() function.

Control handles and identifiers

A control handle is a unique integer value that is returned the control created with wb_create_control(). It is actually a pointer to the WBOBJ structure that defines the control as seen above. A control identifier is an integer number that is assigned by you when the control is created (the id parameter). It is used to easily differentiate between controls. You should assign a unique identifier to each control so a single switch statement in the callback function is enough to process all messages.

Parents and containers

Containers are windows or controls that act as parents for other controls. The only valid containers in WinBinder are windows and tab controls. Therefore the following rule must be observed:

WARNING: You should not try to use a frame (or any other control class except for a tab control) as a container for other controls.

For tab controls, messages and events are sent automatically to and from the main window (i.e. the tab control parent) so there is no need to create an additional callback function for the tab control. All processing of controls contained inside a tab control is handled automatically and transparently by the main window callback function.

Example: obtaining a window handle

// Declare constants for the WBOBJ structure

define("WBOBJ",       "Vhwnd/Vid/Vuclass/litem/lsubitem/Vstyle/Vparent/Vhandler/Vlparam/V8lparams/Vpbuffer");
define("WBOBJ_RAW",   "V3l2V13");
define("WBOBJ_SIZE",  72);

$wbobj = unpack(WBOBJ, wb_peek($window, WBOBJ_SIZE));
$hwnd = $wbobj["hwnd"];

echo "The handle for this window is $hwnd.";

See also

wb_create_control
wb_create_window
Callback functions and window handlers
Window classes
Window messages and events