changeset 1438:bde7ebced556

Initial layout engine 2.0 for Windows and OS/2...Plus some updates for the Mac code... Improved auto-window sizing on Windows and added OS/2 and Mac support.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 08 Dec 2011 09:30:32 +0000
parents a50e8b486a1a
children 09fa437d6a5f
files mac/dw.m os2/dw.c win/dw.c
diffstat 3 files changed, 411 insertions(+), 678 deletions(-) [+]
line wrap: on
line diff
--- a/mac/dw.m	Thu Dec 08 06:47:05 2011 +0000
+++ b/mac/dw.m	Thu Dec 08 09:30:32 2011 +0000
@@ -2674,6 +2674,8 @@
                         [split splitViewDidResizeSubviews:nil];
                     }
                 }
+                
+                /* Advance the current position in the box */
                 if(thisbox->type == DW_HORZ)
                     currentx += width + (pad * 2);
                 if(thisbox->type == DW_VERT)
@@ -8422,13 +8424,32 @@
     int _locked_by_me = FALSE;
     DW_MUTEX_LOCK;
     NSObject *object = handle;
-    NSSize size;
-    size.width = width;
-    size.height = height;
 
     if([ object isKindOfClass:[ NSWindow class ] ])
     {
         NSWindow *window = handle;
+        Box *thisbox;
+        NSSize size;
+       
+        /*
+         * The following is an attempt to dynamically size a window based on the size of its
+         * children before realization. Only applicable when width or height is less than one.
+         */
+        if((width < 1 || height < 1) && (thisbox = [[window contentView] box]))
+        {
+            int depth = 0;
+                
+            /* Calculate space requirements */
+            _resize_box(thisbox, &depth, width, height, 1);
+          
+            /* Might need to take into account the window border here */
+            if(width < 1) width = thisbox->minwidth;
+            if(height < 1) height = thisbox->minheight;
+        }
+       
+        /* Finally set the size */
+        size.width = width;
+        size.height = height;
         [window setContentSize:size];
     }
     DW_MUTEX_UNLOCK;
--- a/os2/dw.c	Thu Dec 08 06:47:05 2011 +0000
+++ b/os2/dw.c	Thu Dec 08 09:30:32 2011 +0000
@@ -1054,23 +1054,24 @@
    return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
 }
 
-#define _DW_DEFAULT_SCROLLBAR_WIDTH 16
+#define _DW_DEFAULT_SCROLLBAR_WIDTH 14
 
 /* This function calculates how much space the widgets and boxes require
  * and does expansion as necessary.
  */
