NAME

XMLBuilder - Build Win32::GUIs using XML.

SYNOPSIS

        use Win32::GUI::XMLBuilder;
        
        my $gui = Win32::GUI::XMLBuilder->new({file=>"file.xml"});
        my $gui = Win32::GUI::XMLBuilder->new(*DATA);
        
        Win32::GUI::Dialog;
        
        sub test {
         $gui->{Status}->Text("testing 1 2 3..");
        }
        
        ...
        
        __END__
        <GUI>
        
        ..
        </GUI>

DEPENDENCIES

        XML::Twig
        Win32::GUI

DESCRIPTION

This module allows Win32::GUIs to be built using XML. For examples on usage please look in samples/ directory.

XML SYNTAX

XMLBuilder will parse an XML file or string that contains elements that describe a Win32::GUI object.

All XML documents must be enclosed in <GUI>..</GUI> elements and each separate GUI window must be enclosed in <Window>..</Window> elements. To create a N-tier window system one might use a construction similar to: -

        <GUI>
         <Window name="W_1">
          ...
         </Window>
         <Window name="W_2">
          ...
         </Window>
         <Window name="W_N">
          ...
         </Window>
        </GUI>

ATTRIBUTES

Elements can additionally be supplemented with attributes that describe its corresponding Win32::GUI object's properties such as top, left, height and width. These properties usually include those provided as standard in each Win32::GUI class. I.e.

        <Window height="200" width="200" title="My Window"/>

Elements that require referencing in your code should be given a name attribute. An element with attribute: -

        <Button name="MyButton"/>

can be called as $gui->{'MyButton'} and event subroutines called using MyButton_Click. From within an XML string the element must be called by $self->{'MyButton'}.

Attributes can contain Perl code or variables and generally any attribute that contains the variable '$self' or starts with 'exec:' will be evaluated. This is useful when one wants to create dynamically sizing windows: -

        <Window name='W'
         left='0' top='0'
         width='400' height='200'
        >
         <StatusBar name='S'
          left='0' top='$self->{W}->ScaleHeight-$self->{S}->Height'
          width='$self->{W}->ScaleWidth' height='$self->{S}->Height'
         />
        </Window>

SPECIAL SUBSTITUTION VARIABLES

If an attribute contains the string %P% then it is subsituted with $self->{<parent>}. Where <parent> is the name of the current elements parent. It is useful when specifying child dimensions where the parent is nameless.

SPECIFYING DIMENSIONS

'pos' and 'size' attributes are supported but converted to top, left, height and width attributes on parsing. I suggest using the attribute dim='left,top,width,height' instead (not an array but an list with brackets).

AUTO-RESIZING

Win32::GUI::XMLBuilder will autogenerate an onResize NEM method by reading in values for top, left, height and width. This will work sufficiently well provided you use values that are dynamic such as $self->{PARENT_WIDGET}->Width, $self->{PARENT_WIDGET}->Height for width, height attributes respectively when creating new widget elements.

NEM EVENTS

NEM events are supported. When specifying a NEM event such as onClick one must use $self syntax to specify current Win32::GUI::XMLBuilder object in anonymous subroutines. An attribute of notify='1' is added automatically when an NEM event is called. One can alo specify other named subroutines by name, but do not prefix with an ampersand! i.e.

        onClick='my_sub' [CORRECT]
        onClick='&my_sub' [INCORRECT]

SIMPLE POSITION AND SIZE

If no dimensions are given for an element whose direct parent is of a Top level widget type such as Window or DialogBox, it will assume a top and left of zero and and a width and height of its parent. I.e.

        dim='0, 0, $self->{PARENT}->ScaleWidth, $self->{PARENT}->ScaleHeight'

AUTO WIDGET NAMING

Win32::GUI::XMLBuilder will autogenerate a name for a wiget if a 'name' attribute is not provided. The current naming convention is Widget_Class_N where N is a number. For example Button_1, Window_23, etc...

ENVIRONMENT VARIABLES

WIN32GUIXMLBUILDER_DEBUG

Setting this to 1 will produce logging.

METHODS

new({file=>$file}) or new($xmlstring)

SUPPORTED WIDGETS - ELEMENTS

Most Win32::GUI widgets are supported and general type widgets can added without any modification being added to this module.

<WGXPre>

The <WGXPre> element is parsed before GUI construction and is useful for defining subroutines and global variables. Code is wrapped in a { package main; no strict; .. } so that if subroutines are created they can contain variables in your program including Win32::GUI::XMLBuilder instances. The current Win32::GUI::XMLBuilder instance can also be accessed outside subroutines as $self. If any data is returned it must be valid XML that will be parsed once by the WGXPost phase, see below.

