Reference: MSEgui: Difference between revisions

From Free Pascal wiki
Jump to navigationJump to search
 
(60 intermediate revisions by 3 users not shown)
Line 10: Line 10:
=== TMseFormWidget ===
=== TMseFormWidget ===
Use it in order to insert a tcustomform descendant into another widget at designtime. Does not try to load resources in "create".
Use it in order to insert a tcustomform descendant into another widget at designtime. Does not try to load resources in "create".
<pre>
        tmseform descendants ( MainForm, SimpleForm,.. )


=== TDockFormWidget ===
Client area of the form & parent of its widgets ( against which the widgets
=== TPaintbox ===
are placed and colored ) is presented by the "container" property
not "container.frame.clientarea"


How to draw line (or circle) on tpaintbox? In event onpaint:
CanClose is called :


<syntaxhighlight lang=pascal>
- on receiving "ek_close" by window
procedure tmainfo.paintboxonpaint(const sender: twidget; const canvas: tcanvas);
- for modal window, on focus change
begin
  with sender,canvas do begin
  drawline(nullpoint,pointty(size),cl_yellow); 
  //diagonal line across widget
  drawellipse(makerect(makepoint(bounds_cx div 2,bounds_cy div 2), size),cl_red);
  //circle (or ellipse) centered in widget                           
  end;
end;
</syntaxhighlight>
Makepoint and makerect are in msegraphutils.


=== TEventWidget ===
- within parent window's "CanClose" where all nested windows are 
A widget which publishes all possible events of a twidget. Normally it is better to implement your own specialized descendant of an existing widget instead to use teventwidget.
checked for OnCloseQuery & OnClose - if any sets "mr_none" then the parent window
can't close as well
- from nested window's "CanParentClose"
- from own "CanParentClose"


=== TButton ===
- some componnets build oneself in own "Loaded" procedure :
* A rectangular clickable area that can show text/bitmap.
= widget grids
- Main properties:
= database access components
Caption: read/write the text that appear on top of it.
= ...
onexecute: read/write the address of a procedure (event handler) to be executed when clicked.


=== TStockGlyphButton ===
The "form.show" has parameter "transientfor".
=== TRichButton ===
The window Z-order is above the "transientfor" window. The exact behaviour
=== TLabel ===
depends on the window manager.
* Draws a piece of text on the given surface (canvas: screen/printer/bitmap).
       
- Main properties:
        caption
Caption: read/write the piece of text.
- run-time caption on the title bar


See also [[Reference:_MSEgui/TLabel|TLabel]]
color
- color behind the client ( contaner ) area


=== TGroupBox ===
container
=== TStepBox ===
- the real parent of form's widgets, <see "tformscrollbox">
=== TStringDisp ===
*A read only version of TStringEdit, difference from TLabel: has a frame around it.
-Main properties:
Value: read/write the text that are showed.
Caption: A label normally describing the purpose or meaning of the presented text, it can be positioned around the frame.


=== TByteStringDisp ===
cursor
=== TIntegerDisp ===
- the mouse over cursor shape
=== TRealDisp ===
=== TDateTimeDisp ===
=== TBooleanDisp ===
=== TToolBar ===
=== TDrawGrid ===
=== TStringGrid ===
=== TTabBar ===
=== TTabPage ===
=== TTabWidget ===
=== TDockHandle ===
=== TDockPanel ===
=== TSpliter ===
A widget very similar to "tspacer" but :
- designed to rearrange areas occupied by adjacent widgets
- a linked widget may only enlarge by "eating" the opposite one, so the summary area of both widgets don't change
- has GUI look ( hatched grip, color etc) switched on by default
- facilitates run-time repositioning oneself and linked widgets
- linked widgets may even be other splitters, spacers (with their linked widgets ),..


=== TSpacer ===
enabled - "false" disables all child widgets
* a regular widget which creates a kind of positional link between surrounding widgets
* designed to maintain distances between widgets
* may have GUI look, caption etc switched off by default
* resizing a spacer repositions its linked widgets


=== TLayouter ===
face
* a tspacer descendant designed to (auto)resize or/and move its contained widgets acc to some size/positon dependencies
<see "tfacecomp"> + some more options
* may have GUI look, frame caption etc switched off by default
* layouters may be nested to achieve copmplex layouts


Each layout change/assignment is divided into performing 3 consequent stages :
font
<see "tfont">


==== Stage 1 ====
frame
<see "tframecomp"> + some more options
icon
<see "timage">


Widgets auto resized using the following options:
mainmenu
<see tmainmenu>


<pre>
name
- if {lao_placex OR lao_placey} :
- name to refer when programming


= if {plo_scalesize in optionslayout}  then
options:
* widgets with "osk_nopropwith" unset in their "optionsskin" are h-scaled
    in the proportion of change of tlayouter's clientwidth
* widgets with "osk_nopropheight" unset in their "optionsskin" are v-scaled
    in the proportion  of change of tlayouter's clientheight


For h-resized layouter, the effect looks like :
fo_main
- assigns this from as the aplication GUI-face & event receiver
- causes the icon of this form to be icon of the application


|--Widget__1---Widget__2--| => the initial look
fo_terminateonclose
- causes the application to terminate once the form has closed ( doesn't depend on "fo_main" )


  |--Widget_1--Widget_2--| => the layouter gets narrower


  |---Widget___1---Widget___2---| => the layouter gets wider
fo_freeonclose
- causes the form (even being modal) to release its memory on closure or OK-return from "CanClose"


*** both widget sizes & margins are affected ***
fo_defaultpos
*** Widget_N may generally situate on different y-levels ***
- lets the WM to position the form initially
 
otherwise :


= if lao_scalewidth in optionslayout :
fo_screencentered
* widgets with "osk_nopropwith" unset in their "optionsskin" enters in the mode
- causes the form initially to show in center of the apllication work area
  ( not applied until the layouter resizes! ) when they are h-scaled in the proportion
  as far as clientwidth of the tlayouter changes, then stages 2 & 3 are reapplied


For h-resized layouter, the effect looks like :
fo_closeonesc
- causes the form to close on "Esc" key pressed ( with MR_ESCAPE & "OnCloseQuery" firing )


  |--Single____widget????| => the initial look
fo_cancelonesc
- causes the form to close on "Esc" key pressed ( with MR_CANCEL & "OnCloseQuery" firing )


  |--Single__widget???| => the layouter gets narrower
fo_closeonenter
- causes the form to close on "Enter" key pressed ( with MR_OK & "OnCloseQuery" firing )


  |--Single_______widget?????| => the layouter gets wider
fo_closeonf10
- causes the form to close on "F10" key pressed ( with MR_F10 & "OnCloseQuery" firing )


* also, if {lao_scaleleft in optionslayout} then left margins of the widgets
fo_globalshortcuts
  with unset "optionsskin.osk_nopropleft" resize too otherwise retain
- allows on-this-form "ao_globalshortcut" actions to trigger


= if lao_scaleheight in optionslayout :
  Notes :
* widgets with "osk_nopropheight" unset in their "optionsskin" enters in the mode
= shortcuts for modal not "fo_localshortcut" forms are processed by app
  ( not applied until the layouter resizes! ) when they are v-scaled in the proportion
= shortcuts for "fo_globalshorcut" forms are processed by the owning window
    as far as clientheight of the tlayouter changes, then stages 2 & 3 are reapplied


* also, if {lao_scaletop in optionslayout} then top margins of the widgets
fo_localshortcuts
  with unset "optionsskin.osk_noproptop" resize too otherwise retain
- disables triggering shortcuts of on-this-form actions


*** only widget sizes & margins not distances between them are affected ***
fo_autoreadstat
- for "cs_ismodule" forms, before "OnLoaded" fires, rereads all statvars from the bound stafile/memorystream
 
fo_autowritestat
- in "CanClose", after "OnClose" fires [ and before app termination for "fo_terminateonlose" form ],
rewrites all statvars to the stafile/memorystream
- for datamodules, does this before "OnDestroy" fires
 
fo_savepos
- saves/restores Z-order, size & scree coordinates of the form
as soon as the stat data are ready


</pre>
fo_savestate
- for top-level form, saves/restores "VSize", "Active" & "Visible"
as soon as the stat data are ready


==== Stage 2 ====
optionswidget
<see "any widget">
optionswindow
<see "any window">
popupmenu
<see "tpopupmenu">
stafile
<see "tstafile">
stavarname
taborder
tag


Widgets may be auto resized in 5 consequent steps using the following options:
visible - for a form, only affects its childs widgets


<pre>
Events:


1. if plo_syncmaxautosize in place_options :
activate = to set focused & redraw the invalidated area
  = all widgets are autosized then their client areas are synchronised to the
    clientareas of the highest and the widest of the widget
  * calls "msegui.syncmaxautosize"


2. if plo_syncpaintwidth in place_options :
oncreate
  = the paintwidths of all widgets are synchronized to the widget with the
- fires before "Loaded" procedure is called
    widest outer frame width ( ex. width of "frame.caption" )
- fires after creating the widget & its subwidgets but before the final arrangement
  * mainly makes sense if "lao_alignx" set and {align_glue = wam_start or wam_end}
- forms arent' yet visible on return
    ( see below ) when the widgets will be adjusted in order to fit into the
    inner client width of tlayouter:


                                  x-align level         
  Since "Loaded" procedure hasn't yet worked at this point then
                                        V               
database contents, values of widget grid's subwidgets
                        +----------------------------------+
are invalid in this event ***
                        | Widget_1 the_widest_frame_caption|
                        | Widget_2 frame_caption2          |
                        | Widget_N wider_frame_captionN    |
                        +----------------------------------+


  here, the effect is shown for "cp_right" frame captions
onloaded
    // otherwise syncronizes to the outer ( of the frame except its caption ) width
- fires once "Loaded" procedure of owns & all form's widgets finishes
    // of the Z-top widget
- processed  after "OnCreate"
  * calls "msegui.syncpaintwidth"
- on finishing, forms aren't yet visible
  * paintwidth is the outer width


3. if plo_syncpaintheight in place_options :
oneventloopstart ( main forms only )
  = the paintheights of all widgets are synchronized to the widget with the
- only applicable to main forms
    highest outer frame width ( ex. width of "frame.caption" ).
- fires once all application GUI is built and shown
  * mainly makes sense if lao_aligny set and {align_glue = wam_start or wam_end}
( and ready to user's interaction )
    ( see below ) the widgets will be adjusted in order to fit into the inner
    client height of tlayouter :
onactivate
- see {any_widget.OnActivate}
 
onenter
= see {any_widget.OnEnter}


                        +------------------------------+
onfocus
                        | The_                        |
- see {any_widget.OnFocus}
                        | tallest_            taller_  |
                        | frame_    frame_    frame_  |
                        | caption  caption2  captionN | 
                        |                              |
                        | Widget1  Widget_2  Widget_N |<== y-align level
                        +------------------------------+   


  here, the effect is shown for "cp_topleft" frame captions
onwindowactivechanged
    // otherwise syncronizes to the outer ( of the frame except its caption )
- fires on :
    // height of the Z-top widget
= touching another window even on clicking in a behind-modal window ( or its title bar )
  * calls "msegui.syncpaintheight"
= 1-st showing the window
- reactivating the window
4. plo_synccaptiondistx in place_options :
  = causes all widgets to have the widest common room for their cp_(left/right)* frame captions
  * calls "msegui.synccaptiondistx"
5. plo_synccaptiondisty in place_options :
  = causes all widgets to have the highest common room for their cp_(top/bottom)* frame captions
  * calls "msegui.synccaptiondisty"
</pre>


==== Stage 3 ====
onbeforepaint
- fires at the very beginning of "paint", before drawing canvas


The widgets may be (re)arranged within the layouter.
onpaint
- fires in "paint" procedure, between drawing canvas and contained widgets


<pre>
onafterpaint (doafterpaint)
There're 2 modes of such (re)arrangement which can be partially (orthogonally)
- fires just on return from "paint" procedure
combined (see later):


1) The place(ment) mode ( lao_place* in optionslayout ) :
        onapplicationactivechanged
- fires :
= if the application gets/looses input focus


- widgets are placed at some distances between each other, possibly with some
onasyncevent (doasyncevent)
  margins, rooms of invisible widgets ( having visible=false) are also allocated
- fires on calling {this_form}.asyncevent(atag) from any place of the application
  unless "plo_noinvisible in place_options"
once delivered by the app even queue
 
"atag" set by caller(s) helps to branch within "onasyncevent", to identify the caller, etc ***
generally, doesn't fire instantly because these events are delivered through the app event queue ***
 
 
onchildmouseevent
- fires on any mouse activity over its child widget(s) not the (containing) widget oneself
 
      for forms, it even fires on enetering "container" therefore it appears as if to be the form itself ***
 
onchildscaled
- see {any_widget.OnChildScaled}
 
onclientmouseevent
- fires on any mouse activity over areas expecting user's mouse input (not titlebars/frames/...)
 
onclose
- fires in "CanClose" if "modalresult <> mr_none"
 
onclosequery
- fires in "CanClose" before "OnClose"
- "mr_none" set on return prevents the window (and its parent) from closing
( "OnClose" is also bypassed )
 
 
ondeactivate
- see {any_widget.OnDeactivate}
 
ondefocus
- see {any_widget.OnDeFocus}
ondestroy
- fires on in-code calling "BeforeDestruction"
 
ondestroyed
- fires on return from the form's destructor ( when all resources are freed )
 
onterminatequery
- fires on an attempt to terminate the app
- by setting "var terminate:= false", allows to cancel termination
 
Termination by debugger/OS facilities can't be blocked this way ( win32 )***


  * the widgets are placed in the order of decreasing their "widgetrect.x"
onterminated
coordinates before alignment
- fires for not-yet-destroyed forms, once the app event loop finishes
 
- may be caused by any closure of the main app form
  * the inter-widget distances and the side margins ( if apllied ) in both
( app termination, WM/OS facilities, )
dimentions are identical and limited between "place_mindist" and
 
"place_maxdist"
 
 
onwindowdestroyed
  = if {lao_placex in optionslayout} and {place_mode <> wam_none} then the
- fires once a descendant window is destroyed
following relevant settings apply:
( for a main form, when a modal simple form is closed by any way,.. )
 
 
* non-limiting value of "place_maxdist" :
onevent
- fires on receiving an event
# |Widget_1------Widget_2------Widget_3|
= for simple forms, it's only "ek_loaded"
 
* non-limiting value of "place_maxdist" and {plo_propmargin in place_options} :
There can be more if the form is connected to object_event sending
components or if the application uses object events, for example by calling
# |---Widget_1---Widget_2---Widget_3---|
tguicomponent.postcomponentevent. ****
 
* limiting value of "place_maxdist" and {place_mode = wam_start} :
onexit
- see {any_widget.OnExit}
# |Widget_1----Widget_2----Widget_3????|
 
onfocusedwidgetchanged
* limiting value of "place_maxdist" and {place_mode = wam_start} and
- for a "prev-new" parent-wide focused wigdets pair, fires once installing new focus has finished,
  {plo_propmargin in place_options} :
after "OnFocus"
- resends for all contained widgets
# |---Widget_1---Widget_2---Widget_3???|
- doesn't fire if the "prev-new" pair don't really change
 
* limiting value of "place_maxdist" and {place_mode = wam_end} :
onfontheightdelta
- see {any_widget.OnFontHeightDelta}
# |??????Widget_1---Widget_2---Widget_3|
 
onhide
* limiting value of "place_maxdist" and {place_mode = wam_end} and
- fires at beginnig of own/parent's
  {plo_propmargin in place_options} :
= hide
= hidden
# |???Widget_1---Widget_2---Widget_3---|
= destroying
= setting "visible:= false"
* limiting value of "place_maxdist" and {place_mode = wam_center} :
= closing the window ( receiving event "ek_close",.. )
= calling "window.close"
# |???Widget_1---Widget_2---Widget_3???|
onidle
* limiting value of "place_maxdist" and {plo_endmargin in place_options} :
- fires everytime when the app GUI event queue gets empty
- to stop calling for a while, set "again" parameter to "false" (the initial value );
# |Widget_1----Widget_2----Widget_____3|, or
DON'T DO ANYTHING AFFECTING THE APP EVENT QUEUE ( MODAL WINDOWS, "ShowMessage", Sleep(N),... ) IN THIS HANDLER.
# |Widget_1----Widget_____2----Widget_3|, or
MODAL WINDOWS CAUSE RECURSION !
# |Widget_____1----Widget_2----Widget_3|, here, the most left amongst
A code fragment:
widgets having both [an_left,an_right] set is expanded otherwise the most
 
right widget ( Widget_3 in the example )
again:= i < 5;
if not again then exit;
* limiting value of "place_maxdist" and {place_mode = wam_end} and
 
  {plo_propmargin in place_options} and {plo_endmargin in place_options} :
onkeydown
 
- fires on pressing down a keyboard key over the client area when none of child widgets is focused
# |--Widget_1--Widget_____2--Widget_3--|,
 
 
onkeyup
The Legend:
- fires on releasing a keyboard key over the client area when none of child widgets is focused
===========
 
limiting value of "place_maxdist" : such value which produce some visual
onmouseevent
effect on the layouter
- fires on any mouse activity over the client area
 
  "----" :          distance ( = number of minuses, limited by place_maxdis )
onmove
  "????" :          some remaining space ( = number of questmarks )
- see {any_window.OnMove}
  "Widget_1" :      widget of the original size
 
  "Widget__..__1" : (auto)resized widget
onpopup
 
- see {any_widget.OnPopup}
  = if {lao_placey in optionslayout} and {place_mode <> wam_none} then the things
 
are handled in the same manner as with "lao_placex" but for the vertical
onresize
"top2bottom" direction of placement instead of the horizontal "left2right" one.
- see {any_widget.OnResize}
 
onshortcut
- fires before built-in shorcut processing
- "info.eventstate=es_processed" set in "OnShortcut" prevents
the event from further auto-processing
 
The app
- recognizes & takes registered shortcuts from app event queue
- passes the shocrcut event to each of its windows until the event
is processed otherwise processes it by oneself
 
onshow
- fires if the widget is visible:
= on calling "Show" method
= on return from "Loaded" procedure
= on showing the parent widget
- since called at end, allows to adjust the default behavior
 
onshowhint
- see {any_widget.OnShowHint}
 
onstatbeforeread
- fires before loading statvars  from the disk file
 
onstatafterread
- fires once statvars are loaded from the disk file
 
onstatupdate
- fires at 1-st stage before updating GUI "state/pos" for read statvars
or
- fires at pre-last stage before saving GUI "state/pos"
 
onstatread
- fires at 2-nd stage before updating GUI "state/pos" for read statvars
 
onstatwrite
- fires at last stage before saving GUI "state/pos"
 
pon stat reading, non-minimized visible windows are shown,  
the active window is activated
 
</pre>
=== TDockFormWidget ===
=== TPaintbox ===
 
How to draw line (or circle) on tpaintbox? In event onpaint:


2) the align(ment) mode ( optionslayout.lao_align* ) :
<syntaxhighlight lang=pascal>
 
procedure tmainfo.paintboxonpaint(const sender: twidget; const canvas: tcanvas);
- widgets are gathered into a visual group to a dedicated "leader" widget of
begin
  the layout ( set by "align_leader" and defaults to the lowest in
  with sender,canvas do begin
  Z-Order = twidget.widgets[0] ) the leader stays in place while the others :
  drawline(nullpoint,pointty(size),cl_yellow)
 
  //diagonal line across widget
  = if lao_alignx in optionslayout ( the hor alignment mode ):
  drawellipse(makerect(makepoint(bounds_cx div 2,bounds_cy div 2), size),cl_red);
  * if align_mode = wam_start :
  //circle (or ellipse) centered in widget                           
snap their left borders to the left border of leader
  end;
  * else if align_mode = wam_end :
end;
snap their right borders to the right border of leader
</syntaxhighlight>
  * else if align_mode = wam_center :
snap their v-axes to the v-axis of leader after that,
Makepoint and makerect are in msegraphutils.
  = if lao_aligny in optionslayout ( the vert alignment mode ):
  * if align_mode = wam_start :
snap their top borders to the top border of leader
  * else if align_mode = wam_end :
snap their bottom borders to the bottom border of leader
  * else if align_mode = wam_center :
snap their h-axes to the h-axis of leader


- after that, the whole widget group can be aligned within the layouter:
=== TEventWidget ===
A widget which publishes all possible events of a twidget. Normally it is better to implement your own specialized descendant of an existing widget instead to use teventwidget.


  = if align_glue = wam_start
=== TButton ===
  * if lao_alignx in optionslayout:
* A rectangular clickable area that can show text/bitmap.
the left extent of group snaps to the left border of layouter
- Main properties:
  * if lao_aligny in optionslayout:
  Caption: read/write the text that appear on top of it.
the top extent of group snaps to the top border of layouter
onexecute: read/write the address of a procedure (event handler) to be executed when clicked.
  = else if align_glue = wam_end
  * if lao_alignx in optionslayout:
the right extent of group snaps to the right border of layouter
  * if lao_aligny in optionslayout:
the bottom extent of group snaps to the bottom border of layouter
  = else if align_glue = wam_center
  * if lao_alignx in optionslayout:
the v-axis of group snaps to the v-axis of layouter
  * if lao_aligny in optionslayout:
the h-axis of group snaps to the h-axis of layouter


Mutually exclusive settings:
=== TStockGlyphButton ===
* only one of "align_mode" can be choosen
=== TRichButton ===
* only one of "glue_mode" can be choosen
=== TLabel ===
* "optionslayout.lao_alignx" & "optionslayout.lao_placex"
* Draws a piece of text on the given surface (canvas: screen/printer/bitmap).
* "optionslayout.lao_aligny" & "optionslayout.lao_placey"
- Main properties:
Caption: read/write the piece of text.


V-alignment ( optionslayout.lao_aligny ) may be combined with h-placement
See also [[Reference:_MSEgui/TLabel|TLabel]]
( optionslayout.lao_placex ), and h-alignment ( optionslayout.lao_alignx ) may
be combined with v-placement ( optionslayout.lao_placey )


NOTE:
=== TGroupBox ===
  The effects of the above described { resizing / placement / alignment } are
=== TStepBox ===
  irreversible. So, the only way to revert is to set "wan_none" then to revert
=== TStringDisp ===
  manually.
*A read only version of TStringEdit, difference from TLabel: has a frame around it.
</pre>
-Main properties:
Value: read/write the text that are showed.
Caption: A label normally describing the purpose or meaning of the presented text, it can be positioned around the frame.


=== TListView ===
=== TByteStringDisp ===
=== TImage ===
=== TIntegerDisp ===
=== TRealDisp ===
=== TDateTimeDisp ===
=== TBooleanDisp ===
=== TToolBar ===
=== TDrawGrid ===
=== TStringGrid ===
=== TTabBar ===
=== TTabPage ===
=== TTabWidget ===
=== TDockHandle ===
=== TDockPanel ===
=== TSpliter ===
<pre>
<pre>
<any image>
      A widget very similar to "tspacer" but :
- designed to rearrange areas occupied by adjacent widgets
- a linked widget may only enlarge by "eating" the opposite one,
so the summary area of both widgets don't change
- has GUI look ( hatched grip, color etc) switched on by default
- facilitates run-time repositioning oneself and linked widgets
- linked widgets may even be other splitters, spacers (with their linked widgets ),..
        Properties:


*** Note that switch to the monochrome mode is irerreversible ! ***
- color
= see {any_widget.color}


alignment:
- cursor
= see {any_widget.cursor}


By default, images are top-left aligned, with the original size preserved.
- enabled
= "false" stops user interaction


al_xcentered = centers the image horizontally
- face
al_ycentered = centers the image vertically
= see {any_face}


al_right = docks the image to the right border of placeholder
- frame
al_bottom = docks the image to the bottom border of placeholder
= see {any_frame}


al_grayed = fills non-transparent areas with the selected color
- colorgrip
= color of grip hatching


al_stretchx = adjusts size so that to fill the placeholder in width
- grip
al_stretchy = adjusts size so that to fill the placeholder in height
= defines hatching pattern of the grip
al_fit = adjusts size so that to fill the placeholder in both width & height


al_tiled = spawns the image & tile the whole  placeholder with the copies
* stb_dens(N) : the pattern is of rhombuses, the painted rhombs occupy "N" persents of the grip


Interpolation mode while stretching
* stb_block(N) : the pattern is of squares, painted & unpainted squares are equally sized and
both have "N" pixels sides
* stb_hatchup(N) : the pattern is of right-tilted lines of 1 pixel width,
each "N"-th pixel forms these lines


al_intpol = antialiases as far as the size changes
* stb_hatchdown(N) : the pattern is of left-tilted lines of 1 pixel width,
(the only working in Linux)
each "N"-th pixel forms these lines
al_or = interpolation pixel operation is "or" -> 1's are extended
al_and = interpolation pixel operation is "and" -> 0's are extended
( al_or and al_and only on win32, mainly useful for stretching of monochrome bitmaps) :


colorbackground = color of image transparent ( masked ) areas in monochrome
* stb_crosshatch(N) : the pattern is of crossing (left & right) tilted lines of 1 pixel width,
non-masked mode
each "N"-th pixel forms these lines
colorforeground = color of non-transparent areas in monochrome mode 


options:


bmo_monochrome = fills non-transparent areas with "colorforeground",
- linkbottom/linkleft/linkright/linktop
also, in non-masked mode, fills transparent areas
= see {tspacer.*}
with "colorbackground"


bmo_masked = activates built-in image transparency {it "hides" transparent (masked) areas}
- options
bmo_colormask = applies faded edge transparency on the color masked areas in the image


transparency = makes the image transparent as long as enlights areas behind
= spo_hmove
the image with the selected color
* "true" allows the spliter to move horizontally


transparentcolor = for a non-masked image, assigns a color indicate transparency areas
= spo_hprop
( on matching areas, the image will be seen through )
* "true" : keep the left position proportional ( on the ratio of creation time )  
<pre/>
to weigth of the client area of parent


=== TDial ===
= spo_hsizeprop
=== TChart ===
* "true" : keep width of the spacer proportional ( on the ratio of creation time )
=== TChartRecorder ===
to weigth of the client area of parent
=== TPolygon ===
* the width stops shrinking on one set in design time
=== TPickWidget ===
=== TOpenglWidget ===


== Edit ==
= spo_vmove
=== TStringEdit ===
* "true" allows the spliter to move vertically
=== TMemoEdit ===
=== THexStringEdit ===
=== TDropdownListEdit ===
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
- deo_autodropdown dropdown on keypress
- deo_selectonly don't allow entering arbitrary text.
- deo_forceselect don't allow entering empty text.


=== THistoryEdit ===
= spo_vprop
A tstringedit which shows the previously entered values in a dropdownlist for selection.
* "true" : keep the top position proportional ( on the ratio of creation time )
to height of the client area of parent


=== TIntegerEdit ===
= spo_vsizeprop
=== TKeyStringEdit ===
* "true" : keep height of the spacer proportional ( on the ratio of creation time )
Maps string to string.
to height of the client area of parent
* the height stops shrinking on one set in design time


=== TEnumEdit ===
= spo_dockleft
Maps integer to string, zero based and sequencial (first item 0, next 1, ...).
* causes the "linkleft" widget to dock to the left border of splitter
* make sence only if linkleft "widget.bounds_x" less than "splitter.bounds_x"


=== TEnumTypeEdit ===
= spo_docktop
A tenumedit which maps Pascal enums to their names. Use oninit to store the typeinfo pointer of the enum type into sender.typeinfopo.
* causes the "linktop" widget to dock to the top border of splitter
* make sence only if linktop "widget.bounds_y" less than "splitter.bounds_y"


=== TSelector ===
= spo_dockright
TSelector  is the most specialized widget of the dropdown editwidget group, it is based on tenumedit (tenumedit maps an integer to a string) and uses for the dropdownlist a second map which must be created on the fly in ongetdropdowninfo. An example is tcommselector where the enumedit maps commnrty to commname and the dropdownlist shows the available RS232 ports
* causes the "linkright" widget to dock to the right border of splitter
only.
* make sence only if linkright "widget.(bounds_x+bounds_cx)" more than "splitter.(bounds_x+bounds_cx)"


=== TRealEdit ===
= spo_dockbottom
=== TRealSpinEdit ===
* causes the "linkbottom" widget to dock to the bottom border of splitter
=== TDateTimeEdit ===
* make sence only if linkbottom "widget.(bounds_y+bounds_cy)" more than "splitter.(bounds_y+bounds_cy)"
=== TCalendarDateTimeEdit ===
=== TEdit ===
MSEgui counterpart of Delphi TEdit. You will never use it.


=== TWidgetGrid ===
!!! Two special cases :
=== TItemEdit ===
=== TDropDownItemEdit ===
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
- deo_autodropdown dropdown on keypress
- deo_selectonly don't allow entering arbitrary text.
- deo_forceselect don't allow entering empty text.


=== TMBDropDownItemEdit ===
1. (spo_dockleft = spo_dockright = TRUE) && (linkleft = linkright = the_same_widget) :
=== TTreeItemEdit ===
causes the "linkleft" widget to adjust to h-positiion & width of the splitter,
=== TRecordFieldEdit ===
it's even possible that the widget doesn't touch the splitter
Used in twidgetgrid in order to edit fields of a ttreeitemedit. Example is MSEide projecttreeform.pas.


=== TDialogStringEdit ===
(spo_docktop = spo_dockbottom = TRUE) && (linktop = linkbottom = the_same_widget) :
A tstringedit with an ellipse button. Use "onexecute" to show the dialog.
causes the "linktop" widget to adjust to v-position & height of the splitter,


=== TPointerEdit ===
It's even possible in these cases that the widget doesn't touch the splitter
=== TSlider ===
=== TProgressBar ===
=== TBooleanEdit ===
=== TBooleanEditRadio ===
=== TDataButton ===
A button with an integer value. Clicking increments the value until "max", then it restarts with "min". Can be inserted into a twidgetgrid. The current value selects the showed image and face by the items of "imagenums" and "valuefaces".


=== TStockGlyphDataButton ===
- optionsscale
=== TDataIcon ===
= see {tscalingwidget.optionsscale}
Shows an imagelist item by lookup from "value" to "imagenums". Clicking increments value until "max" then it restarts with "min". Can be inserted into a twidgetgrid.


=== TTextEdit ===
- optionswidget
Only useful if inserted into a twidgetgrid, builds a text editor, used in MSEide source editor.
= see {anywidget.optionswidget}


=== TDataImage ===
- onactivate, onchildscaled, ondeactivate, ondefocus, onenter, onexit, onfocus,
A pixmap display widget which can be inserted into twidgetgrid.
  onfontheightdelta, onmove, onpopup, onresize, onshowhint
= see "tspacer"


=== TTerminal ===
- onupdatelayout
Only useful if inserted into a twidgetgrid, builds a very simple terminal emulator. Used in MSEide target console.
fires :
= on creating the splitter
= on any reposition of the linked widgets
( due to moving the splitter, resizing the parent,.. )
</pre>


== Properties for all widgets ==
=== TSpacer ===
<pre>
* a regular widget which creates a kind of positional link between surrounding widgets
* designed to maintain distances between widgets
* may have GUI look, caption etc switched off by default
* resizing a spacer repositions its linked widgets


name
Properties:


anchors
- anchors
= see {any_widget.anchors}


-----------
- bounds
= see {any_widget.bounds}
 
- color
= see {any_widget.color}
 
- enabled
= "false" turns color of the caption to gray


- they control of design/runtime sticking widgets to their parents
- visible
= "true" allows displayable settings (caption text, face, frame etc) to take
effect in run-time as well
- <face>
= see {any face}


- dimention pair ( top/bottom or left/right ) both set to "false" cause
- <frame>
the widget to fit the parent's client area in that dimention;
= see {any frame}
this effect may be partial in case of "bounds_c*max" settings limit the extents


*** Return to the look "before dimention fit" is only possible by manual resizing or setting "bounds_*"
- linkbottom
-----------
= widget linked down to most outer edge (incl. frame[.caption]) of the spacer
an_left
- linkleft
- on run-time, resizes/shifts left the widget to keep the design-set distance
= widget linked left to most outer edge of the spacer
between the widget's left border and the left side of parent's client area
- linkright
as the parent resizes, until scrolling begins
= widget linked right to most outer edge of the spacer
- linktop
= widget linked up to most outer edge of the spacer


an_top
- dist_bottom, dist_left, dist_right, dist_top :
- on run-time, resizes/shifts up the widget to keep the design-set distance
= margins between most outer edge the spacer
between the widget's top border and the upper side of parent's client area
and the corresponding linked widget
as the parent resizes, until scrolling begins


an_right
- options :
- on run-time, resizes/shifts right the widget to keep the design-set distance
between the widget's right border and the right side of parent's client area
as the parent resizes, until scrolling begins


an_bottom
= spao_glueright
- on run-time, resizes/shifts down the widget to keep the design-set distance
between the widget's bottom border and the lower side of parent's client area
as the parent resizes, until scrolling begins


bounds
  - if "false"


cx - width of the widget
h-repositioning or h-resizing the linkleft widget shifts
cxmax, cxmin - design/runtime width of the widget is enforced between "cxmax" and "cxmin"
the whole linked construction, it becomes the only way to h-shift
cy - height of the widget
 
cymax, cymin - design/runtime height of the widget is enforced between "cymax" and "cymin"
if {an_right IN linkright_widget.anchors} then the spacer
x - distance between the widget's left border and the left side of parent's client area
may be right-resized with auto h-resizing the linkright widget  
y - distance between the widget's top border and the upper side of parent's client area
so that the right margin of that widget is kept


if NOT {an_right IN linkright_widget.anchors} then the spacer
may be right-resized with auto h-shifting the linkright widget
so that width of that widget is kept


autosize
- if "true"


-----------
h-repositioning or h-resizing the linkright widget shifts
- only appliable to widgets with "ow_autosize" set
the whole linked construction, it becomes the only way to h-shift
- the effect may be partial in case when "bounds_c*max" settings limit the extents
-----------


cx - addition to width of the widget (with h-centering post applied)
if {an_left IN linkleft_widget.anchors} then the spacer
cy - addition to height of the widget (with v-centering post applied)
may be h-resized with auto h-resizing the linkleft widget
so that the left margin of that widget is kept


- color
if NOT {an_left IN linkleft_widget.anchors} then the spacer
= the default color of client area & caption text background
may be h-resized with auto h-shifting the linkleft widget
= may be overwtitten:
so that width of that widget is kept
* the client area - with "frame.colorclient"
* the caption BG - with "frame.font.colorbackground"


- font
= spao_gluebottom
= see {any font}


- frame
- if "false"
= see {any frame}


- face
v-repositioning or v-resizing the linktop widget shifts
= see {any face}
the whole linked construction, it becomes the only way to v-shift


- hint
if {an_bottom IN linkbottom_widget.anchors} then the spacer
= descriptive text appearing when mouse pointer enters the widget
may be v-resized with auto v-resizing the linkbottom widget
so that the bottom margin of that widget is kept


- cursor
if NOT {an_bottom IN linkbottom_widget.anchors} then the spacer
= shape of the mouse pointer over the client area of widget (run-time only)
may be v-resized with auto v-shifting the linkbottom widget
so that height of that widget is kept


- visible
- if "true"  
= "true" allow the widget to appear ( run-time only )


- enabled
        v-repositioning or v-resizing the linkbottom widget shifts
= "true" allows the widget to participate in GUI interaction
the whole linked construction, it becomes the only way to v-shift
= "false" disallows the widget & its childs :
* processing all events & shortcuts & menu calls
* auto "CanClose" check


Also "false" usually aints the widget in color marking
if {an_top IN linktop_widget.anchors} then the spacer
the "disabled" state ( usually light gray font color )
may be v-resized with auto v-resizing the linktop widget  
so that the top margin of that widget is kept


- popupmenu
if NOT {an_top IN linktop_widget.anchors} then the spacer
= reference to a preset tpopupmenu widget serving the right-click menu
may be v-resized with auto v-shifting the linktop widget
so that height of that widget is kept


- taborder
- optionsscale
- {0..N} order number when TAB-key cycling through widgets in the container
= see {tscalingwidget.optionsscale}


- tag
- optionswidget
- an integer value bound to this widget instance
= see {anywidget.optionswidget}


- helpcontext
- onactivate, onchildscaled, ondeactivate, ondefocus, onenter, onexit, onfocus,
= a string returned by "(active/mouse)helpcontext" methods of the owning form
  onfontheightdelta, onpopup, onresize, onshowhint
  when this widget is focued or under mouse in the active window
= see {any_widget.*}


- zorder
- onmove
= reading: finds the current Z-order of the widget's window
= see {any_window.OnMove}
= setting: if the value = 0 then lowers the widget's window in the stacking hierarchy, otherwise rises


any "link*" option set disables the spacer to reposition solely,
repositioning is only controlled by a "glued" widget since then


optionswidget:
=== TLayouter ===
* a tspacer descendant designed to (auto)resize or/and move its contained widgets acc to some size/positon dependencies
* may have GUI look, frame caption etc switched off by default
* layouters may be nested to achieve complex layouts


ow_background
Each layout change/assignment is divided into performing 3 consequent stages :
- keeps the window/widget on bottom of the Z-order stack.


ow_top
==== Stage 1 ====
- keeps the window/widget in foreground


ow_noautosizing
Widgets auto resized using the following options:
- when docking, not to resize for the docking area