-int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
-            int pass, int *usedpadx, int *usedpady)
-{
-   int z, currentx = 0, currenty = 0;
+static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass)
+{
+   /* Current item position */
+   int z, currentx = thisbox->pad, currenty = thisbox->pad;
+   /* Used x, y and padding maximum values...
+    * These will be used to find the widest or
+    * tallest items in a box.
+    */
    int uymax = 0, uxmax = 0;
    int upymax = 0, upxmax = 0;
-   /* Used for the SIZEEXPAND */
-   int nux = *usedx, nuy = *usedy;
-   int nupx = *usedpadx, nupy = *usedpady;
-
-   (*usedx) += (thisbox->pad * 2);
-   (*usedy) += (thisbox->pad * 2);
+    
+   /* Reset the box sizes */
+   thisbox->minwidth = thisbox->minheight = thisbox->usedpadx = thisbox->usedpady = thisbox->pad * 2;
 
    if(thisbox->grouphwnd)
    {
@@ -1097,159 +1098,53 @@
 
       thisbox->grouppadx = 6;
 
-      (*usedx) += thisbox->grouppadx;
-      (*usedpadx) += thisbox->grouppadx;
-      (*usedy) += thisbox->grouppady;
-      (*usedpady) += thisbox->grouppady;
-   }
-
+      thisbox->minwidth += thisbox->grouppadx;
+      thisbox->usedpadx += thisbox->grouppadx;
+      thisbox->minheight += thisbox->grouppady;
+      thisbox->usedpady += thisbox->grouppady;
+   }
+
+   /* Count up all the space for all items in the box */
    for(z=0;z<thisbox->count;z++)
    {
+      int itempad, itemwidth, itemheight;
+        
       if(thisbox->items[z].type == TYPEBOX)
       {
-         int initialx, initialy;
          Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
 
-         initialx = x - (*usedx);
-         initialy = y - (*usedy);
-
          if(tmp)
          {
-            int newx, newy;
-            int nux = *usedx, nuy = *usedy;
-            int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
-
-            /* On the second pass we know how big the box needs to be and how
-             * much space we have, so we can calculate a ratio for the new box.
-             */
-            if(pass == 2)
+            /* On the first pass calculate the box contents */
+            if(pass == 1)
             {
-               int deep = *depth + 1;
-
-               _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
-
-               tmp->upx = upx - *usedpadx;
-               tmp->upy = upy - *usedpady;
-
-               newx = x - nux;
-               newy = y - nuy;
-
-               tmp->width = thisbox->items[z].width = initialx - newx;
-               tmp->height = thisbox->items[z].height = initialy - newy;
-
-               tmp->parentxratio = thisbox->xratio;
-               tmp->parentyratio = thisbox->yratio;
-
-               tmp->parentpad = tmp->pad;
-               tmp->hsize = thisbox->items[z].hsize;
-               tmp->vsize = thisbox->items[z].vsize;
-
-               /* Just in case */
-               tmp->xratio = thisbox->xratio;
-               tmp->yratio = thisbox->yratio;
-
-               if(thisbox->type == DW_VERT)
-               {
-                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
-
-                  if((thisbox->items[z].width - tmppad)!=0)
-                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
-               }
-               else
-               {
-                  if((thisbox->items[z].width-tmp->upx)!=0)
-                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
-               }
-               if(thisbox->type == DW_HORZ)
-               {
-                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
-
-                  if((thisbox->items[z].height-tmppad)!=0)
-                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
-               }
-               else
-               {
-                  if((thisbox->items[z].height-tmp->upy)!=0)
-                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
-               }
-
-               nux = *usedx; nuy = *usedy;
-               upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
+               (*depth)++;
+                    
+               /* Save the newly calculated values on the box */
+               _resize_box(tmp, depth, x, y, pass);
+                    
+               /* Duplicate the values in the item list for use below */
+               thisbox->items[z].width = tmp->minwidth;
+               thisbox->items[z].height = tmp->minheight;
+               
+               (*depth)--;
             }
-
-            (*depth)++;
-
-            _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
-
-            (*depth)--;
-
-            newx = x - nux;
-            newy = y - nuy;
-
-            tmp->minwidth = thisbox->items[z].width = initialx - newx;
-            tmp->minheight = thisbox->items[z].height = initialy - newy;
-         }
-      }
-
-      if(pass > 1 && *depth > 0)
-      {
-         if(thisbox->type == DW_VERT)
-         {
-            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
-
-            if((thisbox->minwidth-tmppad) == 0)
-               thisbox->items[z].xratio = 1.0;
-            else
-               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
-         }
-         else
-         {
-            if(thisbox->minwidth-thisbox->upx == 0)
-               thisbox->items[z].xratio = 1.0;
-            else
-               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
-         }
-
-         if(thisbox->type == DW_HORZ)
-         {
-            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
-
-            if((thisbox->minheight-tmppad) == 0)
-               thisbox->items[z].yratio = 1.0;
-            else
-               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
-         }
-         else
-         {
-            if(thisbox->minheight-thisbox->upy == 0)
-               thisbox->items[z].yratio = 1.0;
-            else
-               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
-         }
-
-         if(thisbox->items[z].type == TYPEBOX)
-         {
-            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-            if(tmp)
-            {
-               tmp->parentxratio = thisbox->items[z].xratio;
-               tmp->parentyratio = thisbox->items[z].yratio;
-            }
-         }
-      }
-      else
-      {
-         thisbox->items[z].xratio = thisbox->xratio;
-         thisbox->items[z].yratio = thisbox->yratio;
-      }
-
+         }
+      }
+        
+      /* Precalculate these values, since they will
+       * be used used repeatedly in the next section.
+       */
+      itempad = thisbox->items[z].pad * 2;
+      itemwidth = thisbox->items[z].width + itempad;
+      itemheight = thisbox->items[z].height + itempad;
+        
+      /* Calculate the totals and maximums */
       if(thisbox->type == DW_VERT)
       {
-         int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
-
          if(itemwidth > uxmax)
             uxmax = itemwidth;
+            
          if(thisbox->items[z].hsize != SIZEEXPAND)
          {
             if(itemwidth > upxmax)
@@ -1257,22 +1152,17 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upxmax)
-               upxmax = thisbox->items[z].pad*2;
-         }
+            if(itempad > upxmax)
+               upxmax = itempad;
+         }
+         thisbox->minheight += itemheight;
+         if(thisbox->items[z].vsize != SIZEEXPAND)
+            thisbox->usedpady += itemheight;
+         else
+            thisbox->usedpady += itempad;
       }
       else
       {
-         (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
-         if(thisbox->items[z].hsize != SIZEEXPAND)
-            (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
-         else
-            (*usedpadx) += thisbox->items[z].pad*2;
-      }
-      if(thisbox->type == DW_HORZ)
-      {
-         int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
-
          if(itemheight > uymax)
             uymax = itemheight;
          if(thisbox->items[z].vsize != SIZEEXPAND)
@@ -1282,123 +1172,72 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upymax)
-               upymax = thisbox->items[z].pad*2;
-         }
-      }
-      else
-      {
-         (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
-         if(thisbox->items[z].vsize != SIZEEXPAND)
-            (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
+            if(itempad > upymax)
+               upymax = itempad;
+         }
+         thisbox->minwidth += itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+            thisbox->usedpadx += itemwidth;
          else
-            (*usedpady) += thisbox->items[z].pad*2;
-      }
-   }
-
-   (*usedx) += uxmax;
-   (*usedy) += uymax;
-   (*usedpadx) += upxmax;
-   (*usedpady) += upymax;
-
-   currentx += thisbox->pad;
-   currenty += thisbox->pad;
-
+            thisbox->usedpadx += itempad;
+      }
+   }
+
+   /* Add the maximums which were calculated in the previous loop */
+   thisbox->minwidth += uxmax;
+   thisbox->minheight += uymax;
+   thisbox->usedpadx += upxmax;
+   thisbox->usedpady += upymax;
+
+   /* Move the groupbox start past the group border */
    if(thisbox->grouphwnd)
    {
       currentx += 3;
       currenty += thisbox->grouppady - 3;
    }
