December 08, 2003
I got cartoon and dedit  working. deditexec.exe still doesn't work (but I don't really care about that)

The problem was:

    /** Get the number of milliseconds the program has been running. */
    static ulong elapsedTime ()
    {
        ulong value;
        LARGE_INTEGER freq;

        return GetTickCount (); //Added by Joel Anderson
        /+if
(!net.BurtonRadons.dig.platform.base.QueryPerformanceFrequency (&freq)
|| freq == 0 || !std.random.QueryPerformanceCounter (&value))
            return GetTickCount ();
        if (!digPlatformElapsedTimeCounter)
            digPlatformElapsedTimeCounter = value;
        return (value - digPlatformElapsedTimeCounter) * 1000 / freq;+/
//Causes access violation -> fix yourself if you really want such accuracy
    }

It's still not quite correct. I'm simply using the low resolution timer (which burton old code defaulted to if the higher one isn't avaliable).

I still haven't gotten my own example to work, I guess I'm mucking up the make file. I did have it working before .75.


December 08, 2003
Carlos Santander B. wrote:

>"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>news:br2koa$2i0q$1@digitaldaemon.com...
>| ...
>|
>| import c.stdio;
>| import net.BurtonRadons.dig.main;
>|
>| class Program : Frame
>| {
>|   this ()
>|   {
>|     //Never gets here, crashes in parent construction
>|     caption ("Caption");
>|
>|       with (new Label (this))
>|       {
>|           grid (0, 0);
>|           caption ("This is a label");
>|       }
>|
>|   }
>| }
>|
>| int main( char [] [] args ) //So I can get messages
>| {
>|     (new Program ()).showModal ();
>|     return 1;
>| }
>|
>| ...
>
>IIRC, you need to call super() in the first line of your constructor (that'd
>be right where you have the comment).
>
>-------------------------
>Carlos Santander
>
>
>---
>
>Checked by AVG anti-virus system (http://www.grisoft.com).
>Version: 6.0.545 / Virus Database: 339 - Release Date: 2003-11-27
>
>
>  
>
Thanks, but that didn't help, the assertions still on the same line.

December 08, 2003
J Anderson wrote:

> Carlos Santander B. wrote:
>
>> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>> news:br2koa$2i0q$1@digitaldaemon.com...
>> | ...
>> |
>> | import c.stdio;
>> | import net.BurtonRadons.dig.main;
>> |
>> | class Program : Frame
>> | {
>> |   this ()
>> |   {
>> |     //Never gets here, crashes in parent construction
>> |     caption ("Caption");
>> |
>> |       with (new Label (this))
>> |       {
>> |           grid (0, 0);
>> |           caption ("This is a label");
>> |       }
>> |
>> |   }
>> | }
>> |
>> | int main( char [] [] args ) //So I can get messages
>> | {
>> |     (new Program ()).showModal ();
>> |     return 1;
>> | }
>> |
>> | ...
>>
>> IIRC, you need to call super() in the first line of your constructor (that'd
>> be right where you have the comment).
>>
>> -------------------------
>> Carlos Santander
>>
>>
>> ---
>>
>> Checked by AVG anti-virus system (http://www.grisoft.com).
>> Version: 6.0.545 / Virus Database: 339 - Release Date: 2003-11-27
>>
>>
>>  
>>
> Thanks, but that didn't help, the assertions still on the same line.
>
I mean, assertion -> access violation.

December 09, 2003
J Anderson wrote:
> I got cartoon and dedit  working. deditexec.exe still doesn't work (but I don't really care about that)
> 

I applied your fixes to my set of the source and voila! Thanks for your help.

Everything seems to work now except cartoon.exe and deditexec.exe.  I'm not even sure that deditexec.exe is even supposed to do anything, so I'm not concerned about that.

I uploaded the newest version to my website:
http://jcc_7.tripod.com/d/dig.html

Justin
December 09, 2003
J C Calvarese wrote:

> J Anderson wrote:
>
>> I got cartoon and dedit  working. deditexec.exe still doesn't work (but I don't really care about that)
>>
>
> I applied your fixes to my set of the source and voila! Thanks for your help.
>
> Everything seems to work now except cartoon.exe and deditexec.exe.  I'm not even sure that deditexec.exe is even supposed to do anything, so I'm not concerned about that.
>
> I uploaded the newest version to my website:
> http://jcc_7.tripod.com/d/dig.html
>
> Justin

I'll send you my complete dig, because cartoon works for me. + I also added my proper-fullscreen mod.  Also, if someone wants to take the time to tidy up my very messy version (I won't have very much time to work on it ATM).  There's also the matter if the two code statements I commented out.  One being the elapsedTime () function in control I just mentioned and other other being the missing DragQueryPoint in frame.

December 09, 2003
J Anderson wrote:
> I'll send you my complete dig, because cartoon works for me. + I also added my proper-fullscreen mod.  Also, if someone wants to take the time to tidy up my very messy version (I won't have very much time to work on it ATM).  There's also the matter if the two code statements I commented out.  One being the elapsedTime () function in control I just mentioned and other other being the missing DragQueryPoint in frame.
> 

Thanks.  Now cartoon works for me too, now.

I uploaded it again: http://jcc_7.tripod.com/d/dig.html

This one's a keeper.

Justin
December 09, 2003
I'm sorry, but I must speak up.

I think Dig is a great thing.  But I don't have a whole lot of time, and I don't even use Dig, and there's always lots of messages in the "Dig broken"/"Dig fixed" thread.

Would that be a good thing to put in it's own newsgroup?

(I suppose I can filter).  But I want to see stuff like major Dig release announcements cross-posted.  It's just better if the dig traffic is kept separate since it's its own fairly big library and warrants a lot of conversation that has little to do with D as a whole..

Sean