ow_mousefocus
<pre>
- "false" here disables focusing the widget with mouse
- if {lao_placex OR lao_placey} :
  ( and "OnFocus" doesn't fire on mouse clicks )


ow_tabfocus
= if {plo_scalesize in optionslayout}  then
- "false" here disables focusing the widget with "TAB" key
* widgets with "osk_nopropwith" unset in their "optionsskin" are h-scaled
  ( and "OnFocus" doesn't fire on TAB pressed )
    in the proportion of change of tlayouter's clientwidth
* widgets with "osk_nopropheight" unset in their "optionsskin" are v-scaled
    in the proportion  of change of tlayouter's clientheight


ow_parenttabfocus
For h-resized layouter, the effect looks like :
- enters the childs on TAB-focusing then returns to the widget after
sequential TAB-ing through its child widgets,
otherwise TAB-ing cycles on the childs if entered


ow_arrowfocus
|--Widget__1---Widget__2--| => the initial look
- allows the widget ( and its childs in turn ) to be focused with
the arrow keys


ow_subfocus, ow_arrowfocusin, ow_arrowfocusout
  |--Widget_1--Widget_2--| => the layouter gets narrower
- in case of arrow keys focusing enabled for child-containing widget,
determine behaviour on entering & leaving the widget, see the below table:


ow_subfocus | ow_arrowfocusin | ow_arrowfocusout | effect
  |---Widget___1---Widget___2---| => the layouter gets wider


  FALSE          FALSE            FALSE        entering-/leaving-
*** both widget sizes & margins are affected ***
  FALSE          FALSE            TRUE          entering-/leaving+
*** Widget_N may generally situate on different y-levels ***
  FALSE          TRUE              FALSE        entering(nearest)+/leaving-
 
  FALSE          TRUE              TRUE          entering(nearest)+/leaving+
otherwise :
  TRUE            FALSE            FALSE        entering(last focused)+/leaving-
  TRUE            FALSE            TRUE          entering(last focused)+/leaving+
  TRUE            TRUE              FALSE        entering(nearest)+/leaving-
  TRUE            TRUE              TRUE          entering(nearest)+/leaving+


- "entering" is focusing on a child within the widget
= if lao_scalewidth in optionslayout :
- "leaving" is return from last child onto the widget's level
* widgets with "osk_nopropwith" unset in their "optionsskin" enters in the mode
- "nearest" is the child closest on the arrow direction
  ( not applied until the layouter resizes! ) when they are h-scaled in the proportion
- "last focused" is the child focused on last leaving the widget
  as far as clientwidth of the tlayouter changes, then stages 2 & 3 are reapplied
*** The Up/Down arrow keys can leave from the childs circle,  
but Left/Right can only toggle between the childs ***


*** mouse entering/leaving isn't controllable by these options
For h-resized layouter, the effect looks like :


  |--Single____widget????| => the initial look


ow_focusbackonesc
  |--Single__widget???| => the layouter gets narrower
- on pressing "Esc", returns input focus to the previously focused widget


ow_noparentshortcut
  |--Single_______widget?????| => the layouter gets wider


*** disables processing of delegated ( from the parent ) shortcuts ***
* also, if {lao_scaleleft in optionslayout} then left margins of the widgets
  with unset "optionsskin.osk_nopropleft" resize too otherwise retain


- "true" here disables processing shortcuts if they're delegated
= if lao_scaleheight in optionslayout :
from the parent widget ( obviously, not processed by the parent )
* widgets with "osk_nopropheight" unset in their "optionsskin" enters in the mode
  ( not applied until the layouter resizes! ) when they are v-scaled in the proportion
    as far as clientheight of the tlayouter changes, then stages 2 & 3 are reapplied


ow_nochildshortcut
* also, if {lao_scaletop in optionslayout} then top margins of the widgets
  with unset "optionsskin.osk_noproptop" resize too otherwise retain


*** disables delegating shortcuts to the parent for taking desision ***  
*** only widget sizes & margins not distances between them are affected ***


- if "true" then the widget tries to process it by oneself
</pre>
otherwise it's passed to the parent widget for further chaining


*** A shortcut can only be processed once ( by one widget ) ***
==== Stage 2 ====


ow_canclosenil
Widgets may be auto resized in 5 consequent steps using the following options:
- "true" here allows to continue even if there's contained widget(s)
not passing "CanClose" check


ow_mousetransparent
<pre>
- "true" here causes the widget oneself ( not its contained ones )
not to react to mouse events ( just allow them through to the childs )


ow_mousewheel
1. if plo_syncmaxautosize in place_options :
- enables/disables {scrolling/navigating} with wheel of ImPS/2 etc mouse
  = all widgets are autosized then their client areas are synchronised to the
    clientareas of the highest and the widest of the widget
  * calls "msegui.syncmaxautosize"


ow_noscroll
2. if plo_syncpaintwidth in place_options :
- don't use screen image scrolling for twidget.scrollrect,
  = the paintwidths of all widgets are synchronized to the widget with the
redraw the whole scrolled widget rectangle instead;
    widest outer frame width ( ex. width of "frame.caption" )
sometimes needed with background fades.
  * mainly makes sense if "lao_alignx" set and {align_glue = wam_start or wam_end}
    ( see below ) when the widgets will be adjusted in order to fit into the
    inner client width of tlayouter:


ow_nochildpaintclip
                                  x-align level         
-  
                                        V               
                        +----------------------------------+
                        | Widget_1 the_widest_frame_caption|
                        | Widget_2 frame_caption2          |
                        | Widget_N wider_frame_captionN    |
                        +----------------------------------+


ow_destroywidgets
  here, the effect is shown for "cp_right" frame captions
- "true" here causes calling "free" for all containing widgets as well
    // otherwise syncronizes to the outer ( of the frame except its caption ) width
    // of the Z-top widget
  * calls "msegui.syncpaintwidth"
  * paintwidth is the outer width


ow_hinton
3. if plo_syncpaintheight in place_options :
- to show the hint even in case of hinting is disabled on the parent
  = the paintheights of all widgets are synchronized to the widget with the
( "parent.ow_hintoff= true & parent.ow_hinton= false" )
    highest outer frame width ( ex. width of "frame.caption" ).
  * mainly makes sense if lao_aligny set and {align_glue = wam_start or wam_end}
    ( see below ) the widgets will be adjusted in order to fit into the inner
    client height of tlayouter :


ow_hintoff
                        +------------------------------+
- "true" here combined with "ow_hinton=false" fully disables displaying the hint
                        | The_                        |
                        | tallest_            taller_  |
                        | frame_    frame_    frame_  |
                        | caption  caption2  captionN | 
                        |                              |
                        | Widget1  Widget_2  Widget_N |<== y-align level
                        +------------------------------+   


ow_multiplehint
  here, the effect is shown for "cp_topleft" frame captions
- "true" here causes the widget to redisplay its hint on each {>3px} move within the widget oneself
    // otherwise syncronizes to the outer ( of the frame except its caption )
 
    // height of the Z-top widget
*mse ow_timedhint
  * calls "msegui.syncpaintheight"
- "true" here causes hint of the widget to disappear after a timed inteval (about 2 secs by default)
 
4. plo_synccaptiondistx in place_options :
ow_fontlineheight (design-time only)
  = causes all widgets to have the widest common room for their cp_(left/right)* frame captions
- causes "extraspace" of the last text line to be drawn,
  * calls "msegui.synccaptiondistx"
in turn it causes adjustment of widget height if "ow_autoscale" is set
5. plo_synccaptiondisty in place_options :
*** makes sence only if "ow_autoscale=true" & ow_autosize=false & "extraspace <> 0" ***
  = causes all widgets to have the highest common room for their cp_(top/bottom)* frame captions
  * calls "msegui.synccaptiondisty"
</pre>


ow_fontglyphheight (design-time only)
==== Stage 3 ====
- causes only interline "extraspace"-s to be drawn, opposite to "ow_fontlineheight"


ow_autoscale (design-time only)
The widgets may be (re)arranged within the layouter.
- causes that if the contents change (design OR run-time) so that its' height changes
then the widget will be v-scaled as well


ow_autosize (design-time only)
<pre>
- causes that widget's heigh & width & client area adjust so that to provide space for contents of the client area
There're 2 modes of such (re)arrangement which can be partially (orthogonally)
- no desing-time change of height/width are possible as long as this option is in effect
combined (see later):


ow_autosizeanright
1) The place(ment) mode ( lao_place* in optionslayout ) :
- when autosizing & {an_right isn't set}, the design-set right margin against the parent is preserved


ow_autosizeanbottom
- widgets are placed at some distances between each other, possibly with some
- when autosizing & {an_bottom isn't set}, the design-set bottom margin against the parent is preserved
  margins, rooms of invisible widgets ( having visible=false) are also allocated
  unless "plo_noinvisible in place_options"


optionsskin:
  * the widgets are placed in the order of decreasing their "widgetrect.x"
 
coordinates before alignment
- osc_noskin
 
- osc_framebuttononly
  * the inter-widget distances and the side margins ( if apllied ) in both
- osc_container
dimentions are identical and limited between "place_mindist" and
 
"place_maxdist"
 
 
Methods:
  = if {lao_placex in optionslayout} and {place_mode <> wam_none} then the
 
following relevant settings apply:
  // tmsecomponent
 
 
* non-limiting value of "place_maxdist" :
// (re)draws the widget according to the related skin if apllicable;
//
// also called internally by "loaded" procedure ( before "OnLoaded" code ),
// by ShowMessage ( for the internal widgets of the message dialogue ),
// when creating tab & form & menu widgets
procedure updateskin(const recursive: boolean = false);
 
// TRUE if the instance is created but not yet ready
// for interaction & accessing data & appearance change & receiving events etc
// ( the stage between firing "OnCreate" & "OnLoaded" )
function loading: boolean;
{$ifdef FPC}
# |Widget_1------Widget_2------Widget_3|
procedure setinline(value: boolean); // ?
procedure setancestor(value: boolean); // ?
* non-limiting value of "place_maxdist" and {plo_propmargin in place_options} :
{$endif}
 
# |---Widget_1---Widget_2---Widget_3---|
// TRUE if all conditios are OK for executing the code of "event" ( a handler must be assigned to the event )
function canevent(const event: tmethod): boolean;
* limiting value of "place_maxdist" and {place_mode = wam_start} :
 
 
# |Widget_1----Widget_2----Widget_3????|
// Shortly, replaces the persistent storage of the widget
//
* limiting value of "place_maxdist" and {place_mode = wam_start} and
// if {value <> nil} then
  {plo_propmargin in place_options} :
// - if "instance" is nil then calls "createproc" to create the instance,
//    then assigns the instance's value:= "value"
# |---Widget_1---Widget_2---Widget_3???|
// otherwise frees "instance"
procedure setoptionalobject(const value: tpersistent; var instance;
* limiting value of "place_maxdist" and {place_mode = wam_end} :
                        createproc: createprocty);
 
# |??????Widget_1---Widget_2---Widget_3|
// creates the persistent storage of the widget via calling "createproc"
procedure getoptionalobject(const instance: tobject; createproc: createprocty);
* limiting value of "place_maxdist" and {place_mode = wam_end} and
 
  {plo_propmargin in place_options} :
// obtains & puts to "obj" a CORBA interface entry for "aintf" (GUID,...)
function getcorbainterface(const aintf: ptypeinfo; out obj) : boolean;
# |???Widget_1---Widget_2---Widget_3---|
 
        // TRUE if the widget is owned, or "self" otherwise
* limiting value of "place_maxdist" and {place_mode = wam_center} :
function checkowned(component: tcomponent): boolean;
 
# |???Widget_1---Widget_2---Widget_3???|
        // TRUE if the widget is owner, or "self" otherwise
function checkowner(component: tcomponent): boolean;
* limiting value of "place_maxdist" and {plo_endmargin in place_options} :
 
// return the top-most widget in owner chain starting from this widget
# |Widget_1----Widget_2----Widget_____3|, or
function rootowner: tcomponent;
# |Widget_1----Widget_____2----Widget_3|, or
# |Widget_____1----Widget_2----Widget_3|, here, the most left amongst
widgets having both [an_left,an_right] set is expanded otherwise the most
right widget ( Widget_3 in the example )
* limiting value of "place_maxdist" and {place_mode = wam_end} and
  {plo_propmargin in place_options} and {plo_endmargin in place_options} :
 
# |--Widget_1--Widget_____2--Widget_3--|,
 
The Legend:
===========
limiting value of "place_maxdist" : such value which produce some visual
effect on the layouter
  "----" :          distance ( = number of minuses, limited by place_maxdis )
  "????" :          some remaining space ( = number of questmarks )
  "Widget_1" :       widget of the original size
  "Widget__..__1" : (auto)resized widget
 
  = if {lao_placey in optionslayout} and {place_mode <> wam_none} then the things
are handled in the same manner as with "lao_placex" but for the vertical
"top2bottom" direction of placement instead of the horizontal "left2right" one.
 
2) the align(ment) mode ( optionslayout.lao_align* ) :


// return the array of owning widgets starting from this widget
- widgets are gathered into a visual group to a dedicated "leader" widget of
// componentarty[0] is the widget oneself
  the layout ( set by "align_leader" and defaults to the lowest in
function getrootcomponentpath: componentarty;
  Z-Order = twidget.widgets[0] ) the leader stays in place while the others :


        // returns items of objeclinker ( which notify this widget )
  = if lao_alignx in optionslayout ( the hor alignment mode ):
        // and free notify list ( which are notified by this widget ),
  * if align_mode = wam_start :
        // duplicates are removed.
snap their left borders to the left border of leader
        //
  * else if align_mode = wam_end :
        // Notifies mainly relate to insertion/removal operation on widgets
snap their right borders to the right border of leader
        // The notify list is maintained by FreeNotification & RemoveFreeNotification
  * else if align_mode = wam_center :
function linkedobjects: objectarty;
snap their v-axes to the v-axis of leader after that,
  = if lao_aligny in optionslayout ( the vert alignment mode ):
  * if align_mode = wam_start :
snap their top borders to the top border of leader
  * else if align_mode = wam_end :
snap their bottom borders to the bottom border of leader
  * else if align_mode = wam_center :
snap their h-axes to the h-axis of leader


// sends "event" recursively to child widgets until no more childs or
- after that, the whole widget group can be aligned within the layouter:
// the event is processed ( cea_processed ) by one of the childs,
// "event" will be destroyed if destroyevent= true and not async
procedure sendcomponentevent(const event: tcomponentevent;
                                        const destroyevent: boolean = true);


// sends "event" to each of owning widgets downward from the root owner,
  = if align_glue =  wam_start
// "event" will be destroyed if destroyevent= true and not async
  * if lao_alignx in optionslayout:
procedure sendrootcomponentevent(const event: tcomponentevent;
the left extent of group snaps to the left border of layouter
                                        const destroyevent: boolean = true);
  * if lao_aligny in optionslayout:
 
the top extent of group snaps to the top border of layouter
// posts an async "atag"-ged event to be handled by oneself
  = else if align_glue = wam_end
procedure asyncevent(atag: integer = 0);
  * if lao_alignx in optionslayout:
the right extent of group snaps to the right border of layouter
  * if lao_aligny in optionslayout:
the bottom extent of group snaps to the bottom border of layouter
  = else if align_glue = wam_center
  * if lao_alignx in optionslayout:
the v-axis of group snaps to the v-axis of layouter
  * if lao_aligny in optionslayout:
the h-axis of group snaps to the h-axis of layouter


// posts a "tcomponentevent" instance from sender=self,
Mutually exclusive settings:
// "kind" is defined when creating the event,
* only one of "align_mode" can be choosen
// and "tag" may be adjusted after creation
* only one of  "glue_mode" can be choosen
procedure postcomponentevent(const event: tcomponentevent);
* "optionslayout.lao_alignx" & "optionslayout.lao_placex"
* "optionslayout.lao_aligny" & "optionslayout.lao_placey"


// returns the classname of the widget if the widget is toplevel,  
V-alignment ( optionslayout.lao_aligny ) may be combined with h-placement
// and "tmsecomponent" otherwise )
( optionslayout.lao_placex ), and h-alignment ( optionslayout.lao_alignx ) may
property moduleclassname: string read getmoduleclassname;
be combined with v-placement ( optionslayout.lao_placey )


// returns the classname of the widget as the entry of its constructor
NOTE:
// ( button => tbutton, datamodule => tdm1mo, form => ttstfo, dbstringedit => tdbstringedit,.. )
  The effects of the above described { resizing / placement / alignment } are
property actualclassname: string read getactualclassname;
  irreversible. So, the only way to revert is to set "wan_none" then to revert
  manually.
</pre>


// returns "fmsecomponentstate"
=== TListView ===
// ( a set of cs_ismodule,cs_endreadproc,cs_loadedproc,cs_noload, cs_hasskin,cs_noskin )
=== TImage ===
property msecomponentstate: msecomponentstatesty read fmsecomponentstate;
<pre>
<any image>


// returns/sets a pointer associated with the widget
*** Note that switch to the monochrome mode is irerreversible ! ***
// ( contrary to the integer "tag", allows to use an arbitary data type
// for associating data )
property tagpo: pointer read ftagpo write ftagpo;


// returns/sets a string identifying the widget in the help system
alignment:
property helpcontext: msestring read gethelpcontext write fhelpcontext;


// twidget
By default, images are top-left aligned, with the original size preserved.


// creates an instance of the widget, owned by "aowner" if not NIL
al_xcentered = centers the image horizontally
constructor create(aowner: tcomponent); override;
al_ycentered = centers the image vertically


destructor destroy; override;
al_right = docks the image to the right border of placeholder
al_bottom = docks the image to the bottom border of placeholder


// ??
al_grayed = fills non-transparent areas with the selected color
procedure afterconstruction; override;


// rescales the widget frame ( if assigned ) then owned widgets ( if exist, recursively ) then bounds_* then the font ( if assigned )
al_stretchx = adjusts size so that to fill the placeholder in width
// called before inserting in parentwidget,
al_stretchy = adjusts size so that to fill the placeholder in height
// calls "scale(ascale)",
al_fit = adjusts size so that to fill the placeholder in both width & height
// no visual repainting
procedure initnewcomponent(const ascale: real); virtual;


// restores the "fontheight" to "font.glyphheight" if "ow_fontglyphheight" or
al_tiled = spawns the image & tile the whole  placeholder with the copies
// to "font.lineheight" if "ow_fontlineheight" otherwise,
// ascale is ignored ?
// calls "synctofontheight->setfontheight",
// called after inserting in parentwidget,
// no visual repainting
procedure initnewwidget(const ascale: real); virtual;


// creates the widget frame if not yet created
Interpolation mode while stretching
procedure createframe;


// creates the widget face if not yet  created
al_intpol = antialiases as far as the size changes
procedure createface;
(the only working in Linux)
al_or = interpolation pixel operation is "or" -> 1's are extended
al_and = interpolation pixel operation is "and" -> 0's are extended
( al_or and al_and only on win32, mainly useful for stretching of monochrome bitmaps) :


// creates the widget font if not yet created
colorbackground = color of image transparent ( masked ) areas in monochrome
procedure createfont;
non-masked mode
colorforeground = color of non-transparent areas in monochrome mode  


// checks ws_loadlock and csdestroing too
options:
function isloading: boolean;


// returns "widgetstatety" - a set of (
bmo_monochrome = fills non-transparent areas with "colorforeground",  
// ws_visible,ws_enabled,ws_active,ws_entered,ws_entering,ws_exiting,
also, in non-masked mode, fills transparent areas
// ws_focused,ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,
with "colorbackground"
// ws_wantmousefocus,ws_iswidget,ws_opaque,ws_nopaint,
// ws_clicked,ws_mousecaptured,ws_clientmousecaptured,
// ws_loadlock,ws_loadedproc,ws_showproc,ws_minclientsizevalid,
// ws_showed,ws_hidden, //used in tcustomeventwidget
// ws_destroying,ws_staticframe,ws_staticface,ws_isvisible
//
// iframe
function widgetstate: widgetstatesty;


// returns "widgetstate1ty" - a set of (
bmo_masked = activates built-in image transparency {it "hides" transparent (masked) areas}
// (ws1_childscaled,ws1_fontheightlock,
bmo_colormask = applies faded edge transparency on the color masked areas in the image
// ws1_widgetregionvalid,ws1_rootvalid,
// ws1_anchorsizing,ws1_isstreamed,
// ws1_scaled, //used in tcustomscalingwidget
// ws1_noclipchildren,
// ws1_nodesignvisible,ws1_nodesignframe,ws1_nodesignhandles,
// ws1_nodesigndelete,ws1_designactive,
// ws1_fakevisible,ws1_nominsize //used for report size calculations
// )
property widgetstate1: widgetstates1ty read fwidgetstate1;
* this set of states is needed because the max FPC set size is 32
  thus "widgetstate1ty" can't fit all states


// TRUE if the widget is contained within another widget
transparency = makes the image transparent as long as enlights areas behind
// ( tcomponent stuff )
the image with the selected color
function hasparent: boolean; override;             


// returns the parent component if it's a widget or the grandparent otherwise
transparentcolor = for a non-masked image, assigns a color indicate transparency areas
function getparentcomponent: tcomponent; override;  //tcomponent
( on matching areas, the image will be seen through )
</pre>


// TRUE if "awidget" is an ascendant or the widget or they are the same widget
=== TDial ===
function checkdescendent(awidget: twidget): boolean;
=== TChart ===
// TRUE if app is running and the widget owns the caret or the caret widget
function hascaret: boolean;


        // TRUE if "winid" allocated and not loading and not destroying,
There are demos here:
        // all widgets on a form have "winid" of this form ( a real window allocated by the OS )
        // thus have this function TRUE
function windowallocated: boolean;


// TRUE if presents a valid toplevelwindow with assigned "winid"
https://github.com/mse-org/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/help/tutorials/widgets/charts
function ownswindow: boolean;


// invalidated area of the widget, the origin is "clientpos" against the roor widget
=== TChartRecorder ===
function updaterect: rectty;
=== TPolygon ===
=== TPickWidget ===
=== TOpenglWidget ===


// calls recursively "canclose" for all contained widgets ( the widget oneself excluded! ),
== Edit ==
// TRUE if none of the widgets return FALSE
=== TStringEdit ===
//
=== TMemoEdit ===
// more specialized widgets may have "canclose" overridden
=== THexStringEdit ===
// to perform more work than just this call recursion
=== TDropdownListEdit ===
// ( not null or range check,.. )
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
//
- deo_autodropdown dropdown on keypress
// "onclosequery" must also pass the check if assigned, for the function to succeed
- deo_selectonly don't allow entering arbitrary text.
function canclose(const newfocus: twidget = nil): boolean; virtual;
- deo_forceselect don't allow entering empty text.


        // checks "canclose" first for focused widget of the window ( form,.. )
=== THistoryEdit ===
        // if it is a descendant of the widget or the widget oneself,
A tstringedit which shows the previously entered values in a dropdownlist for selection.
        // then continues with subwidgets of the widget;
        // also - finishes editing ( snapshots "value" ) in the focused widget before checking
function canparentclose(const newfocus: twidget): boolean; overload;


// the above function but with the preserved focus
=== TIntegerEdit ===
function canparentclose: boolean; overload;
=== TKeyStringEdit ===
                  //newfocus = window.focusedwidget     
Maps string to string.


function canfocus: boolean; virtual;
=== TEnumEdit ===
function setfocus(aactivate: boolean = true): boolean; virtual;//true if ok
Maps integer to string, zero based and sequencial (first item 0, next 1, ...).
procedure nextfocus; //sets inputfocus to then next appropriate widget


function findtabfocus(const ataborder: integer): twidget;
=== TEnumTypeEdit ===
                      //nil if can not focus


function firsttabfocus: twidget;
A TEnumEdit which maps Pascal enums to their names. Use OnInit event to store the typeinfo pointer of the enum type into '''sender.typeinfopo'''.
function lasttabfocus: twidget;
function nexttaborder(const down: boolean = false): twidget;


function focusback(const aactivate: boolean = true): boolean;
<syntaxhighlight lang=pascal>
                              //false if focus not changed
procedure tmainfo.enumtypeeditinit(const sender: tenumtypeedit);
begin
  sender.typeinfopo := PTypeInfo(TypeInfo(TMyEnumeratedType));
end;
</syntaxhighlight>


function parentcolor: colorty;
=== TSelector ===
function actualcolor: colorty; virtual;
TSelector  is the most specialized widget of the dropdown editwidget group, it is based on tenumedit (tenumedit maps an integer to a string) and uses for the dropdownlist a second map which must be created on the fly in ongetdropdowninfo. An example is tcommselector where the enumedit maps commnrty to commname and the dropdownlist shows the available RS232 ports
function actualopaquecolor: colorty;
only.
function backgroundcolor: colorty;
function translatecolor(const acolor: colorty): colorty;


procedure widgetevent(const event: twidgetevent); virtual;
=== TRealEdit ===
=== TRealSpinEdit ===
=== TDateTimeEdit ===
=== TCalendarDateTimeEdit ===
=== TEdit ===
MSEgui counterpart of Delphi TEdit. You will never use it.


procedure sendwidgetevent(const event: twidgetevent);
=== TWidgetGrid ===
                              //event will be destroyed
=== TItemEdit ===
=== TDropDownItemEdit ===
A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
- deo_autodropdown dropdown on keypress
- deo_selectonly don't allow entering arbitrary text.
- deo_forceselect don't allow entering empty text.


procedure release; override;
=== TMBDropDownItemEdit ===
=== TTreeItemEdit ===
=== TRecordFieldEdit ===
Used in twidgetgrid in order to edit fields of a ttreeitemedit. Example is MSEide projecttreeform.pas.


function show(const modal: boolean = false;
=== TDialogStringEdit ===
            const transientfor: twindow = nil): modalresultty; virtual;
A tstringedit with an ellipse button. Use "onexecute" to show the dialog.


procedure hide;
=== TPointerEdit ===
procedure activate(const abringtofront: boolean = true); virtual;
=== TSlider ===
                            //show and setfocus
=== TProgressBar ===
=== TBooleanEdit ===
=== TBooleanEditRadio ===
=== TDataButton ===
A button with an integer value. Clicking increments the value until "max", then it restarts with "min". Can be inserted into a twidgetgrid. The current value selects the showed image and face by the items of "imagenums" and "valuefaces".


procedure bringtofront;
=== TStockGlyphDataButton ===
procedure sendtoback;
=== TDataIcon ===
procedure stackunder(const predecessor: twidget);
Shows an imagelist item by lookup from "value" to "imagenums". Clicking increments value until "max" then it restarts with "min". Can be inserted into a twidgetgrid.


procedure paint(const canvas: tcanvas); virtual;
=== TTextEdit ===
procedure update; virtual;
Only useful if inserted into a twidgetgrid, builds a text editor, used in MSEide source editor.
procedure scrollwidgets(const dist: pointty);


procedure scrollrect(const dist: pointty; const rect: rectty; scrollcaret: boolean);
=== TDataImage ===
                            //origin = paintrect.pos
A pixmap display widget which can be inserted into twidgetgrid.


procedure scroll(const dist: pointty);
=== TTerminal ===
                            //scrolls paintrect and widgets
Only useful if inserted into a twidgetgrid, builds a very simple terminal emulator. Used in MSEide target console.


procedure getcaret;
== NoGui ==
procedure scrollcaret(const dist: pointty);
=== TAction ===
function mousecaptured: boolean;
<pre>
procedure capturemouse(grab: boolean = true);
Shortcut processing order :
procedure releasemouse;
procedure capturekeyboard;
procedure releasekeyboard;
procedure synctofontheight; virtual;


procedure dragevent(var info: draginfoty); virtual;
- the smallest piece of processing is "doshortcut" procedure which
procedure dochildscaled(const sender: twidget); virtual;
is called until processed:
= starting from the sender up to the toplevel widget
= then by all child widgets with non-set "ow_noparentshortcut"
= then, if "ow_nochildshortcut" isn't set, by the parent widget
= then by the widget oneself
- "doshortcut" is checked in the following order:
= starting from form's main menu
= then from the owning window ( the widget oneself )  
= then from the application


procedure invalidatewidget;    //invalidates whole widget
procedure invalidate;          //invalidates clientrect
procedure invalidaterect(const rect: rectty; org: originty = org_client);
procedure invalidateframestate;


procedure invalidateframestaterect(const rect: rectty;
*** A shortcut is bound to a widget by :
                                        const org: originty = org_client); 
- placing an action component on the widget ***
function hasoverlappingsiblings(arect: rectty): boolean; //origin = pos
- direct assigning the shortcut to the widget (menus,..)  
---------------------------


function window: twindow;
caption, color, colorglyph, helpcontext, hint, imagecheckedoffset,
function rootwidget: twidget;
imagelist <see "timagelist">, imagenr, imagenrdisabled


function parentofcontainer: twidget;
- sets look of "clients" (buttons, menu/toolbar items,..), unless
            //parentwidget.parentwidget if parentwidget has not ws_iswidget,
these clients have "state.as_local*" set :
            //parentwidget otherwise


property parentwidget: twidget read fparentwidget write setparentwidget;
*** For meaning of these options, see help on the "client" widgets ***
function getrootwidgetpath: widgetarty; //root widget is last


// number of contained widgets ( the widget oneself excluded ! )
group
function widgetcount: integer;
- default value for one-named property of the bound widgets
( menu items,... )


function parentwidgetindex: integer; //index in parentwidget.widgets, -1 if none
options :
property widgets[const index: integer]: twidget read getwidgets;
ao_updateonidle
function widgetatpos(var info: widgetatposinfoty): twidget; overload;
- runs this action in cycle, waiting for no gui events everytime
function widgetatpos(const pos: pointty): twidget; overload;


function widgetatpos(const pos: pointty;
ao_globalshortcut
                  const state: widgetstatesty): twidget; overload;
- allows the action to trigger on a non-main form
  (the shortcut is triggered whatever form of the applicatin it was pressed on,
  otherwise only when the form where the aption is placed on is focused )


property taborderedwidgets: widgetarty read gettaborderedwidgets;
ao_nocandefocus
- causes the action not to call "CanDefocus" for focused edit widget of active form
  before executing own code
  ( it helps to avoid the effect of cancelling changes in these widgets
  on activating the bound shortcut )


function findtagwidget(const atag: integer; const aclass: widgetclassty): twidget;
shortcut
              //returns first matching descendent
- keyboard combination triggering the action


property container: twidget read getcontainer;
shortcut
function containeroffset: pointty;
- alternative "shortcut" and handled identically
function childrencount: integer; virtual;
property children[const index: integer]: twidget read getchildwidgets; default;


function childatpos(const pos: pointty;
state :
                  const clientorigin: boolean = true): twidget; virtual;


function getsortxchildren: widgetarty;
as_disabled
function getsortychildren: widgetarty;
- prevents the action from triggering, also puts the bound widgets to "disabled" look
property focusedchild: twidget read ffocusedchild;
property focusedchildbefore: twidget read ffocusedchildbefore;


function mouseeventwidget(const info: mouseeventinfoty): twidget;
as_invisible
- in run-time, hides the bound widget, still reacting on the shortcut or direct call


function checkdescendent(widget: twidget): boolean;
as_checked
                    //true if widget is descendent or self
- selects the bound menu item if it has "mao_checkbox" option set


function checkancestor(widget: twidget): boolean;
as_default
                    //true if widget is ancestor or self
as_local*


function containswidget(awidget: twidget): boolean;
statfile
<see "tstatfile">


procedure insertwidget(const awidget: twidget); overload;
stavarname


procedure insertwidget(const awidget: twidget; const apos: pointty); overload; virtual;
                //widget can be child
tagaction
onasyncevent
onchange
onexecute
onupdate
</pre>


function iswidgetclick(const info: mouseeventinfoty; const caption: boolean = false): boolean;
=== TActivator ===
//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect
=== TCustomLookupbuffer ===
//or in frame.caption if caption = true, origin = pos
<pre>
- provides a group of parallel arrays of float(=datetime), integer and widestring types,
and facilities to :
= search in any array
= on found position, quickly obtain corresponding value in another array
- for each type, several arrays  may be kept
- each array is integer-indexed, even string ones ( case[in]sensitive )
- uses two way of accessing arrays data, through :
= physic : array storage index ( row number ) directly
= logical : the integer index ( see above ):
first, physic row number is known for the logical index then the data
are accessed with the found number


function isclick(const info: mouseeventinfoty): boolean;
*** logical index values are built automatically based on array values,
//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect
on updating its data ***
- dont' have interface to load data ( see its descendants for that )
fieldcountfloat - number of float arrays
fieldcountinteger - number of integer arrays
fieldcounttext - number of widestring arrays


Event handlers:
- onchange


function isdblclick(const info: mouseeventinfoty): boolean;
Public interface:
//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
// and timedlay to last buttonpress is short


function isdblclicked(const info: mouseeventinfoty): boolean;
  procedure beginupdate; - marks beginning of "update"
//true if eventtype in [et_buttonpress,et_butonrelease], button is mb_left,
  procedure endupdate; - if all "update" finished, fires "onchange" event
// and timedlay to last same buttonevent is short
procedure clearbuffer; - clears all arrays then fires "onchange"


function isleftbuttondown(const info: mouseeventinfoty): boolean;
  procedure checkbuffer;  
//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
  - [re]loads the arrays with most actual data
//origin = paintrect.pos
  - just a stub here since doesn't have a data source


//======================
  function find(const fieldno: integer; const avalue: integer/realty/msestring;
        out aindex: integer; const filter: lbfiltereventty = nil): boolean;
- applies external filtering ("filter" procedure) then incrementally searches integer/realty(datetime) array "fieldno"
for value "avalue" starting from logical index "aindex", returns "true" and the updated logical index
if found else next bigger;


widgetrect: the widget on-screen area including its frame & frame caption
  function find(const fieldno: integer; const avalue: msestring;
                out aindex: integer;
                const caseinsensitive: boolean;
                const filter: lbfiltereventty = nil): boolean; overload;
- applies external filtering ("filter" procedure) then incrementally searches widestring array "fieldno" for value "avalue",
in "caseinsensitive" manner, starting from logical index "aindex", returns "true" and the updated logical index
if found else next bigger;


paintrect: the widget on-screen area except its frame & frame caption
  function findphys(const fieldno: integer; const avalue: integer;
        out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload;
- applies external filtering ("filter" procedure) then incrementally searches integer/realty(datetime) array "fieldno"
for value "avalue" starting from row number "aindex", returns "true" and the updated row number
if found else next bigger;


clientrect: virtual area which
function findphys(const fieldno: integer; const avalue: msestring;  out aindex: integer; const caseinsensitive: boolean;
- for non-scrolling widgets, equals to "paintrect", with its "pos:= (0,0)"
                const filter: lbfiltereventty = nil): boolean; overload;
- for scrolling widgets, may be bigger than "paintrect",  
- applies external filtering ("filter" procedure) then incrementally searches widestring array "fieldno" for value "avalue",  
  also may shift ( change its "pos" ) when scrolling
in "caseinsensitive" manner, starting from row number "aindex", returns "true" and the updated row number 
if found else next bigger;


//======================
The external filtering ("filter") procedure takes the arguments of the caller
togehther with physical row number found in the caller which allows
to check several values at once for that number, within the filter
function integervaluephys(const fieldno,aindex: integer): integer;
-  returns value of integer array "fieldno" at row number "aindex"
             
function integervaluelog(const fieldno,aindex: integer): integer;
-  returns value of integer array "fieldno" where the array index equals to "aindex"


function integerindex(const fieldno,aindex: integer): integer;
- returns row number of integer array "fieldno" where the array index equals to "aindex"


function integerindexar(const fieldno: integer): integerarty;
- returns all bunch of indexes of integer array "fiedlno"


// the coord of outer top-left corner against the toplevel form = the window owner,
function integerar(const fieldno: integer): integerarty;
// including the frame & frame caption
- returns all bunch of data of integer array "fiedlno"
function rootpos: pointty;  
 
function floatvaluephys(const fieldno,aindex: integer): realty;
-  returns value of real/datetime array "fieldno" at row number "aindex"
 
function floatvaluelog(const fieldno,aindex: integer): realty;
-  returns value of real/datetime array "fieldno" where the array index equals to "aindex"


// the coord of the outer top-left corner against the screen ( the WM decorations aren't counted in )
function floatindex(const fieldno,aindex: integer): integer;
// includes the frame & frame caption
- returns row number of real/datetime array "fieldno" where the array index equals to "aindex"
property screenpos: pointty;


//  the coord of the outer top-left corner against the parent widget,
function floatindexar(const fieldno: integer): integerarty;
// including the frame & frame caption
- returns all bunch of indexes of real/datetime array "fiedlno"
property widgetrect: rectty;
property pos: pointty; // =widgetrect.pos
property size: sizety; // =widgetrect.size
property left: integer; // =bounds_x
property right: integer; //widgetrect.x + widgetrect.cx, sets cx;
property top: integer;  // =bounds_y
property bottom: integer; //widgetrect.y + widgetrect.cy, sets cy;
property width: integer; // =bounds_cx
property height: integer; // =bounds_cy
function widgetsizerect: rectty;          //pos = nullpoint


    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
function floatar(const fieldno: integer): realarty;
    //  except the frame & frame caption
- returns all bunch of data of real/datetime array "fiedlno" 
function paintrect: rectty;
function paintpos: pointty;
function paintsize: sizety;
function innerpaintrect: rectty; // mainly equals to paintrect
function clientwidgetrect: rectty; // mainly equals to paintrect
function clientwidgetpos: pointty;
function clippedpaintrect: rectty; // mainly equals to  but clipped by all parentpaintrects
function innerwidgetrect: rectty;    // mainly equals to paintrect
function innerclientwidgetpos: pointty;


    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
function textvaluephys(const fieldno,aindex: integer): msestring;
    //  except the frame caption
- returns value of widestring array "fieldno" at row number "aindex"  
function framerect: rectty; // =paintrect except the frame caption area
 
function framepos: pointty;
function textvaluelog(const fieldno,aindex: integer;
function framesize: sizety;
                      const caseinsensitive: boolean): msestring;
-  returns value of widestring array "fieldno" where the array index equals to "aindex"
 
function textindex(const fieldno,aindex: integer;
                      const caseinsensitive: boolean): integer;
- returns row number of widestring array "fieldno" where the array index equals to "aindex"


    // the coord of the client area ( clientrect )  against the paint area ( paintrect )
function textindexar(const fieldno: integer;
    //  usually these areas match
                            const caseinsensitive: boolean): integerarty;
function clientrect: rectty;
- returns all bunch of indexes of widestring array "fiedlno"
property clientsize: sizety;
property clientwidth: integer;
property clientheight: integer;
property clientpos: pointty;


    // the coord of the paint area of the parent against the paint area of this widget
function textar(const fieldno: integer): msestringarty;
function paintrectparent: rectty; //nullrect if parent = nil,
- returns all bunch of data of widestring array "fiedlno" 


    // the coord of the client area of the parent against the paint area of this widget
 
function clientrectparent: rectty; //nullrect if parent = nil,
function lookupinteger(const integerkeyfieldno,integerfieldno,
                                keyvalue: integer): integer; overload;
- returns value of integer array "integerfieldno" at position where
value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( 0 if not found )


// the coord of the inner area against the client area ( clientrect )
function lookupinteger(const stringkeyfieldno,integerfieldno: integer;
function innerclientrect: rectty; // mainly equals to clientrect
                        const keyvalue: msestring): integer; overload;
function innerclientsize: sizety;
- returns value of integer array "integerfieldno" at position where
function innerclientpos: pointty;
value of parallel widestring array "stringkeyfieldno" equals to "keyvalue"
                ( 0 if not found )


function framewidth: sizety;             //widgetrect.size - paintrect.size
function lookuptext(const integerkeyfieldno,textfieldno,
function clientframewidth: sizety;        //widgetrect.size - clientrect.size
                                keyvalue: integer): msestring; overload;
function innerclientframewidth: sizety;  //widgetrect.size - innerclientrect.size
- returns value of integer array "textfieldno" at position where
function innerframewidth: sizety;        //clientrect.size - innerclientrect.size 
value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( '' if not found )


    // the coord of the paint area against the widgetrect(pos) of the parent
function lookuptext(const stringkeyfieldno,textfieldno: integer;
function paintparentpos: pointty;    //origin = parentwidget.pos
                      const keyvalue: msestring): msestring; overload;
- returns value of integer array "textfieldno" at position where
value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( '' if not found )


    // the coord of the client area against the widgetrect(pos) of the parent
function clientparentpos: pointty;  //origin = parentwidget.pos


    // the coord of the widgetrect(pos) against the client area of parent
function lookupfloat(const integerkeyfieldno,floatfieldno,
property parentclientpos: pointty;
                                keyvalue: integer): realty; overload;
- returns value of real/datetime array "floatfieldno" at position where
value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( emptyreal if not found )


function lookupfloat(const stringkeyfieldno,floatfieldno: integer;
                                keyvalue: msestring): realty; overload;


function clientpostowidgetpos(const apos: pointty): pointty;
- returns value of real/datetime array "floatfieldno" at position where
function widgetpostoclientpos(const apos: pointty): pointty;
value of parallel widestring array "stringkeyfieldno" equals to "keyvalue"
function widgetpostopaintpos(const apos: pointty): pointty;
                ( emptyreal if not found )
function paintpostowidgetpos(const apos: pointty): pointty;
 
procedure scale(const ascale: real); virtual;
function count: integer; - returns number of data rows
 
property fieldcounttext: integer; -  returns/sets number of widestring arrays
property fieldcountfloat: integer; - returns/sets number of real/datetime arrays
property fieldcountinteger: integer; - returns/sets number of integer arrays


the above "fieldcount*" props clear the buffer on setting a value


property minsize: sizety read fminsize write setminsize;
property integervalue[const fieldno,aindex: integer]: integer; - a shortcut to "integervaluephys"
property maxsize: sizety read fmaxsize write setmaxsize;
property floatvalue[const fieldno,aindex: integer]: realty; - a shortcut to "floatvaluephys"
function maxclientsize: sizety; virtual;
property textvalue[const fieldno,aindex: integer]: msestring; - a shortcut to "textvaluephys"


property onchange: notifyeventty;
- called in "changed" wich in turn is called in :
= clearbuffer
= endupdate
= doasyncevent
= loaded
= tlookupbuffer.addrow


property anchors: anchorsty read fanchors write setanchors default defaultanchors;
</pre>
property defaultfocuschild: twidget read getdefaultfocuschild write setdefaultfocuschild;


=== TLookupBuffer ===
<pre>
tlookupbuffer = class(tcustomlookupbuffer)


procedure changeclientsize(const delta: sizety); //asynchronous
- extends "tcustomlookupbuffer" with methods of run-time data filling


function getcanvas(aorigin: originty = org_client): tcanvas;
- see <tcustomlookupbuffer>


function showing: boolean;
+= Extentions to the public interface:
              //true if self and all ancestors visible and window allocated


function isenabled: boolean;
procedure addrow(const integervalues: array of integer;
              //true if self and all ancestors enabled
                    const textvalues: array of msestring;
                    const floatvalues: array of realty);


function active: boolean;
- adds one row to each of widestring arrays, integer arrays and real/datetime arrays,
function entered: boolean;
array size of  "{type}values" equals to number of {type} arrays


function activeentered: boolean;  
  procedure addrows(const integervalues: array of integerarty;
//true if entered and window is regularactivewindow or inactivated
                    const textvalues: array of msestringarty;
                    const floatvalues: array of realarty);


function focused: boolean;
- adds many data rows  to each of widestring arrays, integer arrays and real/datetime arrays,
function clicked: boolean;
only min length of the input data arrays are inserted, longer data are truncated
array size of  "{type}values" equals to number of {type} arrays and the size of "{type}values[i]"
describes number od data elements in the array
</pre>


function indexofwidget(const awidget: twidget): integer;
=== TDBLookupBuffer ===
<pre>
tdblookupbuffer = class(tcustomdblookupbuffer -> tcustomlookupbuffer)


procedure changedirection(const avalue: graphicdirectionty;
- extends "tcustomlookupbuffer" with interface to fill arrays with DB-data
                                            var dest: graphicdirectionty); virtual;
- see <tcustomlookupbuffer> & <tcustomdblookupbuffer>


// (re)arranges "awidgets" horizontally within the parent's client area
Extentions to the public interface:
// so that awidget[i] were placed next each other
 
// at h-space dist[i], starting from "startx" with the right margin "endmargin";
  procedure checkbuffer; - if data obsolete ("invalid") then reloads them from "datasource"
//
 
// if the number of "dist" is fewer than the number of "awidgets" then the remaining h-spaces are taken
property datasource: tdatasource; - sets/returns DB data source where to load data from
// as the last "dist[i]" or "0" if none;
property textfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of widestring arrays
// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
property integerfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of integer arrays
//
property floatfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of real/datetime arrays
// non-zero "endmargin" causes one of awdidget[i] to h-resize to provide the margin :
 
//  - if one or more of awidgets[i] have [an_left,an_right] set then the first of such is resized
property optionsdb: lbdboptionsty; - tunes some DB behaviour apects
//    otherwise the last awidgets[i] is h-resized
- olbdb_closedataset :
//
= once data obsolete, opens (if needed) the supplier dataset (disabling its bound controls)
procedure placexorder(
then [re]loads data from it then closes it
const startx: integer;
 
const dist: array of integer;
- olbdb_invalidateifmodified :
                const awidgets: array of twidget;
= gets marked "invalid" once contents of the bound dataset change,
                const endmargin: integer = minint);
it signals to reload the buffer with the new data just before next accessing
( for any purpose - searching, lookuping, getting value/(array of values),..)
 
</pre>
 
=== TDBmemoLookupbuffer ===
<pre>
- allows to use for lookup-ing any text-convertable DB-fields
- an analog of tdblookupbuffer, but :
- "integerfields" may be names of any integer-convertable DB-fields
- "floatfields" may be names of any (real/datetime)-convertable DB-fields
- "textfields"  may be names of any text-presentable DB-fields
 
- each DB-field value ( presenting a memo generally of many lines ) may supply many data rows at once
to the bound array of the buffer, since this value will be internally splitted & turned into native array values,
and the resulting "count" (arrays row count) of the whole buffer will be the minimal rows count amongst arrays
of the buffer, the rest data are truncated


// (re)arranges "awidgets" vertically within the parent's client area
- when loading widestring arrays, also checks for & performs "utf8-to-widestring" conversion of values of  
// so that awidget[i] were placed upper/lower each other
the bound DB-fields so that these arrays always store widestrings
// at v-space dist[i], starting from "starty" with the bottom margin "endmargin";
</pre>
//
// if the number of "dist" is fewer than the number of "awidgets" then the remaining v-spaces are taken
// as the last "dist[i]" or "0" if none;
// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
//
// non-zero "endmargin" causes one of awdidget[i] to v-resize to provide the margin :
//  - if one or more of awidgets[i] have [an_top,an_bottom] set then the first of such is resized
//    otherwise the last awidgets[i] is v-resized
//
procedure placeyorder(
const starty: integer;
const dist: array of integer;
                const awidgets: array of twidget;
                const endmargin: integer = minint);
              //origin = clientpos, endmargin by size adjust of widgets
              //with [an_top,an_bottom], minint -> no change


// if {mode <> wam_none} then (re)arranges "awidgets" horizontally  within the parent's client area so that  
=== TThreadComp ===
// awidgets[0] stays on its place but awidgets[1..N] :
=== TStatFile ===
// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_left" set ) so that they right borders match the right border of awidgets[0]
<pre>
// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_right" set ) so that they left borders match the left border of awidgets[0]
- so that to be in effect, it should also be assigned to the form where the widget using the stafile is placed on
// - if {mode = wam_center} then awidgets[i>=1] move so that they Y-axes match the Y-axe of awidgets[0]
- in design, if "onstatwrite" is set and "filedir" is not yet created, deactivate exception "ECreateError" in project settings ( "Debugger" tab )
//
- "filedir" may contain "~/" indicating the user's home directory
// mainly applicable for v-stacked widgets since h-stacked may overlap after such alignment
- options "oe_savestate" & "oe_savevalue" of "client" widgets define what to store to the file
//
- position etc changes or/and value changes
        // returns the reference point ( the coord of awidgets[0] )
- in case when a main form shares its stafile with non-main forms, on creating non-main ones, just edited not saved data of the main form ( bound to vars of the statfile) are reset to values read from the statfile upon creating the form; for "sfo_memory", this effect absents unless widgets on the concurring forms share same variable[s]; to avoid this behaviour, disable "fo_autoreadstat" & "fo_autowritestat" of the non-main forms
function alignx(const mode: widgetalignmodety;
- each "tstafile" owns:
                        const awidgets: array of twidget): integer;
= tstatwriter:
* provides methods of writing sections & statvars to a memory/file stream
- tstatreader:
* holds list of sections with statvars each
* provides search & check & reading interface to the statvars
* provides reading statvars from a memory/file stream


Positioning to a section speeds up accessing its statvars


// if {mode <> wam_none} then (re)arranges "awidgets" vertically within the parent's client area so that
- there also is "tstatfiler" ( exposed by some "tstatfile" events ) which:
// awidgets[0] stays on its place but awidgets[1..N] :  
= may present or "tstatwriter" or "tstatreader" ( there's a check method )
// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_top" set ) so that they bottom borders match the bottom border of awidgets[0]
= provides directionless "update" methods with internal switch to needed direction of processing
// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_bottom" set ) so that they top borders match the top border of awidgets[0]
- "reading" or "writing" statvars on per-section basis
// - if {mode = wam_center} then awidgets[i>=1] move so that they X-axes match the X-axe of awidgets[0]
 
//
 
// mainly applicable for h-stacked widgets since v-stacked may overlap after such alignment
activator :
//
<see tactivator> : NOT YET DONE
        // returns the reference point ( the coord of awidgets[0] )
 
function aligny(const mode: widgetalignmodety;
encoding = "en_utf8" selected here, allows to store non-Latin text in the file
                        const awidgets: array of twidget): integer;
      filedir = directory where to keep the file ( by default - the current working directory )
filename = name of the file
 
options:
sfo_memory = reads & writes not from a disk file but from a named memory stream
( there's an exclusion - see below "sfo_savedata" ),
mostly useful for presenting last used values on recalling
non-main forms etc ( data even survive recreating forms),
or even for data "exchange" between non-main modal( non-concurring ) forms
in case of the target widgets share same statvarnames
 
sfo_createpath = creates "filedir" if necessary
sfo_savedata = used only with "sfo_memory", commands to save
the memory data to the master statfile (see below)


function actualcursor: cursorshapety; virtual;
sfo_activatorread = activator activate triggers reading ???
sfo_activatorwrite = activator deactivate triggers writing ???


statfile = a master statfile
statvarname = name of section of this file in the upper statfile
Tag = an integer property for misc purposes


Event handlers:
Event handlers:
onstatafterread - fires on return from "readstat"
onstatafterwrite - fires on return from "writestat"
onstatbeforeread - fires on beginning of "readstat"
onstatbeforewrite - fires on beginning of "writestat"
onstatread = fires after reading state data
onstatwrite = fires after writing state data
onstatupdate = fires after reading/writing state data just before
"onstatread" & "onstatwrite"


- onactivate
Public methods:


fires :
  procedure initnewcomponent(const ascale: real); override;
  - does nothing but fixes the default file name as the statfile default
 
  procedure readstat(stream: ttextstream = nil); overload;
  - rereads all statvars of the stafile/memorystream
 
  procedure readstat(const aname: msestring; const statreader: tstatreader); overload;
  - rereads "aname" statvar of the statfile


= on receiving input focus, just before "OnFocus"
  procedure writestat(const stream: ttextstream = nil); overload;
  - rewrites all statvars to the stafile/memorystream
= forms specific :
  (if neccessary, prepares to writting - creates "filedir", stafile,...)
* on 1-st display of the form after "OnLoaded" ( from "Loaded" procedure)
 
* on switch back from another apllication/WM ( "oe_activate" event )
  procedure writestat(const aname: msestring; const statwriter: tstatwriter); overload;
* after closure of a descendant form
  - overwrites "aname" statvar of the statfile
* on minimizing/maximizing the form
 
  procedure updatestat(const aname: msestring; const statfiler: tstatfiler);
  - depending on kind of "statfiler" ( writer/reader ), writes/reads
    the most up-to-date stat data
</pre>


- onchildscaled
=== TTimer ===
=== TNoGuiAction ===
=== TPipeReadercomp ===
=== TSysEnvManager ===
=== TProcessMonitor ===
=== TFilechangeNotifier ===
=== TShortCutController ===
=== TPostscriptPrinter ===
=== TGdiPrinter ===
=== TWmfPrinter ===
=== TSkinController ===
=== TGuiThreadComp ===


fires :
== Font ==
See also : [[Reference:_MSEgui/TFont]]


= on child(s) resizing due to font height change
=== Any Font ===
 
<pre>
= form widget: once "form.container" {scrolling widget} is loaded
    charset { ANSI/ DEFAULT/ SYMBOL /SHIFTJIS /HANGEUL /GB2312 /CHINESEBIG5 /OEM
 
/JOHAB / HEBREW/ ARABIC/ GREEK/ TURKISH/ VIETNAMESE/ THAI/ EASTEUROPE/
- ondeactivate
RUSSIAN/ MAC/ BALTIC }
fires
- changes the font to the nearest containing the selected encoding(charset)
= form widget: when the form looses input focus
- no font change made if the supplied encoding doesn't match any font
= non-form widget: when the widget looses input focus
color
 
- color of the glyphs contours
- ondefocus
colorbackground
 
- fill color of the glyph cells ( not including extraspace )
fires
colorshadow
= on disabling the widget
- color of SE glyph "edges" ( if not "cl_none", deactivates "colorbackground" )
 
extraspace
*mse = form widget: if another form is focused
- v-space between glyph cells of adjacent text rows (negative values cause the cells to overlap )
= non-form widget: if another widget is focused
height
 
- v-size of glyph cells, in pixels
- onenter
name
= fires on any way of taking parent-wide focus as soon as
- initially, font is choosen by { "family" = this name }
the parent stores the new child's order, before "OnActivate" & "OnFocus"
options:
 
foo_fixed
- onexit
- changes the font to the nearest "mono" spaced (usually = Courier)
= fires last on parent-wide lossing focus, after "OnDefocus" & "OnDeactivate"
foo_proportional
= for top-level ( not in a container ) forms, doesn't fire
- changes the font to the nearest "proportionally" spaced (usually = Helvetica)
foo_helvetica
- changes the font to the nearest in "sans" category (usually = Helvetica)
foo_roman
- changes the font to the nearest in "serif" category (usually = Times[ New Roman])
foo_script
- Win32 only, changes the font to the nearest in "script" category
foo_decorative
- Win32 only, changes the font to the nearest in "decorative" category
foo_antialiased
- Linux-only, enables antialiasing (if disabled by Xft globally)
foo_nonantialiased
- Linux-only, disables antialiasing (if enabled by Xft globally)
usually making glyph extents (not cells !) a bit wider
style:
fs_bold
- gives the font a "bold" look
fs_italic
- gives the font an "italic" look
fs_underline
- gives the font an "underlined" look
fs_strikeout
- gives the font a "striked out" look
fs_selected
- "TRUE" here combined with {tf_noselect:=FALSE}, causes the text described by this font
to be initially selected ( with the clipboard operations available ),  
currently applicable only to richstrings


- onfocus
width
fires
- 10*{ glyph cell width, average in pixels }, 0 = {font default}
= once the existing widget takes the focus
= on showing the widget's form if the widget has the lowest "TabOrder"


- onfontheightdelta
xscale
fires
- width ratio of each glyph {cell & contour}, the effect is similar to "width"
= if [ow_fontglyphheight OR ow_fontlineheight ] AND {the
new font height differs from the previos one}
= before the parent redraws this widget


- onpopup
*** "foo_*" font selection overrides one made with "name"  
fires :
= on calling a popup-menu ( with "RightClick" ), once the menu items of the current level are loaded
( before building the submenus )


- onresize
*** if change with "foo_*" is unsuccessful then the nearest "sans" font is usually chosen


= fires on creating/(changing size)/(min-max restoring) of widget,
*** The categories :
before actual redrawing


= rechecks if there's real work to do
sans => have no serifs and have strokes of even thickness
serif => have serifs at glyph contours and made up of strokes of varying thickness
script => resemble handwriting
decorative => flashy styles to be used sparingly in headlines or posters


- onshowhint
</pre>
= fires when a installed hint is activated or on "aplication.showint" called
= since called last, allows to adjust the default behavior


- onbeforeupdateskin
== GUI ==
= fires in "updateskin" ( the widget is loaded etc ) before applying the skin
=== TWindow ===
 
<pre>
- onafterupdateskin
twindow = class(teventobject,icanvas)
= fires in "updateskin" ( the widget is loaded etc ) once the skin is applied
  public


<pre/>
// releases mouse, unlinks from the canvas, processes all pending events of the window
// if called from within main thread then destroys the window directly
// otherwise posts a window destroy event for oneself and waits for it to be processed
procedure destroywindow;


== NoGui ==
// registers the instance of onself in the "owner" widget, allocates the canvas,
=== TAction ===
// adds a reference to oneself,
<pre>
// then prepares the "owner" hierarchy to be invalidated ( "owner.rootchanged" )
Shortcut processing order :
// since now, the window is allocated and belongs to the "aowner" widget
constructor create(aowner: twidget);


- the smallest piece of processing is "doshortcut" procedure which
destructor destroy; override;
is called until processed:
= starting from the sender up to the toplevel widget
= then by all child widgets with non-set "ow_noparentshortcut"
= then, if "ow_nochildshortcut" isn't set, by the parent widget
= then by the widget oneself
- "doshortcut" is checked in the following order:
= starting from form's main menu
= then from the owning window ( the widget oneself )
= then from the application


// adds "method" to the internal list of scroll dependants
procedure registeronscroll(const method: notifyeventty);


*** A shortcut is bound to a widget by :
// removes "method" from the internal list of scroll dependants
- placing an action component on the widget ***
procedure unregisteronscroll(const method: notifyeventty);
- direct assigning the shortcut to the widget (menus,..)  
---------------------------


caption, color, colorglyph, helpcontext, hint, imagecheckedoffset,
// releases mouse if captured, resets the cursor, then enters an event loop for the window,
imagelist <see "timagelist">, imagenr, imagenrdisabled
// TRUE on return if the window is destroyed
function beginmodal: boolean;
  * checks if the "sender" window is already modal to avoid circularity,  
    if not then starts an event loop  for the "sender" where the "sender" is a receiver of GUI events,
      once the loop is terminated reactivates the previously active window if it was,
    TRUE if modalwindow destroyed 


- sets look of "clients" (buttons, menu/toolbar items,..), unless
  function tinternalapplication.beginmodal(const sender: twindow): boolean;
these clients have "state.as_local*" set :


*** For meaning of these options, see help on the "client" widgets ***
// removes the internal stuff which indicates the modal state
procedure endmodal;


group
// if the window is visible,
- default value for one-named property of the bound widgets
// deactivates the previously active window, shows the window (see below),
( menu items,... )
// if no active window in the app or the window or its Z-predecessor is modal and
// the app has no focused widget then prepares the bound widget to be focused,
// then addresses the WM to put the window to foreground
procedure activate;


options :
  // if the bound widget has visible=true then:
ao_updateonidle
  //  - if NOT windowevent then :
- runs this action in cycle, waiting for no gui events everytime
  //    = address the WM to set size of the window acc to window opts
  //      wp_maximized, wp_fullscreen or normal size otherwise
  // = if the window is normally sized, moves it to its default position is specified ( screen centered etc )
  // - unhides/unminimizes the window if needed
  // - shows other windows of the applications acc to state of the window group
  // ( in normal size or minimized )


ao_globalshortcut
  private
- allows the action to trigger on a non-main form
procedure twindow.show(windowevent: boolean);
  (the shortcut is triggered whatever form of the applicatin it was pressed on,
  otherwise only when the form where the aption is placed on is focused )


ao_nocandefocus
// TRUE if this window currently grabs user input
- causes the action not to call "CanDefocus" for focused edit widget of active form
( a widget drawn within the window(=form) is in focus,.. )
  before executing own code
function active: boolean;
  ( it helps to avoid the effect of cancelling changes in these widgets
  on activating the bound shortcut )


shortcut
// if the window was active then deactivates the window  & remembers it as the previous active ( to restore leater if requested ),
- keyboard combination triggering the action
// returns TRUE if that storage occurred
function deactivateintermediate: boolean;


shortcut
// makes the window active & clears the above app reference to it ( "active before deactivating" )
- alternative "shortcut" and handled identically
procedure reactivate; //clears app.finactivewindow


state :
// scans the app event queue for "ek_expose" event[s] addressed to the window,
// if found then redraws that part of the window which the event describes
// ( processed events are then deleted )
procedure update;


as_disabled
// TRUE if the window :
- prevents the action from triggering, also puts the bound widgets to "disabled" look
// 1) doesn't have an inner widget grabbing input focus
// or
// 2) has such widget, and this widget ( and all its descendants )
//    pass "CanClose" check
//
// *** see also "twidget.CanClose" ***
//
function candefocus: boolean;


as_invisible
// tries to defocus the currently focused widget if it belongs to the window,
- in run-time, hides the bound widget, still reacting on the shortcut or direct call
// if succeeds then executes code of virtual "DoDefocus" of the widget descessor
 
// ( this code defines behaviour & look of the widget on defocusing );
as_checked
//
- selects the bound menu item if it has "mao_checkbox" option set
// no defocusing is done if the focused widget ( or its descendants )
 
// doesn't pass "CanClose" check
as_default
//
as_local*
procedure nofocus;
 
 
statfile
  // setfocusedwidget(widget)
<see "tstatfile">
 
  property focuscount: cardinal read ffocuscount;
  function close: boolean; //true if ok
  procedure beginmoving; //lock window rect modification
  procedure endmoving;
  procedure bringtofront;
  procedure sendtoback;
  procedure stackunder(const predecessor: twindow);
      //stacking is performed in mainloop idle, nil means top
  procedure stackover(const predecessor: twindow);
      //stacking is performed in mainloop idle, nil means bottom
  function stackedunder: twindow; //nil if top
  function stackedover: twindow;  //nil if bottom
  function hastransientfor: boolean;


stavarname
  procedure capturemouse;
  procedure releasemouse;
  procedure postkeyevent(const akey: keyty;
        const ashiftstate: shiftstatesty = []; const release: boolean = false;
                  const achars: msestring = '');


  function winid: winidty;
tagaction
  function haswinid: boolean;
onasyncevent
  function state: windowstatesty;
onchange
  function visible: boolean;
onexecute
  function activating: boolean; //in internalactivate proc
onupdate
  function normalwindowrect: rectty;
<pre/>
  property updateregion: regionty read fupdateregion;
  function updaterect: rectty;


=== TActivator ===
  procedure registermovenotification(sender: iobjectlink);
=== TThreadComp ===
  procedure unregistermovenotification(sender: iobjectlink);
=== TStatFile ===
- so that to be in effect, it should also be assigned to the form where the widget using the stafile is placed on
- in design, if "onstatwrite" is set and "filedir" is not yet created, deactivate exception "ECreateError" in project settings ( "Debugger" tab )
- "filedir" may contain "~/" indicating the user's home directory
- options "oe_savestate" & "oe_savevalue" of "client" widgets define what to store to the file
- position etc changes or/and value changes
- in case when a main form shares its stafile with non-main forms, on creating non-main ones, just edited not saved data of the main form ( bound to vars of the statfile) are reset to values read from the statfile upon creating the form; for "sfo_memory", this effect absents unless widgets on the concurring forms share same variable[s]; to avoid this behaviour, disable "fo_autoreadstat" & "fo_autowritestat" of the non-main forms
- each "tstafile" owns:
= tstatwriter:
* provides methods of writing sections & statvars to a memory/file stream
- tstatreader:
* holds list of sections with statvars each
* provides search & check & reading interface to the statvars
* provides reading statvars from a memory/file stream


Positioning to a section speeds up accessing its statvars
  property options: windowoptionsty read foptions;


- there also is "tstatfiler" ( exposed by some "tstatfile" events ) which:
// widget
= may present or "tstatwriter" or "tstatreader" ( there's a check method )
property owner: twidget read fowner;
= provides directionless "update" methods with internal switch to needed direction of processing
- "reading" or "writing" statvars on per-section basis


=== TTimer ===
  property focusedwidget: twidget read ffocusedwidget;
=== TNoGuiAction ===
  property transientfor: twindow read ftransientfor;
=== TPipeReadercomp ===
  property modalresult: modalresultty read fmodalresult write setmodalresult;
=== TSysEnvManager ===
  property buttonendmodal: boolean read getbuttonendmodal write setbuttonendmodal;
=== TProcessMonitor ===
  property globalshortcuts: boolean read getglobalshortcuts write setglobalshortcuts;
=== TFilechangeNotifier ===
  property localshortcuts: boolean read getlocalshortcuts write setlocalshortcuts;
  property windowpos: windowposty read getwindowpos write setwindowpos;
  property caption: msestring read fcaption write setcaption;
 
 
windowoptionty = (wo_popup,wo_message,wo_buttonendmodal,wo_groupleader,
                  wo_windowcentermessage); //showmessage centered in window
 
 
optionswindow:
wo_popup
- in run-time, hides all OS windows-manager ( WM ) decorations (title bar, buttons "Close/Resize,Min/Max" etc),
letting only its client area to appear
so :
= the window should have own facilities to replace the deactivated WM functionality if needed
= can't be resized/maximize/minimized/moved
wo_message
- similar to "wo_popup" but allows WM to close ( with "Close" button ) & move the window
 
wo_groupleader
- keeps on the WM taskbar a shortcut to the window
( if the parent window is a groupleader too then displays a step upper in its group )
 
Event handlers:
 
- onmove
= fires once the (window/widget) is created/moved ( with check if really moved by a distance)
 
</pre>


== Font ==
=== TFormScrollbox ===
=== Any Font ===
<pre>
<pre>
    charset { ANSI/ DEFAULT/ SYMBOL /SHIFTJIS /HANGEUL /GB2312 /CHINESEBIG5 /OEM
- presents client area of form & parent of its widgets,
/JOHAB / HEBREW/ ARABIC/ GREEK/ TURKISH/ VIETNAMESE/ THAI/ EASTEUROPE/
initially stretched to fit the form & bound with anchoring
RUSSIAN/ MAC/ BALTIC }
but may be adjusted with "bounds" & "anchors"
- changes the font to the nearest containing the selected encoding(charset)
 
- no font change made if the supplied encoding doesn't match any font
    Properties:
               
anchors
bounds
color
color
- color of the glyphs contours
- color of the whole container area ( except its frame ) & form widgets
colorbackground
if their color is "cl_parent"
- fill color of the glyph cells ( not including extraspace )
 
colorshadow
name = container
- color of SE glyph "edges" ( if not "cl_none", deactivates "colorbackground" )
 
extraspace
cursor, enabled, face, frame, helpcontext, hint, optionswidget, popupmenu,
- v-space between glyph cells of adjacent text rows (negative values cause the cells to overlap )
taborder, tag, visible, onactivate, onafterpaint, onbeforepaint,  
height
onchildmouseevent, onclientmouseevent, ondeativate, ondefocus, onenter,
- v-size of glyph cells, in pixels
onexit, onfocus, onfontheightdelta, onmouseevent, onpaint, onpopup
name
onresize, onshowhint
- initially, font is choosen by { "family" = this name }
- the same meaning as for the served form
options:
 
foo_fixed
 
- changes the font to the nearest "mono" spaced (usually = Courier)
oncalcminscrollsize
foo_proportional
onscroll
- changes the font to the nearest "proportionally" spaced (usually = Helvetica)
onchildscaled
foo_helvetica
</pre>
- changes the font to the nearest in "sans" category (usually = Helvetica)
 
foo_roman
=== TFaceList ===
- changes the font to the nearest in "serif" category (usually = Times[ New Roman])
=== TFrameComp ===
foo_script
 
- Win32 only, changes the font to the nearest in "script" category
See also here: [[Reference:_MSEgui/TFrame]].
foo_decorative
 
- Win32 only, changes the font to the nearest in "decorative" category
foo_antialiased
<pre>
- Linux-only, enables antialiasing (if disabled by Xft globally)
Terminology :
foo_nonantialiased
 
- Linux-only, disables antialiasing (if enabled by Xft globally)
{client area = area of the widget which interacts with a user}
usually making glyph extents (not cells !) a bit wider
style:
fs_bold
- gives the font a "bold" look
fs_italic
- gives the font an "italic" look
fs_underline
- gives the font an "underlined" look
fs_strikeout
- gives the font a "striked out" look
fs_selected
- "TRUE" here combined with {tf_noselect:=FALSE}, causes the text described by this font
to be initially selected ( with the clipboard operations available ),
currently applicable only to richstrings


width
{bevelling = additional facets rising/sinking frame & client area,
- 10*{ glyph cell width, average in pixels }, 0 = {font default}
constists of two parts -  
- external: between frame and widget
- internal: between frame and client area
}


xscale
{frame= flat space between external & internal facets,
- width ratio of each glyph {cell & contour}, the effect is similar to "width"
floats at the inner level of the external facet
}
 
*** Both frame & bevelling affect the client area ***
 
--------------------------
template:


*** "foo_*" font selection overrides one made with "name"
colorclient = color of the client area


*** if change with "foo_*" is usuccessful then the nearest "sans" font is usually choosen
colorframe = color of the frame
colorframeactive = used instead of colorframe if the widget is
active; "cl_default" means same as colorframe.


*** The categories :
works if (leveli/levelo <> 0 that's the facets exist :


sans => have no serifs and have strokes of even thickness
colorshadow = color of facets screened from the NW light source
serif => have serifs at glyph contours and made up of strokes of varying thickness
colordkshadow = color of shadows dropped by the NW light source
script => resemble handwriting
                colordkwidth = width of the shadows in pixel, -1=default
decorative => flashy styles to be used sparingly in headlines or posters


<pre/>
colorlight = color of facets exposed to the NW light source
colorhighlight = color of brighter edges of the facets
                colorhlwidth = width of the brighter edges in pixel, -1=default


== GUI ==
        extraspace = if applied to menu items, adds more space between these items
=== TWindow ===
<pre>
twindow = class(teventobject,icanvas)
  public


// releases mouse, unlinks from the canvas, processes all pending events of the window
framei_:
// if called from within main thead then destroys the window directly
(for extendable widgets like menus, these settings widen the widget,
// otherwise posts a window destroy event for oneself and waits for it to be processed
for non-extendable like buttons - they squeeze the text area )
procedure destroywindow;


// registers the instance of onself in the "owner" widget, allocates the canvas,
bottom= lower margin of text to the client area
// adds a reference to oneself,
left = left margin of text to the client area
// then prepares the "owner" hierarchy to be invalidated ( "owner.rootchanged" )
right = margin of text to the client area
// since now, the window is allocated and belongs to the "aowner" widget
top = upper margin of text to the client area
constructor create(aowner: twidget);


destructor destroy; override;
framewidth= width of the frame
leveli = {width=height} of the internal facet, positive -> raised, negative -> sunken
levelo = {width=height} of the external facet, positive -> raised, negative -> sunken


// adds "method" to the internal list of scroll dependants
<any frame>
procedure registeronscroll(const method: notifyeventty);


// removes "method" from the internal list of scroll dependants
*** extends & customizes "tframecomp" ***
procedure unregisteronscroll(const method: notifyeventty);


// releases mouse if captured, resets the cursor, then enters an event loop for the window,
template
// TRUE on return if the window is destroyed
- "tframecomp" supplying the initial settings
function beginmodal: boolean;
 
colorclient,colordkshadow,colordkwidth,colorframe,colorframeactive,
  * checks if the "sender" window is already modal to avoid circularity,  
colorhighlight,colorhlwidth,colorlight,colorshadow,framewidth,
    if not then starts an event loop  for the "sender" where the "sender" is a receiver of GUI events,
leveli, levelo, framei_*,
      once the loop is terminated reactivates the previously active window if it was,
 
    TRUE if modalwindow destroyed 
<see "tframecomp">


  function tinternalapplication.beginmodal(const sender: twindow): boolean;
font
<see "tfont">


// removes the internal stuff which indicates the modal state
caption
procedure endmodal;
- some descriptive text( function name, user prompt,...) placed
in a N/W/S/E-combination to the widget's client area


// if the window is visible,
***
// deactivates the previously active window, shows the window (see below),
non-empty caption if (captionpos <> cp_center) & (captiondistouter=false & captiondist>0) enlarges the framed widget  
// if no active window in the app or the window or its Z-predescessor is modal and
by the corresponding size of caption
// the app has no focused widget then prepares the bound widget to be focused,
// then addresses the WM to put the window to foreground
procedure activate;


  // if the bound widget has visible=true then:
***
  //  - if NOT windowevent then :
  //    = address the WM to set size of the window acc to window opts
  //      wp_maximized, wp_fullscreen or normal size otherwise
  // = if the window is normally sized, moves it to its default position is specified ( screen centered etc )
  // - unhides/unminimizes the window if needed
  // - shows other windows of the applications acc to state of the window group
  // ( in normal size or minimized )


  private
captiondist - margin between the caption & the client area
procedure twindow.show(windowevent: boolean);


// TRUE if this window currently grabs user input
captiondistouter :
( a widget drawn within the window(=form) is in focus,.. )
function active: boolean;


// if the window was active then deactivates the window  & remembers it as the previous active ( to restore leater if requested ),
- if "false"(by default), the distance is measured between
// returns TRUE if that storage occured
the inner (facing the client area) extent of the caption
function deactivateintermediate: boolean;
and the client area outward the area,  
the caption is placed outside of the client area


// makes the window active & clears the above app reference to it ( "active before deactivating" )
- if "true", the caption is mirrored against the edge of client area as
procedure reactivate; //clears app.finactivewindow
to the position when "false"


// scans the app event queue for "ek_expose" event[s] addressed to the window,
*** nagative values of "captiondist" visually inverse "out of" and within ***
// if found then redraws that part of the window which the event describes
 
// ( processed events are then deleted )
      captionnoclip - do not clip frame and client area for caption background
procedure update;
( the client area preserves own background under the caption text)
 
captionnooffset - shift orthogonal to "captiondist"
 
captionpos - "corner" where to place the caption
 
localprops :
 
frl_levelo - "levelo" overrides "template.levelo"
frl_leveli - "leveli" overrides "template.leveli"
frl_framewidth - "framewidth" overrides "template.framewidth"
frl_colorclient - "colorclient" overrides "template.colorclient"
frl_colorframe - "colorframe" overrides "template.colorframe"
frl_colorframeactive - "colorframeactive" overrides "template.colorframeactive"
frl_colordkshadow - "colordkshadow" overrides "template.colordkshadow"
frl_colorshadow - "colorshadow" overrides "template.colorshadow"
frl_colorlight - "colorlight" overrides "template.colorlight"
frl_colorhighlight - "colorhighlight" overrides "template.colorhighlight"
frl_colordkwidth - "colordkwidth" overrides "template.colordkwidth"
frl_colorhlwidth - "colorhlwidth" overrides "template.colorhlwidth"
frl_fileft - "framei_left" overrides "template.framei_left"
frl_firight - "framei_right" overrides "template.framei_right"
frl_fitop - "framei_top" overrides "template.framei_top"
frl_fibottom - "framei_bottom" overrides "template.framei_bottom"
 
frl_nodisable
</pre>
 
=== TFaceComp ===


// TRUE if the window :
See also here: https://wiki.freepascal.org/Reference:_MSEgui/TFace
// 1) doesn't have an inner widget grabbing input focus
// or
// 2) has such widget, and this widget ( and all its descendants )
//    pass "CanClose" check
//
// *** see also "twidget.CanClose" ***
//
function candefocus: boolean;


// tries to defocus the currently focused widget if it belongs to the window,
<pre>
// if succeeds then executes code of virtual "DoDefocus" of the widget descessor
- doesn't affect the widget frame but client area of the frame
// ( this code defines behaviour & look of the widget on defocusing );
//
// no defocusing is done if the focused widget ( or its descendants )
// doesn't pass "CanClose" check
//
procedure nofocus;
 
  // setfocusedwidget(widget)
 
  property focuscount: cardinal read ffocuscount;
  function close: boolean; //true if ok
  procedure beginmoving; //lock window rect modification
  procedure endmoving;
  procedure bringtofront;
  procedure sendtoback;
  procedure stackunder(const predecessor: twindow);
      //stacking is performed in mainloop idle, nil means top
  procedure stackover(const predecessor: twindow);
      //stacking is performed in mainloop idle, nil means bottom
  function stackedunder: twindow; //nil if top
  function stackedover: twindow;  //nil if bottom
  function hastransientfor: boolean;


  procedure capturemouse;
  procedure releasemouse;
  procedure postkeyevent(const akey: keyty;
        const ashiftstate: shiftstatesty = []; const release: boolean = false;
                  const achars: msestring = '');


  function winid: winidty;
template:
  function haswinid: boolean;
fade:
  function state: windowstatesty;
color[i]: = colors forming the fade
  function visible: boolean;
direction: = direction where the fade grows to
  function activating: boolean; //in internalactivate proc
gd_(right/up/left/down)
  function normalwindowrect: rectty;
  property updateregion: regionty read fupdateregion;
  function updaterect: rectty;


  procedure registermovenotification(sender: iobjectlink);
pos[i]: = relational position of color[i] on the direction (0.0..1.0) extent
  procedure unregistermovenotification(sender: iobjectlink);


  property options: windowoptionsty read foptions;
transparency = makes the face half-transparent and enlighten the underlying widget 
with a light source of the selected color
( in this case, colors of the face & the widget & the light source
simply summarize to higher brightness )


// widget
image:
property owner: twidget read fowner;
see <any image>


  property focusedwidget: twidget read ffocusedwidget;
options:
  property transientfor: twindow read ftransientfor;
  property modalresult: modalresultty read fmodalresult write setmodalresult;
  property buttonendmodal: boolean read getbuttonendmodal write setbuttonendmodal;
  property globalshortcuts: boolean read getglobalshortcuts write setglobalshortcuts;
  property localshortcuts: boolean read getlocalshortcuts write setlocalshortcuts;
  property windowpos: windowposty read getwindowpos write setwindowpos;
  property caption: msestring read fcaption write setcaption;


        *** The fade colors are used not as colors but RGB alpha values ($00 -> opaque, $ff -> transparent)
if fao_alpha* are set *** :


windowoptionty = (wo_popup,wo_message,wo_buttonendmodal,wo_groupleader,
fao_alphafadeall = applies blending to the widget & all its children
                  wo_windowcentermessage); //showmessage centered in window
fao_alphafadenochildren = preserves child widgets from blending
                fao_alphafadeimage = applies blending to "face.image"




optionswindow:
<any face>
wo_popup
- in run-time, hides all OS windows-manager ( WM ) decorations (title bar, buttons "Close/Resize,Min/Max" etc),
letting only its client area to appear
so :
= the window should have own facilities to replace the deactivated WM functionality if needed
= can't be resized/maximize/minimized/moved
wo_message
- similar to "wo_popup" but allows WM to close ( with "Close" button ) & move the window


wo_groupleader
*** extends & customizes "tfacecomp" ***
- keeps on the WM taskbar a shortcut to the window
( if the parent window is a groupleader too then dislpays a step upper in its group )


Event handlers:
fade, image, option
- see "tfacecomp"
template
- "tfacecomp" supplying the initial settings


- onmove
localprops :
= fires once the (window/widget) is created/moved ( with check if really moved by a distance)
fal_options - "options" overrides "template.options"
fal_fadirection - "fade.direction" overrides "template.fade.direction"
fal_image - "image" overrides "template.image"
fal_fapos - "fade.pos[i]" overrides "template.fade.pos[i]"
fal_facolor - "fade.color[i]" overrides "template.fade.color[i]"
fal_fatransparency - "fade.transparency" overrides "template.fade.transparency"
</pre>


<pre/>
=== TBitmapComp ===
=== TFaceList ===
=== TScalingwidget ===
=== TFrameComp ===
<pre>
Terminilogy :
  optionsscale :
autosizing to provide room for :
= {"frame.caption" + "offset_*"}
= "offset_*" if "frame.caption" is unset and "osc_shrink*" is set
= osc_expandx
- makes the widget wider to fit the caption if needed


client area = area of the widget which interacts with a user
= osc_shrinkx
- makes the widget narrower to have no space left & right to the "frame.caption"


bevelling = additional facets rising/sinking frame & client area,
= osc_expandy
constists of two parts
- makes the widget taller to fit the caption if needed
- external: between frame and widget
- internal: between frame and client area


frame= flat space between external & internal facets, floats at the inner level of the external face
= osc_shrinky
- makes the widget lower to have no space up & down to the "frame.caption"


* Both frame & bevelling affect the client area ***
= osc_invisishrinkx
- fully h-collapses if "visible=false" ( run-time only )


=== TFaceComp ===
= osc_invisishrinky
- doesn't affect the widget frame but client area of the frame
- fully v-collapses if "visible=false" ( run-time only )


</pre>


template:
=== TImageList ===
fade:
=== TPopupMenu ===
color[i]: = colors forming the fade
=== TMainMenu ===
direction: = direction where the fade grows to gd_(right/up/left/down)
        pos[i]: = relational position of color[i] on the direction (0.0..1.0) extent


transparency = makes the face half-transparent and enlight the underlying widget 
== Dialog ==
with a light source of the selected color
=== TFileListview ===
( in this case, colors of the face & the widget & the light source
=== TFileDialog ===
simply summarize to higher brightness )
=== TFaceComp ===
=== TFileNameEdit ===
=== TDirDropdownEdit ===
=== TColorEdit ===
=== TMemoDialogEdit ===
=== TPageSizeSelector ===
=== TPageOrientationSelector ===


image:
== Application ==
see <any image>
=== TGuiApplication ===
<pre>
tguiapplication = class(tcustomapplication)
  public


options:
  // [re]starts the system timer with the new period and
  // subscribes the application to be a receiver of the modified "ek_timer" event
  // ( can check for it in the event queue )
  procedure settimer(const us: integer);


*** The fade colors are used not as colors but RGB alpha values ($00 -> opaque, $ff -> transparent)  
  // finds a window by its winID
if fao_alpha* are set *** :
  function findwindow(id: winidty; out window: twindow): boolean;


fao_alphafadeall = applies blending to the widget & all its childs
  // finds a window by its ID & adjusts "rect" so that it
fao_alphafadenochildren = preserves child widgets from blending
  // fits "bounds_minc*" & "bounds_maxc*" of the found window
fao_alphafadeimage = applies blending to "face.image"
  procedure checkwindowrect(winid: winidty; var rect: rectty);


<any face>
  // initialises the timer and "megraphics"
  procedure initialize;


*** extends & customizes "tfacecomp" ***
  // frees the allocated system resources (GDI, event subscription, the timer)
  procedure deinitialize;


fade, image, option
  // creates a form instance, it will be shown in "application.run"
- see "tfacecomp"
  procedure createform(instanceclass: widgetclassty; var reference);
template
- "tfacecomp" supplying the initial settings


localprops :
  // invalidates all registered forms ( all their widgets will be redrawn )
fal_options - "options" overrides "template.options"
  procedure invalidate;
fal_fadirection - "fade.direction" overrides "template.fade.direction"
 
fal_image - "image" overrides "template.image"
  // calls a nested main event loop, forces processing any pending messages,
fal_fapos - "fade.pos[i]" overrides "template.fade.pos[i]"
  procedure processmessages; override; //handle with care!
fal_facolor - "fade.color[i]" overrides "template.fade.color[i]"
fal_fatransparency - "fade.transparency" overrides "template.fade.transparency"


=== TBitmapComp ===
  // TRUE if no pending events to process for the application
=== TImageList ===
  function idle: boolean; override;
=== TPopupMenu ===
 
=== TMainMenu ===
  // requests to indicate waiting ( to show the "watches" cursors )
  procedure beginwait; override;


== No GUI ==
  // removes the "watches" if no unclosed requests for displaying them,
=== TAction ===
  // otherwise closes the currently active request
Shortcut processing order :
  procedure endwait; override;


- the smallest piece of processing is "doshortcut" procedure which
  // TRUE if there are unclosed requests for displaying "watches"
is called until processed:
  function waiting: boolean;
= starting from the sender up to the toplevel widget
= then by all child widgets with non-set "ow_noparentshortcut"
= then, if "ow_nochildshortcut" isn't set, by the parent widget
= then by the widget oneself
- "doshortcut" is checked in the following order:
= starting from form's main menu
= then from the owning window ( the widget oneself )
= then from the application


* A shortcut is bound to a widget by :
  // TRUE if ESC has just been pressed
  - placing an action component on the widget ***
  // - if all requests for displaying "watches" are closed then refreshes
- direct assigning the shortcut to the widget (menus,..)
  //    the internal list of events ( the GUI-queue -> the app event list)
 
  function waitescaped: boolean; //true if escape pressed while waiting
=== TShortCutController ===
=== TPostscriptPrinter ===
=== TGdiPrinter ===
=== TWmfPrinter ===
=== TSkinController ===
=== TGuiThreadComp ===


== Dialog ==
  // sets state of the current wait dialogue ( but doesn't close one ) to undefined
=== TFileListview ===
  procedure resetwaitdialog; 
=== TFileDialog ===
=== TFaceComp ===
=== TFileNameEdit ===
=== TDirDropdownEdit ===
=== TColorEdit ===
=== TMemoDialogEdit ===
=== TPageSizeSelector ===
=== TPageOrientationSelector ===


== Application ==
  // runs "aexecuteaction" in the main thread in OnIdle mode,
=== TGuiApplication ===
  // then shows a cancellable message,
<pre>
  // if the one is cancelled then runs "acancelaction" then
tguiapplication = class(tcustomapplication)
  // either fully clears (if exceptions occur )  
  public
  // or terminates the execution otherwise,
 
   // true if not cancelled;
   // [re]starts the system timer with the new period and
   // "application.processmessages" must be called regularly if "aexecuteaction" is used here,
   // subscribes the application to be a receiver of the modified "ek_timer" event
   // alternatively "aidleaction" can be used, call sleep ( some time ) in order to minimize
   // ( can check for it in the event queue )
  // processor load.
   procedure settimer(const us: integer);
  // If athread <> nil the function starts and terminates the thread   
   function waitdialog(const athread: tthreadcomp = nil; const atext: msestring = '';
                  const caption: msestring = '';
                  const acancelaction: notifyeventty = nil;
                  const aexecuteaction: notifyeventty = nil): boolean; override;


   // finds a window by its winID
   // closes the currently modal waitdialogue with "cancelled" state
   function findwindow(id: winidty; out window: twindow): boolean;
   procedure cancelwait;


   // finds a window by its ID & adjusts "rect" so that it
   // closes the currently modal waitdialogue with "ok" state
  // fits "bounds_minc*" & "bounds_maxc*" of the found window
   procedure terminatewait;
   procedure checkwindowrect(winid: winidty; var rect: rectty);


   // inits the timer and "megraphics"
   function waitstarted: boolean;  // the last waitdialogue is currently showing for some requests
   procedure initialize;
  function waitcanceled: boolean;  // the last waitdialogue has been cancelled for some request (but can be shown fot others ?)
   function waitterminated: boolean; // the last waitdialogue has been terminated for some request (but can be shown fot others ?)


   // frees the allocated system resources (GDI, event subsription, the timer)
   // if called from the main app thread then shows as a modal message describing the exception
   procedure deinitialize;
  // otherwise posts an async event for which the message will be called
   procedure showexception(e: exception; const leadingtext: string = ''); override;


   // creates a form instance, it will be shown in "application.run"
   // posts an async event for which the message describing the exception will be called
   procedure createform(instanceclass: widgetclassty; var reference);
   procedure showasyncexception(e: exception; const leadingtext: string = '');


   // invalidates all registered forms ( all their widgets will be redrawn )
   // "application.errormessage" shows standard error message ( with "ERROR" title )  
   procedure invalidate;
   procedure errormessage(const amessage: msestring); override;
 
  // calls a nested main eventloop, forces processing any pending messages,
  procedure processmessages; override; //handle with care!


   // TRUE if no pending events to process for the application
   // [re]calculates timings & position of hint for "ahintedwidget"
  function idle: boolean; override;
   // if "ow_timedhint" in "ahintedwidget.foptionswidget" then iys showtime will be
    
   // "defaulthintshowtime" ( an app wide setting, 3sec by default)  
   // requests to indicate waiting ( to show the "watches" cursos )
   procedure inithintinfo(var info: hintinfoty; const ahintedwidget: twidget);
   procedure beginwait; override;


  // removes the "watches" if no unclosed requests for displaying them,
  // otherwise closes the currently active request
  procedure endwait; override;


   // TRUE if there're unclosed requests for displaying "watches"
   // shows the supplied hint text within "aposrect" with alignment "aplacement" during "ashowtime",
   function waiting: boolean;
   // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove 
  procedure showhint(const sender: twidget; const hint: msestring;
              const aposrect: rectty; const aplacement: captionposty = cp_bottomleft;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;


   // TRUE if ESC has just been pressed
   // shows the supplied hint text at left-top position"apos" during "ashowtime",
  //  - if all requests for displaying "watches" are closed then refreshes
   // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove 
   //   the internal list of events ( the GUI-queue -> the app event list)
   procedure showhint(const sender: twidget; const hint: msestring;
   function waitescaped: boolean; //true if escape pressed while waiting
              const apos: pointty;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;


   // sets state of the current wait dialogue ( but doesn't close one ) to undefined
   // shows the hint fully defined in "info" for the widget "sender"
   procedure resetwaitdialog;  
   procedure showhint(const sender: twidget; const info: hintinfoty); overload;


   // runs "aexecuteaction" in the main thread in OnIdle mode,
   // removes the current hint widget & frees its resources & stops its stop timer
   // then shows a cancellable message,
   procedure hidehint;
  // if the one is cancelled then runs "acancelaction" then
  // either fully clears (if exceptions occur )
  // or terminates the execution otherwise,
  // true if not cancelled;
  // "application.processmessages" must be called regularly if "aexecuteaction" is used here,
  // alternatively "aidleaction" can be used, call sleep ( some time ) in order to minimize
  // processor load.
  // If athread <> nil the function starts and terminates the thread   
  function waitdialog(const athread: tthreadcomp = nil; const atext: msestring = '';
                  const caption: msestring = '';
                  const acancelaction: notifyeventty = nil;
                  const aexecuteaction: notifyeventty = nil): boolean; override;


   // closes the currently modal waitdialogue with "cancelled" state
   // restarts the current hint and its stop timer
   procedure cancelwait;
   procedure restarthint(const sender: twidget);


   // closes the currently modal waitdialogue with "ok" state
   function hintedwidget: twidget; //last hinted widget
   procedure terminatewait;
   function activehintedwidget: twidget; //nil if no hint active


   function waitstarted: boolean// the last waitdialogue is currently showing for some requests
   // returns helpcontext of active widget, '' if none;   
   function waitcanceled: boolean; // the last waitdialogue has been cancelled for some request (but can be shown fot others ?)
   function activehelpcontext: msestring;
   function waitterminated: boolean; // the last waitdialogue has been terminated for some request (but can be shown fot others ?)
 
  // returns helpcontext of the widget under mouse, '' if none;
   function mousehelpcontext: msestring;


   // if called from the main app thread then shows as a modal message describing the exception
   // TRUE if one of the app's window/console is in input focus
  // otherwise posts an async event for which the message will be called
   function active: boolean;
   procedure showexception(e: exception; const leadingtext: string = ''); override;


   // posts an async event for which the message describing the exception will be called
   // returns the desktop resolution ( or the virtual one if used )
   procedure showasyncexception(e: exception; const leadingtext: string = '');
   function screensize: sizety;


   // "application.errormessage" shows standard error message ( with "ERROR" title )  
   // returns the (virtual) desktop resolution except the tray area,
   procedure errormessage(const amessage: msestring); override;
   // nil -> current active window
  function workarea(const awindow: twindow = nil): rectty;


   // [re]calculates timings & position of hint for "ahintedwidget"
   // returns which application window ( a form not an eventwidget, an openglwidget or a windowwidget !)
   // if "ow_timedhint" in "ahintedwidget.foptionswidget" then iys showtime will be
   // is active ( provides the input focus ),
   // "defaulthintshowtime" ( an app wide setting, 3sec by default) 
   // it's same for all widgets of the form served by this window
   procedure inithintinfo(var info: hintinfoty; const ahintedwidget: twidget);
   function activewindow: twindow;


/ * A transient window is a descendant of ( "transientfor" ) another window in the stacking order hierarchy */


   // shows the supplied hint text within "aposrect" with alignment "aplacement" during "ashowtime",
   // returns a first non-transient ( on top of the app stacking order ) window upward
   // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove 
   // from the currently active window of the application.
   procedure showhint(const sender: twidget; const hint: msestring;
   // or that active window if no such
              const aposrect: rectty; const aplacement: captionposty = cp_bottomleft;
  function regularactivewindow: twindow;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;


   // shows the supplied hint text at left-top position"apos" during "ashowtime",
   // same as "activewindow" but the window must not be released (?)
  // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove 
   function unreleasedactivewindow: twindow;
   procedure showhint(const sender: twidget; const hint: msestring;
              const apos: pointty;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;


   // shows the hint fully defined in "info" for the widget "sender"
   // returns the focused widget of the currently active window if one exists
   procedure showhint(const sender: twidget; const info: hintinfoty); overload;
   function activewidget: twidget;


   // removes the current hint widget & frees its resources & stops its stop timer
   // returns the widget presenteing the currently active window
   procedure hidehint;
  function activerootwidget: twidget;
 
  // returns the window ( not hidden or disabled !) under the screen point "pos"
   function windowatpos(const pos: pointty): twindow;


   // restarts the current hint and its stop timer
   // puts to "awidget" the container of widget pointed by "namepath"
   procedure restarthint(const sender: twidget);
  // ( finalizing "." is discarded if found ) ,
  // FALSE if not found, and NIL and TRUE if "namepath" = ''
   function findwidget(const namepath: string; out awidget: twidget): boolean;


   function hintedwidget: twidget; //last hinted widget
   // rebuilds the application's window list accorrding to the current on-screen Z-order of its windows;
   function activehintedwidget: twidget; //nil if no hint active
  // window list is ordered by "z" - bottom first & top last;
   // invisibles first
  procedure sortzorder;


   // returns helpcontext of active widget, '' if none; 
   // returns a copy of the internal window list of application
   function activehelpcontext: msestring;
   function windowar: windowarty;


   // returns helpcontext of the widget under mouse, '' if none;
   // returns the list of application window winIDs
   function mousehelpcontext: msestring;
   function winidar: winidarty;


   // TRUE if one of the app's window/console is in input focus
   // returns the count of the application windows   
   function active: boolean;
   function windowcount: integer;


   // returns the desktop resolution ( or the virtual one if used )
   // returns the window by its number ( "index" >= 0) in the application window list
   function screensize: sizety;
   property windows[const index: integer]: twindow read getwindows;


   // returns the (virtual) desktop resolution except the tray area,
   // returns the lowest visible window in stackorder,  
   // nil -> current active window
   // calls "sortzorder" within
   function workarea(const awindow: twindow = nil): rectty;
   function bottomwindow: twindow;


   // returns which application window ( a form not an eventwidget, an openglwidget or a windowwidget !)
   // returns the highest visible window in stackorder,  
   // is active ( provides the input focus ),
   // calls "sortzorder" within
  // it's same for all widgets of the form served by this window
   function topwindow: twindow;
   function activewindow: twindow;


/ * A transient window is a descendant of ( "transientfor" ) another window in the stacking order hierarchy */


   // returns a first non-transient ( on top of the app stacking order ) window upward
   // TRUE if all owned windows pass "CanClose" check or
  // from the currently active window of the application.
   // don't have focused widgets
   // or that active window if no such
   function candefocus: boolean;
   function regularactivewindow: twindow;


   // same as "activewindow" but the window must not be released (?)
   // subscribes the handler "method" to receive keyboard events
   function unreleasedactivewindow: twindow;
   procedure registeronkeypress(const method: keyeventty);


   // returns the focused widget of the currently active window if one exists
   // unsubscribes the handler "method" from receiving keyboard events
   function activewidget: twidget;
   procedure unregisteronkeypress(const method: keyeventty);


   // returns the widget presenteing the currently active window
   // subscribes the handler "method" to receive shortcut events
  function activerootwidget: twidget;
   procedure registeronshortcut(const method: keyeventty);
 
  // returns the window ( not hidden or disabled !) under the screen point "pos"
   function windowatpos(const pos: pointty): twindow;


   // puts to "awidget" the container of widget pointed by "namepath"
   // unsubscribes the handler "method" from receiving shortcut events
  // ( finalizing "." is discarded if found ) ,
   procedure unregisteronshortcut(const method: keyeventty);
   // FALSE if not found, and NIL and TRUE if "namepath" = ''
  function findwidget(const namepath: string; out awidget: twidget): boolean;


   // rebuilds the application's window list accorrding to the current on-screen Z-order of its windows;
   // subscribes the handler "method" to receive "OnWindowActiveChanged" event ( form-wide )
  // window list is ordered by "z" - bottom first & top last;
   procedure registeronactivechanged(const method: activechangeeventty);
  // invisibles first
   procedure sortzorder;


   // returns a copy of the internal window list of application
   // unsubscribes the handler "method" from receiving "OnWindowActiveChanged" event ( form-wide )
   function windowar: windowarty;
   procedure unregisteronactivechanged(const method: activechangeeventty);


   // returns the list of application window winIDs
   // subscribes the handler "method" to receive "OnDestroyed" events ( form-wide )
   function winidar: winidarty;
   procedure registeronwindowdestroyed(const method: windoweventty);


   // returns the count of the application windows   
   // unsubscribes the handler "method" from receiving "OnDestroyed" events ( form-wide )
   function windowcount: integer;
   procedure unregisteronwindowdestroyed(const method: windoweventty);


   // returns the window by its number ( "index" >= 0) in the application window list
   // subscribes the handler "method" to receive "OnWindowDestroyed" events ( form-wide )
   property windows[const index: integer]: twindow read getwindows;
   procedure registeronwiniddestroyed(const method: winideventty);


   // returns the lowest visible window in stackorder,
   // unsubscribes the handler "method" form receiving "OnWindowDestroyed" events ( form-wide )
  // calls "sortzorder" within
   procedure unregisteronwiniddestroyed(const method: winideventty);
   function bottomwindow: twindow;


   // returns the highest visible window in stackorder,
   // subscribes the handler "method" to receive "ApplicationActiveChanged" events ( form-wide )
  // calls "sortzorder" within
   procedure registeronapplicationactivechanged(const method: booleaneventty);
   function topwindow: twindow;


  // unsubscribes the handler "method" from receiving "ApplicationActiveChanged" events ( form-wide )
  procedure unregisteronapplicationactivechanged(const method: booleaneventty);


  // TRUE if all owned windows pass "CanClose" check or
// tcustomapplication
  // don't have focused widgets
  function candefocus: boolean;


   // subscribes the handler "method" to receive keyboard events
   // subscribes the handler "method" to receive "OnTerminated" event ( form-wide )
   procedure registeronkeypress(const method: keyeventty);
   procedure registeronterminated(const method: notifyeventty);


   // unsubscribes the handler "method" from receiving keyboard events
   // unsubscribes the handler "method" from receiving "OnTerminated" events ( form-wide )
   procedure unregisteronkeypress(const method: keyeventty);
   procedure unregisteronterminated(const method: notifyeventty);


   // subscribes the handler "method" to receive shortcut events
   // subscribes the handler "method" to receive "OnTerminateQuery" event ( form-wide )
   procedure registeronshortcut(const method: keyeventty);
   procedure registeronterminate(const method: terminatequeryeventty);


   // unsubscribes the handler "method" from receiving shortcut events
   // unsubscribes the handler "method" from receiving "OnTerminateQuery" event ( form-wide )
   procedure unregisteronshortcut(const method: keyeventty);
   procedure unregisteronterminate(const method: terminatequeryeventty);


   // subscribes the handler "method" to receive "OnWindowActiveChanged" event ( form-wide )
   // subscribes the handler "method" to receive "OnIdle" event ( form-wide )
   procedure registeronactivechanged(const method: activechangeeventty);
   procedure registeronidle(const method: idleeventty);


   // unsubscribes the handler "method" from receiving "OnWindowActiveChanged" event ( form-wide )
   // unsubscribes the handler "method" from receiving "OnIdle" events ( form-wide )
   procedure unregisteronactivechanged(const method: activechangeeventty);
   procedure unregisteronidle(const method: idleeventty);


   // subscribes the handler "method" to receive "OnDestroyed" events ( form-wide )
   // calls "canclose" of all application windows except the "sender" window
   procedure registeronwindowdestroyed(const method: windoweventty);
  // if all "canclose"are TRUE then checks "OnTerminateQuery"
  // for all its subscribers ( usually forms of the application )
   procedure terminate(const sender: twindow = nil);  


   // unsubscribes the handler "method" from receiving "OnDestroyed" events ( form-wide )
   // TRUE as long as a "terminate" call is in progress
   procedure unregisteronwindowdestroyed(const method: windoweventty);
   function terminating: boolean;


   // subscribes the handler "method" to receive "OnWindowDestroyed" events ( form-wide )
   // TRUE as long as a "deinitialize" call is in progress
   procedure registeronwiniddestroyed(const method: winideventty);
  function deinitializing: boolean;
 
  // returns the current caret object ( the text input focus indicator ) of the application
   / ( this object provides facilities to control position & appearance & visibility & timings of the caret )
  property caret: tcaret read fcaret;


   // unsubscribes the handler "method" form receiving "OnWindowDestroyed" events ( form-wide )
   // returns the current mouse object of the application
   procedure unregisteronwiniddestroyed(const method: winideventty);
  / ( this object provides facitities to control position & appearance of the mouse )  
   property mouse: tmouse read fmouse;


   // subscribes the handler "method" to receive "ApplicationActiveChanged" events ( form-wide )
   // simulates mouseparkevent
   procedure registeronapplicationactivechanged(const method: booleaneventty);
  // ( an adjusting mouse movement without user intervention - grid snapping, docking etc ?)
   procedure mouseparkevent;


   // unsubscribes the handler "method" from receiving "ApplicationActiveChanged" events ( form-wide )
   // sets mouse position correction for further mouse events,
   procedure unregisteronapplicationactivechanged(const method: booleaneventty);
  // the real position is less the visual one by the supplied shift
   procedure delayedmouseshift(const ashift: pointty);


// tcustomapplication
  // returns/sets a cursor shape used for widgets having their cursor shape set to "cr_default";
  // setting it to "cr_default" restores the individual widget cursor(s)
  property widgetcursorshape: cursorshapety read fwidgetcursorshape write
                                        fwidgetcursorshape;


   // subscribes the handler "method" to receive "OnTerminated" event ( form-wide )
   // returns/sets the current application-wide cursor shape ( not "watches" if a waiting dialog is currently displayed ! )
   procedure registeronterminated(const method: notifyeventty);
  // or request to set a new cursor shape ( app-wide );
  // doesn't change when changing mouse widgets
  //
  // if called from a non-main app thread & no waiting dialogue displayed then redraws
  // the cursor immediately;
   // set it to "cr_default" to restore the shape to one set by "widgetcursorshape"
  //
  property cursorshape: cursorshapety; // cr_arrow, cr_*


   // unsubscribes the handler "method" from receiving "OnTerminated" events ( form-wide )
   // assures the displayed mouse cursor shape to be the shape assigned to the currently under-mouse widget,
   procedure unregisteronterminated(const method: notifyeventty);
  // otherwise "cr_default"  
   procedure updatecursorshape; //restores cursorshape of mousewidget


   // subscribes the handler "method" to receive "OnTerminateQuery" event ( form-wide )
   // returns a widget of the application where the mouse is currently positioned over
   procedure registeronterminate(const method: terminatequeryeventty);
   property mousewidget: twidget read fmousewidget;


   // unsubscribes the handler "method" from receiving "OnTerminateQuery" event ( form-wide )
   // returns a widget of the application currently "owning" the mouse ( grabbing all mouse input )
   procedure unregisteronterminate(const method: terminatequeryeventty);
   property mousecapturewidget: twidget read fmousecapturewidget;


  // subscribes the handler "method" to receive "OnIdle" event ( form-wide )
  procedure registeronidle(const method: idleeventty);


   // unsubscribes the handler "method" from receiving "OnIdle" events ( form-wide )
   // returns/sets a window to become the main window of the application
  procedure unregisteronidle(const method: idleeventty);
   // then resets all other application windows to the window group it belongs to ( Linux only );
 
   //
   // calls "canclose" of all application windows except the "sender" window  
   // the main window minimizes all windows if minimized;
   // if all "canclose"are TRUE then checks "OnTerminateQuery"
   property mainwindow: twindow read fmainwindow write setmainwindow;
   // for all its subscribers ( usually forms of the application )
   procedure terminate(const sender: twindow = nil);  


   // TRUE as long as a "terminate" call is in progress
   // returns which system thread was allocated to the application on its start
   function terminating: boolean;
   // ( the main thread )
  property thread: threadty read fthread;


   // TRUE as long as a "deinitialize" call is in progress
   // returns teh widget where a mouse button click occured last time
  function deinitializing: boolean;
   // ( to compare with when determinibg whether another widget is clicked )
 
   property buttonpresswidgetbefore: twidget read fbuttonpresswidgetbefore;
   // returns the current caret object ( the text input focus indicator ) of the application
  / ( this object provides facitities to control position & appearance & visibility & timings of the caret )
   property caret: tcaret read fcaret;


   // returns the current mouse object of the application
   // returns teh widget where a mouse button release occured last time
   / ( this object provides facitities to control position & appearance of the mouse )  
   // ( to compare with when determinibg whether another widget is clicked )
   property mouse: tmouse read fmouse;
   property buttonreleasewidgetbefore: twidget read fbuttonreleasewidgetbefore;


  // simulates mouseparkevent
  // ( an adjusting mouse movement without user intervention - grid snapping, docking etc ?)
  procedure mouseparkevent;


   // sets mouse position correction for further mouse events,
   // returns/sets the interval of mouse double click recognition ( in microsecs ),
   // the real position is less the visual one by the supplied shift
   // defaults to 0.4 sec
   procedure delayedmouseshift(const ashift: pointty);
   property dblclicktime: integer read fdblclicktime write fdblclicktime default
                defaultdblclicktime; //us


  // returns/sets a cursor shape used for widgets having their cursor shape set to "cr_default";
// tcustomapplication
  // setting it to "cr_default" restores the individual widget cursor(s)
  property widgetcursorshape: cursorshapety read fwidgetcursorshape write
                                        fwidgetcursorshape;


   // returns/sets the current application-wide cursor shape ( not "watches" if a waiting dialogue is curerntly displayed ! )
   // creates a datamodule instance ( its startup code including "OnLoaded" is executed )
   // or request to set a new cursor shape ( app-wide );
   procedure createdatamodule(instanceclass: msecomponentclassty; var reference);
  // doesn't change when changing mouse widgets
  //
  // if called from a non-main app thread & no waiting dialogue displayed then redraws
  // the cursor immediately;
  // set it to "cr_default" to restore the shape to one set by "widgetcursorshape"
  //
  property cursorshape: cursorshapety; // cr_arrow, cr_*


  // assures the displayed mouse cursor shape to be the shape assigned to the currently under-mouse widget,
  // otherwise "cr_default"
  procedure updatecursorshape; //restores cursorshape of mousewidget


   // returns a widget of the application where the mouse is currently positioned over
   // enters the application event loop;
   property mousewidget: twidget read fmousewidget;
  //
  // once the loop finishes, performs "OnTerminated" for all its subscribers,
  // destroys all application forms ( components & windows )
   procedure run;


   // returns a widget of the application currently "owning" the mouse ( grabbing all mouse input )
   // TRUE if the eventloop is entered
   property mousecapturewidget: twidget read fmousecapturewidget;
   function running: boolean;


  // returns/sets the application name
  // ( defaults to the full path to application executable in the native OS format );
  // currently, only for informatiion query purposes
  property applicationname: msestring read fapplicationname write fapplicationname;
 


   // returns/sets a window to become the main window of the application
   // if exclusive "rights" are satisfied for the main thread ( a mutex lock is OK )  & the event loop is in progress
   // then resets all other application windows to the window group it belongs to ( Linux only );
   // then posts the "event" to the main application thread for asyc processing,
  //
   // otherwise adds the event to the internal list for further handling as soon as the above conditions meet
  // the main window minimizes all windows if minimized;
   procedure postevent(event: tevent);
  property mainwindow: twindow read fmainwindow write setmainwindow;
 
   // returns which system thread was allocated to the application on its start
   // ( the main thread )
  property thread: threadty read fthread;


   // returns teh widget where a mouse button click occured last time
   // TRUE if never idle since last call,
   // ( to compare with when determinibg whether another widget is clicked )
   // unlocks the application and calls sleep if not mainthread and asleepus >= 0
  property buttonpresswidgetbefore: twidget read fbuttonpresswidgetbefore;
  function checkoverload(const asleepus: integer = 100000): boolean;


   // returns teh widget where a mouse button release occured last time
   // returns/sets the application exception handler
  // ( to compare with when determinibg whether another widget is clicked )
   property onexception: exceptioneventty read fonexception write fonexception;
   property buttonreleasewidgetbefore: twidget read fbuttonreleasewidgetbefore;


  // if not "eabort" & no unhandled exceptions,
  // executes the above "OnException" code if assigned
  // or shows an exception message otherwise;
  procedure handleexception(sender: tobject = nil;
                                      const leadingtext: string = '');


   // returns/sets the interval of mouse double click recognition ( in microsecs),
   // synchronizes the calling thread with the main event loop ( via a mutex),
   // defaults to 0.4 sec
   // TRUE if the calling thread allready holds the mutex,
   property dblclicktime: integer read fdblclicktime write fdblclicktime default
   // the mutex is recursive
                defaultdblclicktime; //us
  function lock: boolean;


// tcustomapplication
  // tries to synchronize the calling thread with the main event loop ( via a mutex)
  function trylock: boolean;


   // creates a datamodule instance ( its startup code including "OnLoaded" is executed )
   // releases the mutex if the calling thread holds the mutex,
   procedure createdatamodule(instanceclass: msecomponentclassty; var reference);
   // TRUE if no unlock done
  function unlock: boolean;


  // releases the mutex recursively if the calling thread holds the mutex,
  // returns "count" for the below "relockall"
  function unlockall: integer;


   // enters the application event loop;
   // regains the mutex to serve "count" locks
  procedure relockall(count: integer);
 
  // creates a syncronize event ( which will fire asyncronously then waits for another thread will allow it to finish ), assigns "proc" to it as the event handler,
  // then frees all locks temporarily then posts the event to the app event queue & waits fot it to be processed the resores the locks;
  //
  // TRUE if not aborted, quiet -> shows no exceptions if occurs
  //
  // the "syncronize event" is an event owning a semaphore which can be touched by another thread
  // thus causing "event.waitfo" to return & to exec the event handler code
   //
   //
   // once the loop finishes, performs "OnTerminated" for all its subscribers,
   function synchronize(const proc: objectprocty;
  // destroys all application forms ( components & windows )
                      const quite: boolean = false): boolean;
  procedure run;


   // TRUE if the eventloop is entered
   // TRUE if the calling ( this function ) thread is the application main thread
   function running: boolean;
   function ismainthread: boolean;


   // returns/sets the application name
   // TRUE if the currently locked thread is the application main thread
  // ( defaults to the full path to application executable in the native OS format );
   function islockthread: boolean;
   // currently, only for informatiion query purposes
  property applicationname: msestring read fapplicationname write fapplicationname;
 


   // if exclusive "rights" are satisfied for the main thread ( a mutex lock is OK )  & the event loop is in progress
   // waith for "athread" to terminate,
  // then posts the "event" to the main application thread for asyc processing,
   // does "unlock-relock" around waiting
   // otherwise adds the event to the internal list for further handling as soon as the above conditions meet
   procedure waitforthread(athread: tmsethread);
   procedure postevent(event: tevent);


   // TRUE if never idle since last call,
   // post a "nothing-to-do" event for asynchronous processing in the main thread
  // unlocks the application and calls sleep if not mainthread and asleepus >= 0
   procedure wakeupmainthread;
   function checkoverload(const asleepus: integer = 100000): boolean;


   // returns/sets the application exception handler
  // invalidates all registered forms of the application so that their widgets redraw land-specific captions
   property onexception: exceptioneventty read fonexception write fonexception;
  // ( changed by "mseconsts.setlangconsts" ),
  // called internally in "setlangconsts" before return
  procedure langchanged; virtual;
 
   // returns/sets "aps_terminated" state flag ( no actions ? )
  // this flag is also set internally by "terminate" if not cancelled
  property terminated: boolean read getterminated write setterminated;
 
  // returns the number of "handleexception" calls having an effect ( a message or the handler code )
   property exceptioncount: longword read fexceptioncount;


  // if not "eabort" & no unhandled exceptions,
  // executes the above "OnException" code if assigned
  // or shows an exception message otherwise;
  procedure handleexception(sender: tobject = nil;
                                      const leadingtext: string = '');


  // synchronizes the calling thread with the main event loop ( via a mutex),
private
  // TRUE if the calling thread allready holds the mutex,
// function tinternalapplication.beginmodal(const sender: twindow): boolean;
  // the mutex is recursive
  function lock: boolean;


  // tries to synchronize the calling thread with the main event loop ( via a mutex)
</pre>
  function trylock: boolean;


  // releases the mutex if the calling thread holds the mutex,
== DB ==
  // TRUE if no unlock done
  function unlock: boolean;


  // releases the mutex recursively if the calling thread holds the mutex,
=== DBedit ===
  // returns "count" for the below "relockall"
=== DBfields ===
  function unlockall: integer;
=== TDBwidgetgrid ===
<pre>
  Properties:


  // regains the mutex to serve "count" locks
        anchors - ...
  procedure relockall(count: integer);
bounds - ...


  // creates a syncronize event ( which will fire asyncronously then waits for another thread will allow it to finish ), assigns "proc" to it as the event handler,
color
  // then frees all locks temporarily then posts the event to the app event queue & waits fot it to be processed the resores the locks;
- color of the grid's client area
  //
cursor
  // TRUE if not aborted, quiet -> shows no exceptions if occurs
- cursor shape when the mouse is over the client area
  //
 
  // the "syncronize event" is an event owning a semaphore which can be touched by another thread
datacols
  // thus causing "event.waitfo" to return & to exec the event handler code
colorselect
  //
linecolor
  function synchronize(const proc: objectprocty;
linecolorfix
                      const quite: boolean = false): boolean;
linewidth
newrowcol
 
options
co_readonly
co_nofocus
co_invisible
co_disabled
co_drawfocus
co_mousemovefocus
co_lefbuttonfocusonly
co_focusselect
co_mouseselect
co_keyselect
co_multiselect
co_resetselectionexit
co_rowselect
co_fixwidth
co_fixpos
co_fill
co_proportional
co_nohscroll
co_savevalue
co_savestate
co_rowfont
co_rowcolor
co_zebracolor
co_nosort
co_sortdescent
co_norearrange
co_cancopy
co_canpaste
co_mousescrollrow
co_rowdatachange


  // TRUE if the calling ( this function ) thread is the application main thread
sortcol
  function ismainthread: boolean;
width


  // TRUE if the currently locked thread is the application main thread
items[N]
  function islockthread: boolean;
color
colorselect
datalist - ???
face - see <any face>
fontselect - see <any font>
frame - see <any frame>
linecolor
linecolorfix
linewidth
name
options
</pre>


  // waith for "athread" to terminate,
=== Report ===
  // does "unlock-relock" around waiting
  procedure waitforthread(athread: tmsethread);


  // post a "nothing-to-do" event for asynchronous processing in the main thread
==== TRepSpacer ====
  procedure wakeupmainthread;
==== TRecordBand ====
==== TrepValueDisp ====
==== TRepPageNumdisp ====
==== TRepPrintDateDisp ====
==== TBandGroup ====
==== TTileArea ====


  // invalidates all registered forms of the application so that their widgets redraw land-specific captions
== Design ==
  // ( changed by "mseconsts.setlangconsts" ),
  // called internally in "setlangconsts" before return
  procedure langchanged; virtual;


   // returns/sets "aps_terminated" state flag ( no actions ? )
=== TGdbMi ===
  // this flag is also set internally by "terminate" if not cancelled
=== TSyntaxEdit ===
   property terminated: boolean read getterminated write setterminated;
=== TSyntaxPainter ===
 
== Comm ==
 
=== TCommPort ===
=== TAsciiCommPort ===
=== TAsciiProtPort ===
=== TCommSelector ===
 
== General stuff==
 
=== Properties for all widgets ===
<pre>
 
name
 
anchors
 
-----------
 
- they control of design/runtime sticking widgets to their parents
 
- dimention pair ( top/bottom or left/right ) both set to "false" cause
the widget to fit the parent's client area in that dimention;
this effect may be partial in case of "bounds_c*max" settings limit the extents
 
*** Return to the look "before dimention fit" is only possible by manual resizing or setting "bounds_*"
-----------
an_left
- on run-time, resizes/shifts left the widget to keep the design-set distance
between the widget's left border and the left side of parent's client area
as the parent resizes, until scrolling begins
 
an_top
- on run-time, resizes/shifts up the widget to keep the design-set distance
between the widget's top border and the upper side of parent's client area
as the parent resizes, until scrolling begins
 
an_right
- on run-time, resizes/shifts right the widget to keep the design-set distance
between the widget's right border and the right side of parent's client area
as the parent resizes, until scrolling begins
 
an_bottom
- on run-time, resizes/shifts down the widget to keep the design-set distance
between the widget's bottom border and the lower side of parent's client area
as the parent resizes, until scrolling begins
 
bounds
 
cx - width of the widget
cxmax, cxmin - design/runtime width of the widget is enforced between "cxmax" and "cxmin"
cy - height of the widget
cymax, cymin - design/runtime height of the widget is enforced between "cymax" and "cymin"
x - distance between the widget's left border and the left side of parent's client area
y - distance between the widget's top border and the upper side of parent's client area
 
 
autosize
 
-----------
- only applicable to widgets with "ow_autosize" set
- the effect may be partial in case when "bounds_c*max" settings limit the extents
-----------
 
cx - addition to width of the widget (with h-centering post applied)
cy - addition to height of the widget (with v-centering post applied)
 
- color
= the default color of client area & caption text background
= may be overwritten:
* the client area - with "frame.colorclient"
* the caption BG - with "frame.font.colorbackground"
 
- font
= see {any font}
 
- frame
= see {any frame}
 
- face
= see {any face}
 
- hint
= descriptive text appearing when mouse pointer enters the widget
 
- cursor
= shape of the mouse pointer over the client area of widget (run-time only)
 
- visible
= "true" allow the widget to appear ( run-time only )
 
- enabled
= "true" allows the widget to participate in GUI interaction
= "false" disallows the widget & its children :
* processing all events & shortcuts & menu calls
* auto "CanClose" check
 
Also "false" usually paints the widget in color marking
the "disabled" state ( usually light gray font color )
 
- popupmenu
= reference to a preset tpopupmenu widget serving the right-click menu
 
- taborder
- {0..N} order number when TAB-key cycling through widgets in the container
 
- tag
- an integer value bound to this widget instance
 
- helpcontext
= a string returned by "(active/mouse)helpcontext" methods of the owning form
  when this widget is focused or under mouse in the active window
 
- zorder
= reading: finds the current Z-order of the widget's window
= setting: if the value = 0 then lowers the widget's window in the stacking hierarchy, otherwise rises
 
 
optionswidget:
 
ow_background
- keeps the window/widget on bottom of the Z-order stack.
 
ow_top
- keeps the window/widget in foreground
 
ow_noautosizing
- when docking, not to resize for the docking area
 
ow_mousefocus
- "false" here disables focusing the widget with mouse
  ( and "OnFocus" doesn't fire on mouse clicks )
 
ow_tabfocus
- "false" here disables focusing the widget with "TAB" key
  ( and "OnFocus" doesn't fire on TAB pressed )
 
ow_parenttabfocus
- enters the childs on TAB-focusing then returns to the widget after
sequential TAB-ing through its child widgets,
otherwise TAB-ing cycles on the children if entered
 
ow_arrowfocus
- allows the widget ( and its children in turn ) to be focused with
the arrow keys
 
ow_subfocus, ow_arrowfocusin, ow_arrowfocusout
- in case of arrow keys focusing enabled for child-containing widget,
determine behaviour on entering & leaving the widget, see the below table:
 
ow_subfocus | ow_arrowfocusin | ow_arrowfocusout | effect
 
  FALSE          FALSE            FALSE        entering-/leaving-
  FALSE          FALSE            TRUE          entering-/leaving+
  FALSE          TRUE              FALSE        entering(nearest)+/leaving-
  FALSE          TRUE              TRUE          entering(nearest)+/leaving+
  TRUE            FALSE            FALSE        entering(last focused)+/leaving-
  TRUE            FALSE            TRUE          entering(last focused)+/leaving+
  TRUE            TRUE              FALSE        entering(nearest)+/leaving-
  TRUE            TRUE              TRUE          entering(nearest)+/leaving+
 
- "entering" is focusing on a child within the widget
- "leaving"  is return from last child onto the widget's level
- "nearest" is the child closest on the arrow direction
- "last focused" is the child focused on last leaving the widget
*** The Up/Down arrow keys can leave from the children circle,
but Left/Right can only toggle between the children ***
 
*** mouse entering/leaving isn't controllable by these options
 
 
ow_focusbackonesc
- on pressing "Esc", returns input focus to the previously focused widget
 
ow_noparentshortcut
 
*** disables processing of delegated ( from the parent ) shortcuts ***
 
- "true" here disables processing shortcuts if they're delegated
from the parent widget ( obviously, not processed by the parent )
 
ow_nochildshortcut
 
*** disables delegating shortcuts to the parent for taking decision ***
 
- if "true" then the widget tries to process it by oneself
otherwise it's passed to the parent widget for further chaining
 
*** A shortcut can only be processed once ( by one widget ) ***
 
ow_canclosenil
- "true" here allows to continue even if there's contained widget(s)
not passing "CanClose" check
 
ow_mousetransparent
- "true" here causes the widget oneself ( not its contained ones )
not to react to mouse events ( just allow them through to the children )
 
ow_mousewheel
- enables/disables {scrolling/navigating} with wheel of ImPS/2 etc mouse
 
ow_noscroll
- don't use screen image scrolling for twidget.scrollrect,
redraw the whole scrolled widget rectangle instead;
sometimes needed with background fades.
 
ow_nochildpaintclip
-
 
ow_destroywidgets
- "true" here causes calling "free" for all containing widgets as well
 
ow_hinton
- to show the hint even in case of hinting is disabled on the parent
( "parent.ow_hintoff= true & parent.ow_hinton= false" )
 
ow_hintoff
- "true" here combined with "ow_hinton=false" fully disables displaying the hint
 
ow_multiplehint
- "true" here causes the widget to redisplay its hint on each {>3px} move within the widget oneself
 
        ow_timedhint
- "true" here causes hint of the widget to disappear after a timed inteval (about 2 secs by default)
 
ow_fontlineheight (design-time only)
- causes "extraspace" of the last text line to be drawn,
in turn it causes adjustment of widget height if "ow_autoscale" is set
*** makes sence only if "ow_autoscale=true" & ow_autosize=false & "extraspace <> 0" ***
 
ow_fontglyphheight (design-time only)
- causes only interline "extraspace"-s to be drawn, opposite to "ow_fontlineheight"
 
ow_autoscale (design-time only)
- causes that if the contents change (design OR run-time) so that its' height changes
then the widget will be v-scaled as well
 
ow_autosize (design-time only)
- causes that widget's height & width & client area adjust so that to provide space for contents of the client area
- no design-time change of height/width are possible as long as this option is in effect
 
ow_autosizeanright
- when autosizing & {an_right isn't set}, the design-set right margin against the parent is preserved
 
ow_autosizeanbottom
- when autosizing & {an_bottom isn't set}, the design-set bottom margin against the parent is preserved
 
optionsskin:
 
- osc_noskin
- osc_framebuttononly
- osc_container
 
 
Methods:
 
  // tmsecomponent
 
// (re)draws the widget according to the related skin if apllicable;
//
// also called internally by "loaded" procedure ( before "OnLoaded" code ),
// by ShowMessage ( for the internal widgets of the message dialogue ),
// when creating tab & form & menu widgets
procedure updateskin(const recursive: boolean = false);
 
// TRUE if the instance is created but not yet ready
// for interaction & accessing data & appearance change & receiving events etc
// ( the stage between firing "OnCreate" & "OnLoaded" )
function loading: boolean;
{$ifdef FPC}
procedure setinline(value: boolean); // ?
procedure setancestor(value: boolean); // ?
{$endif}
 
// TRUE if all conditios are OK for executing the code of "event" ( a handler must be assigned to the event )
function canevent(const event: tmethod): boolean;
 
 
// Shortly, replaces the persistent storage of the widget
//
// if {value <> nil} then
// - if "instance" is nil then calls "createproc" to create the instance,
//   then assigns the instance's value:= "value"
// otherwise frees "instance"
procedure setoptionalobject(const value: tpersistent; var instance;
                        createproc: createprocty);
 
// creates the persistent storage of the widget via calling "createproc"
procedure getoptionalobject(const instance: tobject; createproc: createprocty);
 
// obtains & puts to "obj" a CORBA interface entry for "aintf" (GUID,...)
function getcorbainterface(const aintf: ptypeinfo; out obj) : boolean;
 
        // TRUE if the widget is owned, or "self" otherwise
function checkowned(component: tcomponent): boolean;
 
        // TRUE if the widget is owner, or "self" otherwise
function checkowner(component: tcomponent): boolean;
 
// return the top-most widget in owner chain starting from this widget
function rootowner: tcomponent;
 
// return the array of owning widgets starting from this widget
// componentarty[0] is the widget oneself
function getrootcomponentpath: componentarty;
 
        // returns items of objeclinker ( which notify this widget )
        // and free notify list ( which are notified by this widget ),
        // duplicates are removed.
        //
        // Notifies mainly relate to insertion/removal operation on widgets
        // The notify list is maintained by FreeNotification & RemoveFreeNotification
function linkedobjects: objectarty;
 
// sends "event" recursively to child widgets until no more children or
// the event is processed ( cea_processed ) by one of the children,
// "event" will be destroyed if destroyevent= true and not async
procedure sendcomponentevent(const event: tcomponentevent;
                                        const destroyevent: boolean = true);
 
// sends "event" to each of owning widgets downward from the root owner,
// "event" will be destroyed if destroyevent= true and not async
procedure sendrootcomponentevent(const event: tcomponentevent;
                                        const destroyevent: boolean = true);
 
// posts an async "atag"-ged event to be handled by oneself
procedure asyncevent(atag: integer = 0);
 
// posts a "tcomponentevent" instance from sender=self,
// "kind" is defined when creating the event,
// and "tag" may be adjusted after creation
procedure postcomponentevent(const event: tcomponentevent);
 
// returns the classname of the widget if the widget is toplevel,
// and "tmsecomponent" otherwise )
property moduleclassname: string read getmoduleclassname;
 
// returns the classname of the widget as the entry of its constructor
// ( button => tbutton, datamodule => tdm1mo, form => ttstfo, dbstringedit => tdbstringedit,.. )
property actualclassname: string read getactualclassname;
 
// returns "fmsecomponentstate"
// ( a set of cs_ismodule,cs_endreadproc,cs_loadedproc,cs_noload, cs_hasskin,cs_noskin )
property msecomponentstate: msecomponentstatesty read fmsecomponentstate;
 
// returns/sets a pointer associated with the widget
// ( contrary to the integer "tag", allows to use an arbitary data type
// for associating data )
property tagpo: pointer read ftagpo write ftagpo;
 
// returns/sets a string identifying the widget in the help system
property helpcontext: msestring read gethelpcontext write fhelpcontext;
 
// twidget
 
// creates an instance of the widget, owned by "aowner" if not NIL
constructor create(aowner: tcomponent); override;
 
destructor destroy; override;
 
// ??
procedure afterconstruction; override;
 
// rescales the widget frame ( if assigned ) then owned widgets ( if exist, recursively ) then bounds_* then the font ( if assigned )
// called before inserting in parentwidget,
// calls "scale(ascale)",
// no visual repainting
procedure initnewcomponent(const ascale: real); virtual;
 
// restores the "fontheight" to "font.glyphheight" if "ow_fontglyphheight" or
// to "font.lineheight" if "ow_fontlineheight" otherwise,
// ascale is ignored ?
// calls "synctofontheight->setfontheight",
// called after inserting in parentwidget,
// no visual repainting
procedure initnewwidget(const ascale: real); virtual;
 
// creates the widget frame if not yet created
procedure createframe;
 
// creates the widget face if not yet  created
procedure createface;
 
// creates the widget font if not yet  created
procedure createfont;
 
// checks ws_loadlock and csdestroing too
function isloading: boolean;
 
// returns "widgetstatety" - a set of (
// ws_visible,ws_enabled,ws_active,ws_entered,ws_entering,ws_exiting,
// ws_focused,ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,
// ws_wantmousefocus,ws_iswidget,ws_opaque,ws_nopaint,
// ws_clicked,ws_mousecaptured,ws_clientmousecaptured,
// ws_loadlock,ws_loadedproc,ws_showproc,ws_minclientsizevalid,
// ws_showed,ws_hidden, //used in tcustomeventwidget
// ws_destroying,ws_staticframe,ws_staticface,ws_isvisible
//
// iframe
function widgetstate: widgetstatesty;
 
// returns "widgetstate1ty" - a set of (
// (ws1_childscaled,ws1_fontheightlock,
// ws1_widgetregionvalid,ws1_rootvalid,
// ws1_anchorsizing,ws1_isstreamed,
// ws1_scaled, //used in tcustomscalingwidget
// ws1_noclipchildren,
// ws1_nodesignvisible,ws1_nodesignframe,ws1_nodesignhandles,
// ws1_nodesigndelete,ws1_designactive,
// ws1_fakevisible,ws1_nominsize //used for report size calculations
// )
property widgetstate1: widgetstates1ty read fwidgetstate1;
* this set of states is needed because the max FPC set size is 32
  thus "widgetstate1ty" can't fit all states
 
// TRUE if the widget is contained within another widget
// ( tcomponent stuff )
function hasparent: boolean; override;             
 
// returns the parent component if it's a widget or the grandparent otherwise
function getparentcomponent: tcomponent; override;  // tcomponent
 
// TRUE if "awidget" is an ascendant or the widget or they are the same widget
function checkdescendent(awidget: twidget): boolean;
// TRUE if app is running and the widget owns the caret or the caret widget
function hascaret: boolean;
 
        // TRUE if "winid" allocated and not loading and not destroying,
        // all widgets on a form have "winid" of this form ( a real window allocated by the OS )
        // thus have this function TRUE
function windowallocated: boolean;
 
// TRUE if presents a valid toplevelwindow with assigned "winid"
function ownswindow: boolean;
 
// invalidated area of the widget, the origin is "clientpos" against the roor widget
function updaterect: rectty;
 
// calls recursively "canclose" for all contained widgets ( the widget oneself excluded! ),
// TRUE if none of the widgets return FALSE
//
// more specialized widgets may have "canclose" overridden
// to perform more work than just this call recursion
// ( not null or range check,.. )
//
// "onclosequery" must also pass the check if assigned, for the function to succeed
function canclose(const newfocus: twidget = nil): boolean; virtual;
 
        // checks "canclose" first for focused widget of the window ( form,.. )
        // if it is a descendant of the widget or the widget oneself,
        // then continues with subwidgets of the widget;
        // also - finishes editing ( snapshots "value" ) in the focused widget before checking
function canparentclose(const newfocus: twidget): boolean; overload;
 
// the above function but with the preserved focus
function canparentclose: boolean; overload;
                  //newfocus = window.focusedwidget     
 
function canfocus: boolean; virtual;
function setfocus(aactivate: boolean = true): boolean; virtual;//true if ok
procedure nextfocus; //sets inputfocus to then next appropriate widget
 
function findtabfocus(const ataborder: integer): twidget;
                      //nil if cannot focus
 
function firsttabfocus: twidget;
function lasttabfocus: twidget;
function nexttaborder(const down: boolean = false): twidget;
 
function focusback(const aactivate: boolean = true): boolean;
                              //false if focus not changed
 
function parentcolor: colorty;
function actualcolor: colorty; virtual;
function actualopaquecolor: colorty;
function backgroundcolor: colorty;
function translatecolor(const acolor: colorty): colorty;
 
procedure widgetevent(const event: twidgetevent); virtual;
 
procedure sendwidgetevent(const event: twidgetevent);
                              //event will be destroyed
 
procedure release; override;
 
function show(const modal: boolean = false; const transientfor: twindow = nil): modalresultty; virtual;
 
procedure hide;
procedure activate(const abringtofront: boolean = true); virtual;
                            //show and setfocus
 
procedure bringtofront;
procedure sendtoback;
procedure stackunder(const predecessor: twidget);
 
procedure paint(const canvas: tcanvas); virtual;
procedure update; virtual;
procedure scrollwidgets(const dist: pointty);
 
procedure scrollrect(const dist: pointty; const rect: rectty; scrollcaret: boolean);
                            //origin = paintrect.pos
 
procedure scroll(const dist: pointty);
                            //scrolls paintrect and widgets
 
procedure getcaret;
procedure scrollcaret(const dist: pointty);
function mousecaptured: boolean;
procedure capturemouse(grab: boolean = true);
procedure releasemouse;
procedure capturekeyboard;
procedure releasekeyboard;
procedure synctofontheight; virtual;
 
procedure dragevent(var info: draginfoty); virtual;
procedure dochildscaled(const sender: twidget); virtual;
 
procedure invalidatewidget;    //invalidates whole widget
procedure invalidate;          //invalidates clientrect
procedure invalidaterect(const rect: rectty; org: originty = org_client);
procedure invalidateframestate;
 
procedure invalidateframestaterect(const rect: rectty;
                                        const org: originty = org_client); 
function hasoverlappingsiblings(arect: rectty): boolean; //origin = pos
 
function window: twindow;
function rootwidget: twidget;
 
function parentofcontainer: twidget;
            //parentwidget.parentwidget if parentwidget has not ws_iswidget,
            //parentwidget otherwise
 
property parentwidget: twidget read fparentwidget write setparentwidget;
function getrootwidgetpath: widgetarty; //root widget is last
 
// number of contained widgets ( the widget oneself excluded ! )
function widgetcount: integer;
 
function parentwidgetindex: integer; //index in parentwidget.widgets, -1 if none
property widgets[const index: integer]: twidget read getwidgets;
function widgetatpos(var info: widgetatposinfoty): twidget; overload;
function widgetatpos(const pos: pointty): twidget; overload;
 
function widgetatpos(const pos: pointty;
                  const state: widgetstatesty): twidget; overload;
 
property taborderedwidgets: widgetarty read gettaborderedwidgets;
 
function findtagwidget(const atag: integer; const aclass: widgetclassty): twidget;
              //returns first matching descendent
 
property container: twidget read getcontainer;
function containeroffset: pointty;
function childrencount: integer; virtual;
property children[const index: integer]: twidget read getchildwidgets; default;
 
function childatpos(const pos: pointty;
                  const clientorigin: boolean = true): twidget; virtual;
 
function getsortxchildren: widgetarty;
function getsortychildren: widgetarty;
property focusedchild: twidget read ffocusedchild;
property focusedchildbefore: twidget read ffocusedchildbefore;
 
function mouseeventwidget(const info: mouseeventinfoty): twidget;
 
function checkdescendent(widget: twidget): boolean;
                    //true if widget is descendent or self
 
function checkancestor(widget: twidget): boolean;
                    //true if widget is ancestor or self
 
function containswidget(awidget: twidget): boolean;
 
procedure insertwidget(const awidget: twidget); overload;
 
procedure insertwidget(const awidget: twidget; const apos: pointty); overload; virtual;
                //widget can be child
 
function iswidgetclick(const info: mouseeventinfoty; const caption: boolean = false): boolean;
//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect
//or in frame.caption if caption = true, origin = pos
 
function isclick(const info: mouseeventinfoty): boolean;
//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect
 
function isdblclick(const info: mouseeventinfoty): boolean;
//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
// and timedlay to last buttonpress is short
 
function isdblclicked(const info: mouseeventinfoty): boolean;
//true if eventtype in [et_buttonpress,et_butonrelease], button is mb_left,
// and timedlay to last same buttonevent is short
 
function isleftbuttondown(const info: mouseeventinfoty): boolean;
//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
//origin = paintrect.pos
 
widgetrect: the widget on-screen area including its frame & frame caption
 
paintrect: the widget on-screen area except its frame & frame caption
 
clientrect: virtual area which
- for non-scrolling widgets, equals to "paintrect", with its "pos:= (0,0)"
- for scrolling widgets, may be bigger than "paintrect",
  also may shift ( change its "pos" ) when scrolling
// the coord of outer top-left corner against the toplevel form = the window owner,
// including the frame & frame caption
function rootpos: pointty;
 
// the coord of the outer top-left corner against the screen ( the WM decorations aren't counted in )
// includes the frame & frame caption
property screenpos: pointty;
 
//  the coord of the outer top-left corner against the parent widget,
// including the frame & frame caption
property widgetrect: rectty;
property pos: pointty; // =widgetrect.pos
property size: sizety; // =widgetrect.size
property left: integer; // =bounds_x
property right: integer; //widgetrect.x + widgetrect.cx, sets cx;
property top: integer;  // =bounds_y
property bottom: integer; //widgetrect.y + widgetrect.cy, sets cy;
property width: integer; // =bounds_cx
property height: integer; // =bounds_cy
function widgetsizerect: rectty;          //pos = nullpoint
 
    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
    //  except the frame & frame caption
function paintrect: rectty;
function paintpos: pointty;
function paintsize: sizety;
function innerpaintrect: rectty; // mainly equals to paintrect
function clientwidgetrect: rectty; // mainly equals to paintrect
function clientwidgetpos: pointty;
function clippedpaintrect: rectty; // mainly equals to  but clipped by all parentpaintrects
function innerwidgetrect: rectty;    // mainly equals to paintrect
function innerclientwidgetpos: pointty;
 
    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
    //  except the frame caption
function framerect: rectty; // =paintrect except the frame caption area
function framepos: pointty;
function framesize: sizety;
 
    // the coord of the client area ( clientrect )  against the paint area ( paintrect )
    //  usually these areas match
function clientrect: rectty;
property clientsize: sizety;
property clientwidth: integer;
property clientheight: integer;
property clientpos: pointty;
 
    // the coord of the paint area of the parent against the paint area of this widget
function paintrectparent: rectty; //nullrect if parent = nil,
 
    // the coord of the client area of the parent against the paint area of this widget
function clientrectparent: rectty; //nullrect if parent = nil,
 
// the coord of the inner area against the client area ( clientrect )
function innerclientrect: rectty;  // mainly equals to clientrect
function innerclientsize: sizety;
function innerclientpos: pointty;
 
function framewidth: sizety;              //widgetrect.size - paintrect.size
function clientframewidth: sizety;        //widgetrect.size - clientrect.size
function innerclientframewidth: sizety;  //widgetrect.size - innerclientrect.size
function innerframewidth: sizety;        //clientrect.size - innerclientrect.size 
 
    // the coord of the paint area against the widgetrect(pos) of the parent
function paintparentpos: pointty;   //origin = parentwidget.pos
 
    // the coord of the client area against the widgetrect(pos) of the parent
function clientparentpos: pointty;  //origin = parentwidget.pos
 
    // the coord of the widgetrect(pos) against the client area of parent
property parentclientpos: pointty;
 
 
function clientpostowidgetpos(const apos: pointty): pointty;
function widgetpostoclientpos(const apos: pointty): pointty;
function widgetpostopaintpos(const apos: pointty): pointty;
function paintpostowidgetpos(const apos: pointty): pointty;
procedure scale(const ascale: real); virtual;
 
 
property minsize: sizety read fminsize write setminsize;
property maxsize: sizety read fmaxsize write setmaxsize;
function maxclientsize: sizety; virtual;
 
 
property anchors: anchorsty read fanchors write setanchors default defaultanchors;
property defaultfocuschild: twidget read getdefaultfocuschild write setdefaultfocuschild;
 
 
procedure changeclientsize(const delta: sizety); //asynchronous
 
function getcanvas(aorigin: originty = org_client): tcanvas;
 
function showing: boolean;
              //true if self and all ancestors visible and window allocated
 
function isenabled: boolean;
              //true if self and all ancestors enabled
 
function active: boolean;
function entered: boolean;
 
function activeentered: boolean;
//true if entered and window is regularactivewindow or inactivated
 
function focused: boolean;
function clicked: boolean;
 
function indexofwidget(const awidget: twidget): integer;
 
procedure changedirection(const avalue: graphicdirectionty;
                                            var dest: graphicdirectionty); virtual;
 
// (re)arranges "awidgets" horizontally within the parent's client area
// so that awidget[i] were placed next each other
// at h-space dist[i], starting from "startx" with the right margin "endmargin";
//
// if the number of "dist" is fewer than the number of "awidgets" then the remaining h-spaces are taken
// as the last "dist[i]" or "0" if none;
// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
//
// non-zero "endmargin" causes one of awdidget[i] to h-resize to provide the margin :
//  - if one or more of awidgets[i] have [an_left,an_right] set then the first of such is resized
//    otherwise the last awidgets[i] is h-resized
//
procedure placexorder(
const startx: integer;
const dist: array of integer;
                const awidgets: array of twidget;
                const endmargin: integer = minint);
 
// (re)arranges "awidgets" vertically within the parent's client area
// so that awidget[i] were placed upper/lower each other
// at v-space dist[i], starting from "starty" with the bottom margin "endmargin";
//
// if the number of "dist" is fewer than the number of "awidgets" then the remaining v-spaces are taken
// as the last "dist[i]" or "0" if none;
// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
//
// non-zero "endmargin" causes one of awdidget[i] to v-resize to provide the margin :
//  - if one or more of awidgets[i] have [an_top,an_bottom] set then the first of such is resized
//    otherwise the last awidgets[i] is v-resized
//
procedure placeyorder(
const starty: integer;
const dist: array of integer;
                const awidgets: array of twidget;
                const endmargin: integer = minint);
              //origin = clientpos, endmargin by size adjust of widgets
              //with [an_top,an_bottom], minint -> no change
 
// if {mode <> wam_none} then (re)arranges "awidgets" horizontally  within the parent's client area so that
// awidgets[0] stays on its place but awidgets[1..N] :
// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_left" set ) so that they right borders match the right border of awidgets[0]
// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_right" set ) so that they left borders match the left border of awidgets[0]
// - if {mode = wam_center} then awidgets[i>=1] move so that they Y-axes match the Y-axe of awidgets[0]
//
// mainly applicable for v-stacked widgets since h-stacked may overlap after such alignment
//
        // returns the reference point ( the coord of awidgets[0] )
function alignx(const mode: widgetalignmodety;
                        const awidgets: array of twidget): integer;
 
 
// if {mode <> wam_none} then (re)arranges "awidgets" vertically within the parent's client area so that
// awidgets[0] stays on its place but awidgets[1..N] :
// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_top" set ) so that they bottom borders match the bottom border of awidgets[0]
// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_bottom" set ) so that they top borders match the top border of awidgets[0]
// - if {mode = wam_center} then awidgets[i>=1] move so that they X-axes match the X-axe of awidgets[0]
//
// mainly applicable for h-stacked widgets since v-stacked may overlap after such alignment
//
        // returns the reference point ( the coord of awidgets[0] )
function aligny(const mode: widgetalignmodety;
                        const awidgets: array of twidget): integer;
 
function actualcursor: cursorshapety; virtual;
 
 
Event handlers:
 
- onactivate
 
fires :
 
= on receiving input focus, just before "OnFocus"
= forms specific :
* on 1-st display of the form after "OnLoaded" ( from "Loaded" procedure)
* on switch back from another apllication/WM ( "oe_activate" event )
* after closure of a descendant form
* on minimizing/maximizing the form
 
- onchildscaled
 
fires :
 
= on child/children resizing due to font height change
 
= form widget: once "form.container" {scrolling widget} is loaded
 
- ondeactivate
fires
= form widget: when the form looses input focus
= non-form widget: when the widget looses input focus
 
- ondefocus
 
fires
= on disabling the widget
 
= form widget: if another form is focused
= non-form widget: if another widget is focused
 
- onenter
= fires on any way of taking parent-wide focus as soon as
the parent stores the new child's order, before "OnActivate" & "OnFocus"
 
- onexit
= fires last on parent-wide lossing focus, after "OnDefocus" & "OnDeactivate"
= for top-level ( not in a container ) forms, doesn't fire
 
- onfocus
fires
= once the existing widget takes the focus
= on showing the widget's form if the widget has the lowest "TabOrder"
 
- onfontheightdelta
fires
= if [ow_fontglyphheight OR ow_fontlineheight ] AND {the
new font height differs from the previos one}
= before the parent redraws this widget
 
- onpopup
fires :
= on calling a popup-menu ( with "RightClick" ), once the menu items of the current level are loaded
( before building the submenus )
 
- onresize
 
= fires on creating/(changing size)/(min-max restoring) of widget,
before actual redrawing
 
= rechecks if there's real work to do
 
- onshowhint
= fires when a installed hint is activated or on "aplication.showint" called
= since called last, allows to adjust the default behavior
 
- onbeforeupdateskin
= fires in "updateskin" ( the widget is loaded etc ) before applying the skin
 
- onafterupdateskin
= fires in "updateskin" ( the widget is loaded etc ) once the skin is applied
 
</pre>
 
=== TWidget stuff ===
<pre>
  Properties:   
- name
- anchors
- bounds
- color
- enabled
- visible
- <face> : see {any face}
- <frame> : see {any frame}
    - hint
    - helpcontext
    - tag
    - taborder
    - cursor
    - optionswidget
    - optionsskin
    - popupmenu
   
twidget's event handlers:
   
- on(de)activate
- onbeforeupdateskin
- onafterupdateskin
- onchildscaled
- onfontheightdelta
- on(de)focus
- onenter
- onmove
- onpopup
- onresize
- onshowhint
     
align_glue :
  ( outer anchoring mode for widget group, in the align mode )
- wam_none
- wam_start
- wan_center
- wm_end
 
align_leader :
the widget ( incl another spacer, splitter or layouter ) against which the alignment applies ( the reference widget )
 
align_mode :
  ( inner anchoring mode within widget group, in the align mode )
- wam_none
- wam_start
- wan_center
- wm_end
 
// Place mode:
 
     
place_mindist, place_maxdist:
- in the place(ment) mode, limits distance between widgets
  ( these distance once calculated also define side margins if applicable )
 
place_mode:
  ( outer anchoring mode for widget group, in the place mode )
- wam_none
- wam_start
- wan_center
- wm_end
 
place_options:
- plo_endmargin
= to resize a widget so that it "eats" extra space if it occurs
* only applicable in the place mode, with a limiting value of "place_maxdist" and:
 
  1) {place_mode <> wam_none}
or
  2) {place_mode = wam_end} and {plo_propmargin in place_options}
 
For the exact look, see above
 
 
- plo_propmargin
= виджеты расставляются теснее так, чтобы образовались отступы перед и после,
  причем расстояние между центрами виджетов было бы таким же,
  как и растояние между серединами крайних виджетов и соотв. границами зоны расстановки
 
- plo_syncmaxautosize
= see above
 
- plo_synccaptiondistx
= see above
 
  * affects widgets with opposite cp_left/right set as well
  * the minimal before-adjustment "captiondist" among all widgets limits "captiondist" for each of the widget
              * don't set cfo_captiondistouter here !
 
- plo_synccaptiondisty
= see above
 
  * affects also widgets with opposite cp_top/bottom set
  * the minimal before-adjustment "captiondist" amongst all widgets limits "captiondist" for each of the widget
 
              ! here, don't set "cfo_captiondistouter" for affected widgets !
 
- plo_syncpaintwidth
= see above
 
- plo_syncpaintheight
= see above
 
- plo_scalesize
= see above
 
 
dist_left, dist_right, dist_top, dist_bottom :
= margins between most outer edge the layouter and
  the corresponding linked widget
 
* see "tspacer" for detail
 
linkleft,linkright,linktop,linkbottom : see "tspacer"
 
options:
- spao_glueright, spao_gluebottom:
= set the adjustment dependencies between the layouter and its link_* widgets
 
* see "tspacer" for more details
 
// which mode of widget placement to apply - see above
optionslayout:
- lao_alignx
- lao_aligny
- lao_placex
- lao_placey
- lao_scalewidth
- lao_scaleheight
- lao_scaleleft
- lao_scaletop
* lao_place* & lao_align* can't be combined for one direction
 
optionsscale:
 
  * cause the layouter to provide full space for the widgets as long as they expand/shrink/move
 
- osc_expandx
= allocates more h-space if needed
 
- osc_shrinkx
= removes extra h-space if occurred
 
- osc_expandy
= allocates more v-space if needed
 
- osc_shrinky
= removes extra v-space if occurred
 
- osc_invisishrinkx
= fully h-collapses the layouter if "visible=false" ( run-time only )
 
- osc_invisishrinky
= fully v-collapses the layoter if "visible=false" ( run-time only )
 
optionsskin:
= see <any widget>
 
 
Methods:
 
constructor create(aowner: tcomponent); override;
</pre>
 
=== Public stuff ===
<pre>
(f)window:
the OS-allocated ( root = toplevel ) window common for all widgets of this window
* "widget.fwindow.fowner = widget.self" in case of the widget present the root "fwindow"
  ( owns the window )
 
(f)rootpos:
position of the widget in the coord of toplevel window not the nearest parent widget alone,
calculated as sum of such positions ( fwidgetrect.pos ) starting from the toplevel through the
                chain of all parents up to the current widget;
"nullpoint" (0,0) for toplevel widgets ( window-owning forms,..)
 
screenpos:
- coord aginst the top-left corner of screen
- WM decoration & title aren't parts of the widget !
 
widgetrect:
the widget on-screen area including its frame & frame caption
 
paintrect:
the widget on-screen area except its frame & frame caption
 
clientrect:
virtual area which
- for non-scrolling widgets, equals to "paintrect", with its "pos:= (0,0)"
- for scrolling widgets, may be bigger than "paintrect",
  also may shift ( change its "pos" ) when scrolling
 
* "t*grid" aren't such scrollable widgets since their virtual height would be limited by
  the X11 "+-32000" limitation,
  so example of such widgets are tscrollbox, "tform.container" etc
 
framerect:
the widget on-screen area except its frame caption but including inner & outer frame
 
****************
 
// releases all thread locks then post the event to the app event queue and
// waits for the event handler finishes ( signalled by "sye_ok on a semaphore )
// finally restores the locks
    // true if the handler is not aborted
function synchronizeevent(const aevent: tsynchronizeevent): boolean;
 
    // translates "point" coord against "source" widgetrect to "dest" widgetrect
//
//  * nil "source" = from screen coord
//  * nil "dest" = to screen coord
procedure translatewidgetpoint1(var point: pointty; const source,dest: twidget);
 
// the function-framed version of "translatewidgetpoint1"
function translatewidgetpoint(const point: pointty; const source,dest: twidget): pointty;
 
// rect isntead of point,
// if dest = nil then to screen
    // if source = nil then against screen
function translatewidgetrect(const rect: rectty; const source,dest: twidget): rectty;
//-----------------
    // translates "point" coord against "source" paintrect to "dest" paintrect
//  * nil "source" = from screen coord
//  * nil "dest" = to screen coord
procedure translatepaintpoint1(var point: pointty; const source,dest: twidget);
 
// the function-framed version of "translatepaintpoint1"
function translatepaintpoint(const point: pointty; const source,dest: twidget): pointty;
 
// rect isntead of point,
// if dest = nil then to screen
    // if source = nil then against screen
function translatepaintrect(const rect: rectty;const source,dest: twidget): rectty;
    //-----------------
    // translates "point" coord against "source" clientrect to "dest" clienttrect
//  * nil "source" = from screen coord
//  * nil "dest" = to screen coord
procedure translateclientpoint1(var point: pointty;
                    const source,dest: twidget);
 
// the function-framed version of "translateclientpoint1"
function translateclientpoint(const point: pointty; const source,dest: twidget): pointty;
 
// rect isntead of point,
// if dest = nil then to screen
    // if source = nil then against screen
function translateclientrect(const rect: rectty; const source,dest: twidget): rectty;
    //-----------------
 
// (re)sorts "awidgets" in order of increasing their "widgetrect.x" coords
//  - if parent = nil then the coords are against individual parent of each of "awidgets"
//  - if parent is supplied then the coords are against this parent
procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil);
 
// (re)sorts "awidgets" in order of increasing their "widgetrect.y" coords
//  - if parent = nil then the coords are against individual parent of each of "awidgets"
//  - if parent is supplied then the coords are against this parent
procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil);
 
// for each  of "widgets", calculates its autosized client area ( min size rect to fit the caption, etc )
    //  - both hor & ver sizes of client area of each of "widgets" are adjusted to the max of the above calculated areas,
//   as the result - client areas of all widgets become identically v+h sized
    //
    //  * right & bottom anchored margins of each widget are preserved
procedure syncmaxautosize(const widgets: array of twidget);
 
// for each  of "widgets", width of client area of each of "widgets" is adjusted so that
    // external ( by the outer border of frame ) widths of all widgets become identical
    // to the external widht of the widest widget
    //   
    //  * if "awidth" >= 0 then no determining the widest widget is taken and
    //    "awidth" is adjusted to instead, for all widgets
    //  * right anchored margins of each widget are lost
procedure syncminframewidth(const awidgets: array of twidget;
                              const awidth: integer = -1);
 
// for each  of "widgets", height of client area of each of "widgets" is adjusted so that
    // external ( by the outer border of frame ) heights of all widgets become identical
    // to the external height of the highest widget
    //   
    //  * if "aheight" >= 0 then no determining the highest widget is taken and
    //    "aheight" is adjusted to instead, for all widgets
    //  * bottom anchored margins of each widget are lost
procedure syncminframeheight(const awidgets: array of twidget; const aheight: integer = -1);
</pre>


  // returns the number of "handleexception" calls having an effect ( a message or the handler code )
== Projects using MSEgui ==
  property exceptioncount: longword read fexceptioncount;


 
* [[Projects using MSEgui]]
private
// function tinternalapplication.beginmodal(const sender: twindow): boolean;
 
<pre/>
 
== DB ==
 
=== DBedit ===
=== DBfields ===
=== Report ===
 
==== TRepSpacer ====
==== TRecordBand ====
==== TrepValueDisp ====
==== TRepPageNumdisp ====
==== TRepPrintDateDisp ====
==== TBandGroup ====
==== TTileArea ====
 
== Design ==
 
=== TGdbMi ===
=== TSyntaxEdit ===
=== TSyntaxPainter ===
 
== Comm ==
 
=== TCommPort ===
=== TAsciiCommPort ===
=== TAsciiProtPort ===
=== TCommSelector ===

Latest revision as of 00:07, 10 April 2021

English (en)

Widgets

TSimpleWidget

see also Reference:_MSEgui/TSimpleWidget

TMainMenuWidget

TSimpleWidget

TMseFormWidget

Use it in order to insert a tcustomform descendant into another widget at designtime. Does not try to load resources in "create".

        tmseform descendants ( MainForm, SimpleForm,.. )

	Client area of the form & parent of its widgets ( against which the widgets 
	are placed and colored ) is presented by the "container" property 
	not "container.frame.clientarea"

	CanClose is called :

		- on receiving "ek_close" by window
		- for modal window, on focus change

		- within parent window's "CanClose"	where all nested windows are  
		checked for OnCloseQuery & OnClose - if any sets "mr_none" then the parent window 
		can't close as well
			
		- from nested window's "CanParentClose"
		- from own "CanParentClose"

		- some componnets build oneself in own "Loaded" procedure :
			= widget grids
			= database access components
			= ...

	The "form.show" has parameter "transientfor".
	The window Z-order is above the "transientfor" window. The exact behaviour
	depends on the window manager.
        
        caption
		- run-time caption on the title bar

	color
		- color behind the client ( contaner ) area

	container
		- the real parent of form's widgets, <see "tformscrollbox">

	cursor
		- the mouse over cursor shape

	enabled - "false" disables all child widgets

	face
		<see "tfacecomp"> + some more options

	font
		<see "tfont">

	frame
		<see "tframecomp"> + some more options
		
	icon 
		<see "timage">

	mainmenu
		<see tmainmenu>

	name
		- name to refer when programming

	options:

		fo_main 
			- assigns this from as the aplication GUI-face & event receiver
			- causes the icon of this form to be icon of the application 

		fo_terminateonclose
			- causes the application to terminate once the form has closed ( doesn't depend on "fo_main" )


		fo_freeonclose
			- causes the form (even being modal) to release its memory on closure or OK-return from "CanClose"

		fo_defaultpos
			- lets the WM to position the form initially

		fo_screencentered
			- causes the form initially to show in center of the apllication work area

		fo_closeonesc
			- causes the form to close on "Esc" key pressed ( with MR_ESCAPE & "OnCloseQuery" firing )

		fo_cancelonesc
			- causes the form to close on "Esc" key pressed ( with MR_CANCEL & "OnCloseQuery" firing )

		fo_closeonenter
			- causes the form to close on "Enter" key pressed ( with MR_OK & "OnCloseQuery" firing )

		fo_closeonf10
			- causes the form to close on "F10" key pressed ( with MR_F10 & "OnCloseQuery" firing )

		fo_globalshortcuts
			- allows on-this-form "ao_globalshortcut" actions to trigger

			  Notes :
				= shortcuts for modal not "fo_localshortcut" forms are processed by app
				= shortcuts for "fo_globalshorcut" forms are processed by the owning window 

		fo_localshortcuts
			- disables triggering shortcuts of on-this-form actions

		fo_autoreadstat
			- for "cs_ismodule" forms, before "OnLoaded" fires, rereads all statvars from the bound stafile/memorystream

		fo_autowritestat
			- in "CanClose", after "OnClose" fires [ and before app termination for "fo_terminateonlose" form ], 
			rewrites all statvars to the stafile/memorystream
			- for datamodules, does this before "OnDestroy" fires

		fo_savepos
			- saves/restores Z-order, size & scree coordinates of the form 
			as soon as the stat data are ready

		fo_savestate
			- for top-level form, saves/restores "VSize", "Active" & "Visible" 
			as soon as the stat data are ready

	optionswidget
		<see "any widget">
	optionswindow
		<see "any window">
	popupmenu
		<see "tpopupmenu">
	stafile
		<see "tstafile">
	stavarname
	taborder
	tag

	visible - for a form, only affects its childs widgets

	Events:

		activate = to set focused & redraw the invalidated area

		oncreate
			- fires before "Loaded" procedure is called
			- fires after creating the widget & its subwidgets but before the final arrangement
			- forms arent' yet visible on return

		  Since "Loaded" procedure hasn't yet worked at this point then 
			database contents, values of widget grid's subwidgets 
			are invalid in this event ***

		onloaded
			- fires once "Loaded" procedure of owns & all form's widgets finishes
			- processed  after "OnCreate"
			- on finishing, forms aren't yet visible

		oneventloopstart ( main forms only )
			- only applicable to main forms
			- fires once all application GUI is built and shown 
			( and ready to user's interaction )
			
		onactivate 
			- see {any_widget.OnActivate}

		onenter
			= see {any_widget.OnEnter}

		onfocus
			- see {any_widget.OnFocus}
			

		onwindowactivechanged
			- fires on :
				= touching another window even on clicking in a behind-modal window ( or its title bar )
				= 1-st showing the window
				- reactivating the window

		onbeforepaint
			- fires at the very beginning of "paint", before drawing canvas

		onpaint
			- fires in "paint" procedure, between drawing canvas and contained widgets

		onafterpaint (doafterpaint)
			- fires just on return from "paint" procedure

        	onapplicationactivechanged 
			- fires :
				= if the application gets/looses input focus

		onasyncevent (doasyncevent)
			- fires on calling {this_form}.asyncevent(atag) from any place of the application
			once delivered by the app even queue

			 "atag" set by caller(s) helps to branch within "onasyncevent", to identify the caller, etc ***
			 generally, doesn't fire instantly because these events are delivered through the app event queue ***


		onchildmouseevent
			- fires on any mouse activity over its child widget(s) not the (containing) widget oneself

		      for forms, it even fires on enetering "container" therefore it appears as if to be the form itself ***

		onchildscaled
			- see {any_widget.OnChildScaled}

		onclientmouseevent
			- fires on any mouse activity over areas expecting user's mouse input (not titlebars/frames/...)

		onclose
			- fires in "CanClose" if "modalresult <> mr_none"

		onclosequery
			- fires in "CanClose" before "OnClose"
			- "mr_none" set on return prevents the window (and its parent) from closing 
			( "OnClose" is also bypassed )


		ondeactivate
			- see {any_widget.OnDeactivate}

		ondefocus
			- see {any_widget.OnDeFocus}
			
		ondestroy
			- fires on in-code calling "BeforeDestruction"

		ondestroyed
			- fires on return from the form's destructor ( when all resources are freed )

		onterminatequery
			- fires on an attempt to terminate the app
			- by setting "var terminate:= false", allows to cancel termination 

			 Termination by debugger/OS facilities can't be blocked this way ( win32 )***

		onterminated
			- fires for not-yet-destroyed forms, once the app event loop finishes 
			- may be caused by any closure of the main app form 
			( app termination, WM/OS facilities, )


		onwindowdestroyed
			- fires once a descendant window is destroyed 
			( for a main form, when a modal simple form is closed by any way,.. )

		onevent
			- fires on receiving an event 
				= for simple forms, it's only "ek_loaded"

			There can be more if the form is connected to object_event sending
			components or if the application uses object events, for example by calling
			tguicomponent.postcomponentevent. ****

		onexit
			- see {any_widget.OnExit}

		onfocusedwidgetchanged
			- for a "prev-new" parent-wide focused wigdets pair, fires once installing new focus has finished, 
			after "OnFocus"
			- resends for all contained widgets
			- doesn't fire if the "prev-new" pair don't really change

		onfontheightdelta
			- see {any_widget.OnFontHeightDelta}

		onhide
			- fires at beginnig of own/parent's 
				= hide
				= hidden
				= destroying
				= setting "visible:= false"
				= closing the window ( receiving event "ek_close",.. )
				= calling "window.close" 
				
		onidle
			- fires everytime when the app GUI event queue gets empty
			- to stop calling for a while, set "again" parameter to "false" (the initial value );
			
			 DON'T DO ANYTHING AFFECTING THE APP EVENT QUEUE ( MODAL WINDOWS, "ShowMessage", Sleep(N),... ) IN THIS HANDLER. 
				MODAL WINDOWS CAUSE RECURSION ! 
			
			A code fragment:

				again:= i < 5;
				if not again then exit;

		onkeydown
			- fires on pressing down a keyboard key over the client area when none of child widgets is focused

		onkeyup
			- fires on releasing a keyboard key over the client area when none of child widgets is focused

		onmouseevent
			- fires on any mouse activity over the client area

		onmove
			- see {any_window.OnMove}

		onpopup
			- see {any_widget.OnPopup}

		onresize
			- see {any_widget.OnResize}

		onshortcut
			- fires before built-in shorcut processing
			- "info.eventstate=es_processed" set in "OnShortcut" prevents 
			the event from further auto-processing

			The app 
				- recognizes & takes registered shortcuts from app event queue
				- passes the shocrcut event to each of its windows until the event 
				is processed otherwise processes it by oneself 
			

		onshow
			- fires if the widget is visible:
				= on calling "Show" method
				= on return from "Loaded" procedure
				= on showing the parent widget
			- since called at end, allows to adjust the default behavior

		onshowhint
			- see {any_widget.OnShowHint}

		onstatbeforeread 
			- fires before loading statvars  from the disk file

		onstatafterread
			- fires once statvars are loaded from the disk file

		onstatupdate 
			- fires at 1-st stage before updating GUI "state/pos" for read statvars
			or 
			- fires at pre-last stage before saving GUI "state/pos"

		onstatread 
			- fires at 2-nd stage before updating GUI "state/pos" for read statvars

		onstatwrite
			- fires at last stage before saving GUI "state/pos"

		pon stat reading, non-minimized visible windows are shown, 
		the active window is activated 

TDockFormWidget

TPaintbox

How to draw line (or circle) on tpaintbox? In event onpaint:

 
 procedure tmainfo.paintboxonpaint(const sender: twidget; const canvas: tcanvas); 
 begin 
  with sender,canvas do begin 
   drawline(nullpoint,pointty(size),cl_yellow);  
   //diagonal line across widget 
   drawellipse(makerect(makepoint(bounds_cx div 2,bounds_cy div 2), size),cl_red); 
   //circle (or ellipse) centered in widget                             
  end; 
 end;

Makepoint and makerect are in msegraphutils.

TEventWidget

A widget which publishes all possible events of a twidget. Normally it is better to implement your own specialized descendant of an existing widget instead to use teventwidget.

TButton

  • A rectangular clickable area that can show text/bitmap.

- Main properties:

Caption: read/write the text that appear on top of it.
onexecute: read/write the address of a procedure (event handler) to be executed when clicked.

TStockGlyphButton

TRichButton

TLabel

  • Draws a piece of text on the given surface (canvas: screen/printer/bitmap).

- Main properties:

Caption: read/write the piece of text.

See also TLabel

TGroupBox

TStepBox

TStringDisp

  • A read only version of TStringEdit, difference from TLabel: has a frame around it.

-Main properties:

Value: read/write the text that are showed.
Caption: A label normally describing the purpose or meaning of the presented text, it can be positioned around the frame.

TByteStringDisp

TIntegerDisp

TRealDisp

TDateTimeDisp

TBooleanDisp

TToolBar

TDrawGrid

TStringGrid

TTabBar

TTabPage

TTabWidget

TDockHandle

TDockPanel

TSpliter

	       A widget very similar to "tspacer" but :
		- designed to rearrange areas occupied by adjacent widgets
		- a linked widget may only enlarge by "eating" the opposite one, 
		so the summary area of both widgets don't change
		- has GUI look ( hatched grip, color etc) switched on by default
		- facilitates run-time repositioning oneself and linked widgets
		- linked widgets may even be other splitters, spacers (with their linked widgets ),..
	
        Properties:

	- color
		= see {any_widget.color}

	- cursor
		= see {any_widget.cursor}

	- enabled
		= "false" stops user interaction

	- face
		= see {any_face}

	- frame
		= see {any_frame}

	- colorgrip
		= color of grip hatching

	- grip
		= defines hatching pattern of the grip

			* stb_dens(N) : the pattern is of rhombuses, the painted rhombs occupy "N" persents of the grip

			* stb_block(N) : the pattern is of squares, painted & unpainted squares are equally sized and 
			both have "N" pixels sides
			
			* stb_hatchup(N) : the pattern is of right-tilted lines of 1 pixel width,
			each "N"-th pixel forms these lines

			* stb_hatchdown(N) : the pattern is of left-tilted lines of 1 pixel width,
			each "N"-th pixel forms these lines

			* stb_crosshatch(N) : the pattern is of crossing (left & right) tilted lines of 1 pixel width,
			each "N"-th pixel forms these lines


	- linkbottom/linkleft/linkright/linktop 
		= see {tspacer.*}

	- options

		= spo_hmove
			* "true" allows the spliter to move horizontally

		= spo_hprop
			* "true" : keep the left position proportional ( on the ratio of creation time ) 
			to weigth of the client area of parent

		= spo_hsizeprop
			* "true" : keep width of the spacer proportional ( on the ratio of creation time ) 
			to weigth of the client area of parent
			* the width stops shrinking on one set in design time

		= spo_vmove
			* "true" allows the spliter to move vertically

		= spo_vprop
			* "true" : keep the top position proportional ( on the ratio of creation time ) 
			to height of the client area of parent

		= spo_vsizeprop
			* "true" : keep height of the spacer proportional ( on the ratio of creation time ) 
			to height of the client area of parent
			* the height stops shrinking on one set in design time

		= spo_dockleft
			* causes the "linkleft" widget to dock to the left border of splitter
			* make sence only if linkleft "widget.bounds_x" less than "splitter.bounds_x"

		= spo_docktop
			* causes the "linktop" widget to dock to the top border of splitter
			* make sence only if linktop "widget.bounds_y" less than "splitter.bounds_y"

		= spo_dockright
			* causes the "linkright" widget to dock to the right border of splitter
			* make sence only if linkright "widget.(bounds_x+bounds_cx)" more than "splitter.(bounds_x+bounds_cx)"

		= spo_dockbottom
			* causes the "linkbottom" widget to dock to the bottom border of splitter
			* make sence only if linkbottom "widget.(bounds_y+bounds_cy)" more than "splitter.(bounds_y+bounds_cy)"

		!!! Two special cases :

		1. (spo_dockleft = spo_dockright = TRUE) && (linkleft = linkright = the_same_widget) : 
			causes the "linkleft" widget to adjust to h-positiion & width of the splitter, 
			it's even possible that the widget doesn't touch the splitter

			(spo_docktop = spo_dockbottom = TRUE) && (linktop = linkbottom = the_same_widget) : 
			causes the "linktop" widget to adjust to v-position & height of the splitter, 

			It's even possible in these cases that the widget doesn't touch the splitter

	- optionsscale
		= see {tscalingwidget.optionsscale}

	- optionswidget
		= see {anywidget.optionswidget}

	- onactivate, onchildscaled, ondeactivate, ondefocus, onenter, onexit, onfocus,
	  onfontheightdelta, onmove, onpopup, onresize, onshowhint
		= see "tspacer"

	- onupdatelayout
		fires :
		
		= on creating the splitter
		= on any reposition of the linked widgets 
		( due to moving the splitter, resizing the parent,.. )

TSpacer

* a regular widget which creates a kind of positional link between surrounding widgets
* designed to maintain distances between widgets
* may have GUI look, caption etc switched off by default
* resizing a spacer repositions its linked widgets

Properties:

- anchors = see {any_widget.anchors}

- bounds = see {any_widget.bounds}

- color = see {any_widget.color}

- enabled = "false" turns color of the caption to gray

- visible = "true" allows displayable settings (caption text, face, frame etc) to take effect in run-time as well

- <face> = see {any face}

- <frame> = see {any frame}

- linkbottom = widget linked down to most outer edge (incl. frame[.caption]) of the spacer - linkleft = widget linked left to most outer edge of the spacer - linkright = widget linked right to most outer edge of the spacer - linktop = widget linked up to most outer edge of the spacer

- dist_bottom, dist_left, dist_right, dist_top : = margins between most outer edge the spacer and the corresponding linked widget

- options :

= spao_glueright

- if "false"

h-repositioning or h-resizing the linkleft widget shifts the whole linked construction, it becomes the only way to h-shift

if {an_right IN linkright_widget.anchors} then the spacer may be right-resized with auto h-resizing the linkright widget so that the right margin of that widget is kept

if NOT {an_right IN linkright_widget.anchors} then the spacer may be right-resized with auto h-shifting the linkright widget so that width of that widget is kept

- if "true"

h-repositioning or h-resizing the linkright widget shifts the whole linked construction, it becomes the only way to h-shift

if {an_left IN linkleft_widget.anchors} then the spacer may be h-resized with auto h-resizing the linkleft widget so that the left margin of that widget is kept

if NOT {an_left IN linkleft_widget.anchors} then the spacer may be h-resized with auto h-shifting the linkleft widget so that width of that widget is kept

= spao_gluebottom

- if "false"

v-repositioning or v-resizing the linktop widget shifts the whole linked construction, it becomes the only way to v-shift

if {an_bottom IN linkbottom_widget.anchors} then the spacer may be v-resized with auto v-resizing the linkbottom widget so that the bottom margin of that widget is kept

if NOT {an_bottom IN linkbottom_widget.anchors} then the spacer may be v-resized with auto v-shifting the linkbottom widget so that height of that widget is kept

- if "true"

v-repositioning or v-resizing the linkbottom widget shifts the whole linked construction, it becomes the only way to v-shift

if {an_top IN linktop_widget.anchors} then the spacer may be v-resized with auto v-resizing the linktop widget so that the top margin of that widget is kept

if NOT {an_top IN linktop_widget.anchors} then the spacer may be v-resized with auto v-shifting the linktop widget so that height of that widget is kept

- optionsscale = see {tscalingwidget.optionsscale}

- optionswidget = see {anywidget.optionswidget}

- onactivate, onchildscaled, ondeactivate, ondefocus, onenter, onexit, onfocus, onfontheightdelta, onpopup, onresize, onshowhint = see {any_widget.*}

- onmove = see {any_window.OnMove}

any "link*" option set disables the spacer to reposition solely, repositioning is only controlled by a "glued" widget since then

TLayouter

  • a tspacer descendant designed to (auto)resize or/and move its contained widgets acc to some size/positon dependencies
  • may have GUI look, frame caption etc switched off by default
  • layouters may be nested to achieve complex layouts

Each layout change/assignment is divided into performing 3 consequent stages :

Stage 1

Widgets auto resized using the following options:

- if {lao_placex OR lao_placey} :

		= if {plo_scalesize in optionslayout}  then
			* widgets with "osk_nopropwith" unset in their "optionsskin" are h-scaled 
		  	  in the proportion of change of tlayouter's clientwidth
			* widgets with "osk_nopropheight" unset in their "optionsskin" are v-scaled 
		  	  in the proportion  of change of tlayouter's clientheight

			For h-resized layouter, the effect looks like :

		 	 |--Widget__1---Widget__2--|		=> the initial look

		  	 |--Widget_1--Widget_2--|			=> the layouter gets narrower

		  	 |---Widget___1---Widget___2---|	=> the layouter gets wider

			*** both widget sizes & margins are affected ***
			*** Widget_N may generally situate on different y-levels *** 
		  	
	otherwise :

		= if lao_scalewidth in optionslayout :
			* widgets with "osk_nopropwith" unset in their "optionsskin" enters in the mode 
		 	  ( not applied until the layouter resizes! ) when they are h-scaled in the proportion 
		 	  as far as clientwidth of the tlayouter changes, then stages 2 & 3 are reapplied

			For h-resized layouter, the effect looks like :

			  |--Single____widget????|		=> the initial look

			  |--Single__widget???|			=> the layouter gets narrower

			  |--Single_______widget?????|	=> the layouter gets wider

			* also, if {lao_scaleleft in optionslayout} then left margins of the widgets 
			  with unset "optionsskin.osk_nopropleft" resize too otherwise retain

		= if lao_scaleheight in optionslayout :
			* widgets with "osk_nopropheight" unset in their "optionsskin" enters in the mode 
		 	  ( not applied until the layouter resizes! ) when they are v-scaled in the proportion 
		  	  as far as clientheight of the tlayouter changes, then stages 2 & 3 are reapplied

			* also, if {lao_scaletop in optionslayout} then top margins of the widgets 
			  with unset "optionsskin.osk_noproptop" resize too otherwise retain

			*** only widget sizes & margins not distances between them are affected ***

Stage 2

Widgets may be auto resized in 5 consequent steps using the following options:


1. if plo_syncmaxautosize in place_options :
   = all widgets are autosized then their client areas are synchronised to the
     clientareas of the highest and the widest of the widget
   * calls "msegui.syncmaxautosize"

2. if plo_syncpaintwidth in place_options :
   = the paintwidths of all widgets are synchronized to the widget with the
     widest outer frame width ( ex. width of "frame.caption" )
   * mainly makes sense if "lao_alignx" set and {align_glue = wam_start or wam_end}
     ( see below ) when the widgets will be adjusted in order to fit into the
     inner client width of tlayouter:

                                   x-align level           
                                         V                 
                        +----------------------------------+
                        | Widget_1 the_widest_frame_caption|
                        | Widget_2 frame_caption2          |
                        | Widget_N wider_frame_captionN    |
                        +----------------------------------+

   here, the effect is shown for "cp_right" frame captions
     // otherwise syncronizes to the outer ( of the frame except its caption ) width 
     // of the Z-top widget
   * calls "msegui.syncpaintwidth"
   * paintwidth is the outer width

3. if plo_syncpaintheight in place_options :
   = the paintheights of all widgets are synchronized to the widget with the
     highest outer frame width ( ex. width of "frame.caption" ).
   * mainly makes sense if lao_aligny set and {align_glue = wam_start or wam_end}
     ( see below ) the widgets will be adjusted in order to fit into the inner
     client height of tlayouter :

                        +------------------------------+
                        | The_                         |
                        | tallest_            taller_  |
                        | frame_    frame_    frame_   |
                        | caption   caption2  captionN |  
                        |                              |
                        | Widget1   Widget_2  Widget_N |<== y-align level 
                        +------------------------------+     		

  here, the effect is shown for "cp_topleft" frame captions
    // otherwise syncronizes to the outer ( of the frame except its caption ) 
    // height of the Z-top widget
  * calls "msegui.syncpaintheight"
 
4. plo_synccaptiondistx in place_options :
   = causes all widgets to have the widest common room for their cp_(left/right)* frame captions
   * calls "msegui.synccaptiondistx"
 
5. plo_synccaptiondisty in place_options :
   = causes all widgets to have the highest common room for their cp_(top/bottom)* frame captions
   * calls "msegui.synccaptiondisty"

Stage 3

The widgets may be (re)arranged within the layouter.

There're 2 modes of such (re)arrangement which can be partially (orthogonally)
combined (see later):

1) The place(ment) mode ( lao_place* in optionslayout ) :

- widgets are placed at some distances between each other, possibly with some
  margins, rooms of invisible widgets ( having visible=false) are also allocated
  unless "plo_noinvisible in place_options"

  * the widgets are placed in the order of decreasing their "widgetrect.x"
	coordinates before alignment
  
  * the inter-widget distances and the side margins ( if apllied ) in both
	dimentions are identical and limited between "place_mindist" and
	"place_maxdist"
  
  = if {lao_placex in optionslayout} and {place_mode <> wam_none} then the
	following relevant settings apply:
  
	* non-limiting value of "place_maxdist" :
	
		# |Widget_1------Widget_2------Widget_3| 
	
	* non-limiting value of "place_maxdist" and {plo_propmargin in place_options} :
	
		# |---Widget_1---Widget_2---Widget_3---|
		
	* limiting value of "place_maxdist" and {place_mode = wam_start} :
	
		# |Widget_1----Widget_2----Widget_3????|
		
	* limiting value of "place_maxdist" and {place_mode = wam_start} and
	  {plo_propmargin in place_options} :
	
		# |---Widget_1---Widget_2---Widget_3???|
		
	* limiting value of "place_maxdist" and {place_mode = wam_end} :
	
		# |??????Widget_1---Widget_2---Widget_3|
		
	* limiting value of "place_maxdist" and {place_mode = wam_end} and
	  {plo_propmargin in place_options} :
	
		# |???Widget_1---Widget_2---Widget_3---|
		
	* limiting value of "place_maxdist" and {place_mode = wam_center} :
	
		# |???Widget_1---Widget_2---Widget_3???|
		
	* limiting value of "place_maxdist" and {plo_endmargin in place_options} :
	
		# |Widget_1----Widget_2----Widget_____3|, or
		
		# |Widget_1----Widget_____2----Widget_3|, or
		
		# |Widget_____1----Widget_2----Widget_3|, here, the most left amongst
		widgets having both [an_left,an_right] set is expanded otherwise the most
		right widget ( Widget_3 in the example )
		
	* limiting value of "place_maxdist" and {place_mode = wam_end} and
	  {plo_propmargin in place_options} and {plo_endmargin in place_options} :
	  
		# |--Widget_1--Widget_____2--Widget_3--|,
		  
	The Legend:
	===========
	limiting value of "place_maxdist" : such value which produce some visual
	effect on the layouter
	
	  "----" :           distance ( = number of minuses, limited by place_maxdis )
	  "????" :           some remaining space ( = number of questmarks )
	  "Widget_1" :       widget of the original size
	  "Widget__..__1" : (auto)resized widget
  
  = if {lao_placey in optionslayout} and {place_mode <> wam_none} then the things
	are handled in the same manner as with "lao_placex" but for the vertical
	"top2bottom" direction of placement instead of the horizontal "left2right" one.

2) the align(ment) mode ( optionslayout.lao_align* ) :

- widgets are gathered into a visual group to a dedicated "leader" widget of
  the layout ( set by "align_leader" and defaults to the lowest in
  Z-Order = twidget.widgets[0] ) the leader stays in place while the others :

  = if lao_alignx in optionslayout ( the hor alignment mode ):
	  * if align_mode = wam_start :
		snap their left borders to the left border of leader
	  * else if align_mode = wam_end :
		snap their right borders to the right border of leader
	  * else if align_mode = wam_center :
		snap their v-axes to the v-axis of leader after that,
  = if lao_aligny in optionslayout ( the vert alignment mode ):
	  * if align_mode = wam_start :
		snap their top borders to the top border of leader
	  * else if align_mode = wam_end :
		snap their bottom borders to the bottom border of leader
	  * else if align_mode = wam_center :
		snap their h-axes to the h-axis of leader

- after that, the whole widget group can be aligned within the layouter:

  = if align_glue =  wam_start
	  * if lao_alignx in optionslayout:
		the left extent of group snaps to the left border of layouter
	  * if lao_aligny in optionslayout:
		the top extent of group snaps to the top border of layouter
  = else if align_glue = wam_end
	  * if lao_alignx in optionslayout:
		the right extent of group snaps to the right border of layouter
	  * if lao_aligny in optionslayout:
		the bottom extent of group snaps to the bottom border of layouter
  = else if align_glue =  wam_center
	  * if lao_alignx in optionslayout:
		the v-axis of group snaps to the v-axis of layouter
	  * if lao_aligny in optionslayout:
		the h-axis of group snaps to the h-axis of layouter

Mutually exclusive settings:
* only one of "align_mode" can be choosen
* only one of  "glue_mode" can be choosen
* "optionslayout.lao_alignx" & 	"optionslayout.lao_placex"
* "optionslayout.lao_aligny" & 	"optionslayout.lao_placey"

V-alignment ( optionslayout.lao_aligny ) may be combined with h-placement
( optionslayout.lao_placex ), and h-alignment ( optionslayout.lao_alignx ) may
be combined with v-placement ( optionslayout.lao_placey )

NOTE:
  The effects of the above described { resizing / placement / alignment } are
  irreversible. So, the only way to revert is to set "wan_none" then to revert
  manually.

TListView

TImage

<any image>

	*** Note that switch to the monochrome mode is irerreversible ! ***

	alignment:

		By default, images are top-left aligned, with the original size preserved.

		al_xcentered = centers the image horizontally
		al_ycentered = centers the image vertically

		al_right = docks the image to the right border of placeholder
		al_bottom = docks the image to the bottom border of placeholder

		al_grayed = fills non-transparent areas with the selected color

		al_stretchx = adjusts size so that to fill the placeholder in width
		al_stretchy = adjusts size so that to fill the placeholder in height
		al_fit = adjusts size so that to fill the placeholder in both width & height

		al_tiled = spawns the image & tile the whole  placeholder with the copies 

		Interpolation mode while stretching

			al_intpol =	antialiases as far as the size changes 
						(the only working in Linux)
			al_or = interpolation pixel operation is "or" -> 1's are extended
			al_and = interpolation pixel operation is "and" -> 0's are extended
		( al_or and al_and only on win32, mainly useful for stretching of monochrome bitmaps) :

	colorbackground = color of image transparent ( masked ) areas in monochrome 
						non-masked mode 
	colorforeground = color of non-transparent areas in monochrome mode  

	options:

		bmo_monochrome = fills non-transparent areas with "colorforeground", 
						also, in non-masked mode, fills transparent areas 
						with "colorbackground"

		bmo_masked = activates built-in image transparency {it "hides" transparent (masked) areas}
		bmo_colormask = applies faded edge transparency on the color masked areas in the image

	transparency = makes the image transparent as long as enlights areas behind 
					the image with the selected color

	transparentcolor = for a non-masked image, assigns a color indicate transparency areas
					( on matching areas, the image will be seen through )

TDial

TChart

There are demos here:

https://github.com/mse-org/mseuniverse/tree/master/attic/msedocumenting/mse/trunk/help/tutorials/widgets/charts

TChartRecorder

TPolygon

TPickWidget

TOpenglWidget

Edit

TStringEdit

TMemoEdit

THexStringEdit

TDropdownListEdit

A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
- deo_autodropdown dropdown on keypress
- deo_selectonly don't allow entering arbitrary text.
- deo_forceselect don't allow entering empty text.

THistoryEdit

A tstringedit which shows the previously entered values in a dropdownlist for selection.

TIntegerEdit

TKeyStringEdit

Maps string to string.

TEnumEdit

Maps integer to string, zero based and sequencial (first item 0, next 1, ...).

TEnumTypeEdit

A TEnumEdit which maps Pascal enums to their names. Use OnInit event to store the typeinfo pointer of the enum type into sender.typeinfopo.

 
procedure tmainfo.enumtypeeditinit(const sender: tenumtypeedit);
begin
  sender.typeinfopo := PTypeInfo(TypeInfo(TMyEnumeratedType));
end;

TSelector

TSelector is the most specialized widget of the dropdown editwidget group, it is based on tenumedit (tenumedit maps an integer to a string) and uses for the dropdownlist a second map which must be created on the fly in ongetdropdowninfo. An example is tcommselector where the enumedit maps commnrty to commname and the dropdownlist shows the available RS232 ports only.

TRealEdit

TRealSpinEdit

TDateTimeEdit

TCalendarDateTimeEdit

TEdit

MSEgui counterpart of Delphi TEdit. You will never use it.

TWidgetGrid

TItemEdit

TDropDownItemEdit

A tstringedit with a dropdownlist to choose text values. Important dropdown.options members:
- deo_autodropdown dropdown on keypress
- deo_selectonly don't allow entering arbitrary text.
- deo_forceselect don't allow entering empty text.

TMBDropDownItemEdit

TTreeItemEdit

TRecordFieldEdit

Used in twidgetgrid in order to edit fields of a ttreeitemedit. Example is MSEide projecttreeform.pas.

TDialogStringEdit

A tstringedit with an ellipse button. Use "onexecute" to show the dialog.

TPointerEdit

TSlider

TProgressBar

TBooleanEdit

TBooleanEditRadio

TDataButton

A button with an integer value. Clicking increments the value until "max", then it restarts with "min". Can be inserted into a twidgetgrid. The current value selects the showed image and face by the items of "imagenums" and "valuefaces".

TStockGlyphDataButton

TDataIcon

Shows an imagelist item by lookup from "value" to "imagenums". Clicking increments value until "max" then it restarts with "min". Can be inserted into a twidgetgrid.

TTextEdit

Only useful if inserted into a twidgetgrid, builds a text editor, used in MSEide source editor.

TDataImage

A pixmap display widget which can be inserted into twidgetgrid.

TTerminal

Only useful if inserted into a twidgetgrid, builds a very simple terminal emulator. Used in MSEide target console.

NoGui

TAction

	Shortcut processing order :

	- the smallest piece of processing is "doshortcut" procedure which 
	is called until processed:
		= starting from the sender up to the toplevel widget
		= then by all child widgets with non-set "ow_noparentshortcut" 
		= then, if "ow_nochildshortcut" isn't set, by the parent widget
		= then by the widget oneself
	
	- "doshortcut" is checked in the following order:
		= starting from form's main menu
		= then from the owning window ( the widget oneself ) 
		= then from the application


		*** A shortcut is bound to a widget by :
			- placing an action component on the widget ***
			- direct assigning the shortcut to the widget (menus,..) 
	---------------------------

		caption, color, colorglyph, helpcontext, hint, imagecheckedoffset,
		imagelist <see "timagelist">, imagenr, imagenrdisabled

			- sets look of "clients" (buttons, menu/toolbar items,..), unless 
			these clients have "state.as_local*" set :

		*** For meaning of these options, see help on the "client" widgets ***

	group
		- default value for one-named property of the bound widgets
		( menu items,... )

	options :
		ao_updateonidle
			- runs this action in cycle, waiting for no gui events everytime

		ao_globalshortcut 
			- allows the action to trigger on a non-main form
			  (the shortcut is triggered whatever form of the applicatin it was pressed on, 
			  otherwise only when the form where the aption is placed on is focused )

		ao_nocandefocus 
			- causes the action not to call "CanDefocus" for focused edit widget of active form
			  before executing own code
			  ( it helps to avoid the effect of cancelling changes in these widgets 
			  on activating the bound shortcut )

	shortcut
		- keyboard combination triggering the action

	shortcut
		- alternative "shortcut" and handled identically

	state :

		as_disabled
			- prevents the action from triggering, also puts the bound widgets to "disabled" look

		as_invisible
			- in run-time, hides the bound widget, still reacting on the shortcut or direct call

		as_checked
			- selects the bound menu item if it has "mao_checkbox" option set

		as_default
		as_local*

	statfile	
		<see "tstatfile">

	stavarname

	
	tagaction
	onasyncevent
	onchange
	onexecute
	onupdate

TActivator

TCustomLookupbuffer

	-	provides a group of parallel arrays of float(=datetime), integer and widestring types,
		and facilities to :
			= search in any array
			= on found position, quickly obtain corresponding value in another array
	-	for each type, several arrays  may be kept
	- 	each array is integer-indexed, even string ones ( case[in]sensitive )
	-	uses two way of accessing arrays data, through :
			= physic : array storage index ( row number ) directly
			= logical : the integer index ( see above ):
				first, physic row number is known for the logical index then the data 
				are accessed with the found number

			*** logical index values are built automatically based on array values, 
			on updating its data ***
	- dont' have interface to load data ( see its descendants for that )
	
	fieldcountfloat - number of float arrays
	fieldcountinteger - number of integer arrays
	fieldcounttext - number of widestring arrays

	Event handlers:
		- onchange

	Public interface:

   		procedure beginupdate; - marks beginning of "update"
   		procedure endupdate; - if all "update" finished, fires "onchange" event
	 	procedure clearbuffer; - clears all arrays then fires "onchange"

   		procedure checkbuffer; 
   			- [re]loads the arrays with most actual data
   			- just a stub here since doesn't have a data source

   		function find(const fieldno: integer; const avalue: integer/realty/msestring;
         	out aindex: integer; const filter: lbfiltereventty = nil): boolean;
			- applies external filtering ("filter" procedure) then incrementally searches integer/realty(datetime) array "fieldno" 
			for value "avalue" starting from logical index "aindex", returns "true" and the updated logical index 
			if found else next bigger; 

   		function find(const fieldno: integer; const avalue: msestring;
                 out aindex: integer;
                 const caseinsensitive: boolean;
                 const filter: lbfiltereventty = nil): boolean; overload;
			- applies external filtering ("filter" procedure) then incrementally searches widestring array "fieldno" for value "avalue", 
			in "caseinsensitive" manner, starting from logical index "aindex", returns "true" and the updated logical index 
			if found else next bigger;

   		function findphys(const fieldno: integer; const avalue: integer;
         	out aindex: integer; const filter: lbfiltereventty = nil): boolean; overload;
			- applies external filtering ("filter" procedure) then incrementally searches integer/realty(datetime) array "fieldno" 
			for value "avalue" starting from row number "aindex", returns "true" and the updated row number 
			if found else next bigger; 

		function findphys(const fieldno: integer; const avalue: msestring;  out aindex: integer; const caseinsensitive: boolean;
                 const filter: lbfiltereventty = nil): boolean; overload;
			- applies external filtering ("filter" procedure) then incrementally searches widestring array "fieldno" for value "avalue", 
			in "caseinsensitive" manner, starting from row number "aindex", returns "true" and the updated row number  
			if found else next bigger;

			The external filtering ("filter") procedure takes the arguments of the caller 
			togehther with physical row number found in the caller which allows 
			to check several values at once for that number, within the filter
			
		function integervaluephys(const fieldno,aindex: integer): integer;
			-  returns value of integer array "fieldno" at row number "aindex" 
              
		function integervaluelog(const fieldno,aindex: integer): integer;
			-  returns value of integer array "fieldno" where the array index equals to "aindex" 

		function integerindex(const fieldno,aindex: integer): integer;
			- returns row number of integer array "fieldno" where the array index equals to "aindex"

		function integerindexar(const fieldno: integer): integerarty;
			- returns all bunch of indexes of integer array "fiedlno"

		function integerar(const fieldno: integer): integerarty;
			- returns all bunch of data of integer array "fiedlno"
   
		function floatvaluephys(const fieldno,aindex: integer): realty;
			-  returns value of real/datetime array "fieldno" at row number "aindex" 

		function floatvaluelog(const fieldno,aindex: integer): realty;
			-  returns value of real/datetime array "fieldno" where the array index equals to "aindex" 

		function floatindex(const fieldno,aindex: integer): integer;
			- returns row number of real/datetime array "fieldno" where the array index equals to "aindex"

		function floatindexar(const fieldno: integer): integerarty;
			- returns all bunch of indexes of real/datetime array "fiedlno"

		function floatar(const fieldno: integer): realarty;
			- returns all bunch of data of real/datetime array "fiedlno"   

		function textvaluephys(const fieldno,aindex: integer): msestring;
			-  returns value of widestring array "fieldno" at row number "aindex" 

		function textvaluelog(const fieldno,aindex: integer;
                       const caseinsensitive: boolean): msestring;
			-  returns value of widestring array "fieldno" where the array index equals to "aindex" 

		function textindex(const fieldno,aindex: integer;
                      const caseinsensitive: boolean): integer;
			- returns row number of widestring array "fieldno" where the array index equals to "aindex"

		function textindexar(const fieldno: integer;
                            const caseinsensitive: boolean): integerarty;
			- returns all bunch of indexes of widestring array "fiedlno"

		function textar(const fieldno: integer): msestringarty;
			- returns all bunch of data of widestring array "fiedlno"   

   
		function lookupinteger(const integerkeyfieldno,integerfieldno,
                                keyvalue: integer): integer; overload;
			- returns value of integer array "integerfieldno" at position where
				value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( 0 if not found )

		function lookupinteger(const stringkeyfieldno,integerfieldno: integer;
                         const keyvalue: msestring): integer; overload;
			- returns value of integer array "integerfieldno" at position where
				value of parallel widestring array "stringkeyfieldno" equals to "keyvalue"
                ( 0 if not found )

		function lookuptext(const integerkeyfieldno,textfieldno,
                                keyvalue: integer): msestring; overload;
			- returns value of integer array "textfieldno" at position where
				value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( '' if not found )

		function lookuptext(const stringkeyfieldno,textfieldno: integer;
                      const keyvalue: msestring): msestring; overload;
			- returns value of integer array "textfieldno" at position where
				value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( '' if not found )


		function lookupfloat(const integerkeyfieldno,floatfieldno,
                                keyvalue: integer): realty; overload;
			- returns value of real/datetime array "floatfieldno" at position where
				value of parallel integer array "integerkeyfieldno" equals to "keyvalue"
                ( emptyreal if not found )

		function lookupfloat(const stringkeyfieldno,floatfieldno: integer;
                                keyvalue: msestring): realty; overload;

			- returns value of real/datetime array "floatfieldno" at position where
				value of parallel widestring array "stringkeyfieldno" equals to "keyvalue"
                ( emptyreal if not found )

		function count: integer; - returns number of data rows

		property fieldcounttext: integer; -  returns/sets number of widestring arrays
		property fieldcountfloat: integer; - returns/sets number of real/datetime arrays
		property fieldcountinteger: integer; - returns/sets number of integer arrays

		 the above "fieldcount*" props clear the buffer on setting a value 

		property integervalue[const fieldno,aindex: integer]: integer; - a shortcut to "integervaluephys"
		property floatvalue[const fieldno,aindex: integer]: realty; - a shortcut to "floatvaluephys"
		property textvalue[const fieldno,aindex: integer]: msestring; - a shortcut to "textvaluephys"

		property onchange: notifyeventty; 
			- called in "changed" wich in turn is called in :
				= clearbuffer
				= endupdate
				= doasyncevent
				= loaded
				= tlookupbuffer.addrow

TLookupBuffer

tlookupbuffer = class(tcustomlookupbuffer)

	- extends "tcustomlookupbuffer" with methods of run-time data filling

	- see <tcustomlookupbuffer>

	+= Extentions to the public interface:

		procedure addrow(const integervalues: array of integer;
                    const textvalues: array of msestring;
                    const floatvalues: array of realty);

			- adds one row to each of widestring arrays, integer arrays and real/datetime arrays,
			array size of  "{type}values" equals to number of {type} arrays

   		procedure addrows(const integervalues: array of integerarty;
                    const textvalues: array of msestringarty;
                    const floatvalues: array of realarty);

			- adds many data rows  to each of widestring arrays, integer arrays and real/datetime arrays, 
			only min length of the input data arrays are inserted, longer data are truncated
			array size of  "{type}values" equals to number of {type} arrays and the size of "{type}values[i]"
			describes number od data elements in the array
		

TDBLookupBuffer

tdblookupbuffer = class(tcustomdblookupbuffer -> tcustomlookupbuffer)

	- extends "tcustomlookupbuffer" with interface to fill arrays with DB-data
	- see <tcustomlookupbuffer> & <tcustomdblookupbuffer>

	 Extentions to the public interface:

   		procedure checkbuffer; - if data obsolete ("invalid") then reloads them from "datasource"
   
		property datasource: tdatasource; - sets/returns DB data source where to load data from
		property textfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of widestring arrays
		property integerfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of integer arrays
		property floatfields: tdbfieldnamearrayprop; - allows to assign a {datasource:datafield} to each of real/datetime arrays

		property optionsdb: lbdboptionsty; - tunes some DB behaviour apects
			-	olbdb_closedataset : 
				= once data obsolete, opens (if needed) the supplier dataset (disabling its bound controls) 
				then [re]loads data from it then closes it

			-	olbdb_invalidateifmodified :
				= gets marked "invalid" once contents of the bound dataset change, 
				it signals to reload the buffer with the new data just before next accessing 
				( for any purpose - searching, lookuping, getting value/(array of values),..)

TDBmemoLookupbuffer

- allows to use  for lookup-ing any text-convertable DB-fields
	- an analog of tdblookupbuffer, but :
		- "integerfields" may be names of any integer-convertable DB-fields
		- "floatfields" may be names of any (real/datetime)-convertable DB-fields
		- "textfields"  may be names of any text-presentable DB-fields

		- each DB-field value ( presenting a memo generally of many lines ) may supply many data rows at once 
		to the bound array of the buffer, since this value will be internally splitted & turned into native array values,
		and the resulting "count" (arrays row count) of the whole buffer will be the minimal rows count amongst arrays 
		of the buffer, the rest data are truncated 

		- when loading widestring arrays, also checks for & performs "utf8-to-widestring" conversion of values of 
		the bound DB-fields so that these arrays always store widestrings

TThreadComp

TStatFile

- so that to be in effect, it should also be assigned to the form where the widget using the stafile is placed on
- in design, if "onstatwrite" is set and "filedir" is not yet created,	deactivate exception "ECreateError" in project settings ( "Debugger" tab )
- "filedir" may contain "~/" indicating the user's home directory
- options "oe_savestate" & "oe_savevalue" of "client" widgets define what to store to the file 
- position etc changes or/and value changes 
- in case when a main form shares its stafile with non-main forms, on creating non-main ones, just edited not saved data of the main form ( bound to vars of the statfile) are reset to values read from the statfile upon creating the form; for "sfo_memory", this effect absents unless widgets on the concurring forms share same variable[s]; to avoid this behaviour, disable "fo_autoreadstat" & "fo_autowritestat" of the non-main forms
- each "tstafile" owns:
 = tstatwriter:
* provides methods of writing sections & statvars to a memory/file stream
- tstatreader:
* holds list of sections with statvars each
* provides search & check & reading interface to the statvars
* provides reading statvars from a memory/file stream

Positioning to a section speeds up accessing its statvars

- there also is "tstatfiler" ( exposed by some "tstatfile" events ) which:
= may present or "tstatwriter" or "tstatreader" ( there's a check method )
= provides directionless "update" methods with internal switch to needed direction of processing 
- "reading" or "writing" statvars on per-section basis


	activator :
		<see tactivator> : NOT YET DONE		

	encoding = "en_utf8" selected here, allows to store non-Latin text in the file
       filedir = directory where to keep the file ( by default - the current working directory )
	filename = name of the file

	options:
		sfo_memory = reads & writes not from a disk file but from a named memory stream 
					( there's an exclusion - see below "sfo_savedata" ),
					mostly useful for presenting last used values on recalling 
					non-main forms etc ( data even survive recreating forms),
					or even for data "exchange" between non-main modal( non-concurring ) forms 
					in case of the target widgets share same statvarnames

		sfo_createpath = creates "filedir" if necessary
		sfo_savedata =	used only with "sfo_memory", commands to save 
						the memory data to the master statfile (see below)						

	sfo_activatorread = activator activate triggers reading ???
	sfo_activatorwrite = activator deactivate triggers writing ???

	statfile = a master statfile
	statvarname = name of section of this file in the upper statfile
	Tag = an integer property for misc purposes

	Event handlers:
		onstatafterread - fires on return from "readstat"
		onstatafterwrite - fires on return from "writestat"
		onstatbeforeread - fires on beginning of "readstat"
		onstatbeforewrite - fires on beginning of "writestat"
		onstatread = fires after reading state data
		onstatwrite = fires after writing state data
		onstatupdate = fires after reading/writing state data just before 
					"onstatread" & "onstatwrite"

	Public methods:

   		procedure initnewcomponent(const ascale: real); override;
   			- does nothing but fixes the default file name as the statfile default
   
   		procedure readstat(stream: ttextstream = nil); overload;
   			- rereads all statvars of the stafile/memorystream
   
   		procedure readstat(const aname: msestring; const statreader: tstatreader); overload;
   			- rereads "aname" statvar of the statfile

   		procedure writestat(const stream: ttextstream = nil); overload;
		   	- rewrites all statvars to the stafile/memorystream
			  (if neccessary, prepares to writting - creates "filedir", stafile,...)
   
   		procedure writestat(const aname: msestring; const statwriter: tstatwriter); overload;
   			- overwrites "aname" statvar of the statfile
   		
   		procedure updatestat(const aname: msestring; const statfiler: tstatfiler);
   			- depending on kind of "statfiler" ( writer/reader ), writes/reads 
   			  the most up-to-date stat data

TTimer

TNoGuiAction

TPipeReadercomp

TSysEnvManager

TProcessMonitor

TFilechangeNotifier

TShortCutController

TPostscriptPrinter

TGdiPrinter

TWmfPrinter

TSkinController

TGuiThreadComp

Font

See also : Reference:_MSEgui/TFont

Any Font

    	charset { ANSI/ DEFAULT/ SYMBOL /SHIFTJIS /HANGEUL /GB2312 /CHINESEBIG5 /OEM 
		/JOHAB / HEBREW/ ARABIC/ GREEK/ TURKISH/ VIETNAMESE/ THAI/ EASTEUROPE/
		RUSSIAN/ MAC/ BALTIC }
		- changes the font to the nearest containing the selected encoding(charset)
		- no font change made if the supplied encoding doesn't match any font
	color
		- color of the glyphs contours
	colorbackground
		- fill color of the glyph cells ( not including extraspace )
	colorshadow
		- color of SE glyph "edges" ( if not "cl_none", deactivates "colorbackground" )
	extraspace
		- v-space between glyph cells of adjacent text rows (negative values cause the cells to overlap )
	height
		- v-size of glyph cells, in pixels
	name
		- initially, font is choosen by { "family" = this name }
	options:
		foo_fixed
			- changes the font to the nearest "mono" spaced (usually = Courier)
		foo_proportional
			- changes the font to the nearest "proportionally" spaced (usually = Helvetica)
		foo_helvetica
			- changes the font to the nearest in "sans" category (usually = Helvetica)
		foo_roman
			- changes the font to the nearest in "serif" category (usually = Times[ New Roman])
		foo_script
			- Win32 only, changes the font to the nearest in "script" category
		foo_decorative
			- Win32 only, changes the font to the nearest in "decorative" category
		foo_antialiased
			- Linux-only, enables antialiasing (if disabled by Xft globally)
		foo_nonantialiased
			- Linux-only, disables antialiasing (if enabled by Xft globally) 
			usually making glyph extents (not cells !) a bit wider
	style:
		fs_bold
			- gives the font a "bold" look
		fs_italic
			- gives the font an "italic" look
		fs_underline
			- gives the font an "underlined" look
		fs_strikeout
			- gives the font a "striked out" look
		fs_selected
			- "TRUE" here combined with {tf_noselect:=FALSE}, causes the text described by this font 
			to be initially selected ( with the clipboard operations available ), 
			currently applicable only to richstrings

	width
		- 10*{ glyph cell width, average in pixels }, 0 = {font default}

	xscale
		- width ratio of each glyph {cell & contour}, the effect is similar to "width"

		*** "foo_*" font selection overrides one made with "name" 

		*** if change with "foo_*" is unsuccessful then the nearest "sans" font is usually chosen

		*** The categories :

			sans		=> have no serifs and have strokes of even thickness
			serif		=> have serifs at glyph contours and made up of strokes of varying thickness
			script		=> resemble handwriting
			decorative	=> flashy styles to be used sparingly in headlines or posters

GUI

TWindow

twindow = class(teventobject,icanvas)
  public

	// releases mouse, unlinks from the canvas, processes all pending events of the window
	// if called from within main thread then destroys the window directly
	// otherwise posts a window destroy event for oneself and waits for it to be processed
	procedure destroywindow;

	// registers the instance of onself in the "owner" widget, allocates the canvas, 
	// adds a reference to oneself,
	// then prepares the "owner" hierarchy to be invalidated ( "owner.rootchanged" )
	// since now, the window is allocated and belongs to the "aowner" widget 
	constructor create(aowner: twidget);

	destructor destroy; override;

	// adds "method" to the internal list of scroll dependants
	procedure registeronscroll(const method: notifyeventty);

	// removes "method" from the internal list of scroll dependants
	procedure unregisteronscroll(const method: notifyeventty);

	// releases mouse if captured, resets the cursor, then enters an event loop for the window,
	// TRUE on return if the window is destroyed
	function beginmodal: boolean;
 
	  * checks if the "sender" window is already modal to avoid circularity, 
	    if not then starts an event loop  for the "sender" where the "sender" is a receiver of GUI events,
   	    once the loop is terminated reactivates the previously active window if it was,
	    TRUE if modalwindow destroyed  

	  function tinternalapplication.beginmodal(const sender: twindow): boolean;

	// removes the internal stuff which indicates the modal state
	procedure endmodal;

	// if the window is visible, 
	// deactivates the previously active window, shows the window (see below),
	// if no active window in the app or the window or its Z-predecessor is modal and 
	// the app has no focused widget then prepares the bound widget to be focused,
	// then addresses the WM to put the window to foreground
	procedure activate;

	  // if the bound widget has visible=true then:
	  //  - if NOT windowevent then :
	  //    = address the WM to set size of the window acc to window opts 
	  //      wp_maximized, wp_fullscreen or normal size otherwise
	  //	= if the window is normally sized, moves it to its default position is specified ( screen centered etc )
	  // - unhides/unminimizes the window if needed
	  // - shows other windows of the applications acc to state of the window group 
	  // ( in normal size or minimized )

	  private 
		procedure twindow.show(windowevent: boolean);

	// TRUE if this window currently grabs user input
	( a widget drawn within the window(=form) is in focus,.. )
	function active: boolean;

	// if the window was active then deactivates the window  & remembers it as the previous active ( to restore leater if requested ),
	// returns TRUE if that storage occurred
	function deactivateintermediate: boolean; 

	// makes the window active & clears the above app reference to it ( "active before deactivating" )
	procedure reactivate; //clears app.finactivewindow

	// scans the app event queue for "ek_expose" event[s] addressed to the window,
	// if found then redraws that part of the window which the event describes
	// ( processed events are then deleted )
	procedure update;

	// TRUE if the window :
	// 1) doesn't have an inner widget grabbing input focus
	// or
	// 2) has such widget, and this widget ( and all its descendants ) 
	//    pass "CanClose" check
	//
	// *** see also "twidget.CanClose" ***
	//
	function candefocus: boolean;

	// tries to defocus the currently focused widget if it belongs to the window,
	// if succeeds then executes code of virtual "DoDefocus" of the widget descessor
	// ( this code defines behaviour & look of the widget on defocusing );
	//
	// no defocusing is done if the focused widget ( or its descendants ) 
	// doesn't pass "CanClose" check
	//
	procedure nofocus;
   
   	// setfocusedwidget(widget)
   
   property focuscount: cardinal read ffocuscount;
   function close: boolean; //true if ok
   procedure beginmoving; //lock window rect modification
   procedure endmoving;
   procedure bringtofront;
   procedure sendtoback;
   procedure stackunder(const predecessor: twindow);
       //stacking is performed in mainloop idle, nil means top
   procedure stackover(const predecessor: twindow);
       //stacking is performed in mainloop idle, nil means bottom
   function stackedunder: twindow; //nil if top
   function stackedover: twindow;  //nil if bottom
   function hastransientfor: boolean;

   procedure capturemouse;
   procedure releasemouse;
   procedure postkeyevent(const akey: keyty; 
        const ashiftstate: shiftstatesty = []; const release: boolean = false;
                  const achars: msestring = '');

   function winid: winidty;
   function haswinid: boolean;
   function state: windowstatesty;
   function visible: boolean;
   function activating: boolean; //in internalactivate proc
   function normalwindowrect: rectty;
   property updateregion: regionty read fupdateregion;
   function updaterect: rectty;

   procedure registermovenotification(sender: iobjectlink);
   procedure unregistermovenotification(sender: iobjectlink);

   property options: windowoptionsty read foptions;

	// widget 
	property owner: twidget read fowner;

   property focusedwidget: twidget read ffocusedwidget;
   property transientfor: twindow read ftransientfor;
   property modalresult: modalresultty read fmodalresult write setmodalresult;
   property buttonendmodal: boolean read getbuttonendmodal write setbuttonendmodal;
   property globalshortcuts: boolean read getglobalshortcuts write setglobalshortcuts;
   property localshortcuts: boolean read getlocalshortcuts write setlocalshortcuts;
   property windowpos: windowposty read getwindowpos write setwindowpos;
   property caption: msestring read fcaption write setcaption;


 windowoptionty = (wo_popup,wo_message,wo_buttonendmodal,wo_groupleader,
                   wo_windowcentermessage); //showmessage centered in window


	optionswindow:
		wo_popup 
			- in run-time, hides all OS windows-manager ( WM ) decorations (title bar, buttons "Close/Resize,Min/Max" etc),
			letting only its client area to appear
			so :
				= the window should have own facilities to replace the deactivated WM functionality if needed
				= can't be resized/maximize/minimized/moved
		wo_message
			- similar to "wo_popup" but allows WM to close ( with "Close" button ) & move the window

		wo_groupleader
			- keeps on the WM taskbar a shortcut to the window 
			( if the parent window is a groupleader too then displays a step upper in its group )

	Event handlers:

	 - onmove
		= fires once the (window/widget) is created/moved ( with check if really moved by a distance)

TFormScrollbox

- presents client area of form & parent of its widgets, 
	initially stretched to fit the form & bound with anchoring 
	but may be adjusted with "bounds" & "anchors"
   
    Properties:
                
	anchors
	bounds
	
	color
		- color of the whole container area ( except its frame ) & form widgets 
		if their color is "cl_parent"

	name = container

	cursor,	enabled, face, frame, helpcontext, hint, optionswidget, popupmenu,
	taborder, tag, visible, onactivate, onafterpaint, onbeforepaint, 
	onchildmouseevent, onclientmouseevent, ondeativate, ondefocus, onenter,
	onexit, onfocus, onfontheightdelta, onmouseevent, onpaint, onpopup
	onresize, onshowhint
		- the same meaning as for the served form


	oncalcminscrollsize	
	onscroll
	onchildscaled	

TFaceList

TFrameComp

See also here: Reference:_MSEgui/TFrame.


	Terminology :

	{client area = area of the widget which interacts with a user}

	{bevelling = additional facets rising/sinking frame & client area, 
		constists of two parts - 
			- external: between frame and widget
			- internal: between frame and client area
	}

	{frame=	flat space between external & internal facets,
			floats at the inner level of the external facet
 	}

	*** Both frame & bevelling affect the client area ***

	--------------------------
	template:

		colorclient	=	color of the client area

		colorframe =	color of the frame
		colorframeactive =	used instead of colorframe if the widget is
							active; "cl_default" means same as colorframe.

		works if (leveli/levelo <> 0 that's the facets exist :

			colorshadow = color of facets screened from the NW light source
			colordkshadow =	color of shadows dropped by the NW light source
        	        colordkwidth =	width of the shadows in pixel, -1=default

			colorlight = color of facets exposed to the NW light source
			colorhighlight = color of brighter edges of the facets
                 	colorhlwidth = width of the brighter edges in pixel, -1=default

		        extraspace = if applied to menu items, adds more space between these items

		framei_:
			(for extendable widgets like menus, these settings widen the widget,
			for non-extendable like buttons - they squeeze the text area )

			bottom=	lower margin of text to the client area
			left =	left margin of text to the client area
			right =	margin of text to the client area
			top =	upper margin of text to the client area

		framewidth=	width of the frame
	leveli = {width=height} of the internal facet, positive -> raised, negative -> sunken
	levelo = {width=height} of the external facet, positive -> raised, negative -> sunken

<any frame>

	*** extends & customizes "tframecomp" ***

	template
		- "tframecomp" supplying the initial settings

	colorclient,colordkshadow,colordkwidth,colorframe,colorframeactive,
	colorhighlight,colorhlwidth,colorlight,colorshadow,framewidth, 
	leveli, levelo, framei_*,

		<see "tframecomp">

	font
		<see "tfont">

	caption	
		- some descriptive text( function name, user prompt,...) placed 
		in a N/W/S/E-combination to the widget's client area

		*** 
		non-empty caption if (captionpos <> cp_center) & (captiondistouter=false & captiondist>0) enlarges the framed widget 
		by the corresponding size of caption

		***

	captiondist - margin between the caption & the client area

	captiondistouter :

	- if "false"(by default), the distance is measured between 
		the inner (facing the client area) extent of the caption 
		and the client area outward the area, 
		the caption is placed outside of the client area

	- if "true", the caption is mirrored against the edge of client area as 
		to the position when "false"

		*** nagative values of "captiondist" visually inverse "out of" and within ***

       captionnoclip - do not clip frame and client area for caption background 
					( the client area preserves own background under the caption text)

	captionnooffset - shift orthogonal to "captiondist"

	captionpos - "corner" where to place the caption

	localprops :

		frl_levelo - "levelo" overrides "template.levelo"
		frl_leveli - "leveli" overrides "template.leveli"
		frl_framewidth - "framewidth" overrides "template.framewidth"
		frl_colorclient - "colorclient" overrides "template.colorclient"
		frl_colorframe - "colorframe" overrides "template.colorframe"
		frl_colorframeactive - "colorframeactive" overrides "template.colorframeactive"
		frl_colordkshadow - "colordkshadow" overrides "template.colordkshadow"
		frl_colorshadow - "colorshadow" overrides "template.colorshadow"
		frl_colorlight - "colorlight" overrides "template.colorlight"
		frl_colorhighlight - "colorhighlight" overrides "template.colorhighlight"
		frl_colordkwidth - "colordkwidth" overrides "template.colordkwidth"
		frl_colorhlwidth - "colorhlwidth" overrides "template.colorhlwidth"
		frl_fileft - "framei_left" overrides "template.framei_left"
		frl_firight - "framei_right" overrides "template.framei_right"
		frl_fitop - "framei_top" overrides "template.framei_top"
		frl_fibottom - "framei_bottom" overrides "template.framei_bottom"

		frl_nodisable

TFaceComp

See also here: https://wiki.freepascal.org/Reference:_MSEgui/TFace

	- doesn't affect the widget frame but client area of the frame


	template:
		fade:
			color[i]: = colors forming the fade
			direction: = direction where the fade grows to
			gd_(right/up/left/down)

		pos[i]: = relational position of color[i] on the direction (0.0..1.0) extent

			transparency = 	makes the face half-transparent and enlighten the underlying widget  
							with a light source of the selected color 
							( in this case, colors of the face & the widget & the light source 
							simply summarize to higher brightness )

		image:
			see <any image>

		options:

        	*** The fade colors are used not as colors but RGB alpha values ($00 -> opaque, $ff -> transparent) 
			if fao_alpha* are set *** :

				fao_alphafadeall = applies blending to the widget & all its children
				fao_alphafadenochildren = preserves child widgets from blending
		                fao_alphafadeimage = applies blending to "face.image" 


<any face>

	*** extends & customizes "tfacecomp" ***

	fade, image, option
		- see "tfacecomp"
	
	template
		- "tfacecomp" supplying the initial settings

	localprops :
		fal_options - "options" overrides "template.options"
		fal_fadirection - "fade.direction" overrides "template.fade.direction"
		fal_image - "image" overrides "template.image"
		fal_fapos - "fade.pos[i]" overrides "template.fade.pos[i]"
		fal_facolor - "fade.color[i]" overrides "template.fade.color[i]"
		fal_fatransparency - "fade.transparency" overrides "template.fade.transparency"

TBitmapComp

TScalingwidget

   optionsscale : 
		autosizing to provide room for :
		= {"frame.caption" + "offset_*"}
		= "offset_*" if "frame.caption" is unset and "osc_shrink*" is set
	
		= osc_expandx 
			- makes the widget wider to fit the caption if needed

		= osc_shrinkx
			- makes the widget narrower to have no space left & right to the "frame.caption"

		= osc_expandy
			- makes the widget taller to fit the caption if needed

		= osc_shrinky
			- makes the widget lower to have no space up & down to the "frame.caption"

		= osc_invisishrinkx
			- fully h-collapses if "visible=false" ( run-time only )

		= osc_invisishrinky
			- fully v-collapses if "visible=false" ( run-time only )

TImageList

TPopupMenu

TMainMenu

Dialog

TFileListview

TFileDialog

TFaceComp

TFileNameEdit

TDirDropdownEdit

TColorEdit

TMemoDialogEdit

TPageSizeSelector

TPageOrientationSelector

Application

TGuiApplication

 tguiapplication = class(tcustomapplication)
  public

   // [re]starts the system timer with the new period and 
   // subscribes the application to be a receiver of the modified "ek_timer" event 
   // ( can check for it in the event queue )
   procedure settimer(const us: integer);

   // finds a window by its winID
   function findwindow(id: winidty; out window: twindow): boolean;

   // finds a window by its ID & adjusts "rect" so that it 
   // fits "bounds_minc*" & "bounds_maxc*" of the found window
   procedure checkwindowrect(winid: winidty; var rect: rectty);

   // initialises the timer and "megraphics"
   procedure initialize;

   // frees the allocated system resources (GDI, event subscription, the timer)
   procedure deinitialize;

   // creates a form instance, it will be shown in "application.run"
   procedure createform(instanceclass: widgetclassty; var reference);

   // invalidates all registered forms ( all their widgets will be redrawn )
   procedure invalidate; 
   
   // calls a nested main event loop, forces processing any pending messages,
   procedure processmessages; override; //handle with care!

   // TRUE if no pending events to process for the application
   function idle: boolean; override;
   
   // requests to indicate waiting ( to show the "watches" cursors )
   procedure beginwait; override;

   // removes the "watches" if no unclosed requests for displaying them,
   // otherwise closes the currently active request
   procedure endwait; override;

   // TRUE if there are unclosed requests for displaying "watches"
   function waiting: boolean;

   // TRUE if ESC has just been pressed
   //  - if all requests for displaying "watches" are closed then refreshes 
   //    the internal list of events ( the GUI-queue -> the app event list)
   function waitescaped: boolean; //true if escape pressed while waiting

   // sets state of the current wait dialogue ( but doesn't close one ) to undefined
   procedure resetwaitdialog;   

   // runs "aexecuteaction" in the main thread in OnIdle mode,
   // then shows a cancellable message,
   // if the one is cancelled then runs "acancelaction" then 
   // either fully clears (if exceptions occur ) 
   // or terminates the execution otherwise,
   // true if not cancelled;
   // "application.processmessages" must be called regularly if "aexecuteaction" is used here,
   // alternatively "aidleaction" can be used, call sleep ( some time ) in order to minimize
   // processor load. 
   // If athread <> nil the function starts and terminates the thread    
   function waitdialog(const athread: tthreadcomp = nil; const atext: msestring = '';
                   const caption: msestring = '';
                   const acancelaction: notifyeventty = nil;
                   const aexecuteaction: notifyeventty = nil): boolean; override;

   // closes the currently modal waitdialogue with "cancelled" state
   procedure cancelwait;

   // closes the currently modal waitdialogue with "ok" state
   procedure terminatewait;

   function waitstarted: boolean;   // the last waitdialogue is currently showing for some requests
   function waitcanceled: boolean;  // the last waitdialogue has been cancelled for some request (but can be shown fot others ?)
   function waitterminated: boolean; // the last waitdialogue has been terminated for some request (but can be shown fot others ?) 

   // if called from the main app thread then shows as a modal message describing the exception 
   // otherwise posts an async event for which the message will be called
   procedure showexception(e: exception; const leadingtext: string = ''); override;

   // posts an async event for which the message describing the exception will be called
   procedure showasyncexception(e: exception; const leadingtext: string = '');

   // "application.errormessage" shows standard error message ( with "ERROR" title ) 
   procedure errormessage(const amessage: msestring); override;

   // [re]calculates timings & position of hint for "ahintedwidget"
   // if "ow_timedhint" in "ahintedwidget.foptionswidget" then iys showtime will be 
   // "defaulthintshowtime" ( an app wide setting, 3sec by default)   
   procedure inithintinfo(var info: hintinfoty; const ahintedwidget: twidget);


   // shows the supplied hint text within "aposrect" with alignment "aplacement" during "ashowtime",
   // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove   
   procedure showhint(const sender: twidget; const hint: msestring;
              const aposrect: rectty; const aplacement: captionposty = cp_bottomleft;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                 // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;

   // shows the supplied hint text at left-top position"apos" during "ashowtime",
   // the avail ( but not used currenly ) flags are : hfl_show,hfl_custom,hfl_noautohidemove,hfl_noautohidemove   
   procedure showhint(const sender: twidget; const hint: msestring;
              const apos: pointty;
              const ashowtime: integer = defaulthintshowtime; //0 -> inifinite,
                 // -1 defaultshowtime if ow_timedhint in sender.optionswidget
              const aflags: hintflagsty = defaulthintflags
                      ); overload;

   // shows the hint fully defined in "info" for the widget "sender"
   procedure showhint(const sender: twidget; const info: hintinfoty); overload;

   // removes the current hint widget & frees its resources & stops its stop timer
   procedure hidehint;

   // restarts the current hint and its stop timer
   procedure restarthint(const sender: twidget);

   function hintedwidget: twidget; //last hinted widget
   function activehintedwidget: twidget; //nil if no hint active

   // returns helpcontext of active widget, '' if none;   
   function activehelpcontext: msestring;

   // returns helpcontext of the widget under mouse, '' if none;
   function mousehelpcontext: msestring;

   // TRUE if one of the app's window/console is in input focus
   function active: boolean;

   // returns the desktop resolution ( or the virtual one if used )
   function screensize: sizety;

   // returns the (virtual) desktop resolution except the tray area,
   // nil -> current active window
   function workarea(const awindow: twindow = nil): rectty;

   // returns which application window ( a form not an eventwidget, an openglwidget or a windowwidget !) 
   // is active ( provides the input focus ),
   // it's same for all widgets of the form served by this window
   function activewindow: twindow;

/ * A transient window is a descendant of ( "transientfor" ) another window in the stacking order hierarchy */

   // returns a first non-transient ( on top of the app stacking order ) window upward 
   // from the currently active window of the application.
   // or that active window if no such
   function regularactivewindow: twindow;

   // same as "activewindow" but the window must not be released (?)
   function unreleasedactivewindow: twindow;

   // returns the focused widget of the currently active window if one exists
   function activewidget: twidget;

   // returns the widget presenteing the currently active window
   function activerootwidget: twidget;
   
   // returns the window ( not hidden or disabled !) under the screen point "pos"
   function windowatpos(const pos: pointty): twindow;

   // puts to "awidget" the container of widget pointed by "namepath"
   // ( finalizing "." is discarded if found ) ,
   // FALSE if not found, and NIL and TRUE if "namepath" = ''
   function findwidget(const namepath: string; out awidget: twidget): boolean;

   // rebuilds the application's window list accorrding to the current on-screen Z-order of its windows;
   // window list is ordered by "z" - bottom first & top last;
   // invisibles first
   procedure sortzorder;

   // returns a copy of the internal window list of application
   function windowar: windowarty;

   // returns the list of application window winIDs
   function winidar: winidarty;

   // returns the count of the application windows    
   function windowcount: integer;

   // returns the window by its number ( "index" >= 0) in the application window list
   property windows[const index: integer]: twindow read getwindows;

   // returns the lowest visible window in stackorder, 
   // calls "sortzorder" within
   function bottomwindow: twindow;

   // returns the highest visible window in stackorder, 
   // calls "sortzorder" within
   function topwindow: twindow;


   // TRUE if all owned windows pass "CanClose" check or 
   // don't have focused widgets
   function candefocus: boolean;

   // subscribes the handler "method" to receive keyboard events
   procedure registeronkeypress(const method: keyeventty);

   // unsubscribes the handler "method" from receiving keyboard events
   procedure unregisteronkeypress(const method: keyeventty);

   // subscribes the handler "method" to receive shortcut events
   procedure registeronshortcut(const method: keyeventty);

   // unsubscribes the handler "method" from receiving shortcut events
   procedure unregisteronshortcut(const method: keyeventty);

   // subscribes the handler "method" to receive "OnWindowActiveChanged" event ( form-wide )
   procedure registeronactivechanged(const method: activechangeeventty);

   // unsubscribes the handler "method" from receiving "OnWindowActiveChanged" event ( form-wide )
   procedure unregisteronactivechanged(const method: activechangeeventty);

   // subscribes the handler "method" to receive "OnDestroyed" events ( form-wide )
   procedure registeronwindowdestroyed(const method: windoweventty);

   // unsubscribes the handler "method" from receiving "OnDestroyed" events ( form-wide )
   procedure unregisteronwindowdestroyed(const method: windoweventty);

   // subscribes the handler "method" to receive "OnWindowDestroyed" events ( form-wide )
   procedure registeronwiniddestroyed(const method: winideventty);

   // unsubscribes the handler "method" form receiving "OnWindowDestroyed" events ( form-wide )
   procedure unregisteronwiniddestroyed(const method: winideventty);

   // subscribes the handler "method" to receive "ApplicationActiveChanged" events ( form-wide )
   procedure registeronapplicationactivechanged(const method: booleaneventty);

   // unsubscribes the handler "method" from receiving "ApplicationActiveChanged" events ( form-wide )
   procedure unregisteronapplicationactivechanged(const method: booleaneventty);

// tcustomapplication

   // subscribes the handler "method" to receive "OnTerminated" event ( form-wide )
   procedure registeronterminated(const method: notifyeventty);

   // unsubscribes the handler "method" from receiving "OnTerminated" events ( form-wide )
   procedure unregisteronterminated(const method: notifyeventty);

   // subscribes the handler "method" to receive "OnTerminateQuery" event ( form-wide )
   procedure registeronterminate(const method: terminatequeryeventty);

   // unsubscribes the handler "method" from receiving "OnTerminateQuery" event ( form-wide )
   procedure unregisteronterminate(const method: terminatequeryeventty);

   // subscribes the handler "method" to receive "OnIdle" event ( form-wide )
   procedure registeronidle(const method: idleeventty);

   // unsubscribes the handler "method" from receiving "OnIdle" events ( form-wide )
   procedure unregisteronidle(const method: idleeventty);

   // calls "canclose" of all application windows except the "sender" window 
   // if all "canclose"are TRUE then checks "OnTerminateQuery" 
   // for all its subscribers ( usually forms of the application )
   procedure terminate(const sender: twindow = nil); 

   // TRUE as long as a "terminate" call is in progress
   function terminating: boolean;

   // TRUE as long as a "deinitialize" call is in progress
   function deinitializing: boolean;
   
   // returns the current caret object ( the text input focus indicator ) of the application
   / ( this object provides facilities to control position & appearance & visibility & timings of the caret )
   property caret: tcaret read fcaret;

   // returns the current mouse object of the application
   / ( this object provides facitities to control position & appearance of the mouse )   
   property mouse: tmouse read fmouse;

   // simulates mouseparkevent 
   // ( an adjusting mouse movement without user intervention - grid snapping, docking etc ?)
   procedure mouseparkevent;

   // sets mouse position correction for further mouse events,
   // the real position is less the visual one by the supplied shift
   procedure delayedmouseshift(const ashift: pointty);

   // returns/sets a cursor shape used for widgets having their cursor shape set to "cr_default";
   // setting it to "cr_default" restores the individual widget cursor(s)
   property widgetcursorshape: cursorshapety read fwidgetcursorshape write
                                        fwidgetcursorshape;

   // returns/sets the current application-wide cursor shape ( not "watches" if a waiting dialog is currently displayed ! )
   // or request to set a new cursor shape ( app-wide );
   // doesn't change when changing mouse widgets
   // 
   // if called from a non-main app thread & no waiting dialogue displayed then redraws 
   // the cursor immediately;
   // set it to "cr_default" to restore the shape to one set by "widgetcursorshape"
   //
   property cursorshape: cursorshapety; // cr_arrow, cr_*

   // assures the displayed mouse cursor shape to be the shape assigned to the currently under-mouse widget,
   // otherwise "cr_default" 
   procedure updatecursorshape; //restores cursorshape of mousewidget

   // returns a widget of the application where the mouse is currently positioned over
   property mousewidget: twidget read fmousewidget;

   // returns a widget of the application currently "owning" the mouse ( grabbing all mouse input )
   property mousecapturewidget: twidget read fmousecapturewidget;


   // returns/sets a window to become the main window of the application
   // then resets all other application windows to the window group it belongs to ( Linux only );
   //
   // the main window minimizes all windows if minimized;
   property mainwindow: twindow read fmainwindow write setmainwindow;

   // returns which system thread was allocated to the application on its start
   // ( the main thread )
   property thread: threadty read fthread;

   // returns teh widget where a mouse button click occured last time 
   // ( to compare with when determinibg whether another widget is clicked )
   property buttonpresswidgetbefore: twidget read fbuttonpresswidgetbefore;

   // returns teh widget where a mouse button release occured last time 
   // ( to compare with when determinibg whether another widget is clicked )
   property buttonreleasewidgetbefore: twidget read fbuttonreleasewidgetbefore;


   // returns/sets the interval of mouse double click recognition ( in microsecs ),
   // defaults to 0.4 sec
   property dblclicktime: integer read fdblclicktime write fdblclicktime default
                 defaultdblclicktime; //us

// tcustomapplication

   // creates a datamodule instance ( its startup code including "OnLoaded" is executed )
   procedure createdatamodule(instanceclass: msecomponentclassty; var reference);


   // enters the application event loop;
   //
   // once the loop finishes, performs "OnTerminated" for all its subscribers,
   // destroys all application forms ( components & windows )
   procedure run;

   // TRUE if the eventloop is entered
   function running: boolean;

   // returns/sets the application name 
   // ( defaults to the full path to application executable in the native OS format );
   // currently, only for informatiion query purposes
   property applicationname: msestring read fapplicationname write fapplicationname;
   

   // if exclusive "rights" are satisfied for the main thread ( a mutex lock is OK )  & the event loop is in progress 
   // then posts the "event" to the main application thread for asyc processing,
   // otherwise adds the event to the internal list for further handling as soon as the above conditions meet
   procedure postevent(event: tevent);

   // TRUE if never idle since last call,
   // unlocks the application and calls sleep if not mainthread and asleepus >= 0
   function checkoverload(const asleepus: integer = 100000): boolean;

   // returns/sets the application exception handler
   property onexception: exceptioneventty read fonexception write fonexception;

   // if not "eabort" & no unhandled exceptions, 
   // executes the above "OnException" code if assigned 
   // or shows an exception message otherwise;
   procedure handleexception(sender: tobject = nil; 
                                       const leadingtext: string = '');

   // synchronizes the calling thread with the main event loop ( via a mutex),
   // TRUE if the calling thread allready holds the mutex,
   // the mutex is recursive
   function lock: boolean;

   // tries to synchronize the calling thread with the main event loop ( via a mutex)
   function trylock: boolean;

   // releases the mutex if the calling thread holds the mutex,
   // TRUE if no unlock done
   function unlock: boolean;

   // releases the mutex recursively if the calling thread holds the mutex,
   // returns "count" for the below "relockall"
   function unlockall: integer;

   // regains the mutex to serve "count" locks
   procedure relockall(count: integer);

   // creates a syncronize event ( which will fire asyncronously then waits for another thread will allow it to finish ), assigns "proc" to it as the event handler, 
   // then frees all locks temporarily then posts the event to the app event queue & waits fot it to be processed the resores the locks;
   // 
   // TRUE if not aborted, quiet -> shows no exceptions if occurs
   //
   // the "syncronize event" is an event owning a semaphore which can be touched by another thread 
   // thus causing "event.waitfo" to return & to exec the event handler code
   //
   function synchronize(const proc: objectprocty;
                       const quite: boolean = false): boolean;

   // TRUE if the calling ( this function ) thread is the application main thread
   function ismainthread: boolean;

   // TRUE if the currently locked thread is the application main thread
   function islockthread: boolean;

   // waith for "athread" to terminate,
   // does "unlock-relock" around waiting
   procedure waitforthread(athread: tmsethread);

   // post a "nothing-to-do" event for asynchronous processing in the main thread 
   procedure wakeupmainthread;

   // invalidates all registered forms of the application so that their widgets redraw land-specific captions 
   // ( changed by "mseconsts.setlangconsts" ),
   // called internally in "setlangconsts" before return
   procedure langchanged; virtual;

   // returns/sets "aps_terminated" state flag ( no actions ? )
   // this flag is also set internally by "terminate" if not cancelled
   property terminated: boolean read getterminated write setterminated;

   // returns the number of "handleexception" calls having an effect ( a message or the handler code )
   property exceptioncount: longword read fexceptioncount;


private
 // function tinternalapplication.beginmodal(const sender: twindow): boolean;

DB

DBedit

DBfields

TDBwidgetgrid

  Properties:

        anchors - ...
	bounds - ...

	color 
		- color of the grid's client area
	cursor 
		- cursor shape when the mouse is over the client area

	datacols
		colorselect
		linecolor
		linecolorfix
		linewidth
		newrowcol

		options
			co_readonly
			co_nofocus
			co_invisible
			co_disabled
			co_drawfocus
			co_mousemovefocus
			co_lefbuttonfocusonly
			co_focusselect
			co_mouseselect
			co_keyselect
			co_multiselect
			co_resetselectionexit
			co_rowselect
			co_fixwidth
			co_fixpos
			co_fill
			co_proportional
			co_nohscroll
			co_savevalue
			co_savestate
			co_rowfont
			co_rowcolor
			co_zebracolor
			co_nosort
			co_sortdescent
			co_norearrange
			co_cancopy
			co_canpaste
			co_mousescrollrow
			co_rowdatachange

		sortcol
		width

		items[N]
			color
			colorselect
			datalist - ???
			face - see <any face>
			fontselect - see <any font>
			frame - see <any frame>
			linecolor
			linecolorfix
			linewidth
			name
			
			options
	

Report

TRepSpacer

TRecordBand

TrepValueDisp

TRepPageNumdisp

TRepPrintDateDisp

TBandGroup

TTileArea

Design

TGdbMi

TSyntaxEdit

TSyntaxPainter

Comm

TCommPort

TAsciiCommPort

TAsciiProtPort

TCommSelector

General stuff

Properties for all widgets


	name

	anchors

		-----------

		- they control of design/runtime sticking widgets to their parents

		- dimention pair ( top/bottom or left/right ) both set to "false" cause 
		the widget to fit the parent's client area in that dimention;
		this effect may be partial in case of "bounds_c*max" settings limit the extents

		*** Return to the look "before dimention fit" is only possible by manual resizing or setting "bounds_*"
		-----------
		an_left 
			- on run-time, resizes/shifts left the widget to keep the design-set distance 
			between the widget's left border and the left side of parent's client area 
			as the parent resizes, until scrolling begins

		an_top
			- on run-time, resizes/shifts up the widget to keep the design-set distance 
			between the widget's top border and the upper side of parent's client area 
			as the parent resizes, until scrolling begins

		an_right
			- on run-time, resizes/shifts right the widget to keep the design-set distance 
			between the widget's right border and the right side of parent's client area 
			as the parent resizes, until scrolling begins

		an_bottom
			- on run-time, resizes/shifts down the widget to keep the design-set distance 
			between the widget's bottom border and the lower side of parent's client area 
			as the parent resizes, until scrolling begins

	bounds

		cx	- width of the widget
		cxmax, cxmin - design/runtime width of the widget is enforced between "cxmax" and "cxmin"
		cy	- height of the widget
		cymax, cymin - design/runtime height of the widget is enforced between "cymax" and "cymin"
		x	- distance between the widget's left border and the left side of parent's client area 
		y	- distance between the widget's top border and the upper side of parent's client area 


	autosize

		-----------
		- only applicable to widgets with "ow_autosize" set
		- the effect may be partial in case when "bounds_c*max" settings limit the extents
		-----------

		cx - addition to width of the widget (with h-centering post applied)
		cy - addition to height of the widget (with v-centering post applied)

	- color
		= the default color of client area & caption text background
		= may be overwritten:
			* the client area - with "frame.colorclient"
			* the caption BG - with "frame.font.colorbackground"

	- font
		= see {any font}

	- frame
		= see {any frame}

	- face
		= see {any face}

	- hint
		= descriptive text appearing when mouse pointer enters the widget

	- cursor
		= shape of the mouse pointer over the client area of widget (run-time only)

	- visible
		= "true" allow the widget to appear ( run-time only )

	- enabled
		= "true" allows the widget to participate in GUI interaction
		= "false" disallows the widget & its children :
			* processing all events & shortcuts & menu calls
			* auto "CanClose" check

			Also "false" usually paints the widget in color marking 
			the "disabled" state ( usually light gray font color )

	- popupmenu
		= reference to a preset tpopupmenu widget serving the right-click menu

	- taborder
		- {0..N} order number when TAB-key cycling through widgets in the container 

	- tag
		- an integer value bound to this widget instance

	- helpcontext
		= a string returned by "(active/mouse)helpcontext" methods of the owning form 
		  when this widget is focused or under mouse in the active window

	- zorder
		= reading: finds the current Z-order of the widget's window
		= setting: if the value = 0 then lowers the widget's window in the stacking hierarchy, otherwise rises


	optionswidget:

		ow_background
			- keeps the window/widget on bottom of the Z-order stack.

		ow_top
			- keeps the window/widget in foreground

		ow_noautosizing
			- when docking, not to resize for the docking area

		ow_mousefocus
			- "false" here disables focusing the widget with mouse
			  ( and "OnFocus" doesn't fire on mouse clicks )

		ow_tabfocus
			- "false" here disables focusing the widget with "TAB" key
			  ( and "OnFocus" doesn't fire on TAB pressed )

		ow_parenttabfocus
			- enters the childs on TAB-focusing then returns to the widget after 
			sequential TAB-ing through its child widgets,
			otherwise TAB-ing cycles on the children if entered

		ow_arrowfocus
			- allows the widget ( and its children in turn ) to be focused with 
			the arrow keys 

		ow_subfocus, ow_arrowfocusin, ow_arrowfocusout
			- in case of arrow keys focusing enabled for child-containing widget, 
			determine behaviour on entering & leaving the widget, see the below table:

			ow_subfocus	| ow_arrowfocusin |	ow_arrowfocusout | effect

			   FALSE           FALSE             FALSE         entering-/leaving-
			   FALSE           FALSE             TRUE          entering-/leaving+
			   FALSE           TRUE              FALSE         entering(nearest)+/leaving-
			   FALSE           TRUE              TRUE          entering(nearest)+/leaving+
			   TRUE            FALSE             FALSE         entering(last focused)+/leaving-
			   TRUE            FALSE             TRUE          entering(last focused)+/leaving+
			   TRUE            TRUE              FALSE         entering(nearest)+/leaving-
			   TRUE            TRUE              TRUE          entering(nearest)+/leaving+

			- "entering" is focusing on a child within the widget
			- "leaving"  is return from last child onto the widget's level
			- "nearest" is the child closest on the arrow direction
			- "last focused" is the child focused on last leaving the widget
 
			*** The Up/Down arrow keys can leave from the children circle, 
				but Left/Right can only toggle between the children ***

			*** mouse entering/leaving isn't controllable by these options


		ow_focusbackonesc 
			- on pressing "Esc", returns input focus to the previously focused widget

		ow_noparentshortcut

			*** disables processing of delegated ( from the parent ) shortcuts *** 

			- "true" here disables processing shortcuts	if they're delegated 
			from the parent widget ( obviously, not processed by the parent )

		ow_nochildshortcut

			*** disables delegating shortcuts to the parent for taking decision *** 

			- if "true" then the widget tries to process it by oneself 
			otherwise it's passed to the parent widget for further chaining

			*** A shortcut can only be processed once ( by one widget ) ***

		ow_canclosenil
			- "true" here allows to continue even if there's contained widget(s) 
			not passing "CanClose" check

		ow_mousetransparent
			- "true" here causes the widget oneself ( not its contained ones ) 
			not to react to mouse events ( just allow them through to the children )

		ow_mousewheel
			- enables/disables {scrolling/navigating} with wheel of ImPS/2 etc mouse

		ow_noscroll
			- don't use screen image scrolling for twidget.scrollrect, 
			redraw the whole scrolled widget rectangle instead;
			sometimes needed with background fades.

		ow_nochildpaintclip
			- 

		ow_destroywidgets
			- "true" here causes calling "free" for all containing widgets as well

		ow_hinton
			- to show the hint even in case of hinting is disabled on the parent
			( "parent.ow_hintoff= true & parent.ow_hinton= false" )

		ow_hintoff 
			- "true" here combined with "ow_hinton=false" fully disables displaying the hint

		ow_multiplehint 
			- "true" here causes the widget to redisplay its hint on each {>3px} move within the widget oneself

        	ow_timedhint 
			- "true" here causes hint of the widget to disappear after a timed inteval (about 2 secs by default)

		ow_fontlineheight (design-time only)
			- causes "extraspace" of the last text line to be drawn, 
			in turn it causes adjustment of widget height if "ow_autoscale" is set
			
			*** makes sence only if "ow_autoscale=true" & ow_autosize=false & "extraspace <> 0" ***

		ow_fontglyphheight (design-time only)
			- causes only interline "extraspace"-s to be drawn, opposite to "ow_fontlineheight" 

		ow_autoscale (design-time only)
			- causes that if the contents change (design OR run-time) so that its' height changes 
			then the widget will be v-scaled as well

		ow_autosize (design-time only)
			- causes that widget's height & width & client area adjust so that to provide space for contents of the client area
			- no design-time change of height/width are possible as long as this option is in effect

		ow_autosizeanright
			- when autosizing & {an_right isn't set}, the design-set right margin against the parent is preserved

		ow_autosizeanbottom
			- when autosizing & {an_bottom isn't set}, the design-set bottom margin against the parent is preserved

	optionsskin:

		- osc_noskin
		- osc_framebuttononly
		- osc_container


	Methods:

	  // tmsecomponent

		// (re)draws the widget according to the related skin if apllicable;
		//
		// also called internally by "loaded" procedure ( before "OnLoaded" code ),
		// by ShowMessage ( for the internal widgets of the message dialogue ), 
		// when creating tab & form & menu widgets
		procedure updateskin(const recursive: boolean = false);

		// TRUE if the instance is created but not yet ready 
		// for interaction & accessing data & appearance change & receiving events etc
		// ( the stage between firing "OnCreate" & "OnLoaded" )
		function loading: boolean;
	
	 {$ifdef FPC}
		procedure setinline(value: boolean); // ?
		procedure setancestor(value: boolean); // ?
	 {$endif}

		// TRUE if all conditios are OK for executing the code of "event" ( a handler must be assigned to the event )
		function canevent(const event: tmethod): boolean;


		// Shortly, replaces the persistent storage of the widget
		//
		// if {value <> nil} then 
		//	- if "instance" is nil then calls "createproc" to create the instance,
		//    then assigns the instance's value:= "value" 
		// otherwise frees "instance"
		procedure setoptionalobject(const value: tpersistent; var instance;
                        createproc: createprocty);

		// creates the persistent storage of the widget via calling "createproc"
		procedure getoptionalobject(const instance: tobject; createproc: createprocty);

		// obtains & puts to "obj" a CORBA interface entry for "aintf" (GUID,...)
		function getcorbainterface(const aintf: ptypeinfo; out obj) : boolean;

        // TRUE if the widget is owned, or "self" otherwise
		function checkowned(component: tcomponent): boolean; 

        // TRUE if the widget is owner, or "self" otherwise
		function checkowner(component: tcomponent): boolean; 

		// return the top-most widget in owner chain starting from this widget
		function rootowner: tcomponent;

		// return the array of owning widgets starting from this widget
		// componentarty[0] is the widget oneself
		function getrootcomponentpath: componentarty;

        // returns items of objeclinker ( which notify this widget )
        // and free notify list ( which are notified by this widget ),
        // duplicates are removed.
        //	
        // Notifies mainly relate to insertion/removal operation on widgets
        // The notify list is maintained by FreeNotification & RemoveFreeNotification
		function linkedobjects: objectarty;

		// sends "event" recursively to child widgets until no more children or 
		// the event is processed ( cea_processed ) by one of the children,
		// "event" will be destroyed if destroyevent= true and not async
		procedure sendcomponentevent(const event: tcomponentevent; 
                                        const destroyevent: boolean = true);

		// sends "event" to each of owning widgets downward from the root owner,
		// "event" will be destroyed if destroyevent= true and not async
		procedure sendrootcomponentevent(const event: tcomponentevent;
                                        const destroyevent: boolean = true);

		// posts an async "atag"-ged event to be handled by oneself
		procedure asyncevent(atag: integer = 0);

		// posts a "tcomponentevent" instance from sender=self, 
		// "kind" is defined when creating the event, 
		// and "tag" may be adjusted after creation
		procedure postcomponentevent(const event: tcomponentevent);

		// returns the classname of the widget if the widget is toplevel, 
		// and "tmsecomponent" otherwise )
		property moduleclassname: string read getmoduleclassname;

		// returns the classname of the widget as the entry of its constructor
		// ( button => tbutton, datamodule => tdm1mo, form => ttstfo, dbstringedit => tdbstringedit,.. )
		property actualclassname: string read getactualclassname;

		// returns "fmsecomponentstate"
		// ( a set of cs_ismodule,cs_endreadproc,cs_loadedproc,cs_noload, cs_hasskin,cs_noskin )
		property msecomponentstate: msecomponentstatesty read fmsecomponentstate;

		// returns/sets a pointer associated with the widget
		// ( contrary to the integer "tag", allows to use an arbitary data type 
		// for associating data )
		property tagpo: pointer read ftagpo write ftagpo;

		// returns/sets a string identifying the widget in the help system
		property helpcontext: msestring read gethelpcontext write fhelpcontext;

	// twidget

		// creates an instance of the widget, owned by "aowner" if not NIL
		constructor create(aowner: tcomponent); override;

		destructor destroy; override;

		// ??
		procedure afterconstruction; override;

		// rescales the widget frame ( if assigned ) then owned widgets ( if exist, recursively ) then bounds_* then the font ( if assigned )
		// called before inserting in parentwidget,
		// calls "scale(ascale)",
		// no visual repainting
		procedure initnewcomponent(const ascale: real); virtual;

 		// restores the "fontheight" to "font.glyphheight" if "ow_fontglyphheight" or
 		// to "font.lineheight" if "ow_fontlineheight" otherwise,
		// ascale is ignored ?
		// calls "synctofontheight->setfontheight",
		// called after inserting in parentwidget,
		// no visual repainting
		procedure initnewwidget(const ascale: real); virtual;

		// creates the widget frame if not yet created
		procedure createframe;

		// creates the widget face if not yet  created
		procedure createface;

		// creates the widget font if not yet  created
		procedure createfont;

		// checks ws_loadlock and csdestroing too
		function isloading: boolean;

		// returns "widgetstatety" - a set of (
		// ws_visible,ws_enabled,ws_active,ws_entered,ws_entering,ws_exiting,
		// ws_focused,ws_mouseinclient,ws_wantmousebutton,ws_wantmousemove,
		// ws_wantmousefocus,ws_iswidget,ws_opaque,ws_nopaint,
		// ws_clicked,ws_mousecaptured,ws_clientmousecaptured,
		// ws_loadlock,ws_loadedproc,ws_showproc,ws_minclientsizevalid,
		// ws_showed,ws_hidden, //used in tcustomeventwidget
		// ws_destroying,ws_staticframe,ws_staticface,ws_isvisible
		//
		// iframe
		function widgetstate: widgetstatesty;

		// returns "widgetstate1ty" - a set of (
		// (ws1_childscaled,ws1_fontheightlock,
		// ws1_widgetregionvalid,ws1_rootvalid,
		// ws1_anchorsizing,ws1_isstreamed,
		// ws1_scaled, //used in tcustomscalingwidget
		// ws1_noclipchildren,
		// ws1_nodesignvisible,ws1_nodesignframe,ws1_nodesignhandles,
		// ws1_nodesigndelete,ws1_designactive,
		// ws1_fakevisible,ws1_nominsize //used for report size calculations
		// )
		property widgetstate1: widgetstates1ty read fwidgetstate1;
		
			* this set of states is needed because the max FPC set size is 32 
			  thus "widgetstate1ty" can't fit all states

		// TRUE if the widget is contained within another widget
		// ( tcomponent stuff )
		function hasparent: boolean; override;               

		// returns the parent component if it's a widget or the grandparent otherwise
		function getparentcomponent: tcomponent; override;   // tcomponent

		// TRUE if "awidget" is an ascendant or the widget or they are the same widget
		function checkdescendent(awidget: twidget): boolean;
		
		// TRUE if app is running and the widget owns the caret or the caret widget
		function hascaret: boolean;

        // TRUE if "winid" allocated and not loading and not destroying,
        // all widgets on a form have "winid" of this form ( a real window allocated by the OS )
        // thus have this function TRUE
		function windowallocated: boolean;

		// TRUE if presents a valid toplevelwindow with assigned "winid"
		function ownswindow: boolean;

		// invalidated area of the widget, the origin is "clientpos" against the roor widget
		function updaterect: rectty; 

		// calls recursively "canclose" for all contained widgets ( the widget oneself excluded! ),
		// TRUE if none of the widgets return FALSE
		//
		// more specialized widgets may have "canclose" overridden 
		// to perform more work than just this call recursion
		// ( not null or range check,.. )
		//
		// "onclosequery" must also pass the check if assigned, for the function to succeed
		function canclose(const newfocus: twidget = nil): boolean; virtual;

        // checks "canclose" first for focused widget of the window ( form,.. ) 
        // if it is a descendant of the widget or the widget oneself,
        // then continues with subwidgets of the widget;
        // also - finishes editing ( snapshots "value" ) in the focused widget before checking
		function canparentclose(const newfocus: twidget): boolean; overload;

		// the above function but with the preserved focus
		function canparentclose: boolean; overload;
                   //newfocus = window.focusedwidget      

		function canfocus: boolean; virtual;
		function setfocus(aactivate: boolean = true): boolean; virtual;//true if ok
		procedure nextfocus; //sets inputfocus to then next appropriate widget

		function findtabfocus(const ataborder: integer): twidget;
                       //nil if cannot focus

		function firsttabfocus: twidget;
		function lasttabfocus: twidget;
		function nexttaborder(const down: boolean = false): twidget;

		function focusback(const aactivate: boolean = true): boolean;
                               //false if focus not changed

		function parentcolor: colorty;
		function actualcolor: colorty; virtual;
		function actualopaquecolor: colorty;
		function backgroundcolor: colorty;
		function translatecolor(const acolor: colorty): colorty;

		procedure widgetevent(const event: twidgetevent); virtual;

		procedure sendwidgetevent(const event: twidgetevent);
                              //event will be destroyed

		procedure release; override;

		function show(const modal: boolean = false; const transientfor: twindow = nil): modalresultty; virtual;

		procedure hide;
		procedure activate(const abringtofront: boolean = true); virtual;
                             //show and setfocus

		procedure bringtofront;
		procedure sendtoback;
		procedure stackunder(const predecessor: twidget);

		procedure paint(const canvas: tcanvas); virtual;
		procedure update; virtual;
		procedure scrollwidgets(const dist: pointty);

		procedure scrollrect(const dist: pointty; const rect: rectty; scrollcaret: boolean);
                             //origin = paintrect.pos

		procedure scroll(const dist: pointty);
                            //scrolls paintrect and widgets

		procedure getcaret;
		procedure scrollcaret(const dist: pointty);
		function mousecaptured: boolean;
		procedure capturemouse(grab: boolean = true);
		procedure releasemouse;
		procedure capturekeyboard;
		procedure releasekeyboard;
		procedure synctofontheight; virtual;

		procedure dragevent(var info: draginfoty); virtual;
		procedure dochildscaled(const sender: twidget); virtual;

		procedure invalidatewidget;     //invalidates whole widget
		procedure invalidate;           //invalidates clientrect
		procedure invalidaterect(const rect: rectty; org: originty = org_client);
		procedure invalidateframestate;

		procedure invalidateframestaterect(const rect: rectty; 
                                        const org: originty = org_client);   
		function hasoverlappingsiblings(arect: rectty): boolean; //origin = pos

		function window: twindow;
		function rootwidget: twidget;

		function parentofcontainer: twidget;
            //parentwidget.parentwidget if parentwidget has not ws_iswidget,
            //parentwidget otherwise

		property parentwidget: twidget read fparentwidget write setparentwidget;
		function getrootwidgetpath: widgetarty; //root widget is last

		// number of contained widgets ( the widget oneself excluded ! )
		function widgetcount: integer;

		function parentwidgetindex: integer; //index in parentwidget.widgets, -1 if none
		property widgets[const index: integer]: twidget read getwidgets;
		function widgetatpos(var info: widgetatposinfoty): twidget; overload;
		function widgetatpos(const pos: pointty): twidget; overload;

		function widgetatpos(const pos: pointty; 
                   const state: widgetstatesty): twidget; overload;

		property taborderedwidgets: widgetarty read gettaborderedwidgets;

		function findtagwidget(const atag: integer; const aclass: widgetclassty): twidget;
              //returns first matching descendent

		property container: twidget read getcontainer;
		function containeroffset: pointty;
		function childrencount: integer; virtual;
		property children[const index: integer]: twidget read getchildwidgets; default;

		function childatpos(const pos: pointty; 
                   const clientorigin: boolean = true): twidget; virtual;

		function getsortxchildren: widgetarty;
		function getsortychildren: widgetarty;
		property focusedchild: twidget read ffocusedchild;
		property focusedchildbefore: twidget read ffocusedchildbefore;

		function mouseeventwidget(const info: mouseeventinfoty): twidget;

		function checkdescendent(widget: twidget): boolean;
                    //true if widget is descendent or self

		function checkancestor(widget: twidget): boolean;
                    //true if widget is ancestor or self

		function containswidget(awidget: twidget): boolean;

		procedure insertwidget(const awidget: twidget); overload;

		procedure insertwidget(const awidget: twidget; const apos: pointty); overload; virtual;
                 //widget can be child

		function iswidgetclick(const info: mouseeventinfoty; const caption: boolean = false): boolean;
		//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect
 		//or in frame.caption if caption = true, origin = pos

		function isclick(const info: mouseeventinfoty): boolean;
		//true if eventtype = et_butonrelease, button is mb_left, clicked and pos in clientrect

		function isdblclick(const info: mouseeventinfoty): boolean;
		//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
		// and timedlay to last buttonpress is short

		function isdblclicked(const info: mouseeventinfoty): boolean;
		//true if eventtype in [et_buttonpress,et_butonrelease], button is mb_left,
		// and timedlay to last same buttonevent is short

		function isleftbuttondown(const info: mouseeventinfoty): boolean;
		//true if eventtype = et_butonpress, button is mb_left, pos in clientrect
		//origin = paintrect.pos

		widgetrect: the widget on-screen area including its frame & frame caption

			paintrect: the widget on-screen area except its frame & frame caption

			clientrect: virtual area which 
				- for non-scrolling widgets, equals to "paintrect", with its "pos:= (0,0)"
				- for scrolling widgets, may be bigger than "paintrect", 
				  also may shift ( change its "pos" ) when scrolling
		
	// the coord of outer top-left corner against the toplevel form = the window owner,
	// including the frame & frame caption 
		function rootpos: pointty; 

	// the coord of the outer top-left corner against the screen ( the WM decorations aren't counted in )
	// includes the frame & frame caption 
		property screenpos: pointty; 

	//  the coord of the outer top-left corner against the parent widget,
	// including the frame & frame caption 
		property widgetrect: rectty; 
		property pos: pointty; // =widgetrect.pos
		property size: sizety; // =widgetrect.size
		property left: integer; // =bounds_x
		property right: integer; //widgetrect.x + widgetrect.cx, sets cx;
		property top: integer;  // =bounds_y
		property bottom: integer; //widgetrect.y + widgetrect.cy, sets cy;
		property width: integer; // =bounds_cx
		property height: integer; // =bounds_cy
		function widgetsizerect: rectty;          //pos = nullpoint

    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
    //  except the frame & frame caption 
		function paintrect: rectty;
		function paintpos: pointty;
		function paintsize: sizety;
		function innerpaintrect: rectty; // mainly equals to paintrect
		function clientwidgetrect: rectty; // mainly equals to paintrect
		function clientwidgetpos: pointty;
		function clippedpaintrect: rectty; // mainly equals to  but clipped by all parentpaintrects
		function innerwidgetrect: rectty;     // mainly equals to paintrect
		function innerclientwidgetpos: pointty;

    // the coord of the paint area ( paintrect ) against own outer top-left corner ( against "widgetrect=pos" )
    //  except the frame caption 
		function framerect: rectty; // =paintrect except the frame caption area
		function framepos: pointty;
		function framesize: sizety;

    // the coord of the client area ( clientrect )  against the paint area ( paintrect )
    //  usually these areas match
		function clientrect: rectty;
		property clientsize: sizety;
		property clientwidth: integer;
		property clientheight: integer;
		property clientpos: pointty;

    // the coord of the paint area of the parent against the paint area of this widget
		function paintrectparent: rectty; //nullrect if parent = nil,

    // the coord of the client area of the parent against the paint area of this widget
		function clientrectparent: rectty; //nullrect if parent = nil,

	// the coord of the inner area against the client area ( clientrect )
		function innerclientrect: rectty;  // mainly equals to clientrect
		function innerclientsize: sizety;
		function innerclientpos: pointty;

		function framewidth: sizety;              //widgetrect.size - paintrect.size
		function clientframewidth: sizety;        //widgetrect.size - clientrect.size
		function innerclientframewidth: sizety;   //widgetrect.size - innerclientrect.size
		function innerframewidth: sizety;         //clientrect.size - innerclientrect.size  

    // the coord of the paint area against the widgetrect(pos) of the parent
		function paintparentpos: pointty;    //origin = parentwidget.pos

    // the coord of the client area against the widgetrect(pos) of the parent
		function clientparentpos: pointty;   //origin = parentwidget.pos

    // the coord of the widgetrect(pos) against the client area of parent
		property parentclientpos: pointty;


		function clientpostowidgetpos(const apos: pointty): pointty;
		function widgetpostoclientpos(const apos: pointty): pointty;
		function widgetpostopaintpos(const apos: pointty): pointty;
		function paintpostowidgetpos(const apos: pointty): pointty;
		procedure scale(const ascale: real); virtual;


		property minsize: sizety read fminsize write setminsize;
		property maxsize: sizety read fmaxsize write setmaxsize;
		function maxclientsize: sizety; virtual;


		property anchors: anchorsty read fanchors write setanchors default defaultanchors;
		property defaultfocuschild: twidget read getdefaultfocuschild write setdefaultfocuschild;


		procedure changeclientsize(const delta: sizety); //asynchronous

		function getcanvas(aorigin: originty = org_client): tcanvas;

		function showing: boolean;
               //true if self and all ancestors visible and window allocated

		function isenabled: boolean;
               //true if self and all ancestors enabled

		function active: boolean;
		function entered: boolean;

		function activeentered: boolean; 
			//true if entered and window is regularactivewindow or inactivated

		function focused: boolean;
		function clicked: boolean;

		function indexofwidget(const awidget: twidget): integer;

		procedure changedirection(const avalue: graphicdirectionty;
                                            var dest: graphicdirectionty); virtual;

		// (re)arranges "awidgets" horizontally within the parent's client area 
		// so that awidget[i] were placed next each other 
		// at h-space dist[i], starting from "startx" with the right margin "endmargin";
		// 
		// if the number of "dist" is fewer than the number of "awidgets" then the remaining h-spaces are taken 
		// as the last "dist[i]" or "0" if none;
		// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
		// 
		// non-zero "endmargin" causes one of awdidget[i] to h-resize to provide the margin :
		//  - if one or more of awidgets[i] have [an_left,an_right] set then the first of such is resized
		//    otherwise the last awidgets[i] is h-resized 
		// 
		procedure placexorder(
				const startx: integer; 
				const dist: array of integer;
                const awidgets: array of twidget;
                const endmargin: integer = minint);

		// (re)arranges "awidgets" vertically within the parent's client area 
		// so that awidget[i] were placed upper/lower each other 
		// at v-space dist[i], starting from "starty" with the bottom margin "endmargin";
		// 
		// if the number of "dist" is fewer than the number of "awidgets" then the remaining v-spaces are taken 
		// as the last "dist[i]" or "0" if none;
		// if the number of "dist" is more than the number of "awidgets" then the extra dist[i] are discarded
		// 
		// non-zero "endmargin" causes one of awdidget[i] to v-resize to provide the margin :
		//  - if one or more of awidgets[i] have [an_top,an_bottom] set then the first of such is resized
		//    otherwise the last awidgets[i] is v-resized 
		// 
		procedure placeyorder(
				const starty: integer; 
				const dist: array of integer;
                const awidgets: array of twidget;
                const endmargin: integer = minint);
               //origin = clientpos, endmargin by size adjust of widgets 
               //with [an_top,an_bottom], minint -> no change

		// if {mode <> wam_none} then (re)arranges "awidgets" horizontally  within the parent's client area so that 
		// awidgets[0] stays on its place but awidgets[1..N] :
		// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_left" set ) so that they right borders match the right border of awidgets[0]
		// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_right" set ) so that they left borders match the left border of awidgets[0]
		// - if {mode = wam_center} then awidgets[i>=1] move so that they Y-axes match the Y-axe of awidgets[0]
		//
		// mainly applicable for v-stacked widgets since h-stacked may overlap after such alignment
		//
        // returns the reference point ( the coord of awidgets[0] )
		function alignx(const mode: widgetalignmodety;
                        const awidgets: array of twidget): integer;


		// if {mode <> wam_none} then (re)arranges "awidgets" vertically within the parent's client area so that 
		// awidgets[0] stays on its place but awidgets[1..N] : 
		// - if {mode = wam_end} then awidgets[i>=1] move or resize ( if "anchors.al_top" set ) so that they bottom borders match the bottom border of awidgets[0]
		// - if {mode = wam_start} then awidgets[i>=1] move or resize ( if "anchors.al_bottom" set ) so that they top borders match the top border of awidgets[0]
		// - if {mode = wam_center} then awidgets[i>=1] move so that they X-axes match the X-axe of awidgets[0]
		//
		// mainly applicable for h-stacked widgets since v-stacked may overlap after such alignment
		//
        // returns the reference point ( the coord of awidgets[0] )
		function aligny(const mode: widgetalignmodety;
                        const awidgets: array of twidget): integer;

		function actualcursor: cursorshapety; virtual;


	Event handlers:

	- onactivate

		 fires :

		= on receiving input focus, just before "OnFocus"
			
		= forms specific :
			* on 1-st display of the form after "OnLoaded" ( from "Loaded" procedure)
			* on switch back from another apllication/WM ( "oe_activate" event )
			* after closure of a descendant form
			* on minimizing/maximizing the form

	- onchildscaled

		 fires :

		= on child/children resizing due to font height change

		= form widget: once "form.container" {scrolling widget} is loaded

	- ondeactivate
		 fires 
			= form widget: when the form looses input focus
			= non-form widget: when the widget looses input focus

	- ondefocus

		fires 
		= on disabling the widget

	= form widget: if another form is focused
		= non-form widget: if another widget is focused

	- onenter
		= fires on any way of taking parent-wide focus as soon as 
		the parent stores the new child's order, before "OnActivate" & "OnFocus"

	- onexit
		= fires last on parent-wide lossing focus, after "OnDefocus" & "OnDeactivate"
		= for top-level ( not in a container ) forms, doesn't fire

	- onfocus
		fires 
			= once the existing widget takes the focus 
			= on showing the widget's form if the widget has the lowest "TabOrder"

	- onfontheightdelta
		fires
			= if [ow_fontglyphheight OR ow_fontlineheight ] AND {the
			new font height differs from the previos one}
			= before the parent redraws this widget

	- onpopup
		fires :
			= on calling a popup-menu ( with "RightClick" ), once the menu items of the current level are loaded
			( before building the submenus ) 

	- onresize

		= fires on creating/(changing size)/(min-max restoring) of widget, 
		before actual redrawing

		= rechecks if there's real work to do

	- onshowhint
		= fires when a installed hint is activated or on "aplication.showint" called
		= since called last, allows to adjust the default behavior

	- onbeforeupdateskin
		= fires in "updateskin" ( the widget is loaded etc ) before applying the skin

	- onafterupdateskin
		= fires in "updateskin" ( the widget is loaded etc ) once the skin is applied

TWidget stuff

   Properties:    
		- name
		- anchors
		- bounds
		- color
		- enabled
		- visible
		- <face> : see {any face}
		- <frame> : see {any frame}
	    - hint
	    - helpcontext
	    - tag
	    - taborder
	    - cursor
	    - optionswidget
	    - optionsskin
	    - popupmenu
    
		twidget's event handlers:
    
			- on(de)activate
			- onbeforeupdateskin
			- onafterupdateskin
			- onchildscaled
			- onfontheightdelta
			- on(de)focus
			- onenter
			- onmove
			- onpopup
			- onresize
			- onshowhint
      
	align_glue : 
	  ( outer anchoring mode for widget group, in the align mode )
		- wam_none
		- wam_start
		- wan_center
		- wm_end

	align_leader : 
		the widget ( incl another spacer, splitter or layouter ) against which the alignment applies ( the reference widget )

	align_mode : 
	  ( inner anchoring mode within widget group, in the align mode )
		- wam_none
		- wam_start
		- wan_center
		- wm_end

// Place mode:

      
	place_mindist, place_maxdist:
		- in the place(ment) mode, limits distance between widgets
		  ( these distance once calculated also define side margins if applicable )

	place_mode: 
	  ( outer anchoring mode for widget group, in the place mode )
		- wam_none
		- wam_start
		- wan_center
		- wm_end

	place_options:
		- plo_endmargin
			= to resize a widget so that it "eats" extra space if it occurs
			
			* only applicable in the place mode, with a limiting value of "place_maxdist" and:

			  1) {place_mode <> wam_none}
			or
			  2) {place_mode = wam_end} and {plo_propmargin in place_options}

			For the exact look, see above


		- plo_propmargin
			= виджеты расставляются теснее так, чтобы образовались отступы перед и после,
			  причем расстояние между центрами виджетов было бы таким же, 
			  как и растояние между серединами крайних виджетов и соотв. границами зоны расстановки

		- plo_syncmaxautosize
			= see above

		- plo_synccaptiondistx
			= see above

			  * affects widgets with opposite cp_left/right set as well	
			  * the minimal before-adjustment "captiondist" among all widgets limits "captiondist" for each of the widget
              * don't set cfo_captiondistouter here !

		- plo_synccaptiondisty
			= see above

			  * affects also widgets with opposite cp_top/bottom set	
			  * the minimal before-adjustment "captiondist" amongst all widgets limits "captiondist" for each of the widget

              ! here, don't set "cfo_captiondistouter" for affected widgets !

		- plo_syncpaintwidth
			= see above

		- plo_syncpaintheight
			= see above

		- plo_scalesize
			= see above


	dist_left, dist_right, dist_top, dist_bottom : 
		= margins between most outer edge the layouter and 
		  the corresponding linked widget

		* see "tspacer" for detail

	linkleft,linkright,linktop,linkbottom : see "tspacer"

	options:
		- spao_glueright, spao_gluebottom: 
			= set the adjustment dependencies between the layouter and its link_* widgets

			* see "tspacer" for more details

	// which mode of widget placement to apply - see above
	optionslayout: 
		- lao_alignx
		- lao_aligny
		- lao_placex
		- lao_placey
		- lao_scalewidth
		- lao_scaleheight
		- lao_scaleleft
		- lao_scaletop
		
		* lao_place* & lao_align* can't be combined for one direction

	optionsscale: 
	  
	  * cause the layouter to provide full space for the widgets as long as they expand/shrink/move

		- osc_expandx 
			= allocates more h-space if needed

		- osc_shrinkx
			= removes extra h-space if occurred

		- osc_expandy
			= allocates more v-space if needed

		- osc_shrinky
			= removes extra v-space if occurred

		- osc_invisishrinkx
			= fully h-collapses the layouter if "visible=false" ( run-time only )

		- osc_invisishrinky
			= fully v-collapses the layoter if "visible=false" ( run-time only )

	optionsskin:
		= see <any widget>


	Methods:

		constructor create(aowner: tcomponent); override;

Public stuff

	(f)window: 
		the OS-allocated ( root = toplevel ) window common for all widgets of this window
		
		* "widget.fwindow.fowner = widget.self" in case of the widget present the root "fwindow" 
		  ( owns the window )

	(f)rootpos: 
		position of the widget in the coord of toplevel window not the nearest parent widget alone,
		calculated as sum of such positions ( fwidgetrect.pos ) starting from the toplevel through the
                chain of all parents up to the current widget;
		"nullpoint" (0,0) for toplevel widgets ( window-owning forms,..)

	screenpos:
		- coord aginst the top-left corner of screen
		- WM decoration & title aren't parts of the widget !

	widgetrect: 
		the widget on-screen area including its frame & frame caption

	paintrect: 
		the widget on-screen area except its frame & frame caption

	clientrect: 
		virtual area which 
			- for non-scrolling widgets, equals to "paintrect", with its "pos:= (0,0)"
			- for scrolling widgets, may be bigger than "paintrect", 
		 	  also may shift ( change its "pos" ) when scrolling

			* "t*grid" aren't such scrollable widgets since their virtual height would be limited by 
			  the X11 "+-32000" limitation, 
			  so example of such widgets are tscrollbox, "tform.container" etc

	framerect: 
		the widget on-screen area except its frame caption but including inner & outer frame

	****************

	// releases all thread locks then post the event to the app event queue and
	// waits for the event handler finishes ( signalled by "sye_ok on a semaphore )
	// finally restores the locks
    // true if the handler is not aborted
	function synchronizeevent(const aevent: tsynchronizeevent): boolean;

    // translates "point" coord against "source" widgetrect to "dest" widgetrect
	//
	//   * nil "source" = from screen coord 
	//   * nil "dest" = to screen coord
	procedure translatewidgetpoint1(var point: pointty; const source,dest: twidget);

	// the function-framed version of "translatewidgetpoint1"
	function translatewidgetpoint(const point: pointty; const source,dest: twidget): pointty;

	// rect isntead of point, 
	// if dest = nil then to screen 
    // if source = nil then against screen
	function translatewidgetrect(const rect: rectty; const source,dest: twidget): rectty;
	//-----------------
    // translates "point" coord against "source" paintrect to "dest" paintrect
	//   * nil "source" = from screen coord 
	//   * nil "dest" = to screen coord
	procedure translatepaintpoint1(var point: pointty; const source,dest: twidget);

	// the function-framed version of "translatepaintpoint1"
	function translatepaintpoint(const point: pointty; const source,dest: twidget): pointty;

	// rect isntead of point, 
	// if dest = nil then to screen 
    // if source = nil then against screen
	function translatepaintrect(const rect: rectty;const source,dest: twidget): rectty;
    //-----------------
    // translates "point" coord against "source" clientrect to "dest" clienttrect
	//   * nil "source" = from screen coord 
	//   * nil "dest" = to screen coord
	procedure translateclientpoint1(var point: pointty;
                    const source,dest: twidget);

	// the function-framed version of "translateclientpoint1"
	function translateclientpoint(const point: pointty; const source,dest: twidget): pointty;

	// rect isntead of point, 
	// if dest = nil then to screen 
    // if source = nil then against screen
	function translateclientrect(const rect: rectty; const source,dest: twidget): rectty;
    //-----------------

	// (re)sorts "awidgets" in order of increasing their "widgetrect.x" coords
	//   - if parent = nil then the coords are against individual parent of each of "awidgets"
	//   - if parent is supplied then the coords are against this parent
	procedure sortwidgetsxorder(var awidgets: widgetarty; const parent: twidget = nil);

	// (re)sorts "awidgets" in order of increasing their "widgetrect.y" coords
	//   - if parent = nil then the coords are against individual parent of each of "awidgets"
	//   - if parent is supplied then the coords are against this parent
	procedure sortwidgetsyorder(var awidgets: widgetarty; const parent: twidget = nil);

	// for each  of "widgets", calculates its autosized client area ( min size rect to fit the caption, etc )
    //   - both hor & ver sizes of client area of each of "widgets" are adjusted to the max of the above calculated areas,
	//	   as the result - client areas of all widgets become identically v+h sized
    // 
    //   * right & bottom anchored margins of each widget are preserved
	procedure syncmaxautosize(const widgets: array of twidget);

	// for each  of "widgets", width of client area of each of "widgets" is adjusted so that 
    // external ( by the outer border of frame ) widths of all widgets become identical 
    // to the external widht of the widest widget
    //    
    //   * if "awidth" >= 0 then no determining the widest widget is taken and
    //     "awidth" is adjusted to instead, for all widgets
    //   * right anchored margins of each widget are lost
	procedure syncminframewidth(const awidgets: array of twidget;
                               const awidth: integer = -1);

	// for each  of "widgets", height of client area of each of "widgets" is adjusted so that 
    // external ( by the outer border of frame ) heights of all widgets become identical 
    // to the external height of the highest widget
    //    
    //   * if "aheight" >= 0 then no determining the highest widget is taken and
    //     "aheight" is adjusted to instead, for all widgets
    //   * bottom anchored margins of each widget are lost
	procedure syncminframeheight(const awidgets: array of twidget; const aheight: integer = -1);

Projects using MSEgui