-
-   /* The second pass is for expansion and actual placement. */
+   
+   /* The second pass is for actual placement. */
    if(pass > 1)
    {
-      /* Any SIZEEXPAND items should be set to uxmax/uymax */
-      for(z=0;z<thisbox->count;z++)
-      {
-         if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
-            thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
-         if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
-            thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
-         /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
-         if(thisbox->items[z].type == TYPEBOX)
-         {
-            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-            if(tmp)
-            {
-               if(*depth > 0)
-               {
-                  float calcval;
-
-                  if(thisbox->type == DW_VERT)
-                  {
-                     calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-                     if(calcval == 0.0)
-                        tmp->xratio = thisbox->xratio;
-                     else
-                        tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-                     tmp->width = thisbox->items[z].width;
-                  }
-                  if(thisbox->type == DW_HORZ)
-                  {
-                     calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-                     if(calcval == 0.0)
-                        tmp->yratio = thisbox->yratio;
-                     else
-                        tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-                     tmp->height = thisbox->items[z].height;
-                  }
-               }
-
-               (*depth)++;
-
-               _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
-
-               (*depth)--;
-
-            }
-         }
-      }
-
       for(z=0;z<(thisbox->count);z++)
       {
          int height = thisbox->items[z].height;
          int width = thisbox->items[z].width;
-         int pad = thisbox->items[z].pad;
-         HWND handle = thisbox->items[z].hwnd;
-         int vectorx, vectory;
-
-         /* When upxmax != pad*2 then ratios are incorrect. */
-         vectorx = (int)((width*thisbox->items[z].xratio)-width);
-         vectory = (int)((height*thisbox->items[z].yratio)-height);
-
-         if(width > 0 && height > 0)
-         {
-            char tmpbuf[100];
-            /* This is a hack to fix rounding of the sizing */
-            if(*depth == 0)
+         int itempad = thisbox->items[z].pad * 2;
+         int thispad = thisbox->pad * 2;
+
+         /* Calculate the new sizes */
+         if(thisbox->items[z].hsize == SIZEEXPAND)
+         {
+            if(thisbox->type == DW_HORZ)
             {
-               vectorx++;
-               vectory++;
+               int expandablex = thisbox->minwidth - thisbox->usedpadx;
+                
+               if(expandablex)
+                  width = (int)(((float)width / (float)expandablex) * (float)(x - thisbox->usedpadx));
             }
-
-            /* If this item isn't going to expand... reset the vectors to 0 */
-            if(thisbox->items[z].vsize != SIZEEXPAND)
-               vectory = 0;
-            if(thisbox->items[z].hsize != SIZEEXPAND)
-               vectorx = 0;
-
-            if(thisbox->type == DW_VERT && thisbox->hsize == SIZESTATIC && thisbox->items[z].hsize == SIZEEXPAND && thisbox->width)
+            else
+               width = x - (itempad + thispad + thisbox->grouppadx);
+         }
+         if(thisbox->items[z].vsize == SIZEEXPAND)
+         {
+            if(thisbox->type == DW_VERT)
             {
-               width = thisbox->width;
-               vectorx = 0;
+               int expandabley = thisbox->minheight - thisbox->usedpady;
+                
+               if(expandabley)
+                  height = (int)(((float)height / (float)expandabley) * (float)(y - thisbox->usedpady));
             }
-            if(thisbox->type == DW_HORZ && thisbox->vsize == SIZESTATIC && thisbox->items[z].vsize == SIZEEXPAND && thisbox->height)
-            {
-               height = thisbox->height;
-               vectory = 0;
-            }
+            else
+               height = y - (itempad + thispad + thisbox->grouppady);
+         }
+         
+         /* If the calculated size is valid... */
+         if(width > 0 && height > 0)
+         {
+            int pad = thisbox->items[z].pad;
+            HWND handle = thisbox->items[z].hwnd;
+            char tmpbuf[100];
            
             WinQueryClassName(handle, 99, (PCH)tmpbuf);
 
@@ -1407,28 +1246,26 @@
                HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
                /* Make the combobox big enough to drop down. :) */
                WinSetWindowPos(handle, HWND_TOP, 0, -100,
-                           width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           width, height + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
                _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
             }
             else if(strncmp(tmpbuf, "#6", 3)==0)
             {
                /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
-                           (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           width - 6, height - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
             }
             else if(strncmp(tmpbuf, "#40", 5)==0)
             {
                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
                _check_resize_notebook(handle);
             }
             else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
             {
                 /* Handle special case of scrollbox */
-                int cx = width + vectorx;
-                int cy = height + vectory;
-                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                int cx, cy, depth = 0;
                 HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox");
                 HWND client = WinWindowFromID(handle, FID_CLIENT);
                 HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL);
@@ -1439,41 +1276,41 @@
                 unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0);
 
                 /* Position the scrollbox parts */
-                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-                WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-                WinSetWindowPos(hscroll, HWND_TOP, 0, 0, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-                WinSetWindowPos(vscroll, HWND_TOP, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-
-                origx = cx = cx - _DW_DEFAULT_SCROLLBAR_WIDTH;
-                origy = cy = cy - _DW_DEFAULT_SCROLLBAR_WIDTH;
+                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, width - _DW_DEFAULT_SCROLLBAR_WIDTH, height - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(hscroll, HWND_TOP, 0, 0, width - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(vscroll, HWND_TOP, width - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, height - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                origx = cx = width - _DW_DEFAULT_SCROLLBAR_WIDTH;
+                origy = cy = height - _DW_DEFAULT_SCROLLBAR_WIDTH;
 
                 /* Get the required space for the box */
-                _resize_box(contentbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-                if(cx < usedx)
+                _resize_box(contentbox, &depth, cx, cy, 1);
+
+                if(cx < contentbox->minwidth)
                 {
-                    cx = usedx;
+                    cx = contentbox->minwidth;
                 }
-                if(cy < usedy)
+                if(cy < contentbox->minheight)
                 {
-                    cy = usedy;
+                    cy = contentbox->minheight;
                 }
 
                 /* Setup vertical scroller */
-                WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)usedy - origy));
-                WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, usedy), 0);
-                if(vpos > usedy)
+                WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)contentbox->minheight - origy));
+                WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, contentbox->minheight), 0);
+                if(vpos > contentbox->minheight)
                 {
-                    vpos = usedy;
+                    vpos = contentbox->minheight;
                     WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0);
                 }
 
                 /* Setup horizontal scroller */