Since you may need to use a illegal XML characters within this element such as

        <  less than      (&lt;)
        >  greater than   (&gt;)
        &  ampersand      (&amp;)
        '  apostrophe     (&apos;)
        "  quotation mark (&quot;)

you can use the alternative predefined entity reference or enclose this data in a "<![CDATA[" "]]>" section. Please look at the samples and read http://www.w3schools.com/xml/xml_cdata.asp.

The <WGXPre> element was previously called <PreExec>. The <PreExec> tag is deprecated but remains only for backward compatibility and will be removed in a later release.

<WGXExec>

The <WGXExec> element is parsed during GUI construction and allows code to be inserted at arbitrary points in the code. It otherwise behaves exactly the same as <WGXPre> and can be used to place _Resize subroutines. If any data is returned it must be valid XML that will be parsed once by the WGXPost phase, see below.

<WGXPost>

The <WGXPost> element is parsed after GUI construction and allows code to be included at the end of an XML file. It otherwise behaves exactly the same as <WGXPre> and can be used to place _Resize subroutines.

The <WGXPost> element was previously called <PostExec>. The <PostExec> tag is deprecated but remains only for backward compatibility and will be removed in a later release.

<Icon>, <Bitmap> and <Cursor> elements.

The <Icon> element allows you to specify an Icon for your program.

        <Icon file="myicon.ico" name='MyIcon' />

The <Bitmap> element allows you to specify an Bitmap for your program.

        <Bitmap file="bitmap.bmp" name='Image' />

The <Cursor> element allows you to specify an Cursor for your program.

        <Cursor file="mycursor.cur" name='Cursor' />
<ImageList>
        <ImageList name='IL' width='16' height='16' maxsize='10'>
         <Item bitmap='one.bmp'/>
         <Item bitmap='two.bmp'/>
         <Item bitmap='$self->{Bitmap}'/>
        </ImageList>
<Font>

Allows you to create a font for use in your program.

        <Font name='Bold'
         size='8'
         face='Arial'
         bold='1'
         italic='0'
        />

You might call this in a label element using something like this: -

        <label
         text='some text'
         font='$self->{Bold}'
         ...
        />.
<Class>

You can create a <Class> element,

        <Class name='MyClass' icon='$self->{MyIcon}'/>

that can be applied to a <Window .. class='$self->{MyClass}'>. The name of a class must be unique over all instances of Win32::GUI::XMLBuilder instances!

Typically one might add an icon to your application using a Class element, i.e.

        <GUI>
         <Icon file="myicon.ico" name='MyIcon'/>
         <Class name='MyClass' icon='$self->{MyIcon}'/>
         <Window class='$self->{MyClass}'/>
        </GUI>
<WGXMenu>

Creates a menu system. Submenus can be nested many times more deeply than using MakeMenu. Although one can use Item elements throughout the structure it is more readable to use the Button attribute when a new nest begins. I.e.

        <WGXMenu>
         <Button>
          <Item/>
         </Button>
        </WGXMenu>

and

        <WGXMenu>
         <Item>
          <Item/>
         </Item>
        </WGXMenu>

are equivalent but the former is more true to what is happening under the hood. One can generally pass a Button to TrackPopupMenu and a Button handle to MDIClient's windowmenu attribute.

A separator line can be specified by setting the separator attribute to 1.

One can also use NEM events directly as attributes such as onClick (or OEM events by using PopupMenu_Click), etc..

        <WGXMenu name='Menu'>
         <Button name='PopupMenu' text='ContextMenu'>
          <Item name='OnEditCut' text='Cut' onClick='OnEditCut'/>
          <Item name='OnEditCopy' text='Copy' onClick='sub { ... do something ...}'/>
          <Item name='OnEditPaste' text='Paste'/>
          <Item separator='1'/>
          <Item name='SelectAll' text='>Select All'/>
         </Button>
        </WGXMenu>

See the menus.xml for an extensive example in the samples/ directory.

<MakeMenu>

Creates a menu system. The amount of '>'s prefixing a text label specifies the menu items depth. A value of text '-' (includes '>-', '>>-', etc) creates a separator line. To access named menu items one must use the menu widgets name, i.e. $gui->{PopupMenu}->{SelectAll}, although one can access an event by its name, i.e. SelectAll_Click. One can also use NEM events directly as attributes such as onClick, etc..

        <MakeMenu name='PopupMenu'>
         <Item text='ContextMenu'/>
         <Item name='OnEditCut' text='>Cut'/>
         <Item name='OnEditCopy' text='>Copy'/>
         <Item name='OnEditPaste' text='>Paste'/>
         <item text='>-' />
         <Item name='SelectAll' text='>Select All'/>
         <item text='>-' />
         <Item name='Mode' text='>Mode' checked='1'/>
        </MakeMenu>