"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:3FD4F0B7.6070608@badmama.com.au...
> I got cartoon and dedit  working. deditexec.exe still doesn't work (but I don't really care about that)
>
> The problem was:
>
>     /** Get the number of milliseconds the program has been running. */
>     static ulong elapsedTime ()
>     {
>         ulong value;
>         LARGE_INTEGER freq;
>
>         return GetTickCount (); //Added by Joel Anderson
>         /+if
> (!net.BurtonRadons.dig.platform.base.QueryPerformanceFrequency (&freq)
> || freq == 0 || !std.random.QueryPerformanceCounter (&value))
>             return GetTickCount ();
>         if (!digPlatformElapsedTimeCounter)
>             digPlatformElapsedTimeCounter = value;
>         return (value - digPlatformElapsedTimeCounter) * 1000 / freq;+/
> //Causes access violation -> fix yourself if you really want such accuracy
>     }
>
> It's still not quite correct. I'm simply using the low resolution timer (which burton old code defaulted to if the higher one isn't avaliable).
>
> I still haven't gotten my own example to work, I guess I'm mucking up the make file. I did have it working before .75.
>


----------------------------------------------------------------------------
----


> module net.BurtonRadons.dig.platform.control;
>
> private import net.BurtonRadons.dig.platform.base;
> private import net.BurtonRadons.dig.platform.windows;
> private import net.BurtonRadons.dig.platform.font;
> private import net.BurtonRadons.dig.platform.clipboard;
> private import net.BurtonRadons.dig.platform.registry;
>
>
>
> //private import std.c.windows.windows;
>
> //private import std.string;
> //private import std.random;
> //private import std.ctype;
>
> /+
> #ifndef DOXYGEN_SHOULD_SKIP_THIS
> +/
>
> std.c.windows.windows.HINSTANCE hinst;
> Font digPlatformMainFont;
> std.c.windows.windows.HFONT digPlatformMainFontHandle;
>
> static this ()
> {
>     hinst = std.c.windows.windows.GetModuleHandleA (null);
>     InitCommonControls ();
>
>     LOGFONT log;
>
>     log.lfHeight = -12; // height
>     log.lfWidth = 0; // width
>     log.lfEscapement = 0; // escapement
>     log.lfOrientation = 0; // orientation
>     log.lfWeight = 400; // weight
>     log.lfItalic = 0; // italic
>     log.lfUnderline = 0; // underline
>     log.lfStrikeOut = 0; // strikeOut
>     log.lfCharSet = 1; // charSet
>     log.lfOutPrecision = 3; // outPrecision
>     log.lfClipPrecision = 2; // clipPrecision
>     log.lfQuality = 1; // quality
>     log.lfPitchAndFamily = 34; // pitchAndFamily
>     std.string.strcpy (log.lfFaceName, "Arial"); // faceName
>
>     digPlatformMainFont = new Font (log);
>     digPlatformMainFontHandle = digPlatformMainFont.digPlatformGetHFONT
();
> }
>
> /+
> #endif
> +/
>
> /** The base GUI widget class.
>
>   <h2>Grid Fitting</h2>
>
>   By default, you are under control of the location of your widgets,
although
>   their dimensions are specified by the class itself.  Gridfitting is also
>   provided that locates the controls based on their position in a table.
>   You can turn on gridfitting using the #grid method and control it with
>   the #sticky method.  These methods will automatically gridfit the
parent.
>   Gridfitting can't modify any client-assigned parameters (assigning to
#left,
>   #top, #width, #height).
>
>   #grid takes two or four arguments.  @a col and @a colspan are
>   the horizontal first cell and number of cells across for the control;
>   @a row and @a rowspan are the same vertically.  Gridfitting will find
the
>   minimum occupiable area for these cells and put the controls within
them.
>
>   #sticky controls the placement of the control within its grid area.
>   For example, the following pseudoimage is built using this code:
>
>   @code
>
> with (a = new MyBox (this))
>     grid (0, 0);
>
> with (b = new MyBox (this))
>     grid (1, 0);
>
> with (c = new MyBox (this))
> {
>     grid (0, 1, 2, 1);
>     sticky ("<");
> }
>
>   @endcode
>
>   This creates this image:
>
>   @image html gridfit_left.gif
>
>   If you don't supply the stickiness for c, then it will be left-aligned
as
>   above.  If you provide a stickiness of "|", meaning horizontal center,
we get:
>
>   @image html gridfit_center.gif
>
>   If you provide a stickiness of ">", meaning right-aligned, we get:
>
>   @image html gridfit_right.gif
>
>   Finally, if we provide a stickiness of "<>", meaning to cover the full
area,
>   we get:
>
>   @image html gridfit_full.gif
>
>   Vertical stickiness works the same, but using "^" for top-aligned, "v"
for
>   bottom-aligned, "-" for vertically centered, and "^v" to cover the full
area
>   vertically.
>
>   */
>
> class Control
> {
>     static Registry registry; /**< The registry std.math.singleton. */
>     static Clipboard clipboard; /**< The clipboard std.math.singleton. */
>
>     /** Setup the registry. */
>     static this ()
>     {
>         registry = new Registry ();
>         clipboard = new Clipboard ();
>     }
>
>     BindingList bindings; /**< The list of bindings attached to this
control. */
>
>     Dispatcher onChar; /**< Character has been pressed or is repeating.
The @a keyCode, @a keyRepeat, and @a keyPrevious fields are filled in. */
>
>     Dispatcher onHelp; /**< Help has been requested for this control; if
empty, sends it to its parent. */
>
>     Dispatcher onHScroll;
>         /**< A horizontal scrollbar action has been requested.
>            * @a scrollType contains the variety of action;
>            * @a scrollPoint contains the current point of the scrollbar.
>            */
>
>     Dispatcher onKeyDown; /**< Key has been pressed or is repeating.  The
@a keyCode, @a keyRepeat, and @a keyPrevious fields are filled in. */
>     Dispatcher onKeyUp; /**< Key has been released.  The @a keyCode, @a
keyRepeat, and @a keyPrevious fields are filled in. */
>
>     Dispatcher onLButtonDown; /**< Left mouse button has been pressed. */
>     Dispatcher onLButtonUp; /**< Left mouse button has been released. */
>     Dispatcher onLostFocus; /**< No longer has keyboard focus. */
>
>     Dispatcher onMButtonDown; /**< Middle mouse button has been pressed.
x, y, and the flag fields are all filled in. */
>     Dispatcher onMButtonUp; /**< Middle mouse button has been released.
x, y, and the flag fields are all filled in. */
>
>     Dispatcher onMouseMove; /**< Posted when the mouse moves. */
>
>     Dispatcher onMouseWheel;
>         /**< The mouse wheel has been spun.  x, y, and the flag fields are
all
>            * filled in, and the wheel field is filled in with the amount
the
>            * wheel has been spun in number of units; positive for spun
away
>            * from the user (pushing it forward), negative for spun towards
the
>            * user (pulling it backward).  Note that this is sent to the
Frame
>            * that is currently the mouse focus, not any of its controls.
>            */
>
>     Dispatcher onMouseOver; /**< The mouse has entered the control's
region.  x and y are filled in with the relative coordinates of the mouse. */
>     Dispatcher onMouseLeave; /**< The mouse has left the control's region.
This is currently supported under Windows 98 and up only. */
>
>     Dispatcher onPaint; /**< Paint the control. */
>
>     Dispatcher onRButtonDown; /**< Right mouse button has been pressed.
x, y, and the flag fields are all filled in. */
>     Dispatcher onRButtonUp; /**< Right mouse button has been released.  x,
y, and the flag fields are all filled in. */
>
>     Dispatcher onVScroll;
>         /**< A vertical scrollbar action has been requested.  The default
is to scroll the control and repaint it.
>            * @a scrollType contains the variety of action.
>            * @a scrollPoint contains the current point of the scrollbar.
>            * @a scrollDest contains one place you could set the scrollbar
to in response.
>            */
>
>     Dispatcher onSizeChanged; /**< The control size has been altered by
gridfitting.  The event's e.x and e.y hold the previous size. */
>
>     /** A dispatcher for the drag and drop message.  The method forms for
add are:
>
>         @code
>         void delegate (char [] [] files);
>         void delegate (int x, int y, char [] [] files);
>         @endcode
>
>         "files" is the list of filenames with full path dropped on the
control.
>         "x" and "y" are the coordinates of the mouse in this control when
dropped.
>
>       */
>
>     struct DropDispatcher
>     {
>         typedef void delegate (char [] [] files) cMethodA; /**< The form
of a registered method. */
>         typedef void delegate (int x, int y, char [] [] files) cMethodB;
/**< Explicit form. */
>
>         cMethodA [] methoda; /**< The list of methods called by notify. */
>         cMethodB [] methodb; /**< Second list of methods called by notify.
*/
>         private Control control;
>
>         /** Add a method to the list and enable dropping. */
>         void add (cMethodA method)
>         {
>             methoda ~= method;
>             enable ();
>         }
>
>         /** Add a second-form method to the list and enable dropping. */
>         void add (cMethodB method)
>         {
>             methodb ~= method;
>             enable ();
>         }
>
>         /** Notify the methods that an event has occured. */
>         void notify (int x, int y, char [] [] files)
>         {
>             for (cMethodA *m = methoda, n = m + methoda.length; m < n; m
++)
>                 (*m) (files);
>             for (cMethodB *m = methodb, n = m + methodb.length; m < n; m
++)
>                 (*m) (x, y, files);
>         }
>
>         /** Remove all methods and stop allowing drop. */
>         void empty ()
>         {
>             methoda = null;
>             methodb = null;
>             disable ();
>         }
>
>         /** Enable acceptance of drop.  This is automatically called when
>           * a method is added.
>           */
>
>         void enable ()
>         {
>             DragAcceptFiles (control.digPlatformHWND, true);
>         }
>
>         /** Disable acceptance of drop. */
>
>         void disable ()
>         {
>             DragAcceptFiles (control.digPlatformHWND, false);
>         }
>     }
>
>     DropDispatcher onDrop;
>        /**< A set of files have been dropped upon the control.  So long
>             as this dispatcher is empty, the control will not accept
>             drops.
>
>             The following example creates a file list control that will
load files
>             dropped upon it.
>
>             @code
>             class FileList : Canvas
>             {
>                 void doDrop (char [] [] files)
>                 {
>                     for (int c; c < files.length; c ++)
>                         load (files [c]);
>                 }
>
>                 this (Control parent)
>                 {
>                     super (parent);
>                     onDrop.add (&doDrop);
>                 }
>             }
>             @endcode
>
>            */
>
>     /** Set the parent and append this to the parent's children list if it
is not null. */
>
>     this (Control parent)
>     {
>         digPlatformCursor = (_HANDLE) 0;//LoadCursorA (0, IDC_ARROW);
>         digPlatformParent = parent;
>         if (parent)
>             parent.digPlatformChildren ~= this;
>
>         onDrop.control = this;
>     }
>
>     /** Free data and children. */
>     ~this ()
>     {
>         /* Release the mouse. */
>         if (digPlatformHWND && GetCapture () === digPlatformHWND)
>             ReleaseCapture ();
>
>         /* Delete the entry. */
>         //if (hwnd)
>             //delete hwndToControl [hwnd]; /* Investigate! */
>
>         /* Remove this from the parent's list of children. */
>         if (parent ())
>         {
>             Control [] pc = parent ().digPlatformChildren;
>
>             for (int c; c < pc.length; c ++)
>                 if (pc [c] === this)
>                 {
>                     for ( ; c < pc.length - 1; c ++)
>                         pc [c] = pc [c + 1];
>                     parent ().digPlatformChildren = pc [0 .. pc.length -
1];
>                     break;
>                 }
>         }
>
>         deleteChildren ();
>
>         if (digPlatformHWND)
>             DestroyWindow (digPlatformHWND);
>         digPlatformHWND = (_HANDLE) 0;
>
>         if (digPlatformFontSet)
>             DeleteObject (digPlatformFontSet);
>         digPlatformClosed = true;
>     }
>
>     /** Close the control. */
>     void close ()
>     {
>         delete this;
>     }
>
> /** @name Hierarchy Methods
>   * These methods deal with the hierarchy tree of controls.
>   */
>
> /**@{*/
>
>     /** Return the parent of this control, or null if it's at the top
level. */
>     Control parent ()
>     {
>         return digPlatformParent;
>     }
>
>     /** Return the number of children of this control. */
>     uint childCount ()
>     {
>         return digPlatformChildren.length;
>     }
>
>     /** Iterate over the children from back-to-front, calling func on
each. */
>     void childIterate (void delegate (Control child) func)
>     {
>         Control *c = digPlatformChildren;
>         Control *e = c + digPlatformChildren.length;
>
>         while (c < e)
>             func (*(c ++));
>     }
>
>     /** Return a child indexed in the control.  Out-of-range values are
bounds checked.
>       * The order of children is from back-to-front.
>       */
>
>     Control child (uint index)
>     {
>         return digPlatformChildren [index];
>     }
>
>     /** Delete all the children of the control. */
>     void deleteChildren ()
>     {
>         for (int c = digPlatformChildren.length - 1; c >= 0; c --)
>             delete digPlatformChildren [c];
>         delete digPlatformChildren;
>         digPlatformChildren = null;
>     }
>
>     /** Find the frame object that this control exists within or null. */
>     Control findFrame ()
>     {
>         if (!parent ())
>             return null;
>         return parent ().findFrame ();
>     }
>
> /**@}*/
>
> /** @name Grid-Fitting
>   * You can optionally locate controls within a grid, similar to HTML
>   * tables.
>   */
>
> /**@{*/
>
>     /** Set grid parameters.   colspan and rowspan are set to 1. */
>     void grid (int col, int row)
>     {
>         grid (col, row, 1, 1);
>     }
>
>     /** Set grid parameters.  col and row are the horizontal and
>       * vertical location of the control in the table; colspan and
>       * rowspan are the number of cells each covers.
>       */
>
>     void grid (int col, int row, int colspan, int rowspan)
>     {
>         this.digPlatformCol = col;
>         this.digPlatformRow = row;
>         this.digPlatformColSpan = colspan;
>         this.digPlatformRowSpan = rowspan;
>         digPlatformMoved ();
>     }
>
>     /** Set grid and add one to the inout row parameter. */
>     void gridAddRow (int col, inout int row)
>     {
>         gridAddRow (col, row, 1, 1);
>     }
>
>     /** Set grid and add rowspan to the inout row parameter. */
>     void gridAddRow (int col, inout int row, int colspan, int rowspan)
>     {
>         grid (col, row, colspan, rowspan);
>         row += rowspan;
>     }
>
>     /** Get the grid row. */
>     int gridRow () { return digPlatformRow; }
>
>     /** Set the control's stickiness.  This determines where it is places
in
>       * its region during gridfitting, and is a combination of:
>       *
>       * "<" - Stick to left, default, and used if none is given.
>       * \n ">" - Stick to right.
>       * \n "|" - Center horizontally.
>       * \n "<" and ">" - Resize width to cover the full region.
>       *
>       * \n "^" - Stick to top, default, and used if none is given.
>       * \n "v" - Stick to bottom.
>       * \n "-" - Center vertically.
>       * \n "^" and "v" - Resize height to cover the full region.
>       *
>       * So "<>^v" means to cover the entire region provided.
>       */
>
>     void sticky (char [] value)
>     {
>         bit w = digPlatformStickyW, e = digPlatformStickyE, hc =
digPlatformStickyHC;
>         bit n = digPlatformStickyN, s = digPlatformStickyS, vc =
digPlatformStickyVC;
>
>         digPlatformStickyW = digPlatformStickyE = digPlatformStickyHC =
false;
>         digPlatformStickyN = digPlatformStickyS = digPlatformStickyVC =
false;
>         if (std.string.find (value, '<') >= 0) digPlatformStickyW = true;
>         if (std.string.find (value, '>') >= 0) digPlatformStickyE = true;
>         if (std.string.find (value, '|') >= 0) digPlatformStickyHC = true;
>         if (std.string.find (value, '^') >= 0) digPlatformStickyN = true;
>         if (std.string.find (value, 'v') >= 0) digPlatformStickyS = true;
>         if (std.string.find (value, '-') >= 0) digPlatformStickyVC = true;
>         if (!digPlatformStickyW && !digPlatformStickyE &&
!digPlatformStickyHC) digPlatformStickyW = true;
>         if (!digPlatformStickyN && !digPlatformStickyS &&
!digPlatformStickyVC) digPlatformStickyN = true;
>
>         if (digPlatformStickyW != w || digPlatformStickyE != e ||
digPlatformStickyHC != hc
>          || digPlatformStickyN != n || digPlatformStickyS != s ||
digPlatformStickyVC != vc)
>             digPlatformMoved ();
>     }
>
>     /** Set padding used to separate this control from its neighbours. */
>     void pad (int x, int y)
>     {
>         digPlatformPadX = x;
>         digPlatformPadY = y;
>         digPlatformMoved ();
>     }
>
>     /** Set border used on each side of the control's children to
>       * separate the contents from the border.
>       */
>
>     void border (int x, int y)
>     {
>         digPlatformBorderX = x;
>         digPlatformBorderY = y;
>         digPlatformMoved ();
>     }
>
>     /** Get the grid extents for the children. */
>     void gridExtents (out int colmax, out int rowmax)
>     {
>         int cw = 0, ch = 0;
>
>         for (Control *c = digPlatformChildren, e = c +
digPlatformChildren.length; c < e; c ++)
>         {
>             if (c.digPlatformCol == -1)
>                 continue;
>             if (c.digPlatformCol + c.digPlatformColSpan > cw)
>                 cw = c.digPlatformCol + c.digPlatformColSpan;
>             if (c.digPlatformRow + c.digPlatformRowSpan > ch)
>                 ch = c.digPlatformRow + c.digPlatformRowSpan;
>         }
>
>         colmax = cw;
>         rowmax = ch;
>     }
>
>     /** Do any necessary gridfitting. */
>     void display ()
>     {
>         if (digPlatformDirty)
>             digPlatformGridfit ();
>     }
>
> /**@}*/
>
> /** @name Advanced Placement
>   * These methods poll and place the exact positioning of a control within
>   * its parent.  Normally these coordinates are unlocked and can be
assigned
>   * by grid-fitting; assigning them locks them so that this value is
always
>   * used.
>   */
>
> /**@{*/
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void left (int value)
>     {
>         digPlatformClientLeft = value;
>         digPlatformMoved ();
>     }
>
>     /** The left margin of the control in its parent's client area. */
>     final int left ()
>     {
>         if (digPlatformClientLeft >= 0)
>             return digPlatformClientLeft;
>         return digPlatformSuggestLeft;
>     }
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void top (int value)
>     {
>         digPlatformClientTop = value;
>         digPlatformMoved ();
>     }
>
>     /** The top margin of the control in its parent's client area. */
>     final int top ()
>     {
>         if (digPlatformClientTop >= 0)
>             return digPlatformClientTop;
>         return digPlatformSuggestTop;
>     }
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void width (int value)
>     {
>         int owidth = width ();
>
>         digPlatformClientWidth = value;
>         if (digPlatformClientWidth != owidth)
>             digPlatformMoved ();
>     }
>
>     /** The width of the control in pixels. */
>     final int width ()
>     {
>         if (digPlatformClientWidth >= 0)
>             return digPlatformClientWidth;
>         return digPlatformSuggestWidth;
>     }
>
>     /** Return the width of the content of the control, before
grid-fitting. */
>     final int actualWidth ()
>     {
>         if (digPlatformClientWidth >= 0)
>             return digPlatformClientWidth;
>         return digPlatformSuggestWidth;
>     }
>
>     /** Make the width flexible. */
>     final void widthFlex ()
>     {
>         int old = width ();
>
>         digPlatformClientWidth = -1;
>         if (width () != old)
>             digPlatformMoved ();
>     }
>
>     /** Change width and height. */
>     final void widthAndHeight (int width, int height)
>     {
>         int owidth = this.width ();
>         int oheight = this.height ();
>
>         digPlatformClientWidth = width;
>         digPlatformClientHeight = height;
>         if (digPlatformClientWidth != owidth || digPlatformClientHeight !=
oheight)
>             digPlatformMoved ();
>     }
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void right (int value) { width (value - left ()); }
>
>     /** The right margin of the control in its parent's client area. */
>     final int right () { return left () + width (); }
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void height (int value)
>     {
>         int oheight = height ();
>
>         digPlatformClientHeight = value;
>         if (digPlatformClientHeight != oheight)
>             digPlatformMoved ();
>     }
>
>     /** The height of the control in pixels. */
>     final int height ()
>     {
>         if (digPlatformClientHeight >= 0)
>             return digPlatformClientHeight;
>         return digPlatformSuggestHeight;
>     }
>
>     /** Make the height flexible. */
>     final void heightFlex ()
>     {
>         int old = height ();
>
>         digPlatformClientHeight = -1;
>         if (height () != old)
>             digPlatformMoved ();
>     }
>
>     /** Return the width of the content of the control, before
grid-fitting. */
>     final int actualHeight ()
>     {
>         if (digPlatformClientHeight >= 0)
>             return digPlatformClientHeight;
>         return digPlatformSuggestHeight;
>     }
>
>     /** Assignment to this property results in the control being
>       * moved and the control being resized; until it is assigned,
>       * it is in flux and can be modified by grid-fitting.
>       */
>
>     final void bottom (int value)
>     {
>         height (value - top ());
>     }
>
>     /** The bottom margin of the control in its parent's client area. */
>     final int bottom ()
>     {
>         return top () + height ();
>     }
>
>     /** Set suggested dimensions. */
>     final void suggestWidthAndHeight (int twidth, int theight)
>     {
>         int owidth = width (), oheight = height ();
>
>         digPlatformSuggestWidth = twidth;
>         digPlatformSuggestHeight = theight;
>         if (width () != owidth || height () != oheight)
>             digPlatformMoved ();
>     }
>
>     /** Set suggested width. */
>     final void suggestWidth (int twidth)
>     {
>         int owidth = width ();
>
>         digPlatformSuggestWidth = twidth;
>         if (width () != owidth)
>             digPlatformMoved ();
>     }
>
>     /** Set suggested height. */
>     final void suggestHeight (int theight)
>     {
>         int oheight = height ();
>
>         digPlatformSuggestHeight = theight;
>         if (height () != oheight)
>             digPlatformMoved ();
>     }
>
>     /** Return the width minus the scrollbar if visible. */
>     final int visualWidth ()
>     {
>         if (/*vscroll () && */vscrollPage () < vscrollRangeMax () -
vscrollRangeMin ())
>             return width () - GetSystemMetrics (SM_CXVSCROLL) + 1;
>         return width ();
>     }
>
>     /** Return the height minus the scrollbar if visible. */
>     final int visualHeight ()
>     {
>         if (hscrollRangeMax () != hscrollRangeMin () && /*hscroll () &&
*/hscrollPage () < hscrollRangeMax () - hscrollRangeMin ())
>             return height () - GetSystemMetrics (SM_CXHSCROLL) + 1;
>         return height ();
>     }
>
> /**@}*/
>
>     /** Spawn a message box with an Okay button. */
>     void messageBox (char [] title, char [] message)
>     {
>         MessageBoxW (digPlatformHWND, toWStringz (message), toWStringz
(title), 0);
>     }
>
>     /** Message box flags, a combination of the sets of fields following.
*/
>     enum MB
>     {
>         /* The buttons to display. */
>         OK = 1 << 0, /**< OK. */
>         AbortRetryIgnore = 1 << 1, /**< Abort, Retry, Ignore. */
>         OKCancel = 1 << 3, /**< OK, Cancel. */
>         RetryCancel = 1 << 4, /**< Retry, Cancel. */
>         YesNo = 1 << 5, /**< Yes, No. */
>         YesNoCancel = 1 << 6, /**< Yes, No, Cancel. */
>
>         /* An icon to display, no icon is the default. */
>         IconExclamation = 1 << 7, /**< An exclamation-point icon. */
>         IconWarning = 1 << 8, /**< A warning icon (may be
IconExclamation). */
>         IconInformation = 1 << 9, /**< Information icon. */
>         IconAsterisk = 1 << 10, /**< Asterisk icon (may be
IconInformation). */
>         IconQuestion = 1 << 11, /**< Question-mark icon. */
>         IconStop = 1 << 12, /**< Stop-sign icon. */
>         IconError = 1 << 13, /**< Error icon (may be IconStop). */
>         IconHand = 1 << 14, /**< Hand icon (may be IconStop). */
>
>         /* The button that is default.  The default is the first button.
*/
>         Default1 = 1 << 15, /**< The first button is the default. */
>         Default2 = 1 << 16, /**< The second button is the default. */
>         Default3 = 1 << 17, /**< The third button is the default. */
>         Default4 = 1 << 18, /**< The fourth button is the default. */
>     }
>
>     /** Spawn a message box with a set of flags.
>       * Returns the name of the button that the user pressed.
>       */
>
>     char [] messageBox (char [] title, char [] message, MB flags)
>     {
>         int type;
>
>         if (flags & MB.OK) type |= MB_OK;
>         if (flags & MB.AbortRetryIgnore) type |= MB_ABORTRETRYIGNORE;
>         if (flags & MB.OKCancel) type |= MB_OKCANCEL;
>         if (flags & MB.RetryCancel) type |= MB_RETRYCANCEL;
>         if (flags & MB.YesNo) type |= MB_YESNO;
>         if (flags & MB.YesNoCancel) type |= MB_YESNOCANCEL;
>         if (flags & MB.IconExclamation) type |= MB_ICONEXCLAMATION;
>         if (flags & MB.IconWarning) type |= MB_ICONWARNING;
>         if (flags & MB.IconInformation) type |= MB_ICONINFORMATION;
>         if (flags & MB.IconAsterisk) type |= MB_ICONASTERISK;
>         if (flags & MB.IconQuestion) type |= MB_ICONQUESTION;
>         if (flags & MB.IconStop) type |= MB_ICONSTOP;
>         if (flags & MB.IconError) type |= MB_ICONERROR;
>         if (flags & MB.IconHand) type |= MB_ICONHAND;
>         if (flags & MB.Default1) type |= MB_DEFBUTTON1;
>         if (flags & MB.Default2) type |= MB_DEFBUTTON2;
>         if (flags & MB.Default3) type |= MB_DEFBUTTON3;
>         if (flags & MB.Default4) type |= MB_DEFBUTTON4;
>
>         int r = MessageBoxW (digPlatformHWND, toWStringz (message),
toWStringz (title), type);
>
>         switch (r)
>         {
>             case IDABORT: return "Abort";
>             case IDCANCEL: return "Cancel";
>             case IDCLOSE: return "Close";
>             case IDHELP: return "Help";
>             case IDIGNORE: return "Ignore";
>             case IDNO: return "No";
>             case IDOK: return "OK";
>             case IDRETRY: return "Retry";
>             case IDYES: return "Yes";
>         }
>     }
>
>     /** Force a painting on this control. */
>     void paint ()
>     {
>         std.c.windows.windows.InvalidateRect (digPlatformHWND, null,
false);
>     }
>
>     /** Paint an inclusive region of the control. */
>     void paintRegion (int left, int top, int right, int bottom)
>     {
>         _RECT rect;
>
>         rect.left = left;
>         rect.top = top;
>         rect.right = right;
>         rect.bottom = bottom;
>         std.c.windows.windows.InvalidateRect (digPlatformHWND, &rect,
false);
>     }
>
>     /** The background color of this control. */
>     Color backgroundColor ()
>     {
>         if (parent ())
>             return parent ().backgroundColor ();
>         return Color.Black;
>     }
>
>     /** Create a timer; the dispatcher will be notified in delay
milliseconds. */
>     static Dispatcher *timer (ulong delay)
>     {
>         digPlatformTimerFunc *func;
>         digPlatformTimerFunc add;
>         Dispatcher dispatcher;
>         int result, c;
>
>         for (c = 0; ; c ++)
>         {
>             if (c >= digPlatformTimers.length)
>             {
>                 digPlatformTimers ~= add;
>                 func = &digPlatformTimers [c];
>                 break;
>             }
>
>             if (!digPlatformTimers [c].mark)
>             {
>                 func = &digPlatformTimers [c];
>                 *func = add;
>                 break;
>             }
>         }
>
>         func.mark = SetTimer ((_HANDLE) 0, 0, delay, null);
>         return &func.dispatcher;
>     }
>
>     /** Create a timer and add a dispatch to it, then return the
dispatcher */
>     static Dispatcher *timer (ulong delay, Dispatcher.Method method)
>     {
>         Dispatcher *dispatcher = timer (delay);
>
>         dispatcher.add (method);
>         return dispatcher;
>     }
>
>     /** Create a timer and add a dispatch to it, then return the
dispatcher */
>     static Dispatcher *timer (ulong delay, Dispatcher.MethodB method)
>     {
>         Dispatcher *dispatcher = timer (delay);
>
>         dispatcher.add (method);
>         return dispatcher;
>     }
>
>     /** Get the number of milliseconds the program has been running. */
>     static ulong elapsedTime ()
>     {
>         ulong value;
> LARGE_INTEGER freq;
>
> return GetTickCount (); //Added by Joel Anderson
>         /+if
(!net.BurtonRadons.dig.platform.base.QueryPerformanceFrequency (&freq) ||
freq == 0 || !std.random.QueryPerformanceCounter (&value))
>             return GetTickCount ();
>         if (!digPlatformElapsedTimeCounter)
>             digPlatformElapsedTimeCounter = value;
>         return (value - digPlatformElapsedTimeCounter) * 1000 / freq;+/
//Causes access voliation -> fix yourself if you really want such accuracy
>     }
>
>     /** Get the number of microseconds the program has been running. */
>     static ulong elapsedMicroTime ()
>     {
>         ulong value;
> LARGE_INTEGER freq;
>
>         if (!net.BurtonRadons.dig.platform.base.QueryPerformanceFrequency
(&freq) || freq == 0 || !std.random.QueryPerformanceCounter (&value))
>             return GetTickCount () * 1000;
>         if (!digPlatformElapsedTimeCounter)
>             digPlatformElapsedTimeCounter = value;
>         return (value - digPlatformElapsedTimeCounter) * 1000000 / freq;
>     }
>
>     /** Return whether this control is visible. */
>     bit visible ()
>     {
>         Control control = this;
>
>         while (control !== null)
>         {
>             if (!control.digPlatformVisible)
>                 return false;
>             control = control.parent ();
>         }
>
>         return true;
>     }
>
>     /** Get the control with keyboard focus, or null if it's not on this
application. */
>     Control focus ()
>     {
>         _HWND f;
>
>         f = GetFocus ();
>         if (f == (_HANDLE) 0 || !(f in digPlatformHWNDToControl))
>             return null;
>         return digPlatformHWNDToControl [f];
>     }
>
>     /** Set the control with keyboard focus; pass null to set to none;
returns previous focus or null. */
>     Control makeFocus ()
>     {
>         _HWND result;
>
>         result = SetFocus (digPlatformHWND);
>         if (result == (_HANDLE) 0 || !(result in
digPlatformHWNDToControl))
>             return null;
>         return digPlatformHWNDToControl [result];
>     }
>
>     /** Set the keyboard focus to none. */
>     void clearFocus ()
>     {
>         SetFocus (null);
>     }
>
>     /** Get whether this control has the keyboard focus. */
>     bit isFocus ()
>     {
>         return GetFocus () == digPlatformHWND;
>     }
>
>     /** Change the text font; passing null results in no effect. */
>     void font (Font font)
>     {
>         if (font === null)
>             return;
>         if (digPlatformFont === null)
>         {
>             digPlatformFont = new Font (digPlatformMainFont);
>             digPlatformFont.digPlatformOnChange.add
(&digPlatformOnFontChange);
>         }
>
>         digPlatformFont.digPlatformLog = font.digPlatformLog;
>         digPlatformOnFontChange ();
>         recalculate ();
>     }
>
>     /** Get the text font. */
>     Font font ()
>     {
>         if (digPlatformFont === null)
>         {
>             digPlatformFont = new Font (digPlatformMainFont);
>             digPlatformFont.digPlatformOnChange.add
(&digPlatformOnFontChange);
>         }
>
>         return digPlatformFont;
>     }
>
>     /** Perform size esimate recalculation. */
>     void recalculate ()
>     {
>     }
>
>     /** Set whether this is active (true) or grayed and inactive (false).
*/
>     void enabled (bit value)
>     {
>         EnableWindow (digPlatformHWND, value);
>     }
>
>     /** Return whether this is enabled. */
>     bit enabled ()
>     {
>         return (bit) IsWindowEnabled (digPlatformHWND);
>     }
>
> /** @name Mouse Methods
>   * These methods relate to the mouse.
>   */
>
>     /** Capture the mouse; when captured,
>       * #onMouseMove, #onLButtonDown, #onLButtonUp, #onMButtonDown,
>       * #onMButtonUp,
>       * #onRButtonDown, #onRButtonUp are sent to this control
>       * regardless of the position of the mouse
>       */
>
>     void captureMouse ()
>     {
>         SetCapture (digPlatformHWND);
>     }
>
>     /** Release the mouse from #captureMouse. */
>     void releaseMouse ()
>     {
>         ReleaseCapture ();
>     }
>
>     /** Return whether this control is holding the mouse captive. */
>     bit isCaptor ()
>     {
>         return GetCapture () == digPlatformHWND;
>     }
>
>     /** Return whether this point is within the client region. */
>     bit inClientRegion (int x, int y)
>     {
>         return x >= 0 && y >= 0 && x < width () && y < height ();
>     }
>
>     /** Cursors that can be passed to the cursor method.
>       * Here is an image showing good cursors for each value:
>       * @image html cursors.gif
>       */
>
>     enum Cursor
>     {
>         Arrow, /**< The standard arrow cursor. */
>         Help, /**< Arrow with a question mark beside it or the normal
arrow cursor if unavailable. */
>         Working, /**< Arrow with an hourglass beside it or the hourglass
cursor if unavailable. */
>         Invalid, /**< A crossed-out circle or other insignia indicating
invalidity. */
>         Text, /**< The "I" beam text editing cursor. */
>         Crosshair, /**< Vertical and horizontal crossed lines, or the
normal arrow cursor if unavailable. */
>         Wait, /**< An hourglass. */
>         SizeAll, /**< An arrow pointing in all four cardinal directions
(north, south, east, west). */
>         SizeNESW, /**< A double-pointed arrow pointing north-east and
south-west. */
>         SizeNWSE, /**< A double-pointed arrow pointing north-west and
south-east. */
>         SizeEW, /**< A double-pointed arrow pointing west and east. */
>         SizeNS, /**< A double-pointed arrow pointing north and south. */
>     }
>
>     /** Set a standard cursor to use when the mouse is over this control.
By default it uses the arrow cursor. */
>     void cursor (Cursor value)
>     {
>         _LPCTSTR set;
>
>         switch (value)
>         {
>             case Cursor.Arrow: set = IDC_ARROW; break;
>             case Cursor.Help: set = IDC_HELP; break;
>             case Cursor.Text: set = IDC_IBEAM; break;
>             case Cursor.Working: set = IDC_APPSTARTING; break;
>             case Cursor.Crosshair: set = IDC_CROSS; break;
>             case Cursor.Invalid: set = IDC_NO; break;
>             case Cursor.SizeAll: set = IDC_SIZEALL; break;
>             case Cursor.SizeNESW: set = IDC_SIZENESW; break;
>             case Cursor.Wait: set = IDC_WAIT; break;
>             case Cursor.SizeNWSE: set = IDC_SIZENWSE; break;
>             case Cursor.SizeEW: set = IDC_SIZEWE; break;
>             case Cursor.SizeNS: set = IDC_SIZENS; break;
>         }
>
>         digPlatformCursor = (_HANDLE) LoadCursorA ((_HANDLE) 0, set);
>     }
>
> /** @name Horizontal Scrollbar
>   * These methods, along with the #onHScroll event, control the horizontal
scrollbar.
>   */
>
> /**@{*/
>
>     /** Set whether to display a horizontal scrollbar. */
>     void hscroll (bit value)
>     {
>         digPlatformHScrollVisible = value;
>         ShowScrollBar (digPlatformHWND, SB_HORZ, value);
>         //setRecreateStyle (WS_HSCROLL, value);
>     }
>
>     /** Set the horizontal scrollbar range. */
>     void hscrollRange (int min, int max)
>     {
>         if (hscrollRangeMin () == min && hscrollRangeMax () == max)
>             return;
>         SetScrollRange (digPlatformHWND, SB_HORZ, min, max, true);
>     }
>
>     /** Get the horizontal scrollbar minimum point. */
>     int hscrollRangeMin ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_ALL;
>         GetScrollInfo (digPlatformHWND, SB_HORZ, &info);
>         return info.nMin;
>     }
>
>     /** Get the horizontal scrollbar maximum point. */
>     int hscrollRangeMax ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_ALL;
>         GetScrollInfo (digPlatformHWND, SB_HORZ, &info);
>         return info.nMax;
>     }
>
>     /** Set the horizontal scrollbar point. */
>     void hscrollPoint (int position)
>     {
>         if (hscrollPoint () == position)
>             return;
>         SetScrollPos (digPlatformHWND, SB_HORZ, position, true);
>     }
>
>     /** Get the horizontal scrollbar point. */
>     int hscrollPoint ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_ALL;
>         GetScrollInfo (digPlatformHWND, SB_HORZ, &info);
>         return info.nPos;
>     }
>
>     /** Get the units count in a std.math.single horizontal scrollbar
page. */
>     int hscrollPage ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_ALL;
>         GetScrollInfo (digPlatformHWND, SB_HORZ, &info);
>         return info.nPage;
>     }
>
>     /** Set the units count in a std.math.single horizontal scrollbar
page. */
>     void hscrollPage (int size)
>     {
>         SCROLLINFO info;
>
>         if (hscrollPage () == size)
>             return;
>         info.cbSize = info.size;
>         info.fMask = SIF_PAGE;
>         info.nPage = size;
>         SetScrollInfo (digPlatformHWND, SB_HORZ, &info, true);
>     }
>
> /**@}*/
>
> /** @name Vertical Scrollbar
>   * These methods, along with the #onVScroll event, control the vertical
scrollbar.
>   */
>
> /**@{*/
>
>     /** Set whether to display a vertical scrollbar. */
>     void vscroll (bit value)
>     {
>         digPlatformVScrollVisible = value;
>         ShowScrollBar (digPlatformHWND, SB_VERT, value);
>         //setRecreateStyle (WS_VSCROLL, value);
>     }
>
>     /** Return whether the vertical scrollbar can be displayed. */
>     bit vscroll ()
>     {
>         return digPlatformVScrollVisible;
>     }
>
>     /** Set both the vertical scrollbar range and page. */
>     void vscrollRangeAndPage (int min, int max, int page)
>     {
>         if (vscrollRangeMin () == min && vscrollRangeMax () == max &&
vscrollPage () == page)
>             return;
>
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_ALL;
>         GetScrollInfo (digPlatformHWND, SB_VERT, &info);
>         info.nMin = min;
>         info.nMax = max;
>         info.nPage = page;
>         SetScrollInfo (digPlatformHWND, SB_VERT, &info, true);
>     }
>
>     /** Set the vertical scrollbar range. */
>     void vscrollRange (int min, int max)
>     {
>         if (vscrollRangeMin () == min && vscrollRangeMax () == max)
>             return;
>         ShowScrollBar (digPlatformHWND, SB_VERT, max - min > vscrollPage
());
>         SetScrollRange (digPlatformHWND, SB_VERT, min, max, true);
>     }
>
>     /** Get the vertical scrollbar minimum point. */
>     int vscrollRangeMin ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_RANGE;
>         GetScrollInfo (digPlatformHWND, SB_VERT, &info);
>         return info.nMin;
>     }
>
>     /** Get the vertical scrollbar maximum point. */
>     int vscrollRangeMax ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_RANGE;
>         GetScrollInfo (digPlatformHWND, SB_VERT, &info);
>         return info.nMax;
>     }
>
>     /** Set the vertical scrollbar point. */
>     void vscrollPoint (int position)
>     {
>         if (vscrollPoint () == position)
>             return;
>         SetScrollPos (digPlatformHWND, SB_VERT, position, true);
>     }
>
>     /** Get the vertical scrollbar point. */
>     int vscrollPoint ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_POS;
>         GetScrollInfo (digPlatformHWND, SB_VERT, &info);
>         return info.nPos;
>     }
>
>     /** Set the units count in a std.math.single vertical scrollbar page.
*/
>     void vscrollPage (int size)
>     {
>         SCROLLINFO info;
>
>         if (vscrollPage () == size)
>             return;
>         ShowScrollBar (digPlatformHWND, SB_VERT, vscrollRangeMax () -
vscrollRangeMin () > size);
>         info.cbSize = info.size;
>         info.fMask = SIF_PAGE;
>         info.nPage = size;
>         SetScrollInfo (digPlatformHWND, SB_VERT, &info, true);
>     }
>
>     /** Get the units count in a std.math.single vertical scrollbar page.
*/
>     int vscrollPage ()
>     {
>         SCROLLINFO info;
>
>         info.cbSize = info.size;
>         info.fMask = SIF_PAGE;
>         GetScrollInfo (digPlatformHWND, SB_VERT, &info);
>         return info.nPage;
>     }
>
> /**@}*/
>
>     /** Bind a keypress to a dispatcher for this control.  code describes
>       * the keypress and ends with a key name (such as "Return") and
starts
>       * with a combination of shift, control, and ctrl, in any case with
>       * any separator.  For example, "Shift-X", "Shift CONTROL y", and
>       * "CtrlZ".  Another modifier is "Focus", which prevents the binding
>       * from being called if the control isn't the keyboard focus.  See
>       * #Event for the key names.
>       *
>       * The dispatcher pointer returned is valid until the next bind
method
>       * call only.  Unless if frames have their own binding for the key,
they
>       * will pass it to the first sub-control which has a binding, so you
>       * don't need to bind to the frame.
>       */
>
>     Dispatcher *bind (char [] code)
>     {
>         return bindings.bind (code);
>     }
>
>     /** Bind a method to the dispatcher and return it. */
>     Dispatcher *bind (char [] code, Dispatcher.Method method)
>     {
>         return bindings.bind (code, method);
>     }
>
>     /** Bind a method to the dispatcher and return it. */
>     Dispatcher *bind (char [] code, Dispatcher.MethodB method)
>     {
>         return bindings.bind (code, method);
>     }
>
>     /** Bind a dispatcher pointer to the dispatcher and return it. */
>     Dispatcher *bind (char [] code, Dispatcher *dispatcher)
>     {
>         return bindings.bind (code, dispatcher);
>     }
>
> /** @name Processor Capabilities
>   * When writing assembly code, it's useful to know not just the processor
you're using but also
>   * its variant.  These functions return such values.
>   */
>
> /**@{*/
>
>     /** Return whether this is an Intel x86 processor with MMX capability
(Pentium Pro/6 and up). */
>     static bit x86_has_mmx ()
>     {
>         version (X86)
>         {
>             asm
>             {
>                 // Check feature flag 23 in cpuid for MMX support
>                 mov EAX, 1;
>                 cpuid; // Note that I don't check that this instruction is
available first
>                 mov EAX, EDX;
>                 shr EAX, 23;
>                 and EAX, 1;
>             }
>         }
>         else
>             return false;
>     }
>
> /**@}*/
>
> /** @name File Listing
>   * This creates a list of search files from a directory; each file has
information such as its
>   * name, whether it's a directory, and size.
>   */
>
> /**@{*/
>
>     /** File found from searching. */
>     class SearchFile
>     {
>         char [] name; /**< Filename. */
>         char [] full; /**< Filename with path. */
>         char [] ext; /**< Extension only, no dot. */
>         char [] alternate; /**< Alternate filename, the 8.3 name in DOS,
or name. */
>
>         bit directory; /**< File is a directory. */
>
>         ulong size; /**< File size in bytes. */
>
>         override int opCmp (Object b) /* operator overloading for
comparison */
>         {
>             if ((SearchFile) b === null)
>                 return 0;
>             return std.string.cmp (name, ((SearchFile) b).name);
>         }
>     }
>
>     /** List files in a directory ("." and ".." are not included). */
>     class Search
>     {
>         /** Assign the path. */
>         this (char [] path)
>         {
>             if (path.length && (path [path.length - 1] == '/' || path
[path.length - 1] == '\\'))
>                 path = path [0 .. path.length - 1];
>             digPlatformPath = path;
>         }
>
>         /** Delete anything attached to the search. */
>         ~this ()
>         {
>             if (digPlatformHandle)
>                 std.file.FindClose (digPlatformHandle);
>         }
>
>         /** Read in the next file or null if this is done. */
>         SearchFile next ()
>         {
>             if (digPlatformDone)
>                 return null;
>             if (digPlatformStarting)
>             {
>                 digPlatformHandle = std.file.FindFirstFileA
(std.string.toStringz (digPlatformPath ~ "/*"), &digPlatformData);
>                 if (digPlatformHandle == (_HANDLE) 0)
>                     throw new Error ("couldn't find path '" ~
digPlatformPath ~ "'");
>                 digPlatformStarting = false;
>             }
>             else if (!std.file.FindNextFileA (digPlatformHandle,
&digPlatformData))
>             {
>                 digPlatformDone = true;
>                 std.file.FindClose (digPlatformHandle);
>                 digPlatformHandle = (_HANDLE) 0;
>                 return null;
>             }
>
>             if (digPlatformData.cFileName [0 .. 2] == ".\0" ||
digPlatformData.cFileName [0 .. 3] == "..\0")
>                 return next ();
>
>             SearchFile file;
>
>             if (std.string.strlen (digPlatformData.cFileName) == 0)
>             {
>                 digPlatformDone = true;
>                 std.file.FindClose (digPlatformHandle);
>                 return null;
>             }
>
>             file = new SearchFile ();
>             file.name = digPlatformData.cFileName [0 .. std.file.strlen
(digPlatformData.cFileName)].dup;
>             file.full = digPlatformPath ~ "/" ~ file.name;
>             for (int c = file.name.length; c > 0; c --)
>                 if (file.name [c - 1] == '.')
>                 {
>                     file.ext = file.name [c .. file.name.length];
>                     break;
>                 }
>
>             if (digPlatformData.cAlternateFileName [0])
>                 file.alternate = digPlatformData.cAlternateFileName [0 ..
std.string.strlen (digPlatformData.cAlternateFileName)].dup;
>             else
>                 file.alternate = file.name;
>
>             if (digPlatformData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY)
>                 file.directory = true;
>
>             file.size = ((ulong) digPlatformData.nFileSizeHigh << 32UL)
>                       + (ulong) digPlatformData.nFileSizeLow;
>
>             return file;
>         }
>
>     /+
>     #ifdef DoxygenMustSkipThis
>     +/
>
>         char [] digPlatformPath; /**< Path to list. */
>         bit digPlatformStarting = true;
>         bit digPlatformDone = false;
>
>         std.c.windows.windows.WIN32_FIND_DATA digPlatformData;
>         std.c.windows.windows.HANDLE digPlatformHandle;
>
>     /+
>     #endif
>     +/
>     }
>
>     /** Get the full list of files in a directory. */
>     static SearchFile [] listPath (char [] path)
>     {
>         Search search = new Search (path);
>         SearchFile [] list;
>         SearchFile add;
>
>         while ((add = search.next ()) !== null)
>             list ~= add;
>
>         return list;
>     }
>
>     /** A static class for operating system calls. */
>     class OS
>     {
>         /** Return the command name that allegedly created this process.
*/
>         static char [] commandName ()
>         {
>             char [] line = std.string.toString (GetCommandLineA ());
>
>             if (line [0] == '\"')
>                 return line [1 .. std.string.find (line [1 ..
line.length], '\"') + 1].dup;
>             for (int c; ; c ++)
>                 if (c >= line.length || std.ctype.isspace (line [c]))
>                     return line [0 .. c];
>         }
>
>         /** Assign the current working directory. */
>         static void currentWorkingDirectory (char [] path)
>         {
> //std.file.chdir (path);
>             if (chdir (std.string.toStringz (path)) < 0)
>                 throw new Error ("Couldn't change current working
directory to '" ~ path ~ "' because the path does not exist.");
>         }
>
>         /** Return the current working directory. */
>         static char [] currentWorkingDirectory ()
>         {
>             char [] buffer;
>
> //buffer = std.file.getcwd ();
> if (getcwd (buffer, buffer.length) === null)
>                 throw new Error ("Couldn't get the current working
directory.");
>             return std.string.toString (buffer).dup;
>         }
>
>         /** Return an environment variable or null if this is not
assigned. */
>         static char [] environmentVariable (char [] name)
>         {
>             return std.string.toString (getenv (std.string.toStringz
(name))).dup;
>         }
>
>         /** Assign an environment variable. */
>         static void environmentVariable (char [] name, char [] value)
>         {
>             putenv (std.string.toStringz (name ~ "=" ~ value));
>         }
>
>         /** A system process.  This is here to allow parallel controlled
execution of
>           * subsidiary processes as well as debugging.
>           */
>
>         class Process
>         {
>             private PROCESS_INFORMATION info;
>             private _DWORD returnValue;
>             private bit finished = false;
>             private bit isPaused = true;
>
>             /** Create a process.  The process will be paused; use "paused
(false)" to start it.
>               * @param command The path and filename of the executable.
>               * This is either an absolute path or searched using whatever
path settings are made for this operating system.
>               * You can control other parameters by prefixing characters
to the command.  Prefixing
>               * "%" shows a command window.  "$" debugs the process.
>               * @param args A list of arguments passed to the command.
>               */
>
>             this (char [] command, char [] [] args)
>             {
>                 bit shouldDebug, window;
>                 int mode;
>                 int *result;
>                 char *[] argv;
>
>                 while (1)
>                 {
>                     if (command [0] == '$')
>                         shouldDebug = true;
>                     else if (command [0] == '%')
>                         window = true;
>                     else
>                         break;
>                     command = command [1 .. command.length];
>                 }
>
>                 char [] commandline;
>                 STARTUPINFOA startup;
>                 int flags;
>
>                 commandline ~= "\"" ~ command ~ "\"";
>
>                 for (int c; c < args.length; c ++)
>                     commandline ~= " \"" ~ args [c] ~ "\"";
>
>                 startup.cb = startup.size;
>                 startup.dwFlags = 0;
>                 flags = NORMAL_PRIORITY_CLASS;
>
>                 if (window)
>                     flags |= CREATE_NEW_CONSOLE;
>                 if (shouldDebug)
>                     flags |= DEBUG_PROCESS;
>
>                 flags |= CREATE_SUSPENDED;
>
>                 if (!CreateProcessA (null, commandline, null, null, false,
>                     flags, null, null, &startup, &info))
>                     digPlatformGetLastError ("Control.OS.system");
>             }
>
>             /** Unpause the process if it is paused, and then wait until
the process is finished and return its exit code. */
>             int finish ()
>             {
>                 if (finished)
>                     return returnValue;
>                 paused (false);
>                 std.c.windows.windows.WaitForSingleObject (info.hProcess,
~0);
>                 if (!GetExitCodeProcess (info.hProcess, &returnValue))
>                     digPlatformGetLastError ("Control.OS.Process.finish:
GetExitCodeProcess");
>                 std.thread.CloseHandle (info.hProcess);
>                 std.thread.CloseHandle (info.hThread);
>                 finished = true;
>                 return returnValue;
>             }
>
>             /** Unpause the process and then wait for it for a number of
milliseconds.  Returns whether the process is not finished. */
>             bit wait (int milliseconds)
>             {
>                 if (finished)
>                     return false;
>                 paused (false);
>                 std.thread.WaitForSingleObject (info.hProcess, ~0);
>                 GetExitCodeProcess (info.hProcess, &returnValue);
>                 if (returnValue != 0x103) // STILL_ACTIVE
>                 {
>                     finished = true;
>                     std.thread.CloseHandle (info.hProcess);
>                     std.thread.CloseHandle (info.hThread);
>                 }
>                 return !finished;
>             }
>
>             /** A debug event created by waitForDebugEvent. */
>             class DebugEvent
>             {
>                 Process process; /**< The process this event is for. */
>             }
>
>             /** Wait for a debug event for a number of milliseconds.  Note
that if
>               * you are debugging a process you just created, you have to
unpause
>               * it first using paused (false).
>               * @param milliseconds The number of milliseconds to wait, or
zero to check if there is a waiting event and return that.
>               * @return Returns a new debug event or null if none occured
before the timeout.
>               */
>             static DebugEvent waitForDebugEvent (int milliseconds)
>             {
>                 DEBUG_EVENT input;
>
>                 if (!WaitForDebugEvent (&input, milliseconds))
>                     return null;
>                 printf ("Got a debug event, woot!\n");
>                 return null;
>             }
>
>             /** Return whether this process is paused.  Initially the
process is paused. */
>             bit paused ()
>             {
>                 return isPaused;
>             }
>
>             /** Assign whether to pause execution of the process or
continue it. */
>             void paused (bit value)
>             {
>                 if (finished)
>                     return;
>                 if (value)
>                     std.thread.SuspendThread (info.hThread);
>                 else
>                     std.thread.ResumeThread (info.hThread);
>                 isPaused = value;
>             }
>         }
>
>         /** Run a command in system and return the result.
>           * @param command The path and filename of the executable.
>           * This is either an absolute path or searched using whatever
path settings are made for this operating system.
>           * You can control other parameters by prefixing characters to
the command.  Prefixing
>           * "&" makes the execution asynchronous, so that it creates an
entirely different process
>           * and returns zero rather than waiting for it to finish.  "%"
shows a command window.
>           * @param args A list of arguments passed to the command.
>           * @return The return value from the executable or zero if it is
asynchronous.
>           */
>         static int system (char [] command, char [] [] args)
>         {
>             bit asynchronous, window;
>             int mode;
>             int *result;
>             char *[] argv;
>
>             while (1)
>             {
>                 if (command [0] == '&')
>                     asynchronous = true;
>                 else if (command [0] == '%')
>                     window = true;
>                 else
>                     break;
>                 command = command [1 .. command.length];
>             }
>
>             char [] commandline;
>             STARTUPINFOA startup;
>             PROCESS_INFORMATION process;
>             int flags;
>
>             commandline ~= "\"" ~ command ~ "\"";
>
>             for (int c; c < args.length; c ++)
>                 commandline ~= " \"" ~ args [c] ~ "\"";
>
>             startup.cb = startup.size;
>             startup.dwFlags = 0;
>             flags = NORMAL_PRIORITY_CLASS;
>
>             if (window)
>                 flags |= CREATE_NEW_CONSOLE;
>
>             if (!CreateProcessA (null, commandline, null, null, false,
>                 flags, null, null, &startup, &process))
>                 digPlatformGetLastError ("Control.OS.system");
>
>             if (!asynchronous)
>             {
>                 _DWORD code;
>
>                 std.thread.WaitForSingleObject (process.hProcess, ~0);
>                 if (!GetExitCodeProcess (process.hProcess, &code))
>                     digPlatformGetLastError ("Control.OS.system:
GetExitCodeProcess");
>                 std.thread.CloseHandle (process.hProcess);
>                 std.thread.CloseHandle (process.hThread);
>                 return code;
>             }
>
>             return 0;
>
>             /+mode |= asynchronous ? _P_NOWAIT : _P_WAIT;
>
>             if (window)
>             {
>                 char [] [] prefix;
>
>                 prefix ~= "/c";
>                 prefix ~= command;
>                 args = prefix ~ args;
>
>                 command = environmentVariable ("COMSPEC");
>                 if (command === null)
>                     command = (osver & 0x8000) ? "command.com" :
"cmd.exe";
>                 /*printf ("added command %.*s", command);
>                 for (int c; c < args.length; c ++)
>                     printf (" %.*s", args [c]);
>                 printf ("\n");*/
>             }
>
>             argv = new char *[args.length + 2];
>             argv [0] = std.string.toStringz (command);
>             for (int c; c < args.length; c ++)
>                 argv [c + 1] = std.string.toStringz (args [c]);
>
>             result = spawnvp (mode, argv [0], argv);
>             if (asynchronous)
>                 return 0;
>             return (int) result;+/
>         }
>
>         /** Split the directory from a string; for example, 'src/foo.c'
becomes 'src/'.  If there is no directory, null is returned. */
>         static char [] pathDir (char [] path)
>         {
>             for (int c = path.length - 1; ; c --)
>                 if (c < 0 || path [c] == '/' || path [c] == '\\')
>                     return path [0 .. c + 1];
>         }
>
>         /** Split everything but the directory from a string; for example,
'src/foo.c' becomes 'foo.c'. */
>         static char [] pathNotDir (char [] path)
>         {
>             for (int c = path.length - 1; ; c --)
>                 if (c < 0 || path [c] == '/' || path [c] == '\\')
>                     return path [c + 1 .. path.length];
>         }
>
>         /** Split the suffix from a string; for example, 'src/foo.c'
becomes '.c'. */
>         static char [] pathSuffix (char [] path)
>         {
>             for (int c = path.length - 1; ; c --)
>                 if (c < 0 || path [c] == '/' || path [c] == '\\')
>                     return null;
>                 else if (path [c] == '.')
>                     return path [c .. path.length];
>         }
>
>         /** Extract all but the suffix from a string; for example,
'src/foo.c' becomes 'src/foo'. */
>         static char [] pathBaseName (char [] path)
>         {
>             for (int c = path.length - 1; ; c --)
>                 if (c < 0 || path [c] == '/' || path [c] == '\\')
>                     return path;
>                 else if (path [c] == '.')
>                     return path [0 .. c];
>         }
>     }
>
> /**@}*/
>
> /+
> #ifndef DOXYGEN_SHOULD_SKIP_THIS
> +/
>
> //protected:
>     Control [] digPlatformChildren; /**< The children of the control. */
>     Control digPlatformParent; /**< The parent of the control, null if
there is none. */
>
>     static Control [std.c.windows.windows.HWND] digPlatformHWNDToControl;
>     std.c.windows.windows.HFONT digPlatformFontSet =
(std.c.windows.windows.HFONT) 0;
>     Font digPlatformFont;
>
>     struct digPlatformTimerFunc
>     {
>         int mark;
>         Dispatcher dispatcher;
>     }
>
>     static digPlatformTimerFunc [] digPlatformTimers;
>
>     std.c.windows.windows.HWND digPlatformHWND =
(std.c.windows.windows.HWND) 0;
>
>     int digPlatformSuggestLeft;
>     int digPlatformSuggestTop;
>     int digPlatformSuggestWidth;
>     int digPlatformSuggestHeight;
>
>     int digPlatformClientLeft = -1;
>     int digPlatformClientTop = -1;
>     int digPlatformClientWidth = -1;
>     int digPlatformClientHeight = -1;
>     std.c.windows.windows.HDC digPlatformHDC;
>     bit digPlatformClosed;
>     bit digPlatformVisible = true;
>
>     int digPlatformCol = -1;
>     int digPlatformRow = -1;
>     int digPlatformColSpan = -1;
>     int digPlatformRowSpan = -1;
>
>     int digPlatformPadX = 4; /* Padding on the outside. */
>     int digPlatformPadY = 1; /* Padding on the outside. */
>
>     int digPlatformBorderX = 5; /* Padding on the inside. */
>     int digPlatformBorderY = 5; /* Padding on the inside. */
>     int digPlatformBorderSY = 0;
>     int digPlatformBorderSX = 0;
>     int digPlatformBorderEY = 0;
>     int digPlatformBorderEX = 0;
>
>     bit digPlatformStickyW = true, digPlatformStickyE = false,
digPlatformStickyHC = false;
>     bit digPlatformStickyN = true, digPlatformStickyS = false,
digPlatformStickyVC = false;
>
>     _WPARAM digPlatformStyle =  std.c.windows.windows.WS_HSCROLL |
std.c.windows.windows.WS_VSCROLL;
>     _WPARAM digPlatformCurrentStyle = 0;
>     wchar [] digPlatformClassName;
>     wchar [] digPlatformCaption;
>
>     bit digPlatformFitting; /* The parent is being asked to gridfit. */
>
>     static ulong digPlatformElapsedTimeCounter;
>
>     void digPlatformOnFontChange ()
>     {
>         _HFONT handle = digPlatformFont.digPlatformGetHFONT ();
>
>         SendMessageA (digPlatformHWND, WM_SETFONT, (uint) handle, 1);
>         if (digPlatformFontSet)
>             DeleteObject (digPlatformFontSet);
>         digPlatformFontSet = handle;
>     }
>
>     /** Change the caption. */
>     void digPlatformSetCaption (char [] value)
>     {
>         digPlatformCaption = toWStringz (value);
>         SendMessageW (digPlatformHWND, WM_SETTEXT, 0, (_LPARAM) (wchar *)
digPlatformCaption);
>     }
>
>     /* Perform gridfitting on the contents. */
>     void digPlatformGridfit ()
>     {
>         Control *cStart = digPlatformChildren, cEnd = cStart +
digPlatformChildren.length, c;
>         int [] coldims, coloffs;
>         int [] rowdims, rowoffs;
>         int rowmax, colmax;
>         int row, col;
>
>         digPlatformGridfitted = true;
>
>         /* Prevent parent-child recursion. */
>         if (digPlatformFitting)
>             return;
>
>         if (!digPlatformChildren.length)
>             return;
>
>         /* Get extents and allocate temporaries. */
>         gridExtents (colmax, rowmax);
>         if (colmax < 0 || rowmax < 0)
>             return;
>
>         digPlatformFitting = true; /* Prevent recursion. */
>
>         rowdims = new int [rowmax + 1];
>         coldims = new int [colmax + 1];
>         rowoffs = new int [rowmax + 1];
>         coloffs = new int [colmax + 1];
>
>         for (c = cStart; c < cEnd; c ++)
>             if (c.digPlatformDirty)
>             {
>                 c.digPlatformDirty = false;
>                 c.digPlatformGridfit ();
>             }
>
>         /* Determine the row heights. */
>         {
>             int bottom = 0;
>
>             for (row = 0; row < rowmax; row ++)
>             {
>                 int height = 0;
>
>                 for (c = cStart; c < cEnd; c ++)
>                 {
>                     if (c.digPlatformCol == -1)
>                         continue;
>                     if (c.digPlatformRow + c.digPlatformRowSpan - 1 ==
row)
>                     {
>                         int child_height;
>
>                         child_height = c.actualHeight () +
c.digPlatformPadY * 2;
>                         if (c.digPlatformRowSpan != 1)
>                             child_height -= bottom;
>                         if (child_height > height)
>                             height = child_height;
>                     }
>                 }
>
>                 rowoffs [row] = bottom;
>                 rowdims [row] = height;
>                 bottom += height;
>             }
>
>             rowoffs [row] = bottom;
>             rowdims [row] = 0;
>         }
>
>         /* Determine the col widths */
>         {
>             int right = 0;
>
>             for (col = 0; col < colmax; col ++)
>             {
>                 int width;
>
>                 width = 0;
>                 for (c = cStart; c < cEnd; c ++)
>                 {
>                     if (c.digPlatformCol == -1)
>                         continue;
>                     if (c.digPlatformCol + c.digPlatformColSpan - 1 ==
col)
>                     {
>                         int child_width;
>
>                         child_width = c.actualWidth () + c.digPlatformPadX
* 2;
>                         if (c.digPlatformColSpan != 1)
>                             child_width -= right;
>                         if (child_width > width)
>                             width = child_width;
>                     }
>                 }
>
>                 coloffs [col] = right;
>                 coldims [col] = width;
>                 right += width;
>             }
>
>             coloffs [col] = right;
>             coldims [col] = 0;
>         }
>
> /*
>         if (force_coldim)
>         {
>             int right = coloffs [colmax];
>
>             for (col = 0; col <= colmax; col ++)
>             {
>                 if (right == 0)
>                     coloffs [col] = coldims [col] = 0;
>                 else
>                 {
>                     int dim = coldims [col], off = coloffs [col];
>
>                     coloffs [col] = off * force_coldim / right;
>                     coldims [col] = dim * force_coldim / right;
>                 }
>             }
>         }
>
>         if (force_rowdim)
>         {
>             int bottom = rowoffs [rowmax];
>
>             for (row = 0; row <= rowmax; row ++)
>             {
>                 if (bottom == 0)
>                     rowoffs [row] = rowdims [row] = 0;
>                 else
>                 {
>                     int dim = rowdims [row], off = rowoffs [row];
>
>                     rowoffs [row] = off * force_rowdim / bottom;
>                     rowdims [row] = dim * force_rowdim / bottom;
>                 }
>             }
>         }
> */
>
>         /* Determine our client offset. */
>         int startx = digPlatformBorderX + digPlatformBorderSX;
>         int starty = digPlatformBorderY + digPlatformBorderSY;
>
>         /* Get jiggy with it */
>         for (c = cStart; c < cEnd; c ++)
>         {
>             int rowch, rowdim, rowoff, rowcell, basey;
>             int colch, coldim, coloff, colcell, basex;
>             int regridfit = 0;
>
>             if (c.digPlatformRow == -1)
>                 continue;
>
>             colch = c.width ();
>             rowch = c.height ();
>
>             rowdim = rowdims [c.digPlatformRow];
>             rowoff = rowoffs [c.digPlatformRow];
>             rowcell = rowoffs [c.digPlatformRow + c.digPlatformRowSpan] -
rowoff - c.digPlatformPadY * 2;
>             basey = (rowcell - rowch) / 2;
>
>             if (c.digPlatformStickyN)
>                 basey = 0;
>             if (c.digPlatformStickyS)
>             {
>                 if (c.digPlatformStickyN)
>                 {
>                     rowch = rowcell;
>                     regridfit = 1;
>                 }
>                 else
>                     basey = rowcell - rowch;
>             }
>             if (c.digPlatformStickyVC)
>                 basey = (rowcell - rowch) / 2;
>
>             coldim = coldims [c.digPlatformCol];
>             coloff = coloffs [c.digPlatformCol];
>             colcell = coloffs [c.digPlatformCol + c.digPlatformColSpan] -
coloff - c.digPlatformPadX * 2;
>             basex = (colcell - colch) / 2;
>
>             if (c.digPlatformStickyW)
>                 basex = 0;
>             if (c.digPlatformStickyE)
>             {
>                 if (c.digPlatformStickyW)
>                 {
>                     colch = colcell;
>                     regridfit = 1;
>                 }
>                 else
>                     basex = colcell - colch;
>             }
>             if (c.digPlatformStickyHC)
>                 basex = (colcell - colch) / 2;
>
>             /*if (regridfit)
>             {
>                 gui_widget_rect rect;
>
>                 if (gui_widget_frame_indent (child, &rect) < 0)
>                     goto failure;
>                 child->need_gridfit = 1;
>                 if (gui_widget_gridfit (child, colch - rect.sx - rect.ex,
rowch - rect.sy - rect.ey) < 0)
>                     goto failure;
>             }*/
>
>             basex += coloff + c.digPlatformPadX;
>             basey += rowoff + c.digPlatformPadY;
>             int oldx = c.width ();
>             int oldy = c.height ();
>             c.digPlatformSuggestLeft = basex + startx;//_borderx +
_bordersx;
>             c.digPlatformSuggestTop = basey + starty;//_bordery +
_bordersy;
>             c.digPlatformSuggestWidth = colch;
>             c.digPlatformSuggestHeight = rowch;
>             c.digPlatformSetDimensions (oldx, oldy);
>             //c.digPlatformMoved ();
>         }
>
>         digPlatformSuggestWidth = coloffs [colmax] + digPlatformBorderX *
2 + digPlatformBorderSX + digPlatformBorderEX;
>         digPlatformSuggestHeight = rowoffs [rowmax] + digPlatformBorderY *
2 + digPlatformBorderSY + digPlatformBorderEY;
>         digPlatformMoved ();
>
>         /*for (c = 0; c < 2; c ++)
>         {
>             gui_widget_rect frame;
>
>             if (gui_widget_frame (self, &frame) < 0)
>                 goto failure;
>             swidth  = (frame.sx - sleft) + (self->ex - frame.ex) + coloffs
[colmax];
>             sheight = (frame.sy - stop) + (self->ey - frame.ey) + rowoffs
[rowmax];
>         }
>
>         self->need_gridfit = 0;
>         self->width = width;
>         self->height = height;
>
>         self->ex = self->sx + width;
>         self->ey = self->sy + height;
>         }*/
>
>         /* Now ask the parent to gridfit. */
>         if (parent () !== null)
>             parent ().digPlatformGridfit ();
>
>         /* All done. */
>         digPlatformFitting = false;
>         delete rowdims;
>         delete coldims;
>         delete rowoffs;
>         delete coloffs;
>     }
>
>     void digPlatformSetDimensions (int oldx, int oldy)
>     {
>         if (oldx != width () || oldy != height ())
>         {
>             Event e;
>
>             e.x = oldx;
>             e.y = oldy;
>             e.deltax = width () - oldx;
>             e.deltay = height () - oldy;
>             onSizeChanged.notify (e);
>         }
>         MoveWindow (digPlatformHWND, left (), top (), width (), height (),
false);
>     }
>
>     static void digPlatformEventKeySet (inout Event e,
std.c.windows.windows.WPARAM wParam)
>     {
>         e.control = (bit) (wParam & MK_CONTROL);
>         e.lbutton = (bit) (wParam & MK_LBUTTON);
>         e.mbutton = (bit) (wParam & MK_MBUTTON);
>         e.rbutton = (bit) (wParam & MK_RBUTTON);
>         e.shift = (bit) (wParam & MK_SHIFT);
>     }
>
>     bit digPlatformDirty = false;
>
>     void digPlatformMoved ()
>     {
>         digPlatformDirty = true;
>     }
>
>     void digPlatformChildMoved (Control control)
>     {
>     }
>
>     void digPlatformChangeStyle ()
>     {
>         if (digPlatformStyle == digPlatformCurrentStyle)
>             return;
>         //SendMessageA (hwnd, BM_SETSTYLE, style, 1);
>         SetWindowLongA (digPlatformHWND, GWL_STYLE, digPlatformStyle);
>         digPlatformCurrentStyle = digPlatformStyle;
>     }
>
>     void digPlatformSetStyle (int mask, bit value)
>     {
>         digPlatformStyle = value ? (digPlatformStyle | mask) :
(digPlatformStyle & ~mask);
>         digPlatformChangeStyle ();
>     }
>
>     void digPlatformSetResetStyle (int setmask, int resetmask, bit value)
>     {
>         if (value)
>         {
>             digPlatformStyle |= setmask;
>             digPlatformStyle &= ~resetmask;
>         }
>         else
>             digPlatformStyle &= ~setmask;
>         digPlatformChangeStyle ();
>     }
>
>     void digPlatformSetRecreateStyle (int mask, bit value)
>     {
>         int ostyle = digPlatformCurrentStyle;
>
>         digPlatformSetStyle (mask, value);
>         if (ostyle == digPlatformCurrentStyle)
>             return;
>
>         digPlatformRecreate ();
>     }
>
>     void digPlatformHWNDCreate (_DWORD dwExStyle,
>                      wchar [] lpClassName,
>                      wchar [] lpWindowName,
>                      _DWORD dwStyle,
>                      int x,
>                      int y,
>                      int nWidth,
>                      int nHeight,
>                      _HWND hWndParent,
>                      _HMENU hMenu,
>                      _HINSTANCE hInstance,
>                      _LPVOID lpParam)
>     {
>         digPlatformClassName = lpClassName;
>         digPlatformHWND = CreateWindowExW (dwExStyle, lpClassName,
lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
>         digPlatformHDC = std.c.windows.windows.GetDC (digPlatformHWND);
>         digPlatformHWNDToControl [digPlatformHWND] = this;
>         digPlatformStyle = digPlatformCurrentStyle = dwStyle;
>         vscroll (digPlatformVScrollVisible);
>         hscroll (digPlatformHScrollVisible);
>         this.font (this.font ());
>         /*if (digPlatformFontSet)
>             SendMessageA (digPlatformHWND, WM_SETFONT, (_DWORD)
digPlatformFontSet, 1);
>         else
>             SendMessageA (digPlatformHWND, WM_SETFONT, (_DWORD)
digPlatformMainFontHandle, 1);*/
>     }
>
>     void digPlatformHWNDCreate (_DWORD dwExStyle,
>                      wchar [] lpClassName,
>                      wchar [] lpWindowName,
>                      _DWORD dwStyle,
>                      _HMENU hMenu)
>     {
>         digPlatformHWNDCreate (dwExStyle, lpClassName, lpWindowName,
dwStyle,
>                     std.c.windows.windows.CW_USEDEFAULT,
> std.c.windows.windows.CW_USEDEFAULT,
> std.c.windows.windows.CW_USEDEFAULT,
> std.c.windows.windows.CW_USEDEFAULT,
>                     parent () ? parent ().digPlatformHWND : (_HANDLE) 0,
hMenu, hinst, null);
>     }
>
>     void digPlatformCommand (int code, int id)
>     {
>     }
>
>     bit digPlatformHScrollVisible = false;
>     bit digPlatformVScrollVisible = false;
>     _HCURSOR digPlatformCursor = (_HCURSOR) 0;
>     bit digPlatformGridfitted = false;
>
>     void digPlatformRecreate ()
>     {
>         SCROLLINFO vscroll, hscroll;
>         bit vokay, hokay;
>         bit hscrollVisibleOld = digPlatformHScrollVisible;
>         bit vscrollVisibleOld = digPlatformVScrollVisible;
>
>         vscroll.cbSize = vscroll.size;
>         vscroll.fMask = SIF_ALL;
>         vokay = (bit) GetScrollInfo (digPlatformHWND, SB_VERT, &vscroll);
>
>         hscroll.cbSize = hscroll.size;
>         hscroll.fMask = SIF_ALL;
>         hokay = (bit) GetScrollInfo (digPlatformHWND, SB_HORZ, &hscroll);
>
>         DestroyWindow (digPlatformHWND);
>         delete digPlatformHWNDToControl [digPlatformHWND];
>         digPlatformHWNDCreate (0, digPlatformClassName,
digPlatformCaption, digPlatformStyle, (_HANDLE) 0);
>         digPlatformMoved ();
>         childIterate (delegate void (Control child) {
child.digPlatformRecreate (); });
>
>         if (vokay) SetScrollInfo (digPlatformHWND, SB_VERT, &vscroll,
true);
>         if (hokay) SetScrollInfo (digPlatformHWND, SB_HORZ, &hscroll,
true);
>         this.vscroll (vscrollVisibleOld);
>         this.hscroll (hscrollVisibleOld);
>     }
>
>     static char [] digPlatformMessageNameBase (_UINT message)
>     {
>         switch (message)
>         {
>             case WM_ACTIVATE: return "WM_ACTIVATE";
>             case WM_ACTIVATEAPP: return "WM_ACTIVATEAPP";
>             case WM_CONTEXTMENU: return "WM_CONTEXTMENU";
>             case WM_CREATE: return "WM_CREATE";
>             case WM_CTLCOLORBTN: return "WM_CTLCOLORBTN";
>             case WM_DESTROY: return "WM_DESTROY";
>             case WM_ERASEBKGND: return "WM_ERASEBKGND";
>             case WM_GETICON: return "WM_GETICON";
>             case WM_GETMINMAXINFO: return "WM_GETMINMAXINFO";
>             case WM_KEYDOWN: return "WM_KEYDOWN";
>             case WM_KEYUP: return "WM_KEYUP";
>             case WM_KILLFOCUS: return "WM_KILLFOCUS";
>             case WM_LBUTTONDOWN: return "WM_LBUTTONDOWN";
>             case WM_LBUTTONUP: return "WM_LBUTTONUP";
>             case WM_MBUTTONDOWN: return "WM_MBUTTONDOWN";
>             case WM_MBUTTONUP: return "WM_MBUTTONUP";
>             case WM_MOUSEACTIVATE: return "WM_MOUSEACTIVATE";
>             case WM_MOUSEMOVE: return "WM_MOUSEMOVE";
>             case WM_MOUSEWHEEL: return "WM_MOUSEWHEEL";
>             case WM_MOVE: return "WM_MOVE";
>             case WM_NCACTIVATE: return "WM_NCACTIVATE";
>             case WM_NCCALCSIZE: return "WM_NCCALCSIZE";
>             case WM_NCCREATE: return "WM_NCCREATE";
>             case WM_NCDESTROY: return "WM_NCDESTROY";
>             case WM_NCHITTEST: return "WM_NCHITTEST";
>             case WM_NCLBUTTONDOWN: return "WM_NCLBUTTONDOWN";
>             case WM_NCMOUSEMOVE: return "WM_NCMOUSEMOVE";
>             case WM_NCPAINT: return "WM_NCPAINT";
>             case WM_PAINT: return "WM_PAINT";
>             case WM_PARENTNOTIFY: return "WM_PARENTNOTIFY";
>             case WM_RBUTTONDOWN: return "WM_RBUTTONDOWN";
>             case WM_RBUTTONUP: return "WM_RBUTTONUP";
>             case WM_SETCURSOR: return "WM_SETCURSOR";
>             case WM_SETFOCUS: return "WM_SETFOCUS";
>             case WM_SETTEXT: return "WM_SETTEXT";
>             case WM_SHOWWINDOW: return "WM_SHOWWINDOW";
>             case WM_SIZE: return "WM_SIZE";
>             case WM_SYSCOMMAND: return "WM_SYSCOMMAND";
>             case WM_WINDOWPOSCHANGED: return "WM_WINDOWPOSCHANGED";
>             case WM_WINDOWPOSCHANGING: return "WM_WINDOWPOSCHANGING";
>             default: return null;
>         }
>     }
>
>     static char [] digPlatformMessageName (_UINT message)
>     {
>         char [] result;
>
>         result = digPlatformMessageNameBase (message);
>         if (result === null)
>         {
>             static char [16] buffer;
>
>             std.c.stdio.sprintf (buffer, "(%d)", message);
>             return buffer [0 .. std.string.strlen (buffer)];
>         }
>     }
>
>     static _COLORREF digPlatformColorToCOLORREF (Color c)
>     {
>         return c.r | (c.g << 8) | (c.b << 16);
>     }
>
>     static Color digPlatformColorFromCOLORREF (_COLORREF r)
>     {
>         return AColor (r & 0xFF, (r >> 8) & 0xFF, (r >> 16) & 0xFF);
>     }
>
>     /* Get the window text, allocated. */
>     char [] digPlatformGetText ()
>     {
>         int length = digPlatformGetTextLength ();
>         char [] data = new char [length + 1];
>
>         length = SendMessageA (digPlatformHWND, WM_GETTEXT, data.length,
(_LPARAM) (char *) data);
>         return data [0 .. length];
>     }
>
>     /* Get the length of the text in the window in characters. */
>     int digPlatformGetTextLength ()
>     {
>         return SendMessageA (digPlatformHWND, WM_GETTEXTLENGTH, 0, 0);
>     }
>
>     /* Set the text of the window. */
>     void digPlatformSetText (char [] text)
>     {
>         char *ztext = std.string.toStringz (text);
>         char [1] empty;
>
>         if (ztext == null)
>             ztext = empty;
>         SendMessageA (digPlatformHWND, WM_SETTEXT, 0, (_LPARAM) ztext);
>     }
>
> /+
> #endif
> +/
> };
>
>


December 10, 2003
Carlos Santander B. wrote:

>"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message
>news:br2koa$2i0q$1@digitaldaemon.com...
>| ...
>|
>| import c.stdio;
>| import net.BurtonRadons.dig.main;
>|
>| class Program : Frame
>| {
>|   this ()
>|   {
>|     //Never gets here, crashes in parent construction
>|     caption ("Caption");
>|
>|       with (new Label (this))
>|       {
>|           grid (0, 0);
>|           caption ("This is a label");
>|       }
>|
>|   }
>| }
>|
>| int main( char [] [] args ) //So I can get messages
>| {
>|     (new Program ()).showModal ();
>|     return 1;
>| }
>|
>| ...
>
>IIRC, you need to call super() in the first line of your constructor (that'd
>be right where you have the comment).
>
>-------------------------
>Carlos Santander
>
>
>---
>
>Checked by AVG anti-virus system (http://www.grisoft.com).
>Version: 6.0.545 / Virus Database: 339 - Release Date: 2003-11-27
>
>
>  
>
Ok, I solved the problem.  (forgot the -I\dig\ switch).

1 2 3
Next ›   Last »