-                WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)usedx - origx));
-                WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, usedx), 0);
-                if(hpos > usedx)
+                WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)contentbox->minwidth - origx));
+                WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, contentbox->minwidth), 0);
+                if(hpos > contentbox->minwidth)
                 {
-                    hpos = usedx;
+                    hpos = contentbox->minwidth;
                     WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0);
                 }
 
@@ -1490,39 +1327,48 @@
                /* Then try the bottom or right box */
                float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
                int type = (int)dw_window_get_data(handle, "_dw_type");
-               int cx = width + vectorx;
-               int cy = height + vectory;
 
                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-                           cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-
-               if(cx > 0 && cy > 0 && percent)
-                  _handle_splitbar_resize(handle, *percent, type, cx, cy);
+                           width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+               if(percent)
+                  _handle_splitbar_resize(handle, *percent, type, width, height);
             }
             else
             {
+               /* Everything else */
                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
-                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           width, height, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                           
+               /* After placing a box... place its components */
                if(thisbox->items[z].type == TYPEBOX)
                {
                   Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
 
-                  if(boxinfo && boxinfo->grouphwnd)
-                     WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
-                                 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE);
-
+                  if(boxinfo)
+                  {
+                     if(boxinfo->grouphwnd)
+                     {
+                        /* Move the group border into place */
+                        WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
+                                       width, height, SWP_MOVE | SWP_SIZE);
+                     }
+                     /* Dive into the box */
+                     (*depth)++;
+                     _resize_box(boxinfo, depth, width, height, pass);
+                     (*depth)--;
+                  }
                }
-
             }
 
+            /* Advance the current position in the box */
             if(thisbox->type == DW_HORZ)
-               currentx += width + vectorx + (pad * 2);
+               currentx += width + (pad * 2);
             if(thisbox->type == DW_VERT)
-               currenty += height + vectory + (pad * 2);
-         }
-      }
-   }
-   return 0;
+               currenty += height + (pad * 2);
+         }
+      }
+   }
 }
 
 void _do_resize(Box *thisbox, int x, int y)
@@ -1531,19 +1377,13 @@
    {
       if(thisbox)
       {
-         int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
-
-         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-         if(usedx-usedpadx == 0 || usedy-usedpady == 0)
-            return;
-
-         thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
-         thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
-
-         usedx = usedy = usedpadx = usedpady = depth = 0;
-
-         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
+         int depth = 0;
+            
+         /* Calculate space requirements */
+         _resize_box(thisbox, &depth, x, y, 1);
+            
+         /* Finally place all the boxes and controls */
+         _resize_box(thisbox, &depth, x, y, 2);
       }
    }
 }
@@ -4756,13 +4596,13 @@
       if(strncmp(tmpbuf, "#8", 3)== 0 &&
          WinQueryWindowULong(handle, QWL_STYLE) & SBS_VERT)
       {
-         thiswidth = 14;
+         thiswidth = _DW_DEFAULT_SCROLLBAR_WIDTH;
          thisheight = 100;
       }
       else
       {
          thiswidth = 100;
-         thisheight = 14;
+         thisheight = _DW_DEFAULT_SCROLLBAR_WIDTH;
       }
    }
    /* Spinbutton */
@@ -5051,9 +4891,8 @@
    WindowData *blah = calloc(1, sizeof(WindowData));
    ULONG winStyle = 0L;
 
-   newbox->pad = 0;
    newbox->type = DW_VERT;
-   newbox->count = 0;
+   newbox->vsize = newbox->hsize = SIZEEXPAND;
 
    flStyle |= FCF_NOBYTEALIGN;
 
@@ -7015,6 +6854,23 @@
  */
 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
 {
+   Box *thisbox;
+   HWND box;
+
+   if((width < 1 || height < 1) && (box = WinWindowFromID(window, FID_CLIENT)) &&
+      (thisbox = WinQueryWindowPtr(box, QWP_USER)))
+   {
+      int depth = 0;
+            
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, width, height, 1);
+      
+      /* Might need to take into account the window border here */
+      if(width < 1) width = thisbox->minwidth;
+      if(height < 1) height = thisbox->minheight;
+   }
+   
+   /* Finally set the size */
    WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
 }
 
@@ -7084,7 +6940,23 @@
 void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height)
 {
    int myy = _get_frame_height(handle) - (y + height);
-
+   Box *thisbox;
+   HWND box;
+
+   if((width < 1 || height < 1) && (box = WinWindowFromID(window, FID_CLIENT)) &&
+      (thisbox = WinQueryWindowPtr(box, QWP_USER)))
+   {
+      int depth = 0;
+            
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, width, height, 1);
+      
+      /* Might need to take into account the window border here */
+      if(width < 1) width = thisbox->minwidth;
+      if(height < 1) height = thisbox->minheight;
+   }
+   
+   /* Finally set the size */
    WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
 }
 