See the makemenu.xml example in the samples/ directory. The MakeMenu element suffers from the limitation of being only able to nest menus to 2 layers. This is inherent from the underlying Win32::GUI module. I would suggest using the more configurable WGXMenu above.

The <MakeMenu> element was previously called <Menu>. The <Menu> tag is deprecated but remains only for backward compatibility and will be removed in a later release. Please try to update your code to use MakeMenu instead.

<AcceleratorTable>

Creates a key accelerator table.

        <AcceleratorTable name='Accel'>
         <Item key='Ctrl-X' sub='Close'/>
         <Item key='Shift-N' sub='New'/>
         <Item key='Ctrl-Alt-Del' sub='Reboot'/>
         <Item key='Shift-A' sub='sub { print "Hello\n"; }'/>
        </AcceleratorTable>
<Window>

The <Window> element creates a top level widget. In addition to standard Win32::GUI::Window attributes it also has a 'show=n' attribute. This instructs XMLBuilder to give the window a Show(n) command on invocation.

        <Window show='0' ... />

NOTE: Since the onResize event is defined automatically for the this element one must set the attribute 'eventmodel' to 'both' to allow <Window_Name>_Event events to be caught!

<DialogBox>

<DialogBox> is very similar to <Window>, except that by default it cannot be resized and it doesn't have the minimize and maximize buttons.

<MDIFrame>

The <MDIFrame> element creates a Multiple Document Interface. It has a similar behaviour to the <Window> attribute. PLease see the MDI.xml sample.

<WGXPanel>

A WGXPanel is a shorthand for a Window element with popstyles WS_CAPTION, WS_SIZEBOX and WS_EX_CONTROLPARENT and pushstyles WS_CHILD, DS_CONTROL and WS_VISIBLE. It is useful for grouping controls together.

        <WGXPanel ...>
         ...
        </WGXPanel>
<TreeView>

Creates a TreeView. These can be nested deeply using the sub element <Item>. Please look at the treeview.pl example in the samples/ directory.

        <TreeView ..>
         <Item .. />
          <Item ..>
           <Item .. />
           <Item .. />
            etc...
          </item>
         ...
        </TreeView>
<Combobox>

Generate a combobox with drop down items specified with the <Items> elements. In addition to standard attributes for Win32::GUI::Combobox there is also a 'dropdown' attribute that automatically sets the 'pushstyle' to 'WS_VISIBLE()|0x3|WS_VSCROLL()|WS_TABSTOP()'. In 'dropdown' mode an <Item> element has the additional attribute 'default'.

<Listbox>

Generate a listbox with drop down items specified with the <Items> elements. In addition to standard attributes for Win32::GUI::Listbox there is also a 'dropdown' attribute that automatically sets the 'pushstyle' to 'WS_CHILD()|WS_VISIBLE()|1'. In 'dropdown' mode an <Item> element has the additional attribute 'default'.

<Rebar>

See rebar.xml example in samples/ directory.

<TabStrip>

A TabStrip can be created using the following structure: -

        <TabStrip ...>
         <Item name='P0' text='Zero'>
          <Label text='Tab 1' .... />
         </Item>
         <Item name='P1' text='One'>
          <Label text='Tab 2' .... />
           ..other elements, etc...
         </Item>
        </TabStrip>

See wizard_tabstrip.xml example in samples/ directory.

<TabFrame>

A TabFrame should behave identically to a TabStrip. TabFrame is no longer supported and will be removed from a future release. Please try to update your code to use TabStrip instead.

<WGXSplitter>

A WGXSplitter can be created using the following structure: -

        <WGXSplitter ...>
         <Item>
          <Label text='Tab 1' .... />
         </Item>
         <Item>
          <Label text='Tab 2' .... />
           ..other elements, etc...
         </Item>
        </WGXSplitter>

The reason this is called a WGXSplitter is because it does not exist as a super-class to a Splitter object. It's width dimension for example holds the complete width of both panes and its splitterwidth ...

See splitter.xml example in samples/ directory.

<Timer>

Allows you to create a timer for use in your program.

        <Timer name='start_thread' elapse='8'/>
Generic Elements

Any widget not explicitly mentioned above can be generated by using its name as an element id. For example a Button widget can be created using: -

        <Button name='B'
         text='Push Me'
         left='20' top='0'
         width='80' height='20'
        />

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 427:

You forgot a '=back' before '=head1'

Around line 513:

You forgot a '=back' before '=head1'

Around line 518:

=over without closing =back