--- a/win/dw.c	Thu Dec 08 06:47:05 2011 +0000
+++ b/win/dw.c	Thu Dec 08 09:30:32 2011 +0000
@@ -1126,18 +1126,19 @@
 /* This function calculates how much space the widgets and boxes require
  * and does expansion as necessary.
  */
-int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
-            int pass, int *usedpadx, int *usedpady)
-{
-   int z, currentx = 0, currenty = 0;
+static void _resize_box(Box *thisbox, int *depth, int x, int y, int pass)
+{
+   /* Current item position */
+   int z, currentx = thisbox->pad, currenty = thisbox->pad;
+   /* Used x, y and padding maximum values...
+    * These will be used to find the widest or
+    * tallest items in a box.
+    */
    int uymax = 0, uxmax = 0;
    int upymax = 0, upxmax = 0;
-   /* Used for the SIZEEXPAND */
-   int nux = *usedx, nuy = *usedy;
-   int nupx = *usedpadx, nupy = *usedpady;
-
-   (*usedx) += (thisbox->pad * 2);
-   (*usedy) += (thisbox->pad * 2);
+    
+   /* Reset the box sizes */
+   thisbox->minwidth = thisbox->minheight = thisbox->usedpadx = thisbox->usedpady = thisbox->pad * 2;
 
    if(thisbox->grouphwnd)
    {
@@ -1164,159 +1165,53 @@
 
       thisbox->grouppadx = 6;
 
-      (*usedx) += thisbox->grouppadx;
-      (*usedpadx) += thisbox->grouppadx;
-      (*usedy) += thisbox->grouppady;
-      (*usedpady) += thisbox->grouppady;
-   }
-
+      thisbox->minwidth += thisbox->grouppadx;
+      thisbox->usedpadx += thisbox->grouppadx;
+      thisbox->minheight += thisbox->grouppady;
+      thisbox->usedpady += thisbox->grouppady;
+   }
+
+   /* Count up all the space for all items in the box */
    for(z=0;z<thisbox->count;z++)
    {
+      int itempad, itemwidth, itemheight;
+        
       if(thisbox->items[z].type == TYPEBOX)
       {
-         int initialx, initialy;
          Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
 
-         initialx = x - (*usedx);
-         initialy = y - (*usedy);
-
          if(tmp)
          {
-            int newx, newy;
-            int nux = *usedx, nuy = *usedy;
-            int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
-
-            /* On the second pass we know how big the box needs to be and how
-             * much space we have, so we can calculate a ratio for the new box.
-             */
-            if(pass == 2)
+            /* On the first pass calculate the box contents */
+            if(pass == 1)
             {
-               int deep = *depth + 1;
-
-               _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
-
-               tmp->upx = upx - *usedpadx;
-               tmp->upy = upy - *usedpady;
-
-               newx = x - nux;
-               newy = y - nuy;
-
-               tmp->width = thisbox->items[z].width = initialx - newx;
-               tmp->height = thisbox->items[z].height = initialy - newy;
-
-               tmp->parentxratio = thisbox->xratio;
-               tmp->parentyratio = thisbox->yratio;
-
-               tmp->parentpad = tmp->pad;
-               tmp->hsize = thisbox->items[z].hsize;
-               tmp->vsize = thisbox->items[z].vsize;
-
-               /* Just in case */
-               tmp->xratio = thisbox->xratio;
-               tmp->yratio = thisbox->yratio;
-
-               if(thisbox->type == DW_VERT)
-               {
-                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
-
-                  if((thisbox->items[z].width - tmppad)!=0)
-                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
-               }
-               else
-               {
-                  if((thisbox->items[z].width-tmp->upx)!=0)
-                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
-               }
-               if(thisbox->type == DW_HORZ)
-               {
-                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
-
-                  if((thisbox->items[z].height-tmppad)!=0)
-                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
-               }
-               else
-               {
-                  if((thisbox->items[z].height-tmp->upy)!=0)
-                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
-               }
-
-               nux = *usedx; nuy = *usedy;
-               upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
-            }
-
-            (*depth)++;
-
-            _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
-
-            (*depth)--;
-
-            newx = x - nux;
-            newy = y - nuy;
-
-            tmp->minwidth = thisbox->items[z].width = initialx - newx;
-            tmp->minheight = thisbox->items[z].height = initialy - newy;
-         }
-      }
-
-      if(pass > 1 && *depth > 0)
-      {
-         if(thisbox->type == DW_VERT)
-         {
-            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
-
-            if((thisbox->minwidth-tmppad) == 0)
-               thisbox->items[z].xratio = 1.0;
-            else
-               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
-         }
-         else
-         {
-            if(thisbox->minwidth-thisbox->upx == 0)
-               thisbox->items[z].xratio = 1.0;
-            else
-               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
-         }
-
-         if(thisbox->type == DW_HORZ)
-         {
-            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
-
-            if((thisbox->minheight-tmppad) == 0)
-               thisbox->items[z].yratio = 1.0;
-            else
-               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
-         }
-         else
-         {
-            if(thisbox->minheight-thisbox->upy == 0)
-               thisbox->items[z].yratio = 1.0;
-            else
-               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
-         }
-
-         if(thisbox->items[z].type == TYPEBOX)
-         {
-            Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-            if(tmp)
-            {
-               tmp->parentxratio = thisbox->items[z].xratio;
-               tmp->parentyratio = thisbox->items[z].yratio;
+               (*depth)++;
+                    
+               /* Save the newly calculated values on the box */
+               _resize_box(tmp, depth, x, y, pass);
+                    
+               /* Duplicate the values in the item list for use below */
+               thisbox->items[z].width = tmp->minwidth;
+               thisbox->items[z].height = tmp->minheight;
+               
+               (*depth)--;
             }
          }
       }
-      else
-      {
-         thisbox->items[z].xratio = thisbox->xratio;
-         thisbox->items[z].yratio = thisbox->yratio;
-      }
-
+        
+      /* Precalculate these values, since they will
+       * be used used repeatedly in the next section.
+       */
+      itempad = thisbox->items[z].pad * 2;
+      itemwidth = thisbox->items[z].width + itempad;
+      itemheight = thisbox->items[z].height + itempad;
+        
+      /* Calculate the totals and maximums */
       if(thisbox->type == DW_VERT)
       {
-         int itemwidth = (thisbox->items[z].pad*2) + thisbox->items[z].width;
-
          if(itemwidth > uxmax)
             uxmax = itemwidth;
+            
          if(thisbox->items[z].hsize != SIZEEXPAND)
          {
             if(itemwidth > upxmax)
@@ -1324,22 +1219,17 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upxmax)
-               upxmax = thisbox->items[z].pad*2;
+            if(itempad > upxmax)
+               upxmax = itempad;
          }
+         thisbox->minheight += itemheight;
+         if(thisbox->items[z].vsize != SIZEEXPAND)
+            thisbox->usedpady += itemheight;
+         else
+            thisbox->usedpady += itempad;
       }
       else
       {
-         (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
-         if(thisbox->items[z].hsize != SIZEEXPAND)
-            (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
-         else
-            (*usedpadx) += thisbox->items[z].pad*2;
-      }
-      if(thisbox->type == DW_HORZ)
-      {
-         int itemheight = (thisbox->items[z].pad*2) + thisbox->items[z].height;
-
          if(itemheight > uymax)
             uymax = itemheight;
          if(thisbox->items[z].vsize != SIZEEXPAND)
@@ -1349,153 +1239,109 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upymax)
-               upymax = thisbox->items[z].pad*2;
+            if(itempad > upymax)
+               upymax = itempad;
          }
-      }
-      else
-      {
-         (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
-         if(thisbox->items[z].vsize != SIZEEXPAND)
-            (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
+         thisbox->minwidth += itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+            thisbox->usedpadx += itemwidth;
          else
-            (*usedpady) += thisbox->items[z].pad*2;
-      }
-   }
-
-   (*usedx) += uxmax;
-   (*usedy) += uymax;
-   (*usedpadx) += upxmax;
-   (*usedpady) += upymax;
-
-   currentx += thisbox->pad;
-   currenty += thisbox->pad;
-
+            thisbox->usedpadx += itempad;
+      }
+   }
+
+   /* Add the maximums which were calculated in the previous loop */
+   thisbox->minwidth += uxmax;
+   thisbox->minheight += uymax;
+   thisbox->usedpadx += upxmax;
+   thisbox->usedpady += upymax;
+
+   /* Move the groupbox start past the group border */
    if(thisbox->grouphwnd)
    {
       currentx += 3;
       currenty += thisbox->grouppady - 3;
    }
 
-   /* The second pass is for expansion and actual placement. */
+   /* The second pass is for actual placement. */
    if(pass > 1)
    {
-      /* Any SIZEEXPAND items should be set to uxmax/uymax */
-      for(z=0;z<thisbox->count;z++)
-      {
-         if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
-            thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
-         if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
-            thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
-         /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
-         if(thisbox->items[z].type == TYPEBOX)
-         {
-            Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-            if(tmp)
-            {
-               if(*depth > 0)
-               {
-                  float calcval;
-
-                  if(thisbox->type == DW_VERT)
-                  {
-                     calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-                     if(calcval == 0.0)
-                        tmp->xratio = thisbox->xratio;
-                     else
-                        tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-                     tmp->width = thisbox->items[z].width;
-                  }
-                  if(thisbox->type == DW_HORZ)
-                  {
-                     calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-                     if(calcval == 0.0)
-                        tmp->yratio = thisbox->yratio;
-                     else
-                        tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-                     tmp->height = thisbox->items[z].height;
-                  }
-               }
-
-               (*depth)++;
-
-               _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
-
-               (*depth)--;
-
-            }
-         }
-      }
-
       for(z=0;z<(thisbox->count);z++)
       {
          int height = thisbox->items[z].height;
          int width = thisbox->items[z].width;
-         int pad = thisbox->items[z].pad;
-         HWND handle = thisbox->items[z].hwnd;
-         int vectorx, vectory;
-
-         /* When upxmax != pad*2 then ratios are incorrect. */
-         vectorx = (int)((width*thisbox->items[z].xratio)-width);
-         vectory = (int)((height*thisbox->items[z].yratio)-height);
-
-         if(width > 0 && height > 0)
+         int itempad = thisbox->items[z].pad * 2;
+         int thispad = thisbox->pad * 2;
+
+         /* Calculate the new sizes */
+         if(thisbox->items[z].hsize == SIZEEXPAND)
+         {
+            if(thisbox->type == DW_HORZ)
+            {
+               int expandablex = thisbox->minwidth - thisbox->usedpadx;
+                
+               if(expandablex)
+                  width = (int)(((float)width / (float)expandablex) * (float)(x - thisbox->usedpadx));
+            }
+            else
+               width = x - (itempad + thispad + thisbox->grouppadx);
+         }
+         if(thisbox->items[z].vsize == SIZEEXPAND)
+         {
+            if(thisbox->type == DW_VERT)
+            {
+               int expandabley = thisbox->minheight - thisbox->usedpady;
+                
+               if(expandabley)
+                  height = (int)(((float)height / (float)expandabley) * (float)(y - thisbox->usedpady));
+            }
+            else
+               height = y - (itempad + thispad + thisbox->grouppady);
+         }
+            
+         if(width < 1 || height < 1)
          {
             char tmpbuf[100];
-            /* This is a hack to fix rounding of the sizing */
-            if(*depth == 0)
-            {
-               vectorx++;
-               vectory++;
-            }
-
-            /* If this item isn't going to expand... reset the vectors to 0 */
-            if(thisbox->items[z].vsize != SIZEEXPAND)
-               vectory = 0;
-            if(thisbox->items[z].hsize != SIZEEXPAND)
-               vectorx = 0;
-
-            if(thisbox->type == DW_VERT && thisbox->hsize == SIZESTATIC && thisbox->items[z].hsize == SIZEEXPAND && thisbox->width)
-            {
-               width = thisbox->width;
-               vectorx = 0;
-            }
-            if(thisbox->type == DW_HORZ && thisbox->vsize == SIZESTATIC && thisbox->items[z].vsize == SIZEEXPAND && thisbox->height)
-            {
-               height = thisbox->height;
-               vectory = 0;
-            }
+               
+            GetClassName(thisbox->items[z].hwnd, tmpbuf, 99);
+            dw_debug("Class %s %dx%d width %d height %d\n", tmpbuf, currentx + thisbox->items[z].pad, currenty + thisbox->items[z].pad, width, height);
+         }
+         
+         /* If the calculated size is valid... */
+         if(width > 0 && height > 0)
+         {
+            int pad = thisbox->items[z].pad;
+            HWND handle = thisbox->items[z].hwnd;
+            char tmpbuf[100];
                
             GetClassName(handle, tmpbuf, 99);
+            dw_debug("Class %s %dx%d width %d height %d\n", tmpbuf, currentx + pad, currenty + pad, width, height);
 
             if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
             {
                /* Handle special case Combobox */
                MoveWindow(handle, currentx + pad, currenty + pad,
-                        width + vectorx, (height + vectory) + 400, FALSE);
+                        width, height + 400, FALSE);
             }
             else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
             {
                /* Handle special case Spinbutton */
                ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
-               MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad,
-                        20, height + vectory, FALSE);
+               MoveWindow(handle, currentx + pad + (width - 20), currenty + pad,
+                        20, height, FALSE);
 
                if(cinfo)
                {
                   MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
-                           (width + vectorx) - 20, height + vectory, FALSE);
+                           width - 20, height, FALSE);
                }
             }
             else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
             {
                 /* Handle special case of scrollbox */
                 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-                int cx = width + vectorx;
-                int cy = height + vectory;
-                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                int cx, cy, depth = 0;
                 Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
                 SCROLLINFO hsi, vsi;
                 RECT rect;
@@ -1508,7 +1354,7 @@
                 GetScrollInfo(handle, SB_VERT, &vsi);
 
                 /* Position the scrollbox */
-                MoveWindow(handle, currentx + pad, currenty + pad, cx, cy, FALSE);
+                MoveWindow(handle, currentx + pad, currenty + pad, width, height, FALSE);
 
                 GetClientRect(handle, &rect);
                 cx = rect.right;
@@ -1516,32 +1362,32 @@
 
 
                 /* Get the required space for the box */
-                _resize_box(thisbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-                if(cx < usedx)
+                _resize_box(thisbox, &depth, cx, cy, 1);
+
+                if(cx < thisbox->minwidth)
                 {
-                    cx = usedx;
+                    cx = thisbox->minwidth;
                 }
-                if(cy < usedy)
+                if(cy < thisbox->minheight)
                 {
-                    cy = usedy;
+                    cy = thisbox->minheight;
                 }
 
                 /* Position the scrolled box */
                 vsi.fMask = hsi.fMask = SIF_POS | SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
                 vsi.nMin = hsi.nMin = vsi.nMax = hsi.nMax = 0;
-                if(rect.bottom < usedy)
+                if(rect.bottom < thisbox->minheight)
                 {
-                    vsi.nMax = usedy;
+                    vsi.nMax = thisbox->minheight;
                     vsi.nPage = rect.bottom;
                     if(vsi.nPos > vsi.nMax)
                     {
                         vsi.nPos = vsi.nMax;
                     }
                 }
-                if(rect.right < usedx)
+                if(rect.right < thisbox->minwidth)
                 {
-                    hsi.nMax = usedx;
+                    hsi.nMax = thisbox->minwidth;
                     hsi.nPage = rect.right;
                     if(hsi.nPos > hsi.nMax)
                     {
@@ -1560,14 +1406,12 @@
                /* Then try the bottom or right box */
                float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
                int type = (int)dw_window_get_data(handle, "_dw_type");
-               int cx = width + vectorx;
-               int cy = height + vectory;
 
                MoveWindow(handle, currentx + pad, currenty + pad,
-                        cx, cy, FALSE);
-
-               if(cx > 0 && cy > 0 && percent)
-                  _handle_splitbar_resize(handle, *percent, type, cx, cy);
+                        width, height, FALSE);
+
+               if(percent)
+                  _handle_splitbar_resize(handle, *percent, type, width, height);
             }
             else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
             {
@@ -1578,7 +1422,7 @@
                {
                   /* We are centered so calculate a new position */
                   char tmpbuf[1024];
-                  int textheight, diff, total = height + vectory;
+                  int textheight, diff, total = height;
 
                   GetWindowText(handle, tmpbuf, 1023);
 
@@ -1588,29 +1432,38 @@
                   diff = (total - textheight) / 2;
 
                   MoveWindow(handle, currentx + pad, currenty + pad + diff,
-                           width + vectorx, height + vectory - diff, FALSE);
+                           width, height - diff, FALSE);
                }
                else
                {
                   MoveWindow(handle, currentx + pad, currenty + pad,
-                           width + vectorx, height + vectory, FALSE);
+                           width, height, FALSE);
                }
             }
             else
             {
                /* Everything else */
                MoveWindow(handle, currentx + pad, currenty + pad,
-                        width + vectorx, height + vectory, FALSE);
+                        width, height, FALSE);
+
+               /* After placing a box... place its components */
                if(thisbox->items[z].type == TYPEBOX)
                {
                   Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
-                  if(boxinfo && boxinfo->grouphwnd)
+                  if(boxinfo)
                   {
-                     MoveWindow(boxinfo->grouphwnd, 0, 0,
-                              width + vectorx, height + vectory, FALSE);
+                     /* Move the group border into place */
+                     if(boxinfo->grouphwnd)
+                     {
+                        MoveWindow(boxinfo->grouphwnd, 0, 0,
+                                 width, height, FALSE);
+                     }
+                     /* Dive into the box */
+                     (*depth)++;
+                     _resize_box(boxinfo, depth, width, height, pass);
+                     (*depth)--;
                   }
-
                }
             }
 
@@ -1630,7 +1483,7 @@
                }
             }
             /* So does the List View... handle delayed cursoring */
-            if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0 && width + vectorx > 10 && height + vectory > 10)
+            if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0 && width > 10 && height > 10)
             {            
                 int index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_cursor"));
                 
@@ -1638,14 +1491,14 @@
                     ListView_EnsureVisible(handle, index, TRUE);
             }
 
+            /* Advance the current position in the box */
             if(thisbox->type == DW_HORZ)
-               currentx += width + vectorx + (pad * 2);
+               currentx += width + (pad * 2);
             if(thisbox->type == DW_VERT)
-               currenty += height + vectory + (pad * 2);
+               currenty += height + (pad * 2);
          }
       }
    }
-   return 0;
 }
 
 void _do_resize(Box *thisbox, int x, int y)
@@ -1654,19 +1507,13 @@
    {
       if(thisbox)
       {
-         int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
-
-         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-         if(usedx-usedpadx == 0 || usedy-usedpady == 0)
-            return;
-
-         thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
-         thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
-
-         usedpadx = usedpady = usedx = usedy = depth = 0;
-
-         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
+         int depth = 0;
+            
+         /* Calculate space requirements */
+         _resize_box(thisbox, &depth, x, y, 1);
+            
+         /* Finally place all the boxes and controls */
+         _resize_box(thisbox, &depth, x, y, 2);
       }
    }
 }
@@ -4748,21 +4595,10 @@
    Box *newbox = calloc(sizeof(Box), 1);
    ULONG flStyleEx = 0;
 
-   newbox->pad = 0;
    newbox->type = DW_VERT;
-   newbox->count = 0;
+   newbox->vsize = newbox->hsize = SIZEEXPAND;
    newbox->cinfo.fore = newbox->cinfo.back = -1;
 
-   /* Hmm, the "correct" way doesn't seem to be
-    * working, but the old hackish SetParent()
-    * at the bottom seems to work, so I'll leave
-    * it like this for now.
-    */
-#if 0
-   if(hwndOwner)
-      flStyleEx |= WS_EX_MDICHILD;
-#endif
-
    if(!(flStyle & WS_CAPTION))
       flStyle |= WS_POPUPWINDOW;
 
@@ -6711,21 +6547,25 @@
  */
 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
 {
-   int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
    Box *thisbox;
+   
    /*
     * The following is an attempt to dynamically size a window based on the size of its
-    * children before realization. Only applicable when width or height is zero.
-    * It doesn't work vey well :-(
+    * children before realization. Only applicable when width or height is less than one.
     */
-   thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
-   if ( thisbox )
-   {
-      _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady);
-      _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
-   }
-   if ( width == 0 ) width = usedx;
-   if ( height == 0 ) height = usedy;
+   if ( (width < 1 || height < 1) && (thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA)) )
+   {
+      int depth = 0;
+            
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, width, height, 1);
+      
+      /* Might need to take into account the window border here */
+      if ( width < 1 ) width = thisbox->minwidth;
+      if ( height < 1 ) height = thisbox->minheight;
+   }
+   
+   /* Finally set the size */
    SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
 }
 
@@ -6794,26 +6634,26 @@
  */
 void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height)
 {
-   int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
    Box *thisbox;
+   
    /*
     * The following is an attempt to dynamically size a window based on the size of its
-    * children before realization. Only applicable when width or height is zero.
-    * It doesn't work vey well :-(
+    * children before realization. Only applicable when width or height is less than one.
     */
-   thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
-   if ( thisbox )
-   {
-      _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady);
-      _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
-   }
-   if ( width == 0 ) width = usedx;
-   if ( height == 0 ) height = usedy;
+   if ( (width < 1 || height < 1) && (thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA)) )
+   {
+      int depth = 0;
+            
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, width, height, 1);
+      
+      /* Might need to take into account the window border here */
+      if ( width < 1 ) width = thisbox->minwidth;
+      if ( height < 1 ) height = thisbox->minheight;
+   }
+   
+   /* Finally set the size */
    SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
-#if 0
-   /* force a configure event */
-   SendMessage( handle, WM_SIZE, 0, MAKELPARAM(width, height) );
-#endif
 }
 
 /*