changeset 10:dd61d68f3b75

Update to the latest DW and a few minor fixes.
author Brian Smith <brian@dbsoft.org>
date Wed, 25 Jul 2012 00:05:29 -0500
parents bd8f2c281cae
children 9b5da2f35bee
files dw.h os2/dw.c rexx.c sfxace/makefile.vac win/dw.c
diffstat 5 files changed, 5607 insertions(+), 2379 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Sun Nov 20 11:11:53 2011 -0600
+++ b/dw.h	Wed Jul 25 00:05:29 2012 -0500
@@ -1,11 +1,11 @@
-/* $Id: dw.h 1311 2011-11-03 23:34:10Z bsmith $ */
+/* $Id: dw.h 1790 2012-07-24 22:52:57Z bsmith $ */
 
 #ifndef _H_DW
 #define _H_DW
 
 /* Dynamic Windows version numbers */
 #define DW_MAJOR_VERSION 2
-#define DW_MINOR_VERSION 1
+#define DW_MINOR_VERSION 4
 #define DW_SUB_VERSION 0
 
 #if !defined(__PHOTON__)
@@ -57,6 +57,14 @@
 #define DW_MIS_CHECKED           (1 << 2)
 #define DW_MIS_UNCHECKED         (1 << 3)
 
+/* Gravity */
+#define DW_GRAV_TOP              0
+#define DW_GRAV_LEFT             0
+#define DW_GRAV_CENTER           1
+#define DW_GRAV_RIGHT            2
+#define DW_GRAV_BOTTOM           2
+#define DW_GRAV_OBSTACLES        (1 << 10)
+
 /* ensure we can build the Gtk port with MingW on Windows */
 #if defined(DW_USE_GTK) && defined(__MINGW32__)
 # ifndef GDK_WINDOWING_WIN32
@@ -67,8 +75,10 @@
 #if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || defined(__MAC__) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__)
 /* OS/2, Windows or MacOS */
 
-#if (defined(__IBMC__) || defined(_System)) && !defined(API)
-#define API _System
+#ifdef __OS2__
+# if (defined(__IBMC__) || defined(__WATCOMC__) || defined(_System)) && !defined(API)
+# define API _System
+# endif
 #endif
 
 /* Used internally */
@@ -79,7 +89,6 @@
 #define SIZEEXPAND 1
 
 #define SPLITBAR_WIDTH 4
-#define BUBBLE_HELP_MAX 256
 
 typedef struct _user_data
 {
@@ -124,13 +133,9 @@
 #define DW_FCF_MINBUTTON         FCF_MINBUTTON
 #define DW_FCF_MAXBUTTON         FCF_MAXBUTTON
 #define DW_FCF_MINMAX            FCF_MINMAX
-#define DW_FCF_VERTSCROLL        FCF_VERTSCROLL
-#define DW_FCF_HORZSCROLL        FCF_HORZSCROLL
 #define DW_FCF_DLGBORDER         FCF_DLGBORDER
 #define DW_FCF_BORDER            FCF_BORDER
-#define DW_FCF_SHELLPOSITION     FCF_SHELLPOSITION
 #define DW_FCF_TASKLIST          FCF_TASKLIST
-#define DW_FCF_NOBYTEALIGN       FCF_NOBYTEALIGN
 #define DW_FCF_NOMOVEWITHOWNER   FCF_NOMOVEWITHOWNER
 #define DW_FCF_SYSMODAL          FCF_SYSMODAL
 #define DW_FCF_HIDEBUTTON        FCF_HIDEBUTTON
@@ -167,8 +172,6 @@
 
 #define DW_BS_NOBORDER           BS_NOBORDER
 
-#define DW_OS2_NEW_WINDOW        1
-
 /* flag values for dw_messagebox() */
 #define DW_MB_OK                 MB_OK
 #define DW_MB_OKCANCEL           MB_OKCANCEL
@@ -222,12 +225,15 @@
 #define VK_LMENU             VK_MENU
 #define VK_RMENU             VK_MENU
 
+#define BUBBLE_HELP_MAX 256
+
 typedef struct _window_data {
    PFNWP oldproc;
    UserData *root;
    HWND clickdefault;
    ULONG flags;
    void *data;
+   char bubbletext[BUBBLE_HELP_MAX];
 } WindowData;
 
 typedef struct _hpixmap {
@@ -237,6 +243,7 @@
    HBITMAP hbm;
    HWND handle, font;
    unsigned long transcolor;
+   int depth;
 } *HPIXMAP;
 
 typedef void *HTREEITEM;
@@ -336,13 +343,9 @@
 #define DW_FCF_MINBUTTON         (1 << 2) /* NSMiniaturizableWindowMask */
 #define DW_FCF_MAXBUTTON         0
 #define DW_FCF_MINMAX            (1 << 2) /* NSMiniaturizableWindowMask */
-#define DW_FCF_VERTSCROLL        0
-#define DW_FCF_HORZSCROLL        0
 #define DW_FCF_DLGBORDER         0
 #define DW_FCF_BORDER            0
-#define DW_FCF_SHELLPOSITION     0
 #define DW_FCF_TASKLIST          0
-#define DW_FCF_NOBYTEALIGN       0
 #define DW_FCF_NOMOVEWITHOWNER   0
 #define DW_FCF_SYSMODAL          0
 #define DW_FCF_HIDEBUTTON        0
@@ -484,12 +487,8 @@
 #include <commctrl.h>
 
 #if defined(MSVC) && !defined(API)
-# ifdef __MINGW32__
-#  ifdef BUILD_DLL
-#   define API APIENTRY __declspec(dllexport)
-#  else
-#   define API APIENTRY __declspec(dllimport)
-#  endif
+# if defined(__MINGW32__) && defined(BUILD_DLL)
+#  define API _cdecl __declspec(dllexport)
 # else
 #  define API _cdecl
 #endif
@@ -519,13 +518,9 @@
 #define DW_FCF_MINBUTTON         WS_MINIMIZEBOX
 #define DW_FCF_MAXBUTTON         WS_MAXIMIZEBOX
 #define DW_FCF_MINMAX            (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
-#define DW_FCF_VERTSCROLL        WS_VSCROLL
-#define DW_FCF_HORZSCROLL        WS_HSCROLL
 #define DW_FCF_DLGBORDER         WS_DLGFRAME
 #define DW_FCF_BORDER            WS_BORDER
-#define DW_FCF_SHELLPOSITION     0
-#define DW_FCF_TASKLIST          WS_VSCROLL
-#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_TASKLIST          (1 << 1)
 #define DW_FCF_NOMOVEWITHOWNER   0
 #define DW_FCF_SYSMODAL          0
 #define DW_FCF_HIDEBUTTON        WS_MINIMIZEBOX
@@ -533,6 +528,7 @@
 #define DW_FCF_AUTOICON          0
 #define DW_FCF_MAXIMIZE          WS_MAXIMIZE
 #define DW_FCF_MINIMIZE          WS_MINIMIZE
+#define DW_FCF_COMPOSITED        1
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -578,22 +574,6 @@
 #define KC_SHIFT                 (1 << 1)
 #define KC_ALT                   (1 << 2)
 
-#define STATICCLASSNAME "STATIC"
-#define COMBOBOXCLASSNAME "COMBOBOX"
-#define LISTBOXCLASSNAME "LISTBOX"
-#define BUTTONCLASSNAME "BUTTON"
-#define POPUPMENUCLASSNAME "POPUPMENU"
-#define EDITCLASSNAME "EDIT"
-#define FRAMECLASSNAME "FRAME"
-#define SCROLLBARCLASSNAME "SCROLLBAR"
-
-#define ClassName "dynamicwindows"
-#define SplitbarClassName "dwsplitbar"
-#define ObjectClassName "dwobjectclass"
-#define BrowserClassName "dwbrowserclass"
-#define ScrollClassName "dwscrollclass"
-#define DefaultFont NULL
-
 typedef struct _color {
    int fore;
    int back;
@@ -653,8 +633,6 @@
    int hsize, vsize;
    /* Padding */
    int pad;
-   /* Ratio of current item */
-   float xratio, yratio;
 } Item;
 
 typedef struct _box {
@@ -670,16 +648,16 @@
    int count;
    /* Box type - horizontal or vertical */
    int type;
+   /* Keep track of how box is packed */
+   int hsize, vsize;
    /* Padding */
-   int pad, parentpad, grouppadx, grouppady;
+   int pad, grouppadx, grouppady;
    /* Groupbox */
    HWND grouphwnd;
    /* Default item */
    HWND defaultitem;
    /* Used as temporary storage in the calculation stage */
-   int upx, upy, minheight, minwidth;
-   /* Ratio in this box */
-   float xratio, yratio, parentxratio, parentyratio;
+   int usedpadx, usedpady, minheight, minwidth;
    /* Used for calculating individual item ratios */
    int width, height;
    /* Any combinations of flags describing the box */
@@ -688,20 +666,6 @@
    struct _item *items;
 } Box;
 
-typedef struct _bubblebutton {
-#if defined(__WIN32__) || defined(WINNT)
-   ColorInfo cinfo;
-   int checkbox;
-   WNDPROC pOldProc;
-#endif
-#if defined(__OS2__) || defined(__EMX__)
-   PFNWP pOldProc;
-   UserData *root;
-   unsigned long id;
-   char bubbletext[BUBBLE_HELP_MAX];
-#endif
-} BubbleButton;
-
 #elif defined(__PHOTON__)
 #include <stdio.h>
 #include <stdlib.h>
@@ -817,13 +781,9 @@
 #define DW_FCF_MINBUTTON         Ph_WM_RENDER_MIN
 #define DW_FCF_MAXBUTTON         Ph_WM_RENDER_MAX
 #define DW_FCF_MINMAX            (Ph_WM_RENDER_MIN|Ph_WM_RENDER_MAX)
-#define DW_FCF_VERTSCROLL        0
-#define DW_FCF_HORZSCROLL        0
 #define DW_FCF_DLGBORDER         0
 #define DW_FCF_BORDER            Ph_WM_RENDER_BORDER
-#define DW_FCF_SHELLPOSITION     0
 #define DW_FCF_TASKLIST          0
-#define DW_FCF_NOBYTEALIGN       0
 #define DW_FCF_NOMOVEWITHOWNER   0
 #define DW_FCF_SYSMODAL          0
 #define DW_FCF_HIDEBUTTON        0
@@ -1002,13 +962,9 @@
 #define DW_FCF_MINBUTTON         (1 << 4)
 #define DW_FCF_MAXBUTTON         (1 << 5)
 #define DW_FCF_MINMAX            (1 << 6)
-#define DW_FCF_VERTSCROLL        (1 << 7)
-#define DW_FCF_HORZSCROLL        (1 << 8)
 #define DW_FCF_DLGBORDER         (1 << 9)
 #define DW_FCF_BORDER            (1 << 10)
-#define DW_FCF_SHELLPOSITION     (1 << 11)
 #define DW_FCF_TASKLIST          (1 << 12)
-#define DW_FCF_NOBYTEALIGN       (1 << 13)
 #define DW_FCF_NOMOVEWITHOWNER   (1 << 14)
 #define DW_FCF_SYSMODAL          (1 << 15)
 #define DW_FCF_HIDEBUTTON        (1 << 16)
@@ -1361,7 +1317,12 @@
 /* Obsolete, should disappear sometime */
 #define BOXHORZ DW_HORZ
 #define BOXVERT DW_VERT
+#define DW_FCF_SHELLPOSITION     0
+#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_VERTSCROLL        0
+#define DW_FCF_HORZSCROLL        0
 
+/* Scrolling constants */
 #define DW_SCROLL_UP 0
 #define DW_SCROLL_DOWN 1
 #define DW_SCROLL_TOP 2
@@ -1414,11 +1375,11 @@
 #define DW_HTML_STOP       5
 #define DW_HTML_PRINT      6
 
-/* Drawing flags... used for Arc currently */
+/* Drawing flags  */
 #define DW_DRAW_DEFAULT    0
 #define DW_DRAW_FILL       1
 #define DW_DRAW_FULL       (1 << 1)
-
+#define DW_DRAW_NOAA       (1 << 2)
 
 /* Macro for casting resource IDs to HICN */
 #define DW_RESOURCE(a) (a < 65536 ? (HICN)a : (HICN)0)
@@ -1436,6 +1397,11 @@
 #define DW_UINT_TO_POINTER(a) ((void *)a)
 #define DW_POINTER_TO_UINT(a) ((unsigned int)a)
 #endif
+#define DW_POINTER(a) ((void *)a)
+
+#ifndef DW_FCF_COMPOSITED
+#define DW_FCF_COMPOSITED        0
+#endif
 
 #ifndef API
 #define API
@@ -1443,6 +1409,14 @@
 
 #define DWSIGNAL API
 
+/* Constants for sizing scrolled widgets */
+#define _DW_SCROLLED_MIN_WIDTH   100
+#define _DW_SCROLLED_MIN_HEIGHT  75
+#define _DW_SCROLLED_MAX_WIDTH   500
+#define _DW_SCROLLED_MAX_HEIGHT  400
+
+#include <wchar.h>
+
 /* Let other APIs know what types we've defined,
  * Regina REXX in particular, on Unix.
  */
@@ -1457,10 +1431,43 @@
 #define UINT_TYPEDEFED 1
 #define INT_TYPEDEFED 1
 
+/* Support for API deprecation in supported compilers */
+#if defined(__has_feature) && !defined(__has_extension)
+#define __has_extension __has_feature
+#endif
+
+/* Visual C */
+#if defined(_MSC_VER) 
+#  if _MSC_VER >= 1400
+#  define DW_DEPRECATED(func, message) __declspec(deprecated(message)) func
+#  endif
+/* Clang */
+#elif defined(__has_extension)
+#  if __has_extension(attribute_deprecated_with_message) 
+#  define DW_DEPRECATED(func, message) func __attribute__ ((deprecated (message)))
+#  else
+#  define DW_DEPRECATED(func, message) func __attribute__ ((deprecated))
+#  endif
+/* GCC */
+#elif defined(__GNUC__)
+#  if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 
+#  define DW_DEPRECATED(func, message) func __attribute__ ((deprecated (message)))
+#  else
+#  define DW_DEPRECATED(func, message) func __attribute__ ((deprecated))
+#  endif
+#endif
+
+/* Compiler without deprecation support */
+#ifndef DW_DEPRECATED
+#define DW_DEPRECATED(func, message) func
+#endif
+
 /* Public function prototypes */
 void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
 void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
 void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad);
+HWND API dw_box_unpack_at_index(HWND box, int index);
+int API dw_box_unpack(HWND handle);
 #if !defined(__OS2__) && !defined(__WIN32__) && !defined(__EMX__) && !defined(__MAC__)
 int API dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]);
 #define dw_init(a, b, c) dw_int_init(&_resources, a, &b, &c)
@@ -1468,6 +1475,7 @@
 int API dw_init(int newthread, int argc, char *argv[]);
 #endif
 void API dw_main(void);
+void API dw_main_quit(void);
 void API dw_main_sleep(int seconds);
 void API dw_main_iteration(void);
 void API dw_free(void *ptr);
@@ -1487,7 +1495,7 @@
 int API dw_scrollbox_get_pos( HWND handle, int orient );
 int API dw_scrollbox_get_range( HWND handle, int orient );
 HWND API dw_groupbox_new(int type, int pad, char *title);
-HWND API dw_mdi_new(unsigned long id);
+DW_DEPRECATED(HWND API dw_mdi_new(unsigned long id), "Due to lack of full Mac support consider avoiding this function.");
 HWND API dw_bitmap_new(unsigned long id);
 HWND API dw_bitmapbutton_new(char *text, unsigned long id);
 HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename);
@@ -1530,12 +1538,15 @@
 void API dw_window_set_size(HWND handle, unsigned long width, unsigned long height);
 void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height);
 void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height);
+void API dw_window_get_preferred_size(HWND handle, int *width, int *height);
+void API dw_window_set_gravity(HWND handle, int horz, int vert);
 void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask);
 void API dw_window_set_icon(HWND handle, HICN icon);
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
 void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len);
 char * API dw_window_get_text(HWND handle);
 void API dw_window_set_text(HWND handle, char *text);
+void API dw_window_set_tooltip(HWND handle, char *bubbletext);
 int API dw_window_set_border(HWND handle, int border);
 void API dw_window_disable(HWND handle);
 void API dw_window_enable(HWND handle);
@@ -1598,6 +1609,7 @@
 void API dw_container_delete_row(HWND handle, char *text);
 void API dw_container_optimize(HWND handle);
 void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor);
+void API dw_filesystem_set_column_title(HWND handle, char *title);
 int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count);
 void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data);
 void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon);
@@ -1624,10 +1636,8 @@
 HMENUI API dw_menu_new(unsigned long id);
 HMENUI API dw_menubar_new(HWND location);
 HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu);
-#ifdef INCOMPLETE
-void API dw_menu_delete_item(HMENUI menu, unsigned long id);
-#endif
-void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check);
+int API dw_menu_delete_item(HMENUI menu, unsigned long id);
+DW_DEPRECATED(void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check), "Use dw_menu_item_set_state() for new code.");
 void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state);
 void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y);
 void API dw_menu_destroy(HMENUI *menu);
@@ -1680,6 +1690,7 @@
 int API dw_browse(char *url);
 char * API dw_file_browse(char *title, char *defpath, char *ext, int flags);
 char * API dw_user_dir(void);
+char * API dw_app_dir(void);
 DWDialog * API dw_dialog_new(void *data);
 int API dw_dialog_dismiss(DWDialog *dialog, void *result);
 void * API dw_dialog_wait(DWDialog *dialog);
@@ -1715,5 +1726,7 @@
 HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata);
 int API dw_print_run(HPRINT print, unsigned long flags);
 void API dw_print_cancel(HPRINT print);
+wchar_t * API dw_utf8_to_wchar(char *utf8string);
+char * API dw_wchar_to_utf8(wchar_t *wstring);
 
 #endif
--- a/os2/dw.c	Sun Nov 20 11:11:53 2011 -0600
+++ b/os2/dw.c	Wed Jul 25 00:05:29 2012 -0500
@@ -2,10 +2,11 @@
  * Dynamic Windows:
  *          A GTK like implementation of the PM GUI
  *
- * (C) 2000-2011 Brian Smith <brian@dbsoft.org>
- * (C) 2003-2008 Mark Hessling <m.hessling@qut.edu.au>
+ * (C) 2000-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2003-2011 Mark Hessling <mark@rexx.org>
  * (C) 2000 Achim Hasenmueller <achimha@innotek.de>
  * (C) 2000 Peter Nielsen <peter@pmview.com>
+ * (C) 2007 Alex Taylor (some code borrowed from clipuni)
  * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit)
  *
  */
@@ -37,6 +38,11 @@
 #ifdef __WATCOMC__
 #include <alloca.h>
 #endif
+#include <fcntl.h>
+#ifdef UNICODE
+#include <uconv.h>
+#include <unikbd.h>
+#endif
 #include "dw.h"
 
 #define QWP_USER 0
@@ -44,20 +50,65 @@
 /* The toolkit headers don't seem to have this */
 BOOL APIENTRY WinStretchPointer(HPS hps, LONG x, LONG y, LONG cx, LONG cy, HPOINTER hptr, ULONG fs);
 
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif
+
+#ifdef __IBMC__
+#define API_FUNC * API
+#else
+#define API_FUNC API *
+#endif
+
 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
 MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
 MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
 void _do_resize(Box *thisbox, int x, int y);
 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
-int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height);
-void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
-void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height, int *depth);
 void _free_menu_data(HWND menu);
-ULONG (* _System _PmPrintfString)(char *String) = 0;
+BOOL (API_FUNC _WinQueryDesktopWorkArea)(HWND hwndDesktop, PWRECT pwrcWorkArea) = 0;
+/* PMPrintf support for dw_debug() */
+ULONG (API_FUNC _PmPrintfString)(char *String) = 0;
+/* GBM (Generalize Bitmap Module) support for file loading */
+#pragma pack(4)
+typedef struct
+{
+    int w, h, bpp;
+    unsigned char priv[2000];
+} GBM;
+typedef struct { unsigned char r, g, b; } GBMRGB;
+#pragma pack()
+int (API_FUNC _gbm_init)(void) = 0;
+int (API_FUNC _gbm_deinit)(void) = 0;
+int (API_FUNC _gbm_query_n_filetypes)(int *count) = 0;
+int (API_FUNC _gbm_io_open)(const char *fn, int mode) = 0;
+int (API_FUNC _gbm_io_close)(int fd) = 0;
+int (API_FUNC _gbm_read_header)(const char *fn, int fd, int ft, GBM *gbm, const char *info) = 0;
+int (API_FUNC _gbm_read_palette)(int fd, int ft, GBM *gbm, GBMRGB *gbmrgb) = 0;
+int (API_FUNC _gbm_read_data)(int fd, int ft, GBM *gbm, unsigned char *data) = 0;
+const char * (API_FUNC _gbm_err)(int rc) = 0;
+/*
+ * GBM List of supported formats: BMP, PNG, JPEG, Targa, TIFF and XPM.
+ */
+#define NUM_EXTS 8
+char *image_exts[NUM_EXTS] =
+{
+   ".bmp",
+   ".png",
+   ".jpg",
+   ".jpeg",
+   ".tga",
+   ".tif",
+   ".tiff",
+   ".xpm"
+};
+
 
 char ClassName[] = "dynamicwindows";
 char SplitbarClassName[] = "dwsplitbar";
 char ScrollClassName[] = "dwscroll";
+char CalendarClassName[] = "dwcalendar";
 char *DefaultFont = "9.WarpSans";
 
 HAB dwhab = 0;
@@ -67,11 +118,19 @@
 
 HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
 HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE;
-;
+
 PRECORDCORE pCoreEmph = NULL;
 ULONG aulBuffer[4];
 HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
-HMOD wpconfig = 0, pmprintf = 0;
+HMOD wpconfig = 0, pmprintf = 0, pmmerge = 0, gbm = 0;
+static char _dw_exec_dir[MAX_PATH+1] = {0};
+
+#ifdef UNICODE
+/* Atom for "text/unicode" clipboard format */
+ATOM  Unicode;
+KHAND Keyboard;
+UconvObject Uconv;                      /* conversion object */
+#endif
 
 unsigned long _colors[] = {
    CLR_BLACK,
@@ -92,6 +151,8 @@
    CLR_WHITE
 };
 
+#define DW_OS2_NEW_WINDOW        1
+
 #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40)
 
 #ifndef min
@@ -223,19 +284,41 @@
    return TRUE;
 }
 
+/* Internal function to queue a window redraw */
+void _dw_redraw(HWND window, int skip)
+{
+    static HWND lastwindow = 0;
+    HWND redraw = lastwindow;
+    
+    if(skip && !window)
+        return;
+
+    lastwindow = window;
+    if(redraw != lastwindow && redraw)
+    {
+        dw_window_redraw(redraw);
+    }
+}
+
 /* Find the desktop window handle */
 HWND _toplevel_window(HWND handle)
 {
    HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
 
    /* Find the toplevel window */
-   while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0)
+   while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box)
    {
       lastbox = box;
    }
-   if(box > 0)
-      return lastbox;
-   return handle;
+   if(box)
+   {
+       char tmpbuf[100] = {0};
+
+       WinQueryClassName(lastbox, 99, (PCH)tmpbuf);
+       if(strncmp(tmpbuf, "#1", 3) == 0)
+           return lastbox;
+   }
+   return NULLHANDLE;
 }
 
 
@@ -295,7 +378,7 @@
    henum = WinBeginEnumWindows(handle);
    while((child = WinGetNextWindow(henum)) != NULLHANDLE)
    {
-      char tmpbuf[100];
+      char tmpbuf[100] = {0};
 
       WinQueryClassName(child, 99, (PCH)tmpbuf);
 
@@ -320,7 +403,7 @@
    henum = WinBeginEnumWindows(handle);
    while((child = WinGetNextWindow(henum)) != NULLHANDLE)
    {
-      char tmpbuf[100];
+      char tmpbuf[100] = {0};
 
       WinQueryClassName(child, 99, (PCH)tmpbuf);
 
@@ -399,7 +482,7 @@
    if(ptr)
    {
       WindowData *wd = (WindowData *)ptr;
-      char tmpbuf[100];
+      char tmpbuf[100] = {0};
 
       WinQueryClassName(handle, 99, (PCH)tmpbuf);
 
@@ -424,14 +507,25 @@
          }
          else if(strncmp(tmpbuf, "#37", 4)==0)
          {
+            char *coltitle = (char *)dw_window_get_data(handle, "_dw_coltitle");
+            PFIELDINFO first;
+
             dw_container_clear(handle, FALSE);
             if(wd && dw_window_get_data(handle, "_dw_container"))
             {
                void *oldflags = wd->data;
-
                wd->data = NULL;
                free(oldflags);
             }
+            /* Free memory allocated for the container column titles */
+            while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO,  0, MPFROMSHORT(CMA_FIRST))) != NULL)
+            {
+                if(first->pTitleData)
+                    free(first->pTitleData);
+                WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE));
+            }
+            if(coltitle)
+               free(coltitle);
          }
 
          if(wd->oldproc)
@@ -490,7 +584,7 @@
  */
 int _validate_focus(HWND handle)
 {
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    if(!handle)
       return 0;
@@ -591,7 +685,7 @@
          }
          else
          {
-            char tmpbuf[100] = "";
+            char tmpbuf[100] = {0};
 
             WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf);
             if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
@@ -726,7 +820,7 @@
          }
          else
          {
-            char tmpbuf[100] = "";
+            char tmpbuf[100] = {0};
 
             WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf);
             if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
@@ -971,7 +1065,7 @@
 
 void _check_resize_notebook(HWND hwnd)
 {
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    WinQueryClassName(hwnd, 99, (PCH)tmpbuf);
 
@@ -1027,194 +1121,151 @@
    return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
 }
 
-#define _DW_DEFAULT_SCROLLBAR_WIDTH 16
+#ifdef UNICODE
+#define MAX_CP_NAME     12      /* maximum length of a codepage name */
+#define MAX_CP_SPEC     64      /* maximum length of a UconvObject codepage specifier */
+
+char *_WideToUTF8(UniChar *unistr)
+{
+    /* Convert text to UTF-8 codepage */
+    char *retval = NULL;
+    /* Now do the conversion */
+    ULONG ulBufLen = (UniStrlen(unistr) * 4) + 1;
+    char *s, *pszLocalText = (char *)malloc(ulBufLen);
+
+    if(UniStrFromUcs(Uconv, pszLocalText,
+                     unistr, ulBufLen) == ULS_SUCCESS)
+    {
+        /* (some codepages use 0x1A for substitutions; replace with ?) */
+        while((s = strchr(pszLocalText, 0x1A)) != NULL) *s = '?';
+        /* Output the converted text */
+        retval = pszLocalText;
+    }
+    else if(pszLocalText)
+        free(pszLocalText);
+    return retval;
+}
+
+UniChar *_UTF8toWide(char *utf8str)
+{
+    /* Convert text to Unicode */
+    UniChar *retval = NULL;
+    /* Now do the conversion */
+    UniChar *buf = calloc(strlen(utf8str) + 1, sizeof(UniChar));
+
+    if(UniStrToUcs(Uconv, buf,
+                   utf8str, strlen(utf8str) * sizeof(UniChar)) == ULS_SUCCESS)
+    {
+        /* Output the converted text */
+        retval = buf;
+    }
+    else if(buf)
+        free(buf);
+    return retval;
+}
+#endif
 
 /* 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)
    {
-      char *text = dw_window_get_text(thisbox->grouphwnd);
-
-      thisbox->grouppady = 0;
-
-      if(text)
-      {
-         dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
-         dw_free(text);
-      }
-
-      if(thisbox->grouppady)
-         thisbox->grouppady += 3;
-      else
-         thisbox->grouppady = 6;
-
-      thisbox->grouppadx = 6;
-
-      (*usedx) += thisbox->grouppadx;
-      (*usedpadx) += thisbox->grouppadx;
-      (*usedy) += thisbox->grouppady;
-      (*usedpady) += thisbox->grouppady;
-   }
-
+      /* Only calculate the size on the first pass...
+       * use the cached values on second.
+       */
+      if(pass == 1)
+      {
+         char *text = dw_window_get_text(thisbox->grouphwnd);
+
+         thisbox->grouppady = 9;
+
+         if(text)
+         {
+            if(*text)
+               dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
+            dw_free(text);
+         }
+         /* If the string height is less than 9...
+          * set it to 9 anyway since that is the minimum.
+          */
+         if(thisbox->grouppady < 9)
+            thisbox->grouppady = 9;
+
+         if(thisbox->grouppady)
+            thisbox->grouppady += 3;
+         else
+            thisbox->grouppady = 6;
+
+         thisbox->grouppadx = 6;
+      }
+      
+      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;
-
-               /* 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;
+               
+               /* If the box has no contents but is expandable... default the size to 1 */
+               if(!thisbox->items[z].width && thisbox->items[z].hsize)
+                  thisbox->items[z].width = 1;
+               if(!thisbox->items[z].height && thisbox->items[z].vsize)
+                  thisbox->items[z].height = 1;
+               
+               (*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)
@@ -1222,30 +1273,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
       {
-         if(thisbox->items[z].width == -1)
-         {
-            /* figure out how much space this item requires */
-            /* thisbox->items[z].width = */
-         }
-         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)
@@ -1255,121 +1293,73 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upymax)
-               upymax = thisbox->items[z].pad*2;
-         }
-      }
-      else
-      {
-         if(thisbox->items[z].height == -1)
-         {
-            /* figure out how much space this item requires */
-            /* thisbox->items[z].height = */
-         }
+            if(itempad > upymax)
+               upymax = itempad;
+         }
+         thisbox->minwidth += itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+            thisbox->usedpadx += itemwidth;
          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;
-            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);
-
+         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 the calculated size is valid... */
          if(width > 0 && height > 0)
          {
-            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;
-
+            int pad = thisbox->items[z].pad;
+            HWND handle = thisbox->items[z].hwnd;
+            char tmpbuf[100] = {0};
+           
             WinQueryClassName(handle, 99, (PCH)tmpbuf);
 
             if(strncmp(tmpbuf, "#2", 3)==0)
@@ -1377,28 +1367,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);
@@ -1409,46 +1397,46 @@
                 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, WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL), width - WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL), height - WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL), SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(hscroll, HWND_TOP, 0, 0, width - WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL), WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL), SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(vscroll, HWND_TOP, width - WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL), WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL), WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL), height - WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL), SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                origx = cx = width - WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
+                origy = cy = height - WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
 
                 /* 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);
                 }
 
                 /* Position the scrolled box */
-                WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(box, HWND_TOP, -hpos, -(cy - origy - vpos), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
 
                 dw_window_set_data(handle, "_dw_cy", (void *)(cy - origy));
 
@@ -1460,39 +1448,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)
@@ -1501,19 +1498,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);
       }
    }
 }
@@ -1608,6 +1599,258 @@
    GpiLine(hpsPaint, &ptl2);
 }
 
+void _drawtext(HWND hWnd, HPS hpsPaint)
+{
+    RECTL rclPaint;
+    int len = WinQueryWindowTextLength(hWnd);
+    ULONG style = WinQueryWindowULong(hWnd, QWL_STYLE) & (DT_TOP|DT_VCENTER|DT_BOTTOM|DT_LEFT|DT_CENTER|DT_RIGHT|DT_WORDBREAK);
+    char *tempbuf = alloca(len + 2);
+    ULONG fcolor = DT_TEXTATTRS, bcolor = DT_TEXTATTRS;
+
+    WinQueryWindowText(hWnd, len + 1, (PSZ)tempbuf);
+    WinQueryWindowRect(hWnd, &rclPaint);
+
+    if(WinQueryPresParam(hWnd, PP_BACKGROUNDCOLOR, 0, NULL, sizeof(bcolor), &bcolor, QPF_NOINHERIT) ||
+       WinQueryPresParam(hWnd, PP_BACKGROUNDCOLORINDEX, 0, NULL, sizeof(bcolor), &bcolor, QPF_NOINHERIT))
+        GpiSetBackColor(hpsPaint, bcolor);
+    if(WinQueryPresParam(hWnd, PP_FOREGROUNDCOLOR, 0, NULL, sizeof(fcolor), &fcolor, QPF_NOINHERIT) ||
+       WinQueryPresParam(hWnd, PP_FOREGROUNDCOLORINDEX, 0, NULL, sizeof(fcolor), &fcolor, QPF_NOINHERIT))
+        GpiSetColor(hpsPaint, fcolor);
+    WinDrawText(hpsPaint, -1, (PCH)tempbuf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, style | DT_TEXTATTRS | DT_ERASERECT);
+}
+
+/* Function: BubbleProc
+ * Abstract: Subclass procedure for bubble help
+ */
+MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
+
+   if(msg == WM_PAINT)
+   {
+      POINTL ptl;
+      HPS hpsTemp;
+      RECTL rcl;
+      int height, width;
+
+      WinQueryWindowRect(hwnd, &rcl);
+      height = rcl.yTop - rcl.yBottom - 1;
+      width = rcl.xRight - rcl.xLeft - 1;
+
+      /* Draw a border around the bubble help */
+      hpsTemp = WinBeginPaint(hwnd, 0, 0);
+
+      _drawtext(hwnd, hpsTemp);
+      GpiSetColor(hpsTemp, CLR_BLACK);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      WinEndPaint(hpsTemp);
+      return (MRESULT)TRUE;
+   }
+   if(proc)
+      return proc(hwnd, msg, mp1, mp2);
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* Subclass WC_STATIC to draw a bitmap centered */
+MRESULT EXPENTRY _BitmapProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+    WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWL_USER);
+
+    if(msg == WM_PAINT)
+    {
+        HPS hps = WinBeginPaint(hwnd, 0, 0);
+        HBITMAP hbm = (HBITMAP)dw_window_get_data(hwnd, "_dw_bitmap");
+        RECTL rcl;
+
+        WinQueryWindowRect(hwnd, &rcl) ;
+        WinFillRect(hps, &rcl, CLR_PALEGRAY);
+
+        /* If we have a bitmap... draw it */
+        if(hbm)
+        {
+            BITMAPINFOHEADER sl;
+
+            sl.cbFix = sizeof(BITMAPINFOHEADER);
+
+            /* Check the bitmap size */
+            if(GpiQueryBitmapParameters(hbm, &sl))
+            {
+               /* Figure out the window size before clobbering the data */
+                int width = rcl.xRight - rcl.xLeft, height = rcl.yTop - rcl.yBottom;
+
+                /* If the control is bigger than the bitmap, center it */
+               if(width > sl.cx)
+                   rcl.xLeft = (width-sl.cx)/2;
+               if(height > sl.cy)
+                   rcl.yBottom = (height-sl.cy)/2;
+
+           }
+            /* Draw the bitmap unscaled at the desired location */
+            WinDrawBitmap(hps, hbm, NULL, (PPOINTL) &rcl,
+                          CLR_NEUTRAL, CLR_BACKGROUND, DBM_NORMAL);
+        }
+
+       WinEndPaint(hps);
+       return 0;
+    }
+    if(blah && blah->oldproc)
+        return blah->oldproc(hwnd, msg, mp1, mp2);
+    return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* Function to handle tooltip messages from a variety of procedures */
+MRESULT EXPENTRY _TooltipProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, WindowData *blah)
+{
+    static HWND hstart, hend;
+
+    switch(msg)
+    {
+    case 0x041f:
+        /* Mouse has left the area.. remove tooltip and stop timer */
+        if(hwndBubble)
+        {
+            WinDestroyWindow(hwndBubble);
+            hwndBubble = 0;
+        }
+        if(hstart)
+            WinStopTimer(dwhab, hstart, 1);
+        if(hend)
+            WinStopTimer(dwhab, hend, 2);
+        hstart = hend = 0;
+        break;
+
+    case 0x041e:
+        /* Mouse has entered... stop any pending timer...
+         * then start a new timer to creat the tooltip delayed.
+         */
+        if(hstart)
+            WinStopTimer(dwhab, hstart, 1);
+        /* Two seconds to create */
+        WinStartTimer(dwhab, hwnd, 1, 2000);
+        hstart = hwnd;
+        break;
+    case WM_TIMER:
+        if((int)mp1 == 1 || (int)mp1 == 2)
+        {
+            if(hwndBubble)
+            {
+                WinDestroyWindow(hwndBubble);
+                hwndBubble = 0;
+            }
+            /* Either starting or ending... remove tooltip and timers */
+            if(hstart)
+                WinStopTimer(dwhab, hstart, 1);
+            if(hend)
+                WinStopTimer(dwhab, hend, 2);
+            hstart = hend = 0;
+            /* If we are starting... create a new tooltip */
+            if((int)mp1 == 1)
+            {
+                HPS   hpsTemp = 0;
+                LONG  lHight;
+                LONG  lWidth;
+                POINTL txtPointl[TXTBOX_COUNT];
+                POINTL ptlWork = {0,0};
+                ULONG ulColor = CLR_YELLOW;
+                void *bubbleproc;
+
+                hwndBubbleLast   = hwnd;
+                hwndBubble = WinCreateWindow(HWND_DESKTOP,
+                                             WC_STATIC,
+                                             NULL,
+                                             SS_TEXT |
+                                             DT_CENTER |
+                                             DT_VCENTER,
+                                             0,0,0,0,
+                                             HWND_DESKTOP,
+                                             HWND_TOP,
+                                             0,
+                                             NULL,
+                                             NULL);
+
+                WinSetPresParam(hwndBubble,
+                                PP_FONTNAMESIZE,
+                                strlen(DefaultFont)+1,
+                                DefaultFont);
+
+
+                WinSetPresParam(hwndBubble,
+                                PP_BACKGROUNDCOLORINDEX,
+                                sizeof(ulColor),
+                                &ulColor);
+
+                WinSetWindowText(hwndBubble,
+                                 (PSZ)blah->bubbletext);
+
+                WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
+
+                hpsTemp = WinGetPS(hwndBubble);
+                GpiQueryTextBox(hpsTemp,
+                                strlen(blah->bubbletext),
+                                (PCH)blah->bubbletext,
+                                TXTBOX_COUNT,
+                     txtPointl);
+                WinReleasePS(hpsTemp);
+
+                lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
+                    txtPointl[TXTBOX_TOPLEFT ].x + 8;
+
+                lHight = txtPointl[TXTBOX_TOPLEFT].y -
+                    txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
+
+                ptlWork.y -= lHight + 2;
+
+                /* Make sure it is visible on the screen */
+                if(ptlWork.x + lWidth > dw_screen_width())
+                {
+                    ptlWork.x = dw_screen_width() - lWidth;
+                    if(ptlWork.x < 0)
+                        ptlWork.x = 0;
+                }
+
+                bubbleproc = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
+
+                if(bubbleproc)
+                    WinSetWindowPtr(hwndBubble, QWP_USER, bubbleproc);
+
+                WinSetWindowPos(hwndBubble,
+                                HWND_TOP,
+                                ptlWork.x,
+                                ptlWork.y,
+                                lWidth,
+                                lHight,
+                                SWP_SIZE | SWP_MOVE | SWP_SHOW);
+
+                /* Start a timer to remove it after 15 seconds */
+                WinStartTimer(dwhab, hwnd, 2, 15000);
+                hend = hwnd;
+            }
+        }
+        break;
+	}
+    return (MRESULT)FALSE;
+}
 
 #define CALENDAR_BORDER 3
 #define CALENDAR_ARROW 8
@@ -1634,13 +1877,15 @@
     return rclPaint;
 }
 
+/* These will be filled in during dw_init() */
+static char months[12][20];
+static char daysofweek[7][20];
+
 /* This procedure handles drawing of a status border */
 MRESULT EXPENTRY _calendarproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
    /* How many days are in each month usually (not including leap years) */
    static int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-   static char *months[] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
-   static char *daysofweek[] = { "Sunday", "Monday", "Tuesday","Wednesday", "Thursday", "Friday", "Saturday" };
    WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
    PFNWP oldproc = 0;
 
@@ -1648,6 +1893,9 @@
    {
       oldproc = blah->oldproc;
 
+      if(blah->bubbletext[0])
+          _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
       switch(msg)
       {
       case WM_BUTTON1DOWN:
@@ -1883,14 +2131,21 @@
 /* This procedure handles drawing of a status border */
 MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
 
    if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2))
       return MPFROMSHORT(FALSE);
 
-   if(blah && *blah)
-   {
-      PFNWP myfunc = *blah;
+   if(blah)
+   {
+      oldproc = blah->oldproc;
+
+      if(blah->bubbletext[0])
+          _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
+      if(blah->bubbletext[0])
+          _TooltipProc(hWnd, msg, mp1, mp2, blah);
 
       switch(msg)
       {
@@ -1925,7 +2180,8 @@
             return (MRESULT)TRUE;
          }
       }
-      return myfunc(hWnd, msg, mp1, mp2);
+      if(oldproc)
+          return oldproc(hWnd, msg, mp1, mp2);
    }
 
    return WinDefWindowProc(hWnd, msg, mp1, mp2);
@@ -1934,16 +2190,31 @@
 /* This procedure handles pointer changes */
 MRESULT EXPENTRY _textproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
 
    if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2))
       return MPFROMSHORT(FALSE);
 
-   if(blah && *blah)
-   {
-      PFNWP myfunc = *blah;
-
-      return myfunc(hWnd, msg, mp1, mp2);
+   if(blah && blah->oldproc)
+   {
+      PFNWP myfunc = blah->oldproc;
+
+      switch(msg)
+      {
+      case WM_PAINT:
+          {
+              HPS hpsPaint = WinBeginPaint(hWnd, 0, 0);
+
+              _drawtext(hWnd, hpsPaint);
+              WinEndPaint(hpsPaint);
+              return (MRESULT)TRUE;
+          }
+      default:
+          return myfunc(hWnd, msg, mp1, mp2);
+      }
    }
 
    return WinDefWindowProc(hWnd, msg, mp1, mp2);
@@ -1952,10 +2223,10 @@
 /* This procedure handles scrollbox */
 MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-   switch(msg)
-   {
-      case WM_PAINT:
-         {
+    switch(msg)
+    {
+    case WM_PAINT:
+        {
             HPS hpsPaint;
             RECTL rclPaint;
 
@@ -1963,80 +2234,79 @@
             WinQueryWindowRect(hWnd, &rclPaint);
             WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
             WinEndPaint(hpsPaint);
-
             break;
-         }
-   case WM_HSCROLL:
-   case WM_VSCROLL:
-      {
-         MPARAM res;
-         int *pos, min, max, page, which = SHORT2FROMMP(mp2);
-         HWND handle, client = WinWindowFromID(hWnd, FID_CLIENT);
-         HWND box = (HWND)dw_window_get_data(hWnd, "_dw_resizebox");
-         HWND hscroll = WinWindowFromID(hWnd, FID_HORZSCROLL);
-         HWND vscroll = WinWindowFromID(hWnd, FID_VERTSCROLL);
+        }
+    case WM_HSCROLL:
+    case WM_VSCROLL:
+        {
+            MPARAM res;
+            int *pos, min, max, page, which = SHORT2FROMMP(mp2);
+            HWND handle, client = WinWindowFromID(hWnd, FID_CLIENT);
+            HWND box = (HWND)dw_window_get_data(hWnd, "_dw_resizebox");
+            HWND hscroll = WinWindowFromID(hWnd, FID_HORZSCROLL);
+            HWND vscroll = WinWindowFromID(hWnd, FID_VERTSCROLL);
             int hpos = dw_scrollbar_get_pos(hscroll);
             int vpos = dw_scrollbar_get_pos(vscroll);
-         int cy = (int)dw_window_get_data(hWnd, "_dw_cy");
+            int cy = (int)dw_window_get_data(hWnd, "_dw_cy");
             RECTL rect;
 
-         WinQueryWindowRect(client, &rect);
-
-         if(msg == WM_VSCROLL)
-         {
-            page = rect.yTop - rect.yBottom;
-            handle = vscroll;
+            WinQueryWindowRect(client, &rect);
+
+            if(msg == WM_VSCROLL)
+            {
+                page = rect.yTop - rect.yBottom;
+                handle = vscroll;
                 pos = &vpos;
-         }
-         else
-         {
-            page = rect.xRight - rect.xLeft;
-            handle = hscroll;
+            }
+            else
+            {
+                page = rect.xRight - rect.xLeft;
+                handle = hscroll;
                 pos = &hpos;
-         }
-
-         res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
-         min = SHORT1FROMMP(res);
-         max = SHORT2FROMMP(res);
-
-         switch(which)
-         {
-         case SB_SLIDERTRACK:
+            }
+
+            res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
+            min = SHORT1FROMMP(res);
+            max = SHORT2FROMMP(res);
+
+            switch(which)
+            {
+            case SB_SLIDERTRACK:
                 *pos = SHORT1FROMMP(mp2);
                 break;
-         case SB_LINEUP:
-            (*pos)--;
-            if(*pos < min)
-               *pos = min;
+            case SB_LINEUP:
+                (*pos)--;
+                if(*pos < min)
+                    *pos = min;
                 break;
-         case SB_LINEDOWN:
-            (*pos)++;
-            if(*pos > max)
-               *pos = max;
+            case SB_LINEDOWN:
+                (*pos)++;
+                if(*pos > max)
+                    *pos = max;
                 break;
-         case SB_PAGEUP:
-            (*pos) -= page;
-            if(*pos < min)
-               *pos = min;
+            case SB_PAGEUP:
+                (*pos) -= page;
+                if(*pos < min)
+                    *pos = min;
                 break;
-         case SB_PAGEDOWN:
-            (*pos) += page;
-            if(*pos > max)
-               *pos = max;
-            break;
-         }
+            case SB_PAGEDOWN:
+                (*pos) += page;
+                if(*pos > max)
+                    *pos = max;
+                break;
+            }
             WinSendMsg(handle, SBM_SETPOS, (MPARAM)*pos, 0);
             /* Position the scrolled box */
             WinSetWindowPos(box, HWND_TOP, -hpos, -(cy - vpos), 0, 0, SWP_MOVE);
-         break;
-      }
-   }
-   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+            break;
+        }
+    }
+    return WinDefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 void _click_default(HWND handle)
 {
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    WinQueryClassName(handle, 99, (PCH)tmpbuf);
 
@@ -2053,7 +2323,7 @@
       {
          if(tmp->message == WM_COMMAND)
          {
-            int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+            int (API_FUNC clickfunc)(HWND, void *) = (int (API_FUNC)(HWND, void *))tmp->signalfunction;
 
             /* Make sure it's the right window, and the right ID */
             if(tmp->window == handle)
@@ -2076,6 +2346,103 @@
 #define ENTRY_UNDO  60904
 #define ENTRY_SALL  60905
 
+#ifdef UNICODE
+void _combine_text(HWND handle, USHORT pos1, char *text, char *pastetext)
+{
+    char *combined = calloc((text ? strlen(text) : 0) + strlen(pastetext) + 1, 1);
+    SHORT newsel = pos1 + strlen(pastetext);
+
+    /* Combine the two strings into 1... or just use pastetext if no text */
+    if(text)
+        strncpy(combined, text, pos1);
+    strcat(combined, pastetext);
+    if(text && pos1 < strlen(text))
+        strcat(combined, &text[pos1]);
+
+    /* Set the new combined text to the entryfield */
+    dw_window_set_text(handle, combined);
+    /* Move the cursor to the old selection start plus paste length */
+    WinSendMsg(handle, EM_SETSEL, MPFROM2SHORT(newsel, newsel), 0);
+    /* Free temporary memory */
+    free(combined);
+}
+
+/* Internal function to handle Unicode enabled MLE cut, copy and paste */
+void _MleCopyPaste(HWND hWnd, int command)
+{
+    /* MLE insertion points (for querying selection) */
+    IPT ipt1, ipt2;
+
+    /* Get the selected text */
+    ipt1 = (IPT)WinSendMsg(hWnd, MLM_QUERYSEL, MPFROMSHORT(MLFQS_MINSEL), 0);
+    ipt2 = (IPT)WinSendMsg(hWnd, MLM_QUERYSEL, MPFROMSHORT(MLFQS_MAXSEL), 0);
+
+    /* Get the selection and put on clipboard for copy and cut */
+    if(command != ENTRY_PASTE)
+    {
+        char *text = (char *)malloc((ULONG)WinSendMsg(hWnd, MLM_QUERYFORMATTEXTLENGTH, MPFROMLONG(ipt1), MPFROMLONG(ipt2 - ipt1)) + 1);
+        ULONG ulCopied = (ULONG)WinSendMsg(hWnd, MLM_QUERYSELTEXT, MPFROMP(text), 0);
+
+        dw_clipboard_set_text(text, ulCopied);
+        free(text);
+    }
+    /* Clear selection for cut and paste */
+    if(command != ENTRY_COPY)
+        WinSendMsg(hWnd, MLM_CLEAR, 0, 0);
+    if(command == ENTRY_PASTE)
+    {
+        char *text = dw_clipboard_get_text();
+
+        if(text)
+        {
+            WinSendMsg(hWnd, MLM_INSERT, MPFROMP(text), 0);
+            dw_free(text);
+        }
+    }
+}
+
+/* Internal function to handle Unicode enabled Entryfield cut, copy and paste */
+void _EntryCopyPaste(HWND handle, int command)
+{
+    /* Get the selected text */
+    char *text = dw_window_get_text(handle);
+    ULONG sel = (ULONG)WinSendMsg(handle, EM_QUERYSEL, 0, 0);
+    SHORT pos1 = SHORT1FROMMP(sel), pos2 = SHORT2FROMMP(sel);
+
+    /* Get the selection and put on clipboard for copy and cut */
+    if(text)
+    {
+        if(command != ENTRY_PASTE)
+        {
+            if(pos2 > pos1)
+            {
+                text[pos2] = 0;
+
+                dw_clipboard_set_text(&text[pos1], pos2 - pos1);
+            }
+        }
+        free(text);
+    }
+    /* Clear selection for cut and paste */
+    if(command != ENTRY_COPY)
+        WinSendMsg(handle, EM_CLEAR, 0, 0);
+    text = dw_window_get_text(handle);
+    if(command == ENTRY_PASTE)
+    {
+        char *pastetext = dw_clipboard_get_text();
+
+        if(pastetext)
+        {
+            _combine_text(handle, pos1, text, pastetext);
+            /* Free temporary memory */
+            dw_free(pastetext);
+        }
+    }
+    if(text)
+        free(text);
+}
+#endif
+
 /* Originally just intended for entryfields, it now serves as a generic
  * procedure for handling TAB presses to change input focus on controls.
  */
@@ -2083,13 +2450,16 @@
 {
    WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
    PFNWP oldproc = 0;
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    if(blah)
       oldproc = blah->oldproc;
 
    WinQueryClassName(hWnd, 99, (PCH)tmpbuf);
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
    /* These are the window classes which should get a menu */
    if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
       strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
@@ -2098,6 +2468,26 @@
    {
       switch(msg)
       {
+#ifdef UNICODE
+      case MLM_PASTE:
+          _MleCopyPaste(hWnd, ENTRY_PASTE);
+          return (MRESULT)TRUE;
+      case MLM_CUT:
+          _MleCopyPaste(hWnd, ENTRY_CUT);
+          return (MRESULT)TRUE;
+      case MLM_COPY:
+          _MleCopyPaste(hWnd, ENTRY_COPY);
+          return (MRESULT)TRUE;
+      case EM_PASTE:
+          _EntryCopyPaste(hWnd, ENTRY_PASTE);
+          return (MRESULT)TRUE;
+      case EM_CUT:
+          _EntryCopyPaste(hWnd, ENTRY_CUT);
+          return (MRESULT)TRUE;
+      case EM_COPY:
+          _EntryCopyPaste(hWnd, ENTRY_COPY);
+          return (MRESULT)TRUE;
+#endif
       case WM_CONTEXTMENU:
          {
             HMENUI hwndMenu = dw_menu_new(0L);
@@ -2188,11 +2578,11 @@
       }
       break;
    case WM_CONTROL:
-      {
-         if(strncmp(tmpbuf, "#38", 4)==0)
-            _run_event(hWnd, msg, mp1, mp2);
-      }
-      break;
+       {
+           if(strncmp(tmpbuf, "#38", 4)==0)
+               _run_event(hWnd, msg, mp1, mp2);
+       }
+       break;
    case WM_SETFOCUS:
       _run_event(hWnd, msg, mp1, mp2);
       break;
@@ -2214,7 +2604,52 @@
        */
       else if(SHORT1FROMMP(mp2) == 283)
          return (MRESULT)TRUE;
-
+#ifdef UNICODE
+      else if(!SHORT1FROMMP(mp2))
+      {
+          UniChar uc[2] = {0};
+          VDKEY vdk;
+          BYTE bscan;
+          char *utf8;
+
+          UniTranslateKey(Keyboard, SHORT1FROMMP(mp1) & KC_SHIFT  ? 1 : 0, CHAR4FROMMP(mp1), uc, &vdk, &bscan);
+
+          if((utf8 = _WideToUTF8(uc)) != NULL)
+          {
+              if(*utf8)
+              {
+                  /* MLE */
+                  if(strncmp(tmpbuf, "#10", 4)==0)
+                  {
+                      WinSendMsg(hWnd, MLM_INSERT, MPFROMP(utf8), 0);
+                  }
+                  else /* Other */
+                  {
+                      HWND handle = hWnd;
+
+                      /* Get the entryfield handle from multi window controls */
+                      if(strncmp(tmpbuf, "#2", 3)==0)
+                          handle = WinWindowFromID(hWnd, 667);
+
+                      if(handle)
+                      {
+                          char *text = dw_window_get_text(handle);
+                          ULONG sel = (ULONG)WinSendMsg(hWnd, EM_QUERYSEL, 0, 0);
+                          SHORT pos1 = SHORT1FROMMP(sel);
+
+                           WinSendMsg(handle, EM_CLEAR, 0, 0);
+                          _combine_text(handle, pos1, text, utf8);
+
+                          if(text)
+                              free(text);
+                      }
+                  }
+              }
+              free(utf8);
+          }
+          return (MRESULT)TRUE;
+      }
+#endif
       break;
    case WM_SIZE:
       {
@@ -2246,6 +2681,9 @@
 {
    WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -2254,6 +2692,11 @@
       break;
    case WM_CONTEXTMENU:
    case WM_COMMAND:
+#ifdef UNICODE
+   case EM_PASTE:
+   case EM_CUT:
+   case EM_COPY:
+#endif
       return _entryproc(hWnd, msg, mp1, mp2);
    case WM_SETFOCUS:
       _run_event(hWnd, msg, mp1, mp2);
@@ -2299,6 +2742,9 @@
    if(blah)
       oldproc = blah->oldproc;
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -2307,7 +2753,12 @@
       break;
    case WM_CONTEXTMENU:
    case WM_COMMAND:
-      return _entryproc(hWnd, msg, mp1, mp2);
+#ifdef UNICODE
+   case EM_PASTE:
+   case EM_CUT:
+   case EM_COPY:
+#endif
+       return _entryproc(hWnd, msg, mp1, mp2);
    }
 
    if(oldproc)
@@ -2348,6 +2799,9 @@
    if(blah)
       oldproc = blah->oldproc;
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -2379,6 +2833,9 @@
    if(blah)
       oldproc = blah->oldproc;
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hWnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -2577,7 +3034,7 @@
             {
                if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
                {
-                  int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+                  int (API_FUNC setfocusfunc)(HWND, void *) = (int (API_FUNC)(HWND, void *))tmp->signalfunction;
 
                   if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
                   {
@@ -2589,7 +3046,7 @@
             break;
          case WM_TIMER:
             {
-               int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
+               int (API_FUNC timerfunc)(void *) = (int (API_FUNC)(void *))tmp->signalfunction;
                if(tmp->id == (int)mp1)
                {
                   if(!timerfunc(tmp->data))
@@ -2601,7 +3058,7 @@
             break;
          case WM_SIZE:
             {
-               int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
+               int (API_FUNC sizefunc)(HWND, int, int, void *) = (int (API_FUNC)(HWND, int, int, void *))tmp->signalfunction;
 
                if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2))
                {
@@ -2613,7 +3070,7 @@
          case WM_BUTTON1DOWN:
             {
                POINTS pts = (*((POINTS*)&mp1));
-               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+               int (API_FUNC buttonfunc)(HWND, int, int, int, void *) = (int (API_FUNC)(HWND, int, int, int, void *))tmp->signalfunction;
 
                if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
                {
@@ -2640,7 +3097,7 @@
          case WM_BUTTON1UP:
             {
                POINTS pts = (*((POINTS*)&mp1));
-               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+               int (API_FUNC buttonfunc)(HWND, int, int, int, void *) = (int (API_FUNC)(HWND, int, int, int, void *))tmp->signalfunction;
 
                if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
                {
@@ -2666,7 +3123,7 @@
             break;
          case WM_MOUSEMOVE:
             {
-               int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+               int (API_FUNC motionfunc)(HWND, int, int, int, void *) = (int (API_FUNC)(HWND, int, int, int, void *))tmp->signalfunction;
 
                if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
                {
@@ -2687,15 +3144,23 @@
             break;
          case WM_CHAR:
             {
-               int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction;
-
-               if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
-               {
+                int (API_FUNC keypressfunc)(HWND, char, int, int, void *, char *) = (int (API_FUNC)(HWND, char, int, int, void *, char *))tmp->signalfunction;
+
+                if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
+                {
                   int vk;
-                  char ch = 0;
+                  char ch[2] = {0};
+                  char *utf8 = NULL;
+#ifdef UNICODE
+                  UniChar uc[2] = {0};
+                  VDKEY vdk;
+                  BYTE bscan;
+                  UniTranslateKey(Keyboard, SHORT1FROMMP(mp1) & KC_SHIFT  ? 1 : 0, CHAR4FROMMP(mp1), uc, &vdk, &bscan);
+                  utf8 = _WideToUTF8(uc);
+#endif
 
                   if(SHORT1FROMMP(mp1) & KC_CHAR)
-                     ch = (char)SHORT1FROMMP(mp2);
+                     ch[0] = (char)SHORT1FROMMP(mp2);
                   if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
                      vk = SHORT2FROMMP(mp2);
                   else
@@ -2704,21 +3169,24 @@
                   /* This is a hack to fix shift presses showing
                    * up as tabs!
                    */
-                  if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
+                  if(ch[0] == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
                   {
-                     ch = 0;
+                     ch[0] = 0;
                      vk = VK_SHIFT;
                   }
 
-                  result = keypressfunc(tmp->window, ch, vk,
-                                   SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data);
+                  result = keypressfunc(tmp->window, ch[0], vk,
+                                        SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data, utf8 ? utf8 : ch);
                   tmp = NULL;
+
+                  if(utf8)
+                      free(utf8);
                }
             }
             break;
          case WM_CLOSE:
             {
-               int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+               int (API_FUNC closefunc)(HWND, void *) = (int (API_FUNC)(HWND, void *))tmp->signalfunction;
 
                if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
                {
@@ -2733,7 +3201,7 @@
             {
                HPS hps;
                DWExpose exp;
-               int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction;
+               int (API_FUNC exposefunc)(HWND, DWExpose *, void *) = (int (API_FUNC)(HWND, DWExpose *, void *))tmp->signalfunction;
                RECTL  rc;
 
                if(hWnd == tmp->window)
@@ -2742,7 +3210,7 @@
 
                   hps = WinBeginPaint(hWnd, 0L, &rc);
                   exp.x = rc.xLeft;
-                  exp.y = height - rc.yTop - 1;
+                  exp.y = height - rc.yTop;
                   exp.width = rc.xRight - rc. xLeft;
                   exp.height = rc.yTop - rc.yBottom;
                   result = exposefunc(hWnd, &exp, tmp->data);
@@ -2752,7 +3220,7 @@
             break;
          case WM_COMMAND:
             {
-               int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+               int (API_FUNC clickfunc)(HWND, void *) = (int (API_FUNC)(HWND, void *))tmp->signalfunction;
                ULONG command = COMMANDMSG(&msg)->cmd;
 
                if(tmp->id && command == tmp->id)
@@ -2774,20 +3242,24 @@
             break;
          case WM_CONTROL:
             if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
-               (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
+               (tmp->message == SLN_SLIDERTRACK && (SHORT2FROMMP(mp1) == SLN_CHANGE || SHORT2FROMMP(mp1) == SPBN_CHANGE)))
             {
                int svar = SLN_SLIDERTRACK;
                int id = SHORT1FROMMP(mp1);
                HWND notifyhwnd = dw_window_from_id(hWnd, id);
 
                if(origmsg == WM_CONTROL)
-                  svar = SHORT2FROMMP(mp1);
+               {
+                   svar = SHORT2FROMMP(mp1);
+                   if(!notifyhwnd && WinIsWindow(dwhab, (HWND)mp2))
+                       notifyhwnd = (HWND)mp2;
+               }
 
                switch(svar)
                {
                case CN_ENTER:
                   {
-                     int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction;
+                     int (API_FUNC containerselectfunc)(HWND, char *, void *) = (int (API_FUNC)(HWND, char *, void *))tmp->signalfunction;
                      char *text = NULL;
 
                      if(mp2)
@@ -2808,7 +3280,7 @@
                   break;
                case CN_EXPANDTREE:
                   {
-                     int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
+                     int (API_FUNC treeexpandfunc)(HWND, HTREEITEM, void *) = (int (API_FUNC)(HWND, HTREEITEM, void *))tmp->signalfunction;
 
                      if(tmp->window == notifyhwnd)
                      {
@@ -2819,7 +3291,7 @@
                   break;
                case CN_CONTEXTMENU:
                   {
-                     int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
+                     int (API_FUNC containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (API_FUNC)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
                      char *text = NULL;
                      void *user = NULL;
                      LONG x,y;
@@ -2884,7 +3356,7 @@
 
                               if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
                               {
-                                 int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
+                                 int (API_FUNC treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (API_FUNC)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
 
                                  if(dw_window_get_data(tmp->window, "_dw_container"))
                                     result = treeselectfunc(tmp->window, 0, (char *)pci->rc.pszIcon, tmp->data, 0);
@@ -2916,9 +3388,10 @@
 
                      WinQueryClassName(tmp->window, 99, (PCH)classbuf);
 
+                     /* Slider/Percent */
                      if(strncmp(classbuf, "#38", 4) == 0)
                      {
-                        int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+                        int (API_FUNC valuechangedfunc)(HWND, int, void *) = (int (API_FUNC)(HWND, int, void *))tmp->signalfunction;
 
                         if(tmp->window == hWnd || tmp->window == notifyhwnd)
                         {
@@ -2936,7 +3409,7 @@
                      }
                      else
                      {
-                        int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction;
+                        int (API_FUNC listboxselectfunc)(HWND, int, void *) = (int (API_FUNC)(HWND, int, void *))tmp->signalfunction;
                         static int _recursing = 0;
 
                         if(_recursing == 0 && (tmp->window == notifyhwnd || (!id && tmp->window == (HWND)mp2)))
@@ -2948,6 +3421,7 @@
 
                            _recursing = 1;
 
+                           /* Combobox */
                            if(id && strncmp(classbuf, "#2", 3)==0)
                            {
                               char *buf2;
@@ -2972,9 +3446,25 @@
                      }
                   }
                   break;
+               case SPBN_CHANGE:
+                  {
+                     int (API_FUNC valuechangedfunc)(HWND, int, void *) = (int (API_FUNC)(HWND, int, void *))tmp->signalfunction;
+
+                     if(origmsg == WM_CONTROL && tmp->message == SLN_SLIDERTRACK)
+                     {
+                        /* Handle Spinbutton control */
+                        if(tmp->window == hWnd || tmp->window == notifyhwnd)
+                        {
+                            int position = dw_spinbutton_get_pos(tmp->window);
+                            result = valuechangedfunc(tmp->window, position, tmp->data);
+                            tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
                case SLN_SLIDERTRACK:
                   {
-                     int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+                     int (API_FUNC valuechangedfunc)(HWND, int, void *) = (int (API_FUNC)(HWND, int, void *))tmp->signalfunction;
 
                      if(origmsg == WM_CONTROL)
                      {
@@ -3018,7 +3508,7 @@
 
                      if(psn && tmp->window == psn->hwndBook)
                      {
-                        int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction;
+                        int (API_FUNC switchpagefunc)(HWND, unsigned long, void *) = (int (API_FUNC)(HWND, unsigned long, void *))tmp->signalfunction;
 
                         result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data);
                         tmp = NULL;
@@ -3035,6 +3525,12 @@
          tmp = tmp->next;
 
    }
+   if(result != -1)
+   {
+      /* Make sure any queued redraws are handled */
+      _dw_redraw(0, FALSE);
+      /* Then finally return */
+   }
    return (MRESULT)result;
 }
 
@@ -3104,20 +3600,35 @@
             _dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF));
       }
       break;
+   case WM_USER:
+       _run_event(hWnd, WM_CONTROL, mp1, mp2);
+       break;
    case WM_CONTROL:
-      if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN))
-      {
-         HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
-
-         if(window && !dw_window_get_data(window, "_dw_updating"))
-         {
-            unsigned long val = _dw_color_spin_get(window);
-            HWND col = (HWND)dw_window_get_data(window, "_dw_col");
-
-            _dw_col_set(col, val);
-         }
-      }
-      _run_event(hWnd, msg, mp1, mp2);
+       {
+           char tmpbuf[100];
+
+           WinQueryClassName((HWND)mp2, 99, (PCH)tmpbuf);
+           /* Don't set the ownership if it's an entryfield or spinbutton  */
+           if(strncmp(tmpbuf, "#32", 4)==0)
+           {
+               if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN))
+               {
+                   HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
+
+                   if(window && !dw_window_get_data(window, "_dw_updating"))
+                   {
+                       unsigned long val = _dw_color_spin_get(window);
+                       HWND col = (HWND)dw_window_get_data(window, "_dw_col");
+
+                       _dw_col_set(col, val);
+                   }
+               }
+               if(!dw_window_get_data((HWND)mp2, "_dw_updating"))
+                   WinPostMsg(hWnd, WM_USER, mp1, mp2);
+           }
+           else
+               _run_event(hWnd, msg, mp1, mp2);
+      }
       break;
    }
 
@@ -3132,7 +3643,7 @@
 {
    int result = -1;
    static int command_active = 0;
-   void (* API windowfunc)(PVOID) = 0L;
+   void (API_FUNC windowfunc)(PVOID) = 0L;
 
    if(!command_active)
    {
@@ -3282,7 +3793,7 @@
       }
       return MRFROMSHORT(FALSE);
    case WM_USER:
-      windowfunc = (void (* API)(void *))mp1;
+      windowfunc = (void (API_FUNC)(void *))mp1;
 
       if(windowfunc)
          windowfunc((void *)mp2);
@@ -3533,60 +4044,6 @@
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
-/* Function: BubbleProc
- * Abstract: Subclass procedure for bubble help
- */
-MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-   MRESULT res;
-   PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
-
-   if(proc)
-      res = proc(hwnd, msg, mp1, mp2);
-   else
-      res = WinDefWindowProc(hwnd, msg, mp1, mp2);
-
-   if(msg == WM_PAINT)
-   {
-      POINTL ptl;
-      HPS hpsTemp;
-      RECTL rcl;
-      int height, width;
-
-      WinQueryWindowRect(hwnd, &rcl);
-      height = rcl.yTop - rcl.yBottom - 1;
-      width = rcl.xRight - rcl.xLeft - 1;
-
-      /* Draw a border around the bubble help */
-      hpsTemp = WinGetPS(hwnd);
-      GpiSetColor(hpsTemp, CLR_BLACK);
-      ptl.x = ptl.y = 0;
-      GpiMove(hpsTemp, &ptl);
-      ptl.x = 0;
-      ptl.y = height;
-      GpiLine(hpsTemp, &ptl);
-      ptl.x = ptl.y = 0;
-      GpiMove(hpsTemp, &ptl);
-      ptl.y = 0;
-      ptl.x = width;
-      GpiLine(hpsTemp, &ptl);
-      ptl.x = width;
-      ptl.y = height;
-      GpiMove(hpsTemp, &ptl);
-      ptl.x = 0;
-      ptl.y = height;
-      GpiLine(hpsTemp, &ptl);
-      ptl.x = width;
-      ptl.y = height;
-      GpiMove(hpsTemp, &ptl);
-      ptl.y = 0;
-      ptl.x = width;
-      GpiLine(hpsTemp, &ptl);
-      WinReleasePS(hpsTemp);
-   }
-   return res;
-}
-
 MRESULT EXPENTRY _button_draw(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, PFNWP oldproc, int indent)
 {
    HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap");
@@ -3595,6 +4052,7 @@
    MRESULT res;
    unsigned long width, height;
    int x = 5, y = 5;
+   ULONG style = WinQueryWindowULong(hwnd, QWL_STYLE);
 
    dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height);
 
@@ -3612,33 +4070,62 @@
       if(dw_window_get_data(hwnd, "_dw_disabled"))
          halftone = DP_HALFTONED;
 
-      cx = width - 10;
-      cy = height - 10;
+      /* If there is a border take that into account */
+      if(style & BS_NOBORDER)
+      {
+          cx = width;
+          cy = height;
+      }
+      else
+      {
+          cx = width - 8;
+          cy = height - 8;
+      }
 
       if(WinQueryPointerInfo(icon, &pi))
       {
          BITMAPINFOHEADER sl;
          int newcx = cx, newcy = cy;
 
+         sl.cbFix = sizeof(BITMAPINFOHEADER);
+
          /* Check the mini icon first */
          if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl))
          {
-            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
-            {
-               newcx = sl.cx;
-               newcy = sl.cy;
-            }
+             if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
+             {
+                 newcx = sl.cx;
+                 newcy = sl.cy;
+             }
          }
          /* Check the normal icon second */
          if(GpiQueryBitmapParameters(pi.hbmColor, &sl))
          {
-            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
-            {
-               newcx = sl.cx;
-               newcy = sl.cy;
-            }
+             if(sl.cx && sl.cy)
+             {
+                 if(cx > sl.cx && cy > sl.cy)
+                 {
+                     newcx = sl.cx;
+                     newcy = sl.cy;
+                 }
+                 /* In case there was no mini icon... cut it in half */
+                 else if(cx >= (sl.cx/2) && cy >= (sl.cy/2))
+                 {
+                     newcx = sl.cx/2;
+                     newcy = sl.cy/2;
+                 }
+             }
          }
          cx = newcx; cy = newcy;
+         /* Safety check to avoid icon dimension stretching */
+         if(cx != cy)
+         {
+             if(cx > cy)
+                 cx = cy;
+             else
+                 cy = cx;
+         }
+         /* Finally center it in the window */
          x = (width - cx)/2;
          y = (height - cy)/2;
       }
@@ -3664,15 +4151,17 @@
 
 MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-   BubbleButton *bubble;
+   WindowData *blah = WinQueryWindowPtr(hwnd, QWL_USER);
    PFNWP oldproc;
-
-   bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
-
-   if(!bubble)
+   int retval = -1;
+
+   if(!blah)
       return WinDefWindowProc(hwnd, msg, mp1, mp2);
 
-   oldproc = bubble->pOldProc;
+   oldproc = blah->oldproc;
+
+   if(blah->bubbletext[0])
+       _TooltipProc(hwnd, msg, mp1, mp2, blah);
 
    switch(msg)
    {
@@ -3741,14 +4230,14 @@
       break;
    case WM_USER:
       {
-            SignalHandler *tmp = (SignalHandler *)mp1;
-         int (* API clickfunc)(HWND, void *) = NULL;
+         SignalHandler *tmp = (SignalHandler *)mp1;
+         int (API_FUNC clickfunc)(HWND, void *) = NULL;
 
          if(tmp)
          {
-            clickfunc = (int (* API)(HWND, void *))tmp->signalfunction;
-
-            clickfunc(tmp->window, tmp->data);
+            clickfunc = (int (API_FUNC)(HWND, void *))tmp->signalfunction;
+
+            retval = clickfunc(tmp->window, tmp->data);
          }
       }
         break;
@@ -3798,97 +4287,11 @@
          }
       }
       break;
-   case 0x041f:
-      if (hwndBubble)
-      {
-         WinDestroyWindow(hwndBubble);
-         hwndBubble = 0;
-      }
-      break;
-
-   case 0x041e:
-
-      if(!*bubble->bubbletext)
-         break;
-
-      if(hwndBubble)
-      {
-         WinDestroyWindow(hwndBubble);
-         hwndBubble = 0;
-      }
-
-      if(!hwndBubble)
-      {
-         HPS   hpsTemp = 0;
-         LONG  lHight;
-         LONG  lWidth;
-         POINTL txtPointl[TXTBOX_COUNT];
-         POINTL ptlWork = {0,0};
-         ULONG ulColor = CLR_YELLOW;
-         void *blah;
-
-         hwndBubbleLast   = hwnd;
-         hwndBubble = WinCreateWindow(HWND_DESKTOP,
-                               WC_STATIC,
-                               NULL,
-                               SS_TEXT |
-                               DT_CENTER |
-                               DT_VCENTER,
-                                         0,0,0,0,
-                               HWND_DESKTOP,
-                               HWND_TOP,
-                               0,
-                               NULL,
-                               NULL);
-
-         WinSetPresParam(hwndBubble,
-                     PP_FONTNAMESIZE,
-                     strlen(DefaultFont)+1,
-                     DefaultFont);
-
-
-         WinSetPresParam(hwndBubble,
-                     PP_BACKGROUNDCOLORINDEX,
-                     sizeof(ulColor),
-                     &ulColor);
-
-         WinSetWindowText(hwndBubble,
-                      (PSZ)bubble->bubbletext);
-
-         WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
-
-         hpsTemp = WinGetPS(hwndBubble);
-         GpiQueryTextBox(hpsTemp,
-                     strlen(bubble->bubbletext),
-                     (PCH)bubble->bubbletext,
-                     TXTBOX_COUNT,
-                     txtPointl);
-         WinReleasePS(hpsTemp);
-
-         lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
-            txtPointl[TXTBOX_TOPLEFT ].x + 8;
-
-         lHight = txtPointl[TXTBOX_TOPLEFT].y -
-            txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
-
-         ptlWork.y -= lHight;
-
-         blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
-
-         if(blah)
-            WinSetWindowPtr(hwndBubble, QWP_USER, blah);
-
-         WinSetWindowPos(hwndBubble,
-                     HWND_TOP,
-                     ptlWork.x,
-                     ptlWork.y,
-                     lWidth,
-                     lHight,
-                     SWP_SIZE | SWP_MOVE | SWP_SHOW);
-      }
-      break;
-   }
-
+   }
+   
+   /* Make sure windows are up-to-date */
+   if(retval != -1)
+      _dw_redraw(0, FALSE);
    if(!oldproc)
       return WinDefWindowProc(hwnd, msg, mp1, mp2);
    return oldproc(hwnd, msg, mp1, mp2);
@@ -3896,8 +4299,12 @@
 
 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
 {
-   int res = 0;
-   res = (int)_run_event(hwnd, msg, mp1, mp2);
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER);
+   int res = (int)_run_event(hwnd, msg, mp1, mp2);
+
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hwnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -3923,6 +4330,9 @@
    if(blah)
       oldproc = blah->oldproc;
 
+   if(blah && blah->bubbletext[0])
+       _TooltipProc(hwnd, msg, mp1, mp2, blah);
+
    switch(msg)
    {
    case WM_MOUSEMOVE:
@@ -3974,6 +4384,42 @@
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
+#ifdef UNICODE
+/* Internal function to detect the active keyboard layout */
+UniChar *_detect_keyb(void)
+{
+    HFILE handle;
+    struct
+    {
+        USHORT length;
+        USHORT codepage;
+        CHAR   strings[8];
+    } kd;
+    ULONG action;
+    UniChar *buf = NULL;
+
+    if(DosOpen((PSZ)"KBD$", &handle, &action, 0, 0,
+               OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+               OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE,
+               NULL) == 0)
+    {
+        ULONG plen = 0, dlen = sizeof(kd);
+
+        kd.length = dlen;
+
+        if(DosDevIOCtl(handle, 4, 0x7b, NULL, plen, &plen,
+                       &kd, dlen, &dlen) == 0 && strlen(kd.strings) > 0)
+        {
+
+            /* Convert to Unicode */
+            buf = _UTF8toWide(kd.strings);
+        }
+        DosClose (handle);
+    }
+    return buf;
+}
+#endif
+
 /*
  * Initializes the Dynamic Windows engine.
  * Parameters:
@@ -3984,18 +4430,68 @@
 {
    APIRET rc;
    char objnamebuf[300] = "";
-
-   argc = argc; /* keep compiler happy */
-   argv = argv; /* keep compiler happy */
+   int x;
+   struct tm thistm = { 0 };
+
+   /* Setup the private data directory */
+   if(argc > 0 && argv[0])
+   {
+      char *pos = strrchr(argv[0], '\\');
+      
+      /* Just to be safe try the unix style */
+      if(!pos)
+         pos = strrchr(argv[0], '/');
+         
+      if(pos)
+         strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0]));
+   }
+   /* If that failed... just get the current directory */
+   if(!_dw_exec_dir[0])
+      _getcwd(_dw_exec_dir, MAX_PATH);
+      
    if(newthread)
    {
+#ifdef UNICODE
+      UniChar *kbd;
+      UniChar  suCodepage[MAX_CP_SPEC];    /* conversion specifier */
+#endif
       dwhab = WinInitialize(0);
       dwhmq = WinCreateMsgQueue(dwhab, 0);
+#ifdef UNICODE
+      /* Create the conversion object */
+      UniMapCpToUcsCp(1208, suCodepage, MAX_CP_NAME);
+      UniStrcat(suCodepage, (UniChar *) L"@map=cdra,path=no");
+      UniCreateUconvObject(suCodepage, &Uconv);
+      /* Create the Unicode atom for copy and paste */
+      Unicode = WinAddAtom(WinQuerySystemAtomTable(), (PSZ)"text/unicode");
+      /* Figure out how to determine the correct keyboard here */
+      kbd = _detect_keyb();
+      /* Default to US if could not detect */
+      UniCreateKeyboard(&Keyboard, (UniChar *)kbd ? kbd : L"us", 0);
+      /* Free temporary memory */
+      if(kbd)
+          free(kbd);
+      /* Set the codepage to 1208 (UTF-8) */
+      WinSetCp(dwhmq, 1208);
+#endif
    }
 
    rc = WinRegisterClass(dwhab, (PSZ)ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32);
    rc = WinRegisterClass(dwhab, (PSZ)SplitbarClassName, _splitwndproc, 0L, 32);
    rc = WinRegisterClass(dwhab, (PSZ)ScrollClassName, _scrollwndproc, 0L, 32);
+   rc = WinRegisterClass(dwhab, (PSZ)CalendarClassName, _calendarproc, 0L, 32);
+
+   /* Fill in the the calendar fields */
+   for(x=0;x<7;x++)
+   {
+       thistm.tm_wday = x;
+       strftime(daysofweek[x], 19, "%A", &thistm);
+   }
+   for(x=0;x<12;x++)
+   {
+       thistm.tm_mon = x;
+       strftime(months[x], 19, "%B", &thistm);
+   }
 
    /* Get the OS/2 version. */
    DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
@@ -4018,9 +4514,33 @@
    DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"WPCONFIG", &wpconfig);
    if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMPRINTF", &pmprintf))
        DosQueryProcAddr(pmprintf, 0, (PSZ)"PmPrintfString", (PFN*)&_PmPrintfString);
+   if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"PMMERGE", &pmmerge))
+       DosQueryProcAddr(pmmerge, 5469, NULL, (PFN*)&_WinQueryDesktopWorkArea);
+   if(!DosLoadModule((PSZ)objnamebuf, sizeof(objnamebuf), (PSZ)"GBM", &gbm))
+   {
+       /* Load the _System versions of the functions from the library */
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_err", (PFN*)&_gbm_err);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_init", (PFN*)&_gbm_init);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_deinit", (PFN*)&_gbm_deinit);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_io_open", (PFN*)&_gbm_io_open);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_io_close", (PFN*)&_gbm_io_close);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_data", (PFN*)&_gbm_read_data);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_header", (PFN*)&_gbm_read_header);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_read_palette", (PFN*)&_gbm_read_palette);
+       DosQueryProcAddr(gbm, 0, (PSZ)"Gbm_query_n_filetypes", (PFN*)&_gbm_query_n_filetypes);
+       /* If we got the functions, try to initialize the library */
+       if(!_gbm_init || _gbm_init())
+       {
+           /* Otherwise clear out the function pointers */
+           _gbm_init=0;_gbm_deinit=0;_gbm_io_open=0;_gbm_io_close=0;_gbm_query_n_filetypes=0;
+           _gbm_read_header=0;_gbm_read_palette=0;_gbm_read_data=0;_gbm_err=0;
+       }
+   }
    return rc;
 }
 
+static int _dw_main_running = FALSE;
+
 /*
  * Runs a message loop for Dynamic Windows.
  */
@@ -4029,16 +4549,27 @@
    QMSG qmsg;
 
    _dwtid = dw_thread_id();
-
-   while(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   /* Make sure any queued redraws are handled */
+   _dw_redraw(0, FALSE);
+
+   /* Set the running flag to TRUE */
+   _dw_main_running = TRUE;
+   
+   /* Run the loop until the flag is unset... or error */
+   while(_dw_main_running && WinGetMsg(dwhab, &qmsg, 0, 0, 0))
    {
       if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
          _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
       WinDispatchMsg(dwhab, &qmsg);
    }
-
-   WinDestroyMsgQueue(dwhmq);
-   WinTerminate(dwhab);
+}
+
+/*
+ * Causes running dw_main() to return.
+ */
+void API dw_main_quit(void)
+{
+    _dw_main_running = FALSE;
 }
 
 /*
@@ -4181,14 +4712,25 @@
 void API dw_debug(char *format, ...)
 {
    va_list args;
-   char outbuf[1024];
+   char outbuf[1025] = { 0 };
 
    va_start(args, format);
+#if defined(__IBMC__)
    vsprintf(outbuf, format, args);
+#else
+   vsnprintf(outbuf, 1024, format, args);
+#endif
    va_end(args);
 
    if(_PmPrintfString)
+   {
+       int len = strlen(outbuf);
+
+       /* Trim off trailing newline for PMPrintf */
+       if(len > 0 && outbuf[len-1] == '\n')
+           outbuf[len-1] = 0;
        _PmPrintfString(outbuf);
+   }
    else
        fprintf(stderr, "%s", outbuf);
 }
@@ -4204,11 +4746,15 @@
 int API dw_messagebox(char *title, int flags, char *format, ...)
 {
    va_list args;
-   char outbuf[1024];
+   char outbuf[1025] = { 0 };
    int rc;
 
    va_start(args, format);
+#if defined(__IBMC__)
    vsprintf(outbuf, format, args);
+#else
+   vsnprintf(outbuf, 1024, format, args);
+#endif
    va_end(args);
 
    rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PSZ)outbuf, (PSZ)title, 0, flags | MB_MOVEABLE);
@@ -4250,7 +4796,7 @@
  */
 int API dw_window_show(HWND handle)
 {
-   int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
+   int rc = WinShowWindow(handle, TRUE);
    HSWITCH hswitch;
    SWCNTRL swcntrl;
 
@@ -4272,27 +4818,82 @@
 
       if(blah && !(blah->flags & DW_OS2_NEW_WINDOW))
       {
+         /* Handle auto-positioning and auto-sizing */
          ULONG cx = dw_screen_width(), cy = dw_screen_height();
+         HWND parent = WinQueryWindow(handle, QW_PARENT);
          int newx, newy, changed = 0;
          SWP swp;
 
+         /* If it is an MDI window...
+          * find the MDI area.
+          */
+         if(parent && parent != desktop)
+         {
+             WinQueryWindowPos(parent, &swp);
+             cx = swp.cx;
+             cy = swp.cy;
+             /* If the MDI parent isn't visible...
+              * we can't calculate. Drop out.
+              */
+             if(cx < 1 || cy < 1)
+             {
+                 WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MOVE);
+                 return rc;
+             }
+         }
+
          blah->flags |= DW_OS2_NEW_WINDOW;
 
          WinQueryWindowPos(handle, &swp);
 
-         newx = swp.x;
-         newy = swp.y;
-
-         if((swp.x+swp.cx) > cx)
+         /* If the size is 0 then auto-size */
+         if(swp.cx == 0 || swp.cy == 0)
+         {
+             dw_window_set_size(handle, 0, 0);
+             WinQueryWindowPos(handle, &swp);
+         }
+
+         /* If the position was not set... generate a default
+          * default one in a similar pattern to SHELLPOSITION.
+          */
+         if(swp.x == -2000 || swp.y == -2000)
+         {
+             static int defaultx = 0, defaulty = 0;
+             int maxx = cx / 4, maxy = cy / 4;
+
+             defaultx += 20;
+             defaulty += 20;
+
+             if(defaultx > maxx)
+                 defaultx = 20;
+             if(defaulty > maxy)
+                 defaulty = 20;
+
+             newx = defaultx;
+             /* Account for flipped Y */
+             newy = cy - defaulty - swp.cy;
+             changed = 1;
+         }
+         else
+         {
+             newx = swp.x;
+             newy = swp.y;
+         }
+
+         /* Make sure windows shown for the first time are
+          * completely visible if possible.
+          */
+         if(swp.cx < cx && (newx+swp.cx) > cx)
          {
             newx = (cx - swp.cx)/2;
             changed = 1;
          }
-         if((swp.y+swp.cy) > cy)
+         if(swp.cy < cy && (newy+swp.cy) > cy)
          {
             newy = (cy - swp.cy)/2;
             changed = 1;
          }
+
          if(changed)
             WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE);
       }
@@ -4351,12 +4952,25 @@
  */
 int API dw_window_destroy(HWND handle)
 {
-   HWND frame, menu, parent = WinQueryWindow(handle, QW_PARENT);
-   Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
+   HWND frame, menu, parent;
 
    if(!handle)
-      return -1;
-
+      return DW_ERROR_UNKNOWN;
+
+   /* Handle special case for menu handle */
+   if(handle < 65536)
+   {
+      char buffer[30];
+
+      sprintf(buffer, "_dw_id%ld", handle);
+      menu = (HWND)dw_window_get_data(hwndApp, buffer);
+
+      if(menu && WinIsWindow(dwhab, menu))
+          return dw_menu_delete_item((HMENUI)menu, handle);
+      return DW_ERROR_UNKNOWN;
+   }
+   
+   parent = WinQueryWindow(handle, QW_PARENT);
    frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
 
    if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
@@ -4365,39 +4979,7 @@
    /* If it is a desktop window let WM_DESTROY handle it */
    if(parent != desktop)
    {
-      /* If the parent box has items... 
-       * try to remove it from the layout 
-       */
-     if(thisbox && thisbox->count)
-      {
-         int z, index = -1;
-         Item *tmpitem, *thisitem = thisbox->items;
-
-         for(z=0;z<thisbox->count;z++)
-         {
-            if(thisitem[z].hwnd == handle)
-               index = z;
-         }
-
-         if(index == -1)
-            return 0;
-
-         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-         /* Copy all but the current entry to the new list */
-         for(z=0;z<index;z++)
-         {
-            tmpitem[z] = thisitem[z];
-         }
-         for(z=index+1;z<thisbox->count;z++)
-         {
-            tmpitem[z-1] = thisitem[z];
-         }
-
-         thisbox->items = tmpitem;
-         free(thisitem);
-         thisbox->count--;
-      }
+      dw_box_unpack(handle);
       _free_window_memory(frame ? frame : handle);
    }
    return WinDestroyWindow(frame ? frame : handle);
@@ -4472,6 +5054,10 @@
             strcpy(fd.fAttrs.szFacename, currfont);
         }
     }
+#ifdef UNICODE
+    fd.fAttrs.usCodePage = 1208;
+#endif
+    fd.fAttrs.usRecordLength = sizeof(FATTRS);
 
     /* Fill in the font dialog struct */
     fd.cbSize = sizeof(fd);
@@ -4511,6 +5097,424 @@
     free(oldfont);
 }
 
+/* Internal function to return a pointer to an item struct
+ * with information about the packing information regarding object.
+ */
+Item *_box_item(HWND handle)
+{
+   HWND parent = WinQueryWindow(handle, QW_PARENT);
+   Box *thisbox = (Box *)WinQueryWindowPtr(parent, QWP_USER);   
+   
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != HWND_DESKTOP)
+   {
+      if(thisbox && thisbox->count)
+      {
+         int z;
+         Item *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               return &thisitem[z];
+         }
+      }
+   }
+   return NULL;
+}
+
+/* Internal function to calculate the widget's required size..
+ * These are the general rules for widget sizes:
+ * 
+ * Render/Unspecified: 1x1
+ * Scrolled(Container,Tree,MLE): Guessed size clamped to min and max in dw.h
+ * Entryfield/Combobox/Spinbutton: 150x(maxfontheight)
+ * Spinbutton: 50x(maxfontheight)
+ * Text/Status: (textwidth)x(textheight)
+ * Ranged: 100x14 or 14x100 for vertical.
+ * Buttons/Bitmaps: Size of text or image and border.
+ */
+void _control_size(HWND handle, int *width, int *height)
+{
+   int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0;
+   char tmpbuf[100] = {0}, *buf = dw_window_get_text(handle);
+   static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+    /* If we have a string... 
+     * calculate the size with the current font.
+     */
+    if(buf)
+    {
+       if(*buf)
+          dw_font_text_extents_get(handle, NULL, buf, &thiswidth, &thisheight);
+       dw_free(buf);
+    }
+        
+   /* Combobox */
+   if(strncmp(tmpbuf, "#2", 3)==0)
+   {
+      dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+      thiswidth = 150;
+      extraheight = 4;
+      if(thisheight < 18)
+        thisheight = 18;
+   }
+   /* Calendar */
+   else if(strncmp(tmpbuf, CalendarClassName, strlen(CalendarClassName)+1)==0)
+   {
+       thiswidth = 200;
+       thisheight = 150;
+   }
+   /* Bitmap/Static */
+   else if(strncmp(tmpbuf, "#5", 3)==0)
+   {
+       HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
+
+       /* If we got a bitmap handle */
+       if(hbm)
+       {
+            BITMAPINFOHEADER2 bmp;
+            bmp.cbFix = sizeof(BITMAPINFOHEADER2);
+            /* Get the parameters of the bitmap */
+            if(GpiQueryBitmapInfoHeader(hbm, &bmp))
+            {
+               thiswidth = bmp.cx;
+               thisheight = bmp.cy;
+            }
+       }
+       else if(dw_window_get_data(handle, "_dw_status"))
+       {
+           extrawidth = 4;
+           extraheight = 4;
+       }
+   }
+   /* Ranged: Slider/Percent */
+   else if(strncmp(tmpbuf, "#38", 4)== 0)
+   {
+       thiswidth = 100;
+       thisheight = 20;
+   }
+   /* Scrollbar */
+   else if(strncmp(tmpbuf, "#8", 3)== 0)
+   {
+      /* Check for vertical scrollbar */
+      if(WinQueryWindowULong(handle, QWL_STYLE) & SBS_VERT)
+      {
+         thiswidth = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
+         thisheight = 100;
+      }
+      else
+      {
+         thiswidth = 100;
+         thisheight = WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
+      }
+   }
+   /* Spinbutton */
+   else if(strncmp(tmpbuf, "#32", 4)==0)
+   {
+      dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+      thiswidth = 50;
+      extraheight = 6;
+   }
+   /* Entryfield */
+   else if(strncmp(tmpbuf, "#6", 3)==0)
+   {
+      dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+      thiswidth = 150;
+      extraheight = 6;
+   }
+   /* MLE */
+   else if(strncmp(tmpbuf, "#10", 4)==0)
+   {
+       unsigned long bytes;
+       int height, width;
+       char *buf, *ptr;
+       int basicwidth;
+       int wrap = (int)WinSendMsg(handle, MLM_QUERYWRAP, 0,0);
+
+       thisheight = 8;
+       basicwidth = thiswidth = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL) + 8;
+
+       dw_mle_get_size(handle, &bytes, NULL);
+
+       ptr = buf = alloca(bytes + 2);
+       dw_mle_export(handle, buf, 0, (int)bytes);
+       buf[bytes] = 0;
+       strcat(buf, "\n");
+
+       /* MLE */
+       while((ptr = strstr(buf, "\n")) != NULL)
+       {
+           ptr[0] = 0;
+           width = 0;
+           if(strlen(buf))
+               dw_font_text_extents_get(handle, NULL, buf, &width, &height);
+           else
+               dw_font_text_extents_get(handle, NULL, testtext, NULL, &height);
+
+           width += basicwidth;
+
+           if(wrap && width > _DW_SCROLLED_MAX_WIDTH)
+           {
+               thiswidth = _DW_SCROLLED_MAX_WIDTH;
+               thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH);
+
+           }
+           else
+           {
+               if(width > thiswidth)
+                   thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width;
+           }
+           thisheight += height;
+           buf = &ptr[1];
+       }
+
+       if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+           thiswidth = _DW_SCROLLED_MIN_WIDTH;
+       if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+           thisheight = _DW_SCROLLED_MIN_HEIGHT;
+       if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+           thisheight = _DW_SCROLLED_MAX_HEIGHT;
+   }
+   /* Listbox */
+   else if(strncmp(tmpbuf, "#7", 3)==0)
+   {
+      char buf[1025] = {0};
+      int x, count = dw_listbox_count(handle);
+      int basicwidth = thiswidth = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL) + 8;
+      
+      thisheight = 8;
+      
+      for(x=0;x<count;x++)
+      {
+         int height, width = 0;
+         
+         dw_listbox_get_text(handle, x, buf, 1024);
+         
+         if(strlen(buf))
+            dw_font_text_extents_get(handle, NULL, buf, &width, &height);
+         else
+            dw_font_text_extents_get(handle, NULL, testtext, NULL, &height);
+        
+         width += basicwidth;
+         
+         if(width > thiswidth)
+            thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width;
+         thisheight += height;
+      }
+      
+      if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+         thiswidth = _DW_SCROLLED_MIN_WIDTH;
+      if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+         thisheight = _DW_SCROLLED_MIN_HEIGHT;
+      if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+         thisheight = _DW_SCROLLED_MAX_HEIGHT;
+   }
+   /* Container and Tree */
+   else if(strncmp(tmpbuf, "#37", 4)==0)
+   {
+       /* Container */
+       if(dw_window_get_data(handle, "_dw_container"))
+       {
+           CNRINFO ci;
+
+           if(WinSendMsg(handle, CM_QUERYCNRINFO, MPFROMP(&ci), MPFROMSHORT(sizeof(CNRINFO))))
+           {
+               RECTL item;
+               PRECORDCORE pCore = NULL;
+               int right = FALSE, max = 0;
+               /* Get the left title window */
+               HWND title = WinWindowFromID(handle, 32752);
+
+               thiswidth = WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
+               thisheight = WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
+
+               /* If the pFieldInfoList is filled in we want to look at the right side */
+               if(ci.pFieldInfoLast)
+               {
+                   right = TRUE;
+                   /* Left side include splitbar position */
+                   thiswidth += ci.xVertSplitbar + 4;
+                   /* If split... find the right side */
+                   title = WinWindowFromID(handle, 32753);
+               }
+
+               /* If there are column titles ... */
+               if(title)
+               {
+                   unsigned long height = 0;
+
+                   dw_window_get_pos_size(title, 0, 0, 0, &height);
+                   if(height)
+                       thisheight += height;
+                   else
+                       thisheight += 28;
+               }
+
+               /* Cycle through all the records finding the maximums */
+               pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+               /* Method 1: With items in container */
+               if(pCore)
+               {
+                   while(pCore)
+                   {
+                       QUERYRECORDRECT qrr;
+                       int vector;
+
+                       qrr.cb = sizeof(QUERYRECORDRECT);
+                       qrr.pRecord = pCore;
+                       qrr.fRightSplitWindow = right;
+                       qrr.fsExtent = CMA_TEXT;
+
+                       WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
+
+                       vector = item.xRight - item.xLeft;
+
+                       if(vector > max)
+                           max = vector;
+
+                       thisheight += (item.yTop - item.yBottom);
+
+                       pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+                   }
+
+                   /* Add the widest item to the width */
+                   thiswidth += max;
+               }
+               else
+               {
+                   /* Method 2: No items */
+                   unsigned long width, height;
+                   HWND hscroll = WinWindowFromID(handle, right ? 32756 : 32755);
+                   MRESULT mr;
+
+                   /* Save the original size */
+                   dw_window_get_pos_size(handle, 0, 0, &width, &height);
+
+                   /* Set the size to the minimum */
+                   dw_window_set_size(handle, _DW_SCROLLED_MIN_WIDTH, _DW_SCROLLED_MIN_HEIGHT);
+
+                   /* With the minimum size check to see what the scrollbar says */
+                   mr = WinSendMsg(hscroll, SBM_QUERYRANGE, 0, 0);
+                   if(right)
+                       thiswidth += SHORT2FROMMP(mr);
+                   else if(SHORT2FROMMP(mr) != _DW_SCROLLED_MIN_HEIGHT)
+                       thiswidth += SHORT2FROMMP(mr) + _DW_SCROLLED_MIN_HEIGHT + WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
+
+                   /* Reload the original size */
+                   dw_window_set_size(handle, width, height);
+               }
+
+               /* Clamp to min and max */
+               if(thiswidth > _DW_SCROLLED_MAX_WIDTH)
+                   thiswidth = _DW_SCROLLED_MAX_WIDTH;
+               if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+                   thiswidth = _DW_SCROLLED_MIN_WIDTH;
+               if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+                   thisheight = _DW_SCROLLED_MIN_HEIGHT;
+               if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+                   thisheight = _DW_SCROLLED_MAX_HEIGHT;
+           }
+       }
+       else
+       {
+           /* Tree */
+           thiswidth = (int)((_DW_SCROLLED_MAX_WIDTH + _DW_SCROLLED_MIN_WIDTH)/2);
+           thisheight = (int)((_DW_SCROLLED_MAX_HEIGHT + _DW_SCROLLED_MIN_HEIGHT)/2);
+       }
+   }
+   /* Button */
+   else if(strncmp(tmpbuf, "#3", 3)==0)
+   {
+      ULONG style = WinQueryWindowULong(handle, QWL_STYLE);
+      
+      if(style & BS_AUTOCHECKBOX || style & BS_AUTORADIOBUTTON)
+      {
+         extrawidth = 24;
+         extraheight = 4;
+      }
+      else
+      {
+          /* Handle bitmap buttons */
+          if(dw_window_get_data(handle, "_dw_bitmapbutton"))
+          {
+              HPOINTER hpr = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon");
+              HBITMAP hbm = 0;
+              int iconwidth = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_button_icon_width"));
+              HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap");
+
+              /* Handle case of icon resource */
+              if(hpr)
+              {
+                  if(iconwidth)
+                      thisheight = thiswidth = iconwidth;
+                  else
+                  {
+                      POINTERINFO pi;
+
+                      /* Get the internal HBITMAP handles */
+                      if(WinQueryPointerInfo(hpr, &pi))
+                          hbm = pi.hbmColor ? pi.hbmColor : pi.hbmPointer;
+                  }
+              }
+              /* Handle case of pixmap resource */
+              else if(pixmap)
+              {
+                  thiswidth = pixmap->width;
+                  thisheight = pixmap->height;
+              }
+
+              /* If we didn't load it from the icon... */
+              if(!hbm && !iconwidth)
+              {
+                  WNDPARAMS wp;
+                  BTNCDATA bcd;
+
+                  wp.fsStatus = WPM_CTLDATA;
+                  wp.cbCtlData = sizeof(BTNCDATA);
+                  wp.pCtlData = &bcd;
+
+                  /* Query the button's bitmap */
+                  if(WinSendMsg(handle, WM_QUERYWINDOWPARAMS, (MPARAM)&wp, MPVOID) && bcd.hImage)
+                      hbm = bcd.hImage;
+              }
+
+              /* If we got a bitmap handle */
+              if(hbm)
+              {
+                  BITMAPINFOHEADER2 bmp;
+                  bmp.cbFix = sizeof(BITMAPINFOHEADER2);
+                  /* Get the parameters of the bitmap */
+                  if(GpiQueryBitmapInfoHeader(hbm, &bmp))
+                  {
+                      thiswidth = bmp.cx;
+                      thisheight = bmp.cy;
+                  }
+              }
+          }
+          else
+          {
+              extrawidth = 4;
+              extraheight = 4;
+          }
+          if(!(style & BS_NOBORDER))
+          {
+              extrawidth += 4;
+              extraheight += 4;
+          }
+      }
+   }
+
+   /* Set the requested sizes */    
+   if(width)
+      *width = thiswidth + extrawidth;
+   if(height)
+      *height = thisheight + extraheight;
+}
+
 /*
  * Sets the font used by a specified window (widget) handle.
  * Parameters:
@@ -4520,7 +5524,21 @@
 int API dw_window_set_font(HWND handle, char *fontname)
 {
    HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy");
-   return WinSetPresParam(group ? group : handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+   /* If we changed the font... */
+   if(!WinSetPresParam(group ? group : handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname))
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+          /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+      return DW_ERROR_NONE;
+   }
+   return DW_ERROR_UNKNOWN;
 }
 
 /*
@@ -4538,9 +5556,36 @@
    return NULL;
 }
 
+/* Internal function to handle transparent children */
+void _handle_transparent(HWND handle)
+{
+    ULONG pcolor, which = PP_BACKGROUNDCOLOR;;
+
+
+    if(!WinQueryPresParam(handle, which, 0, NULL, sizeof(pcolor), &pcolor, QPF_NOINHERIT))
+        which = PP_BACKGROUNDCOLORINDEX;
+
+    if(which == PP_BACKGROUNDCOLOR ||
+       WinQueryPresParam(handle, which, 0, NULL, sizeof(pcolor), &pcolor, QPF_NOINHERIT))
+    {
+        HWND child;
+        HENUM henum = WinBeginEnumWindows(handle);
+
+        while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+        {
+            if(dw_window_get_data(child, "_dw_transparent"))
+            {
+                WinSetPresParam(child, which, sizeof(pcolor), &pcolor);
+            }
+        }
+        WinEndEnumWindows(henum);
+    }
+}
+
 /* Internal version */
 int _dw_window_set_color(HWND handle, ULONG fore, ULONG back)
 {
+    /* Handle foreground */
    if((fore & DW_RGB_COLOR) == DW_RGB_COLOR)
    {
       RGB2 rgb2;
@@ -4559,7 +5604,23 @@
 
       WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore);
    }
-   if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
+   /* Handle background */
+   if(back == DW_RGB_TRANSPARENT)
+   {
+       /* Special case for setting transparent */
+       ULONG pcolor;
+       HWND parent = WinQueryWindow(handle, QW_PARENT);
+
+       dw_window_set_data(handle, "_dw_transparent", DW_INT_TO_POINTER(1));
+
+       if(WinQueryPresParam(parent, PP_BACKGROUNDCOLOR, 0, NULL,
+                            sizeof(pcolor), &pcolor, QPF_NOINHERIT | QPF_PURERGBCOLOR))
+           WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(pcolor), &pcolor);
+       else if(WinQueryPresParam(parent, PP_BACKGROUNDCOLORINDEX, 0, NULL,
+                            sizeof(pcolor), &pcolor, QPF_NOINHERIT))
+           WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(pcolor), &pcolor);
+   }
+   else if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
    {
       RGB2 rgb2;
 
@@ -4569,15 +5630,18 @@
       rgb2.fcOptions = 0;
 
       WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2);
-      return 0;
+      dw_window_set_data(handle, "_dw_transparent", NULL);
    }
    else if(back != DW_CLR_DEFAULT)
    {
       back = _internal_color(back);
 
       WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
-   }
-   return 0;
+      dw_window_set_data(handle, "_dw_transparent", NULL);
+   }
+   /* If this is a box... check if any of the children are transparent */
+   _handle_transparent(handle);
+   return DW_ERROR_NONE;
 }
 /*
  * Sets the colors used by a specified window (widget) handle.
@@ -4671,9 +5735,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;
 
@@ -4682,9 +5745,6 @@
    else
       flStyle |= FCF_TITLEBAR;
 
-   if(!(flStyle & FCF_SHELLPOSITION))
-      blah->flags |= DW_OS2_NEW_WINDOW;
-
    if(flStyle & WS_MAXIMIZED)
    {
       winStyle |= WS_MAXIMIZED;
@@ -4696,14 +5756,17 @@
       flStyle &= ~WS_MINIMIZED;
    }
 
+   /* Then create the real window window without FCF_SHELLPOSITION */
+   flStyle &= ~FCF_SHELLPOSITION;
    hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, (PSZ)ClassName, (PSZ)title, 0L, NULLHANDLE, 0L, &newbox->hwnd);
+   /* Default the window to a ridiculus place so it can't possibly be intentional */
+   WinSetWindowPos(hwndframe, NULLHANDLE, -2000, -2000, 0, 0, SWP_MOVE);
    newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR);
    if(!newbox->titlebar && newbox->hwndtitle)
       WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE);
    blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc);
    WinSetWindowPtr(hwndframe, QWP_USER, blah);
    WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
-
    return hwndframe;
 }
 
@@ -4872,7 +5935,7 @@
                         NULL,
                         WS_VISIBLE | WS_CLIPCHILDREN |
                         FS_NOBYTEALIGN,
-                        0,0,2000,1000,
+                        0,0,0,0,
                         NULLHANDLE,
                         HWND_TOP,
                         id,
@@ -4890,16 +5953,20 @@
  */
 HWND API dw_bitmap_new(ULONG id)
 {
-   return WinCreateWindow(HWND_OBJECT,
-                     WC_STATIC,
-                     NULL,
-                     WS_VISIBLE | SS_TEXT,
-                     0,0,2000,1000,
-                     NULLHANDLE,
-                     HWND_TOP,
-                     id,
-                     NULL,
-                     NULL);
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                              WC_STATIC,
+                              NULL,
+                              WS_VISIBLE | SS_TEXT,
+                              0,0,0,0,
+                              NULLHANDLE,
+                              HWND_TOP,
+                              id,
+                              NULL,
+                              NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _BitmapProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   return tmp;
 }
 
 /*
@@ -5198,6 +6265,27 @@
 }
 
 /*
+ * Deletes the menu item specified
+ * Parameters:
+ *       menu: The handle to the  menu in which the item was appended.
+ *       id: Menuitem id.
+ * Returns: 
+ *       DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure.
+ */
+int API dw_menu_delete_item(HMENUI menux, unsigned long id)
+{
+   if(id < 65536 && menux)
+   {
+      WinSendMsg(menux, MM_DELETEITEM, MPFROM2SHORT(id, FALSE), 0);
+      /* If the ID was autogenerated it is safe to remove it */
+      if(id >= 30000)
+         dw_signal_disconnect_by_window((HWND)id);
+      return DW_ERROR_NONE;
+   }
+   return DW_ERROR_UNKNOWN;
+}
+
+/*
  * Pops up a context menu at given x and y coordinates.
  * Parameters:
  *       menu: The handle the the existing menu.
@@ -5260,7 +6348,7 @@
                         WS_VISIBLE | CCS_READONLY |
                         (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) |
                         CCS_AUTOPOSITION,
-                        0,0,2000,1000,
+                        0,0,0,0,
                         NULLHANDLE,
                         HWND_TOP,
                         id ? id : _GlobalID(),
@@ -5332,7 +6420,7 @@
    blah->oldproc = WinSubclassWindow(tmp, _textproc);
    WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
-   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -5359,6 +6447,7 @@
    WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
    dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_data(tmp, "_dw_status", DW_INT_TO_POINTER(1));
    return tmp;
 }
 
@@ -5377,10 +6466,9 @@
    HWND tmp = WinCreateWindow(HWND_OBJECT,
                         WC_MLE,
                         NULL,
-                        WS_VISIBLE |
+                        WS_VISIBLE | MLS_WORDWRAP |
                         MLS_BORDER | MLS_IGNORETAB |
-                        MLS_VSCROLL |
-                        MLS_LIMITVSCROLL,
+                        MLS_VSCROLL | MLS_LIMITVSCROLL,
                         0,0,2000,1000,
                         NULLHANDLE,
                         HWND_TOP,
@@ -5499,8 +6587,7 @@
  */
 HWND API dw_button_new(char *text, ULONG id)
 {
-   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-
+   WindowData *blah = calloc(1, sizeof(WindowData));
    HWND tmp = WinCreateWindow(HWND_OBJECT,
                         WC_BUTTON,
                         (PSZ)text,
@@ -5512,11 +6599,9 @@
                         NULL,
                         NULL);
 
-   bubble->id = id;
-   bubble->bubbletext[0] = '\0';
-   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   blah->oldproc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
    dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
    return tmp;
@@ -5565,7 +6650,7 @@
 {
    char idbuf[256], *name = NULL;
    HWND tmp;
-   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   WindowData *blah = calloc(1, sizeof(WindowData));
    HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id);
 
    if(!icon)
@@ -5587,16 +6672,45 @@
                     NULL,
                     NULL);
 
-   bubble->id = id;
-   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   if(text)
+      strncpy(blah->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   blah->oldproc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, blah);
 
    if(icon)
-      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
-   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   {
+       PVOID ResPtr;
+       ULONG ResSize;
+
+       /* Since WinLoadPointer() can change the size of the icon...
+        * We will query the resource directly and check the size ourselves.
+        */
+       if(DosQueryResourceSize(NULLHANDLE, RT_POINTER, id, &ResSize) == NO_ERROR && ResSize &&
+          DosGetResource(NULLHANDLE, RT_POINTER, id, &ResPtr) == NO_ERROR)
+       {
+           PBITMAPFILEHEADER2 header = ResPtr;
+
+           /* We can only check for icons and pointers */
+           if(header->usType == 0x4943 /* Icon 'CI' */ ||
+              header->usType == 0x5043 /* Pointer 'CP' */)
+           {
+               /* Check the new style header */
+               if(header->bmp2.cbFix == sizeof(BITMAPINFOHEADER2))
+                   dw_window_set_data(tmp, "_dw_button_icon_width", DW_INT_TO_POINTER(header->bmp2.cx));
+               else if(header->bmp2.cbFix == sizeof(BITMAPINFOHEADER))
+               {
+                   /* Check the old style header */
+                   PBITMAPINFOHEADER bi = (PBITMAPINFOHEADER)&(header->bmp2);
+
+                   dw_window_set_data(tmp, "_dw_button_icon_width", DW_INT_TO_POINTER(((int)bi->cx)));
+               }
+           }
+           DosFreeResource(ResPtr);
+       }
+       dw_window_set_data(tmp, "_dw_button_icon", DW_POINTER(icon));
+   }
+   dw_window_set_data(tmp, "_dw_bitmapbutton", DW_INT_TO_POINTER(1));
    return tmp;
 }
 
@@ -5611,7 +6725,7 @@
  */
 HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
 {
-   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   WindowData *blah = calloc(1, sizeof(WindowData));
    HWND tmp = WinCreateWindow(HWND_OBJECT,
                         WC_BUTTON,
                         NULL,
@@ -5623,7 +6737,7 @@
                         id,
                         NULL,
                         NULL);
-   char *file = alloca(strlen(filename) + 5);
+   char *file = alloca(strlen(filename) + 6);
    HPIXMAP pixmap = NULL, disabled = NULL;
    HPOINTER icon = 0;
 
@@ -5643,7 +6757,7 @@
             if(stricmp(file + len - 4, ".ico") == 0)
                icon = WinLoadFileIcon((PSZ)file, FALSE);
             else
-               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth);
          }
       }
       else
@@ -5654,10 +6768,14 @@
             icon = WinLoadFileIcon((PSZ)file, FALSE);
          else
          {
-            strcpy(file, filename);
-            strcat(file, ".bmp");
-            if(access(file, 04) == 0)
-               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+            for(z=0;z<(_gbm_init?NUM_EXTS:1);z++)
+            {
+                strcpy(file, filename);
+                strcat(file, image_exts[z]);
+                if(access(file, 04) == 0 &&
+                   _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
+                    break;
+            }
          }
       }
 
@@ -5686,12 +6804,11 @@
       }
    }
 
-   bubble->id = id;
-   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   if(text)
+      strncpy(blah->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   blah->oldproc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, blah);
 
    if(icon)
       dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
@@ -5716,7 +6833,7 @@
 HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len)
 {
    FILE *fp;
-   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   WindowData *blah = calloc(1, sizeof(WindowData));
    HWND tmp = WinCreateWindow(HWND_OBJECT,
                         WC_BUTTON,
                         NULL,
@@ -5732,7 +6849,7 @@
    HPIXMAP pixmap = NULL, disabled = NULL;
    HPOINTER icon = 0;
 
-   if ( ( pixmap = calloc( 1, sizeof(struct _hpixmap) ) ) )
+   if((pixmap = calloc(1, sizeof(struct _hpixmap))) != NULL)
    {
       int z, j, lim;
       LONG fore;
@@ -5744,11 +6861,7 @@
          {
             fwrite( data, 1, len, fp );
             fclose( fp );
-            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
-            {
-               _load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height );
-            }
-            else /* otherwise its assumed to be an ico */
+            if(!_load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
             {
                icon = WinLoadFileIcon((PSZ)file, FALSE);
             }
@@ -5786,12 +6899,11 @@
       }
    }
 
-   bubble->id = id;
-   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   if(text)
+      strncpy(blah->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   blah->oldproc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, blah);
 
    if(icon)
       dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
@@ -5860,7 +6972,7 @@
    blah->oldproc = WinSubclassWindow(tmp, _entryproc);
    WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
-   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -5879,7 +6991,7 @@
    HWND tmp;
 
    sldcData.cbSize = sizeof(SLDCDATA);
-    sldcData.usScale1Increments = increments;
+   sldcData.usScale1Increments = increments;
 
    tmp = WinCreateWindow(HWND_OBJECT,
                     WC_SLIDER,
@@ -5953,7 +7065,7 @@
  */
 HWND API dw_checkbox_new(char *text, ULONG id)
 {
-   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   WindowData *blah = calloc(1, sizeof(WindowData));
    HWND tmp = WinCreateWindow(HWND_OBJECT,
                         WC_BUTTON,
                         (PSZ)text,
@@ -5964,12 +7076,10 @@
                         id,
                         NULL,
                         NULL);
-   bubble->id = id;
-   bubble->bubbletext[0] = '\0';
-   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   blah->oldproc = WinSubclassWindow(tmp, _BtProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
-   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -6012,109 +7122,217 @@
    WinSendMsg(handle, WM_SETICON, (MPARAM)hptr, 0);
 }
 
+/* GBM seems to be compiled with VisualAge which defines O_BINARY and O_RDONLY
+ * as follows... but other compilers (GCC and Watcom at least) define them
+ * differently... so we add defines that are compatible with VAC here.
+ */
+#define GBM_O_BINARY        0x00008000
+#define GBM_O_RDONLY        0x00000004
+
 /* Internal function to load a bitmap from a file and return handles
  * to the bitmap, presentation space etc.
  */
-int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height)
-{
-   HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
-   ULONG OpenAction = 0;
-   PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data  */
-   FILESTATUS BitmapStatus;
-   ULONG cbRead;
-   PBITMAPFILEHEADER2 pBitmapFileHeader;
-   PBITMAPINFOHEADER2 pBitmapInfoHeader;
-   ULONG ScanLines, ulFlags;
-   HPS hps1;
-   HDC hdc1;
-   SIZEL sizl = { 0, 0 };
-
-   /* open bitmap file */
-   DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L,
-         FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
-         OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
-         OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
-         OPEN_FLAGS_NOINHERIT, 0L);
-
-   if(!BitmapFileHandle)
-      return 0;
-
-   /* find out how big the file is  */
-   DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
-                sizeof(BitmapStatus));
-
-   /* allocate memory to load the bitmap */
-   DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
-            PAG_READ | PAG_WRITE | PAG_COMMIT);
-
-   /* read bitmap file into memory buffer */
-   DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
-         BitmapStatus.cbFile, &cbRead);
-
-   /* access first bytes as bitmap header */
-   pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
-
-   /* check if it's a valid bitmap data file */
-   if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
-      (pBitmapFileHeader->usType != BFT_BMAP))
-   {
-      /* free memory of bitmap file buffer */
-      DosFreeMem(BitmapFileBegin);
-      /* close the bitmap file */
-      DosClose(BitmapFileHandle);
-      return 0;
-   }
-
-   /* check if it's a file with multiple bitmaps */
-   if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
-   {
-      /* we'll just use the first bitmap and ignore the others */
-      pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
-   }
-
-   /* set pointer to bitmap information block */
-   pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
-
-   /* find out if it's the new 2.0 format or the old format */
-   /* and query number of lines */
-   if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
-   {
-      *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
-      *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
-   }
-   else
-   {
-      *height = ScanLines = pBitmapInfoHeader->cy;
-      *width = pBitmapInfoHeader->cx;
-   }
-
-   /* now we need a presentation space, get it from static control */
-   hps1 = WinGetPS(handle);
-
-   hdc1    = GpiQueryDevice(hps1);
-   ulFlags = GpiQueryPS(hps1, &sizl);
-
-   *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1);
-   *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-   /* create bitmap now using the parameters from the info block */
-   *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
-
-   /* select the new bitmap into presentation space */
-   GpiSetBitmap(*hps, *hbm);
-
-   /* now copy the bitmap data into the bitmap */
-   GpiSetBitmapBits(*hps, 0L, ScanLines,
-                BitmapFileBegin + pBitmapFileHeader->offBits,
-                (PBITMAPINFO2)pBitmapInfoHeader);
-
-   WinReleasePS(hps1);
-
-   /* free memory of bitmap file buffer */
-   DosFreeMem(BitmapFileBegin);
-   /* close the bitmap file */
-   DosClose(BitmapFileHandle);
-   return 1;
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height, int *depth)
+{
+    PBITMAPINFOHEADER2 pBitmapInfoHeader;
+    /* pointer to the first byte of bitmap data  */
+    PBYTE BitmapFileBegin, BitmapBits;
+    ULONG ulFlags;
+    SIZEL sizl = { 0 };
+    HPS hps1;
+    HDC hdc1;
+
+    /* If we have GBM support open the file using GBM */
+    if(_gbm_init)
+    {
+        int fd, z, err = -1, ft = 0;
+        GBM gbm;
+        GBMRGB *gbmrgb;
+        ULONG byteswidth;
+
+        /* Try to open the file */
+        if((fd = _gbm_io_open(file, GBM_O_RDONLY|GBM_O_BINARY)) == -1)
+        {
+#ifdef DEBUG
+            dw_debug("Failed to open file %s\n", file);
+#endif
+            return 0;
+        }
+
+        /* guess the source file type from the source filename */
+        _gbm_query_n_filetypes(&ft);
+
+        for(z=0;z<ft;z++)
+        {
+            /* Read the file header */
+            if((err = _gbm_read_header(file, fd, z, &gbm, "")) == 0)
+                break;
+        }
+
+        /* If we failed to load the header */
+        if(err)
+        {
+#ifdef DEBUG
+            dw_debug("GBM: Read header type %d \"%s\" %d %s\n", z, file, err, _gbm_err(err));
+#endif
+            _gbm_io_close(fd);
+            return 0;
+        }
+
+        /* if less than 24-bit, then have palette */
+        if(gbm.bpp < 24)
+        {
+            gbmrgb = alloca(sizeof(GBMRGB));
+            /* Read the palette from the file */
+            if((err = _gbm_read_palette(fd, z, &gbm, gbmrgb)) != 0)
+            {
+#ifdef DEBUG
+                dw_debug("GBM: Read palette type %d \"%s\" %d %s\n", z, file, err, _gbm_err(err));
+#endif
+                _gbm_io_close(fd);
+                return 0;
+            }
+        }
+        else
+            gbmrgb = NULL;
+
+        /* Save the dimension for return */
+        *width = gbm.w;
+        *height = gbm.h;
+        *depth = gbm.bpp;
+        byteswidth = (((gbm.w*gbm.bpp + 31)/32)*4);
+
+        /* Allocate a buffer to store the image */
+        DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)byteswidth * gbm.h,
+                    PAG_READ | PAG_WRITE | PAG_COMMIT);
+
+        /* Read the data into our buffer */
+        if((err = _gbm_read_data(fd, z, &gbm, BitmapFileBegin)) != 0)
+        {
+#ifdef DEBUG
+            dw_debug("GBM: Read data type %d \"%s\" %d %s\n", z, file, err, _gbm_err(err));
+#endif
+            _gbm_io_close(fd);
+            DosFreeMem(BitmapFileBegin);
+            return 0;
+        }
+
+        /* Close the file */
+        _gbm_io_close(fd);
+
+        pBitmapInfoHeader = alloca(sizeof(BITMAPINFOHEADER2));
+        memset(pBitmapInfoHeader, 0, sizeof(BITMAPINFOHEADER2));
+        pBitmapInfoHeader->cbFix     = sizeof(BITMAPINFOHEADER2);
+        pBitmapInfoHeader->cx        = (SHORT)gbm.w;
+        pBitmapInfoHeader->cy        = (SHORT)gbm.h;
+        pBitmapInfoHeader->cPlanes   = (SHORT)1;
+        pBitmapInfoHeader->cBitCount = (SHORT)gbm.bpp;
+
+        /* Put the bitmap bits into the destination */
+        BitmapBits = BitmapFileBegin;
+    }
+    else
+    {
+        HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
+        ULONG OpenAction = 0;
+        FILESTATUS BitmapStatus;
+        ULONG cbRead;
+        PBITMAPFILEHEADER2 pBitmapFileHeader;
+
+        /* open bitmap file */
+        DosOpen((PSZ)file, &BitmapFileHandle, &OpenAction, 0L,
+                FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
+                OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+                OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
+                OPEN_FLAGS_NOINHERIT, 0L);
+
+        if(!BitmapFileHandle)
+            return 0;
+
+        /* find out how big the file is  */
+        DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
+                         sizeof(BitmapStatus));
+
+        /* allocate memory to load the bitmap */
+        DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
+                    PAG_READ | PAG_WRITE | PAG_COMMIT);
+
+        /* read bitmap file into memory buffer */
+        DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
+                BitmapStatus.cbFile, &cbRead);
+
+        /* access first bytes as bitmap header */
+        pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
+
+        /* check if it's a valid bitmap data file */
+        if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
+           (pBitmapFileHeader->usType != BFT_BMAP))
+        {
+            /* free memory of bitmap file buffer */
+            DosFreeMem(BitmapFileBegin);
+            /* close the bitmap file */
+            DosClose(BitmapFileHandle);
+            return 0;
+        }
+
+        /* check if it's a file with multiple bitmaps */
+        if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
+        {
+            /* we'll just use the first bitmap and ignore the others */
+            pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
+        }
+
+        /* set pointer to bitmap information block */
+        pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
+
+        /* find out if it's the new 2.0 format or the old format */
+        /* and query number of lines */
+        if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
+        {
+            *height = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
+            *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
+            *depth = (int)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cBitCount;
+        }
+        else
+        {
+            *height = pBitmapInfoHeader->cy;
+            *width = pBitmapInfoHeader->cx;
+            *depth = pBitmapInfoHeader->cBitCount;
+        }
+
+        /* Put the bitmap bits into the destination */
+        BitmapBits = BitmapFileBegin + pBitmapFileHeader->offBits;
+
+        /* close the bitmap file */
+        DosClose(BitmapFileHandle);
+    }
+
+    /* now we need a presentation space, get it from static control */
+    hps1 = WinGetPS(handle);
+
+    hdc1    = GpiQueryDevice(hps1);
+    ulFlags = GpiQueryPS(hps1, &sizl);
+
+    *hdc = DevOpenDC(dwhab, OD_MEMORY, (PSZ)"*", 0L, NULL, hdc1);
+    *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+    /* create bitmap now using the parameters from the info block */
+    *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
+
+    /* select the new bitmap into presentation space */
+    GpiSetBitmap(*hps, *hbm);
+
+    /* now copy the bitmap data into the bitmap */
+    GpiSetBitmapBits(*hps, 0L, *height,
+                     BitmapBits,
+                     (PBITMAPINFO2)pBitmapInfoHeader);
+
+    WinReleasePS(hps1);
+
+    /* free memory of bitmap file buffer */
+    if(BitmapFileBegin)
+        DosFreeMem(BitmapFileBegin);
+    return 1;
 }
 
 /*
@@ -6143,9 +7361,10 @@
    }
    else if ( filename )
    {
-      HDC hdc;
+      HDC hdc = 0;
       unsigned long width, height;
-      char *file = alloca(strlen(filename) + 5);
+      char *file = alloca(strlen(filename) + 6);
+      int depth;
 
       if(!file)
          return;
@@ -6155,13 +7374,22 @@
       /* check if we can read from this file (it exists and read permission) */
       if(access(file, 04) != 0)
       {
-         /* Try with .bmp extention */
-         strcat(file, ".bmp");
-         if(access(file, 04) != 0)
-            return;
-      }
-
-      if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height))
+          int z;
+
+          /* Try with supported extensions */
+          for(z=0;z<(_gbm_init?NUM_EXTS:1);z++)
+          {
+              strcpy(file, filename);
+              strcat(file, image_exts[z]);
+              if(access(file, 04) == 0 &&
+                 _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth))
+                  break;
+          }
+      }
+      else
+          _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth);
+
+      if(!hdc)
          return;
 
       dw_window_set_data(handle, "_dw_hps", (void *)hps);
@@ -6172,11 +7400,22 @@
    else
       return;
 
-   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
-   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
    if ( id )
       WinReleasePS(hps);
    dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+   
+   /* If we changed the bitmap... */
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+   }
 }
 
 /*
@@ -6197,17 +7436,12 @@
    unsigned long width, height;
    char *file;
    FILE *fp;
+   int depth;
 
    /* Destroy any old bitmap data */
    _free_bitmap(handle);
 
-   /* If id is non-zero use the resource */
-   if ( id )
-   {
-      hps = WinGetPS( handle );
-      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
-   }
-   else if ( data )
+   if ( data )
    {
       file = tmpnam( NULL );
       if ( file != NULL )
@@ -6217,11 +7451,9 @@
          {
             fwrite( data, 1, len, fp );
             fclose( fp );
-            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
-               _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height);
-            else /* otherwise its assumed to be an ico */
+            if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth))
             {
-               /* con't use ICO ? */
+               /* can't use ICO ? */
                unlink( file );
                return;
             }
@@ -6239,11 +7471,15 @@
       dw_window_set_data(handle, "_dw_width", (void *)width);
       dw_window_set_data(handle, "_dw_height", (void *)height);
    }
+   /* If id is non-zero use the resource */
+   else if ( id )
+   {
+      hps = WinGetPS( handle );
+      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+   }
    else
       return;
 
-   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
-   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
    if ( id )
       WinReleasePS(hps);
    dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
@@ -6259,6 +7495,38 @@
 {
    HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy");
    WinSetWindowText(entryfield ? entryfield : handle, (PSZ)text);
+   /* If we changed the text... */
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+          /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+   }
+}
+
+/*
+ * Sets the text used for a given window's floating bubble help.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       bubbletext: The text in the floating bubble tooltip.
+ */
+void API dw_window_set_tooltip(HWND handle, char *bubbletext)
+{
+   HWND buddy = (HWND)dw_window_get_data(handle, "_dw_comboentry");
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(buddy ? buddy : handle, QWP_USER);
+   char *text = bubbletext ? bubbletext : "";
+
+   buddy = (HWND)dw_window_get_data(handle, "_dw_buddy");
+
+   if(blah)
+       strncpy(blah->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   if(buddy && (blah = (WindowData *)WinQueryWindowPtr(buddy, QWP_USER)))
+       strncpy(blah->bubbletext, text, BUBBLE_HELP_MAX - 1);
 }
 
 /*
@@ -6286,7 +7554,7 @@
  */
 void API dw_window_disable(HWND handle)
 {
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    if(handle < 65536)
    {
@@ -6387,7 +7655,7 @@
 {
    HENUM henum;
    HWND child;
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    henum = WinBeginEnumWindows(handle);
    while((child = WinGetNextWindow(henum)) != NULLHANDLE)
@@ -6437,7 +7705,6 @@
       else
       {
          box = WinWindowFromID(box, FID_CLIENT);
-         hsize = vsize = TRUE;
       }
    }
    
@@ -6447,16 +7714,18 @@
    {
       int z, x = 0;
       Item *tmpitem, *thisitem = thisbox->items;
-      char tmpbuf[100];
+      char tmpbuf[100] = {0};
       HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
 
       /* Do some sanity bounds checking */
+      if(!thisitem)
+        thisbox->count = 0;
       if(index < 0)
         index = 0;
       if(index > thisbox->count)
         index = thisbox->count;
         
-      tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
+      tmpitem = calloc(sizeof(Item), (thisbox->count+1));
 
       for(z=0;z<thisbox->count;z++)
       {
@@ -6466,7 +7735,6 @@
          x++;
       }
 
-
       WinQueryClassName(item, 99, (PCH)tmpbuf);
 
       if(vsize && !height)
@@ -6474,7 +7742,7 @@
       if(hsize && !width)
          width = 1;
 
-      if(strncmp(tmpbuf, "#1", 3)==0)
+      if(strncmp(tmpbuf, "#1", 3)==0 && !dw_window_get_data(item, "_dw_render"))
          tmpitem[index].type = TYPEBOX;
       else
       {
@@ -6490,36 +7758,160 @@
       tmpitem[index].origwidth = tmpitem[index].width = width;
       tmpitem[index].origheight = tmpitem[index].height = height;
       tmpitem[index].pad = pad;
-      if(hsize)
-         tmpitem[index].hsize = SIZEEXPAND;
-      else
-         tmpitem[index].hsize = SIZESTATIC;
-
-      if(vsize)
-         tmpitem[index].vsize = SIZEEXPAND;
-      else
-         tmpitem[index].vsize = SIZESTATIC;
+      tmpitem[index].hsize = hsize ? SIZEEXPAND : SIZESTATIC;
+      tmpitem[index].vsize = vsize ? SIZEEXPAND : SIZESTATIC;
+    
+      /* If either of the parameters are -1 ... calculate the size */
+      if(width == -1 || height == -1)
+         _control_size(item, width == -1 ? &tmpitem[index].width : NULL, height == -1 ? &tmpitem[index].height : NULL);
 
       thisbox->items = tmpitem;
 
-      if(thisbox->count)
+      if(thisitem)
          free(thisitem);
 
       thisbox->count++;
 
       WinQueryClassName(item, 99, (PCH)tmpbuf);
-      /* Don't set the ownership if it's an entryfield or spinbutton */
-      if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
-         WinSetOwner(item, box);
+      /* Don't set the ownership if it's an entryfield
+       * NOTE: spinbutton used to be in this list but it was preventing value change events
+       * from firing, so I removed it.  If spinbuttons cause problems revisit this.
+       */
+      if(strncmp(tmpbuf, "#6", 3)!=0 && /*strncmp(tmpbuf, "#32", 4)!=0 &&*/ strncmp(tmpbuf, "#2", 3)!=0)
+          WinSetOwner(item, box);
       WinSetParent(frame ? frame : item, box, FALSE);
-   }
+      _handle_transparent(box);
+      /* Queue a redraw on the top-level window */
+      _dw_redraw(_toplevel_window(box), TRUE);
+   }
+}
+
+/*
+ * Remove windows (widgets) from the box they are packed into.
+ * Parameters:
+ *       handle: Window handle of the packed item to be removed.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_box_unpack(HWND handle)
+{
+   HWND parent = WinQueryWindow(handle, QW_PARENT);
+   
+   if(parent != desktop)
+   {
+      Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
+      
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+      if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem = NULL, *thisitem = thisbox->items;
+
+         if(!thisitem)
+            thisbox->count = 0;
+            
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return DW_ERROR_GENERAL;
+
+         if(thisbox->count > 1)
+         {
+            tmpitem = calloc(sizeof(Item), (thisbox->count-1));
+
+            /* Copy all but the current entry to the new list */
+            for(z=0;z<index;z++)
+            {
+               tmpitem[z] = thisitem[z];
+            }
+            for(z=index+1;z<thisbox->count;z++)
+            {
+               tmpitem[z-1] = thisitem[z];
+            }
+         }
+
+         thisbox->items = tmpitem;
+         if(thisitem)
+            free(thisitem);
+         if(tmpitem)
+            thisbox->count--;
+         else
+            thisbox->count = 0;
+            
+         /* If it isn't padding, reset the parent */
+         if(handle)
+            WinSetParent(handle, HWND_OBJECT, FALSE);
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(parent), TRUE);
+         return DW_ERROR_NONE;
+      }
+   }
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Remove windows (widgets) from a box at an arbitrary location.
+ * Parameters:
+ *       box: Window handle of the box to be removed from.
+ *       index: 0 based index of packed items.
+ * Returns:
+ *       Handle to the removed item on success, 0 on failure or padding.
+ */
+HWND API dw_box_unpack_at_index(HWND box, int index)
+{
+   Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
+   
+   /* Try to remove it from the layout */
+   if(thisbox && index > -1 && index < thisbox->count)
+   {
+      int z;
+      Item *tmpitem = NULL, *thisitem = thisbox->items;
+      HWND handle = thisitem[index].hwnd;
+
+      if(thisbox->count > 1)
+      {
+         tmpitem = calloc(sizeof(Item), (thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+      }
+
+      thisbox->items = tmpitem;
+      if(thisitem)
+         free(thisitem);
+      if(tmpitem)
+         thisbox->count--;
+      else
+         thisbox->count = 0;
+         
+      /* If it isn't padding, reset the parent */
+      if(handle)
+         WinSetParent(handle, HWND_OBJECT, FALSE);
+      /* Queue a redraw on the top-level window */
+      _dw_redraw(_toplevel_window(box), TRUE);
+      return handle;
+   }
+   return 0;
 }
 
 /*
  * Pack windows (widgets) into a box at an arbitrary location.
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       index: 0 based index of packed items. 
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
@@ -6536,7 +7928,7 @@
  * Pack windows (widgets) into a box from the start (or top).
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
  *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
@@ -6555,7 +7947,7 @@
  * Pack windows (widgets) into a box from the end (or bottom).
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
  *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
@@ -6568,6 +7960,34 @@
 }
 
 /*
+ * 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.
+ */
+void _get_window_for_size(HWND handle, unsigned long *width, unsigned long *height)
+{
+   HWND box = WinWindowFromID(handle, FID_CLIENT);
+   Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox)
+   {
+      int depth = 0;
+      RECTL rect = { 0 };
+
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, *width, *height, 1);
+      
+      rect.xRight = thisbox->minwidth;
+      rect.yTop = thisbox->minheight;
+
+      /* Take into account the window border and menu here */
+      WinCalcFrameRect(handle, &rect, FALSE);
+      
+      if(*width < 1) *width = rect.xRight - rect.xLeft;
+      if(*height < 1) *height = rect.yTop - rect.yBottom;
+   }
+}
+
+/*
  * Sets the size of a given window (widget).
  * Parameters:
  *          handle: Window (widget) handle.
@@ -6576,7 +7996,61 @@
  */
 void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
 {
-   WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
+   /* Attempt to auto-size */
+   if ( width < 1 || height < 1 )
+      _get_window_for_size(handle, &width, &height);
+   
+   /* Finally set the size */
+   WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SIZE);
+}
+
+/*
+ * Gets the size the system thinks the widget should be.
+ * Parameters:
+ *       handle: Window handle of the item to be back.
+ *       width: Width in pixels of the item or NULL if not needed.
+ *       height: Height in pixels of the item or NULL if not needed.
+ */
+void API dw_window_get_preferred_size(HWND handle, int *width, int *height)
+{
+   char tmpbuf[100] = {0};
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+   if(strncmp(tmpbuf, "#1", 3)==0)
+   {
+      HWND box = WinWindowFromID(handle, FID_CLIENT);
+      
+      if(box)
+      {
+         unsigned long thiswidth = 0, thisheight = 0;
+         
+         /* Get the size with the border */
+         _get_window_for_size(handle, &thiswidth, &thisheight);
+         
+         /* Return what was requested */
+         if(width) *width = (int)thiswidth;
+         if(height) *height = (int)thisheight;
+      }
+      else
+      {
+         Box *thisbox = WinQueryWindowPtr(handle, QWP_USER);
+         
+         if(thisbox)
+         {
+            int depth = 0;
+            
+            /* Calculate space requirements */
+            _resize_box(thisbox, &depth, 0, 0, 1);
+            
+            /* Return what was requested */
+            if(width) *width = thisbox->minwidth;
+            if(height) *height = thisbox->minheight;
+         }
+      }
+   }
+   else
+      _control_size(handle, width, height);
 }
 
 /*
@@ -6606,6 +8080,70 @@
    return colors;
 }
 
+/*
+ * Sets the gravity of a given window (widget).
+ * Gravity controls which corner of the screen and window the position is relative to.
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          horz: DW_GRAV_LEFT (default), DW_GRAV_RIGHT or DW_GRAV_CENTER.
+ *          vert: DW_GRAV_TOP (default), DW_GRAV_BOTTOM or DW_GRAV_CENTER.
+ */
+void API dw_window_set_gravity(HWND handle, int horz, int vert)
+{
+   dw_window_set_data(handle, "_dw_grav_horz", DW_INT_TO_POINTER(horz));
+   dw_window_set_data(handle, "_dw_grav_vert", DW_INT_TO_POINTER(vert));
+}
+
+/* Convert the coordinates based on gravity */
+void _handle_gravity(HWND handle, long *x, long *y, unsigned long width, unsigned long height)
+{
+   int horz = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_grav_horz"));
+   int vert = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_grav_vert"));
+   
+   /* Do any gravity calculations */
+   if(horz || (vert & 0xf) != DW_GRAV_BOTTOM)
+   {
+      long newx = *x, newy = *y;
+   
+      /* Handle horizontal center gravity */
+      if((horz & 0xf) == DW_GRAV_CENTER)
+         newx += ((dw_screen_width() / 2) - (width / 2));
+      /* Handle right gravity */
+      else if((horz & 0xf) == DW_GRAV_RIGHT)
+         newx = dw_screen_width() - width - *x;
+      /* Handle vertical center gravity */
+      if((vert & 0xf) == DW_GRAV_CENTER)
+         newy += ((dw_screen_height() / 2) - (height / 2));
+      else if((vert & 0xf) == DW_GRAV_TOP)
+         newy = dw_screen_height() - height - *y;
+        
+      /* Save the new values */
+      *x = newx;
+      *y = newy;
+   }            
+   /* Adjust the values to avoid WarpCenter/XCenter/eCenter if requested */
+   if(_WinQueryDesktopWorkArea && (horz | vert) & DW_GRAV_OBSTACLES)
+   {
+       RECTL rect;
+
+       _WinQueryDesktopWorkArea(HWND_DESKTOP, &rect);
+
+       if(horz & DW_GRAV_OBSTACLES)
+       {
+           if((horz & 0xf) == DW_GRAV_LEFT)
+               *x += rect.xLeft;
+           else if((horz & 0xf) == DW_GRAV_RIGHT)
+               *x -= dw_screen_width() - rect.xRight;
+       }
+       if(vert & DW_GRAV_OBSTACLES)
+       {
+           if((vert & 0xf) == DW_GRAV_BOTTOM)
+               *y += rect.yBottom;
+           else if((vert & 0xf) == DW_GRAV_TOP)
+               *y -= dw_screen_height() - rect.yTop;
+       }
+    }
+}
 
 /*
  * Sets the position of a given window (widget).
@@ -6616,9 +8154,17 @@
  */
 void API dw_window_set_pos(HWND handle, LONG x, LONG y)
 {
-   int myy = _get_frame_height(handle) - (y + _get_height(handle));
-
-   WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE);
+   unsigned long width, height;
+
+   dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+   /* Can't position an unsized window, so attempt to auto-size */
+   if(width == 0 || height == 0)
+   {
+      dw_window_set_size(handle, 0, 0);
+      dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+   }
+   _handle_gravity(handle, &x, &y, width, height);
+   WinSetWindowPos(handle, NULLHANDLE, x, y, 0, 0, SWP_MOVE);
 }
 
 /*
@@ -6632,9 +8178,13 @@
  */
 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);
-
-   WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+   /* Attempt to auto-size */
+   if ( width < 1 || height < 1 )
+      _get_window_for_size(handle, &width, &height);
+   
+   _handle_gravity(handle, &x, &y, width, height);
+   /* Finally set the size */
+   WinSetWindowPos(handle, NULLHANDLE, x, y, width, height, SWP_MOVE | SWP_SIZE);
 }
 
 /*
@@ -6927,7 +8477,7 @@
  */
 void API dw_listbox_select(HWND handle, int index, int state)
 {
-   char tmpbuf[100];
+   char tmpbuf[100] = {0};
 
    WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state);
 
@@ -7309,7 +8859,9 @@
  */
 void API dw_spinbutton_set_pos(HWND handle, long position)
 {
+   dw_window_set_data(handle, "_dw_updating", (void *)1);
    WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L);
+   dw_window_set_data(handle, "_dw_updating", NULL);
 }
 
 /*
@@ -7687,7 +9239,7 @@
       details->cb = sizeof(FIELDINFO);
       details->flData = flags[z];
       details->flTitle = CFA_FITITLEREADONLY;
-      details->pTitleData = titles[z];
+      details->pTitleData = strdup(titles[z]);
       details->offStruct = offStruct[z];
       details = details->pNextFieldInfo;
    }
@@ -7719,6 +9271,19 @@
 }
 
 /*
+ * Configures the main filesystem columnn title for localization.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          title: The title to be displayed in the main column.
+ */
+void API dw_filesystem_set_column_title(HWND handle, char *title)
+{
+	char *newtitle = strdup(title ? title : "");
+	
+	dw_window_set_data(handle, "_dw_coltitle", newtitle);
+}
+
+/*
  * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
  * Parameters:
  *          handle: Handle to the container to be configured.
@@ -7730,9 +9295,10 @@
 {
    char **newtitles = malloc(sizeof(char *) * (count + 2));
    unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
-
-   newtitles[0] = "Icon";
-   newtitles[1] = "Filename";
+   char *coltitle = (char *)dw_window_get_data(handle, "_dw_coltitle");
+
+   newtitles[0] = "";
+   newtitles[1] = coltitle ? coltitle : "Filename";
 
    newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
    newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
@@ -7760,6 +9326,43 @@
    return WinLoadPointer(HWND_DESKTOP,module,id);
 }
 
+/* Internal function to create an icon from an existing pixmap */
+HICN _create_icon(HPIXMAP src)
+{
+    HPIXMAP pntr = dw_pixmap_new(hwndApp, WinQuerySysValue(HWND_DESKTOP, SV_CXICON), WinQuerySysValue(HWND_DESKTOP, SV_CYICON), src->depth);
+    HPIXMAP mask = dw_pixmap_new(hwndApp, pntr->width, pntr->height*2, 1);
+    HPIXMAP minipntr = dw_pixmap_new(hwndApp, pntr->width/2, pntr->height/2, src->depth);
+    HPIXMAP minimask = dw_pixmap_new(hwndApp, minipntr->width, minipntr->height*2, 1);
+    ULONG oldcol = _foreground;
+    POINTERINFO pi = {0};
+
+    /* Create the color pointers, stretching it to the necessary size */
+    dw_pixmap_stretch_bitblt(0, pntr, 0, 0, pntr->width, pntr->height, 0, src, 0, 0, src->width, src->height);
+    dw_pixmap_stretch_bitblt(0, minipntr, 0, 0, minipntr->width, minipntr->height, 0, src, 0, 0, src->width, src->height);
+
+    /* Create the masks, all in black */
+    dw_color_foreground_set(DW_CLR_BLACK);
+    dw_draw_rect(0, mask, DW_DRAW_FILL, 0, 0, mask->width, mask->height);
+    dw_draw_rect(0, minimask, DW_DRAW_FILL, 0, 0, minimask->width, minimask->height);
+    _foreground = oldcol;
+
+    /* Assemble the Pointer Info structure */
+    pi.hbmPointer = mask->hbm;
+    pi.hbmColor = pntr->hbm;
+    pi.hbmMiniPointer = minimask->hbm;
+    pi.hbmMiniColor = minipntr->hbm;
+
+    /* Destroy the pixmaps but not the bitmaps */
+    mask->hbm = pntr->hbm = minimask->hbm = minipntr->hbm = 0;
+    dw_pixmap_destroy(mask);
+    dw_pixmap_destroy(pntr);
+    dw_pixmap_destroy(minimask);
+    dw_pixmap_destroy(minipntr);
+
+    /* Generate the icon */
+    return WinCreatePointerIndirect(HWND_DESKTOP, &pi);
+}
+
 /*
  * Obtains an icon from a file.
  * Parameters:
@@ -7769,9 +9372,11 @@
  */
 HICN API dw_icon_load_from_file(char *filename)
 {
-   char *file = alloca(strlen(filename) + 5);
-
-   if(!file)
+   char *file = alloca(strlen(filename) + 6);
+   HPIXMAP src = alloca(sizeof(struct _hpixmap));
+   HICN icon = 0;
+
+   if(!file || !src)
       return 0;
 
    strcpy(file, filename);
@@ -7779,12 +9384,39 @@
    /* check if we can read from this file (it exists and read permission) */
    if(access(file, 04) != 0)
    {
-      /* Try with .bmp extention */
-      strcat(file, ".ico");
-      if(access(file, 04) != 0)
-         return 0;
-   }
-   return WinLoadFileIcon((PSZ)file, FALSE);
+       int z;
+
+       /* Try with .ico extention */
+       strcat(file, ".ico");
+       if(access(file, 04) == 0)
+           return WinLoadFileIcon((PSZ)file, FALSE);
+
+       /* Try with supported extensions */
+       for(z=0;z<(_gbm_init?NUM_EXTS:1);z++)
+       {
+           strcpy(file, filename);
+           strcat(file, image_exts[z]);
+           if(access(file, 04) == 0 &&
+              _load_bitmap_file(file, hwndApp, &src->hbm, &src->hdc, &src->hps, &src->width, &src->height, &src->depth))
+           {
+               icon = _create_icon(src);
+               break;
+           }
+       }
+   }
+   else if(_load_bitmap_file(file, hwndApp, &src->hbm, &src->hdc, &src->hps, &src->width, &src->height, &src->depth))
+       icon = _create_icon(src);
+   /* Free temporary resources if in use */
+   if(icon)
+   {
+       GpiSetBitmap(src->hps, NULLHANDLE);
+       GpiDeleteBitmap(src->hbm);
+       GpiAssociate(src->hps, NULLHANDLE);
+       GpiDestroyPS(src->hps);
+       DevCloseDC(src->hdc);
+   }
+   /* Otherwise fall back to the classic method */
+   return icon ? icon : WinLoadFileIcon((PSZ)file, FALSE);
 }
 
 /*
@@ -7810,12 +9442,7 @@
       {
          fwrite( data, 1, len, fp );
          fclose( fp );
-         icon = WinLoadFileIcon( (PSZ)file, FALSE );
-      }
-      else
-      {
-         unlink( file );
-         return 0;
+         icon = dw_icon_load_from_file(file);
       }
       unlink( file );
    }
@@ -7899,7 +9526,7 @@
    ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
    int z, currentcount;
    CNRINFO cnr;
-    void *dest;
+   void *dest;
 
    if(!flags)
       return;
@@ -7932,7 +9559,12 @@
    dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
 
    if(flags[column] & DW_CFA_BITMAPORICON)
-      memcpy(dest, data, sizeof(HPOINTER));
+   {
+       if(data)
+           memcpy(dest, data, sizeof(HPOINTER));
+       else
+           memset(dest, 0, sizeof(HPOINTER));
+   }
    else if(flags[column] & DW_CFA_STRING)
    {
       char **newstr = (char **)data, **str = dest;
@@ -7946,11 +9578,26 @@
          *str = NULL;
    }
    else if(flags[column] & DW_CFA_ULONG)
-      memcpy(dest, data, sizeof(ULONG));
+   {
+       if(data)
+           memcpy(dest, data, sizeof(ULONG));
+       else
+           memset(dest, 0, sizeof(ULONG));
+   }
    else if(flags[column] & DW_CFA_DATE)
-      memcpy(dest, data, sizeof(CDATE));
+   {
+       if(data)
+           memcpy(dest, data, sizeof(CDATE));
+       else
+           memset(dest, 0, sizeof(CDATE));
+   }
    else if(flags[column] & DW_CFA_TIME)
-      memcpy(dest, data, sizeof(CTIME));
+   {
+       if(data)
+           memcpy(dest, data, sizeof(CTIME));
+       else
+           memset(dest, 0, sizeof(CTIME));
+   }
 }
 
 /* Internal function that free()s any strings allocated for a container item */
@@ -8274,7 +9921,7 @@
 
    free(ci);
 
-   if((pCore = _dw_container_start(handle, CRA_CURSORED)))
+   if((pCore = _dw_container_start(handle, CRA_CURSORED)) != NULL)
    {
        NOTIFYRECORDEMPHASIS pre;
 
@@ -8603,6 +10250,7 @@
                             NULL,
                             NULL);
    WinSubclassWindow(hwndframe, _RendProc);
+   dw_window_set_data(hwndframe, "_dw_render", DW_INT_TO_POINTER(1));
    return hwndframe;
 }
 
@@ -8672,7 +10320,7 @@
    DWDialog *dwwait;
    HMTX mtx = dw_mutex_new();
 
-   window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+   window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
 
    vbox = dw_box_new(DW_VERT, 5);
 
@@ -8802,7 +10450,7 @@
    if(handle)
    {
       hps = _set_colors(handle);
-        height = _get_height(handle);
+      height = _get_height(handle);
    }
    else if(pixmap)
    {
@@ -8816,7 +10464,7 @@
    ptl.y = height - y - 1;
 
    GpiSetPel(hps, &ptl);
-   if(!pixmap)
+   if(handle)
       WinReleasePS(hps);
 }
 
@@ -8838,7 +10486,7 @@
    if(handle)
    {
       hps = _set_colors(handle);
-        height = _get_height(handle);
+      height = _get_height(handle);
    }
    else if(pixmap)
    {
@@ -8856,8 +10504,8 @@
    GpiMove(hps, &ptl[0]);
    GpiLine(hps, &ptl[1]);
 
-   if(!pixmap)
-      WinReleasePS(hps);
+   if(handle)
+       WinReleasePS(hps);
 }
 
 
@@ -8873,6 +10521,9 @@
 
    fat.usRecordLength  = sizeof(FATTRS);
    fat.lMatch          = fm.lMatch;
+#ifdef UNICODE
+   fat.usCodePage      = 1208;
+#endif
    strcpy(fat.szFacename, fm.szFacename);
 
    GpiCreateLogFont(hpsDst, 0, 1L, &fat);
@@ -8936,7 +10587,7 @@
     else
         WinDrawText(hps, -1, (PCH)text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT);
 
-    if(!pixmap)
+    if(handle)
         WinReleasePS(hps);
 }
 
@@ -8976,7 +10627,7 @@
    if(height)
       *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y;
 
-   if(!pixmap)
+   if(handle)
       WinReleasePS(hps);
 }
 
@@ -9041,7 +10692,7 @@
       if ( flags & DW_DRAW_FILL )
          GpiEndArea( hps );
    }
-   if ( !pixmap )
+   if(handle)
       WinReleasePS(hps);
    free( pptl );
 }
@@ -9065,7 +10716,7 @@
    if(handle)
    {
       hps = _set_colors(handle);
-        thisheight = _get_height(handle);
+      thisheight = _get_height(handle);
    }
    else if(pixmap)
    {
@@ -9083,7 +10734,7 @@
    GpiMove(hps, &ptl[0]);
    GpiBox(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0);
 
-   if(!pixmap)
+   if(handle)
       WinReleasePS(hps);
 }
 
@@ -9169,7 +10820,7 @@
            GpiEndArea(hps);
    }
 
-   if(!pixmap)
+   if(handle)
       WinReleasePS(hps);
 }
 
@@ -9198,7 +10849,7 @@
    HDC hdc;
    HPS hps;
    ULONG ulFlags;
-    LONG cPlanes, cBitCount;
+   LONG cPlanes, cBitCount;
 
    if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
       return NULL;
@@ -9228,6 +10879,7 @@
 
    pixmap->width = width; pixmap->height = height;
    pixmap->transcolor = DW_CLR_DEFAULT;
+   pixmap->depth = depth;
 
    pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL);
 
@@ -9264,17 +10916,21 @@
    /* check if we can read from this file (it exists and read permission) */
    if ( access(file, 04) != 0 )
    {
-      /* Try with .bmp extention */
-      strcat(file, ".bmp");
-      if ( access(file, 04) != 0 )
-      {
-         free(pixmap);
-         return NULL;
-      }
+       int z;
+
+       /* Try with supported extensions */
+       for(z=0;z<(_gbm_init?NUM_EXTS:1);z++)
+       {
+           strcpy(file, filename);
+           strcat(file, image_exts[z]);
+           if(access(file, 04) == 0 &&
+              _load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
+               break;
+       }
    }
 
    /* Try to load the bitmap from file */
-   if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
+   if(!pixmap->hbm)
    {
       free(pixmap);
       return NULL;
@@ -9314,18 +10970,9 @@
       {
          fwrite( data, 1, len, fp );
          fclose( fp );
-         if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
-         {
-            /* Try to load the bitmap from file */
-            if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
-            {
-               free(pixmap);
-               return NULL;
-            }
-         }
-         else /* otherwise its assumed to be an ico */
-         {
-            /* con't use ICO ? */
+         if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
+         {
+            /* can't use ICO ? */
             unlink( file );
             return NULL;
          }
@@ -9513,7 +11160,7 @@
    }
    else
    {
-      if(!destp)
+      if(dest)
          WinReleasePS(hpsdest);
       return DW_ERROR_GENERAL;
    }
@@ -9549,9 +11196,9 @@
        GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
    }
 
-   if(!destp)
+   if(dest)
       WinReleasePS(hpsdest);
-   if(!srcp)
+   if(src)
       WinReleasePS(hpssrc);
    return DW_ERROR_NONE;
 }
@@ -9949,11 +11596,16 @@
 void _dwthreadstart(void *data)
 {
    HAB thishab = WinInitialize(0);
-   HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
-   void (* API threadfunc)(void *) = NULL;
+   HMQ thishmq = WinCreateMsgQueue(thishab, 0);
+   void (API_FUNC threadfunc)(void *) = NULL;
    void **tmp = (void **)data;
 
-   threadfunc = (void (* API)(void *))tmp[0];
+#ifdef UNICODE
+   /* Set the codepage to 1208 (UTF-8) */
+   WinSetCp(thishmq, 1208);
+#endif
+
+   threadfunc = (void (API_FUNC)(void *))tmp[0];
    threadfunc(tmp[1]);
 
    free(tmp);
@@ -9971,12 +11623,19 @@
  */
 DWTID API dw_thread_new(void *func, void *data, int stack)
 {
-   void **tmp = malloc(sizeof(void *) * 2);
-
-   tmp[0] = func;
-   tmp[1] = data;
-
-   return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp);
+    void **tmp = malloc(sizeof(void *) * 2);
+    int z = 1;
+
+    /* Clamp the stack size to 4K blocks...
+     * since some CRTs require it (VAC)
+     */
+    while(stack > (4096*z))
+        z++;
+
+    tmp[0] = func;
+    tmp[1] = data;
+
+    return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, (z*4096), (void *)tmp);
 }
 
 /*
@@ -10011,7 +11670,28 @@
     */
    Root = NULL;
 
+   /* Deinit the GBM */
+   if(_gbm_deinit)
+       _gbm_deinit();
+
+#ifdef UNICODE
+   /* Free the conversion object */
+   UniFreeUconvObject(Uconv);
+   /* Deregister the Unicode clipboard format */
+   WinDeleteAtom(WinQuerySystemAtomTable(), Unicode);
+#endif
+
+   /* Destroy the main message queue and anchor block */
+   WinDestroyMsgQueue(dwhmq);
+   WinTerminate(dwhab);
+
+   /* Free any in use modules */
    DosFreeModule(wpconfig);
+   DosFreeModule(pmprintf);
+   DosFreeModule(pmmerge);
+   DosFreeModule(gbm);
+   
+   /* And finally exit */
    exit(exitcode);
 }
 
@@ -10216,19 +11896,27 @@
  *       Pointer to an allocated string of text or NULL if clipboard empty or contents could not
  *       be converted to text.
  */
-char *dw_clipboard_get_text()
-{
-    APIRET rc;
+char * API dw_clipboard_get_text(void)
+{
     char *retbuf = NULL;
-    ULONG fmtInfo;
+#ifdef UNICODE
+    UniChar *unistr;
+#endif
 
     WinOpenClipbrd(dwhab);
 
-    rc = WinQueryClipbrdFmtInfo(dwhab, CF_TEXT, &fmtInfo);
-    if (rc) /* Text data in clipboard */
+#ifdef UNICODE
+    if(!Unicode || !(unistr = (UniChar *)WinQueryClipbrdData(dwhab, Unicode)) ||
+       !(retbuf = _WideToUTF8(unistr)))
+#endif
     {
-        PSZ pszClipText = (PSZ)WinQueryClipbrdData(dwhab, CF_TEXT); /* Query data handle */
-        retbuf = strdup((char *)pszClipText);
+        ULONG fmtInfo;
+
+        if (WinQueryClipbrdFmtInfo(dwhab, CF_TEXT, &fmtInfo)) /* Text data in clipboard */
+        {
+            PSZ pszClipText = (PSZ)WinQueryClipbrdData(dwhab, CF_TEXT); /* Query data handle */
+            retbuf = strdup((char *)pszClipText);
+        }
     }
     WinCloseClipbrd(dwhab);
     return retbuf;
@@ -10239,25 +11927,57 @@
  * Parameters:
  *       Text.
  */
-void dw_clipboard_set_text( char *str, int len )
-{
-    APIRET rc;
+void API dw_clipboard_set_text( char *str, int len )
+{
     static PVOID shared;
+    PVOID old = shared, src = str;
+    int buflen = len + 1;
 
     WinOpenClipbrd(dwhab); /* Open clipboard */
     WinEmptyClipbrd(dwhab); /* Empty clipboard */
 
     /* Ok, clipboard wants giveable unnamed shared memory */
-
     shared = NULL;
-    rc = DosAllocSharedMem(&shared, NULL, len, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE);
-
-    if (rc == 0)
+    if(!DosAllocSharedMem(&shared, NULL, buflen, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE))
     {
-        memcpy(shared, str, len);
+        memcpy(shared, src, buflen);
 
         WinSetClipbrdData(dwhab, (ULONG)shared, CF_TEXT, CFI_POINTER);
     }
+    if(old)
+        DosFreeMem(old);
+
+#ifdef UNICODE
+    if(Unicode)
+    {
+        UniChar *unistr = NULL;
+        static PVOID ushared;
+        PVOID uold = ushared;
+
+        src = calloc(len + 1, 1);
+
+        memcpy(src, str, len);
+        unistr = _UTF8toWide((char *)src);
+        free(src);
+
+        if(unistr)
+        {
+            buflen = (UniStrlen(unistr) + 1) * sizeof(UniChar);
+            src = unistr;
+            /* Ok, clipboard wants giveable unnamed shared memory */
+            ushared = NULL;
+            if(!DosAllocSharedMem(&ushared, NULL, buflen, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE))
+            {
+                memcpy(ushared, src, buflen);
+
+                WinSetClipbrdData(dwhab, (ULONG)ushared, Unicode, CFI_POINTER);
+            }
+            free(unistr);
+        }
+        if(uold)
+            DosFreeMem(uold);
+    }
+#endif
 
     WinCloseClipbrd(dwhab); /* Close clipboard */
     return;
@@ -10488,7 +12208,7 @@
       DWDialog *dwwait;
       HMTX mtx = dw_mutex_new();
 
-      window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
+      window = dw_window_new( HWND_DESKTOP, title, FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
 
       vbox = dw_box_new(DW_VERT, 5);
 
@@ -10621,7 +12341,11 @@
 int API dw_exec(char *program, int type, char **params)
 {
    type = type; /* keep compiler happy */
+#ifdef __EMX__
    return spawnvp(P_NOWAIT, program, (char * const *)params);
+#else
+   return spawnvp(P_NOWAIT, program, (const char * const *)params);
+#endif
 }
 
 /*
@@ -10747,7 +12471,7 @@
 {
     HDC hdc;
     char *printername;
-    int (* API drawfunc)(HPRINT, HPIXMAP, int, void *);
+    int (API_FUNC drawfunc)(HPRINT, HPIXMAP, int, void *);
     void *drawdata;
     unsigned long flags;
     unsigned int startpage, endpage;
@@ -10864,7 +12588,7 @@
     if(!drawfunc || !(print = calloc(1, sizeof(DWPrint))))
         return NULL;
     
-    print->drawfunc = drawfunc;
+    print->drawfunc = (int (API_FUNC)(HPRINT, HPIXMAP, int, void *))drawfunc;
     print->drawdata = drawdata;
     print->jobname = jobname ? jobname : "Dynamic Windows Print Job";
     print->startpage = 1;
@@ -10902,7 +12626,7 @@
     }
 
     /* Create the print dialog */
-    window = dw_window_new(HWND_DESKTOP, "Choose Printer", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+    window = dw_window_new(HWND_DESKTOP, "Choose Printer", FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
 
     vbox = dw_box_new(DW_VERT, 5);
 
@@ -11099,7 +12823,7 @@
  */
 char * API dw_user_dir(void)
 {
-   static char _user_dir[1024] = "";
+   static char _user_dir[MAX_PATH+1] = {0};
 
    if(!_user_dir[0])
    {
@@ -11114,6 +12838,15 @@
 }
 
 /*
+ * Returns a pointer to a static buffer which containes the
+ * private application data directory. 
+ */
+char * API dw_app_dir(void)
+{
+    return _dw_exec_dir;
+}
+
+/*
  * Call a function from the window (widget)'s context.
  * Parameters:
  *       handle: Window handle of the widget.
@@ -11490,16 +13223,15 @@
     WindowData *blah = calloc(sizeof(WindowData), 1);
     DATETIME dt;
     HWND tmp = WinCreateWindow(HWND_OBJECT,
-                        WC_STATIC,
+                        (PSZ)CalendarClassName,
                         NULL,
-                        WS_VISIBLE | SS_TEXT,
+                        WS_VISIBLE,
                         0,0,2000,1000,
                         NULLHANDLE,
                         HWND_TOP,
                         id,
                         NULL,
                         NULL);
-    blah->oldproc = WinSubclassWindow(tmp, _calendarproc);
     WinSetWindowPtr(tmp, QWP_USER, blah);
     dw_window_set_font(tmp, DefaultFont);
     if(!DosGetDateTime(&dt))
@@ -11547,3 +13279,37 @@
     if(day)
         *day = DW_POINTER_TO_UINT(dw_window_get_data(window, "_dw_day")) + 1;
 }
+
+/*
+ * Converts a UTF-8 encoded string into a wide string.
+ * Parameters:
+ *       utf8string: UTF-8 encoded source string.
+ * Returns:
+ *       Wide string that needs to be freed with dw_free()
+ *       or NULL on failure.
+ */
+wchar_t * API dw_utf8_to_wchar(char *utf8string)
+{
+#ifdef UNICODE
+    return _UTF8toWide(utf8string);
+#else
+    return NULL;
+#endif
+}
+
+/*
+ * Converts a wide string into a UTF-8 encoded string.
+ * Parameters:
+ *       wstring: Wide source string.
+ * Returns:
+ *       UTF-8 encoded string that needs to be freed with dw_free()
+ *       or NULL on failure.
+ */
+char * API dw_wchar_to_utf8(wchar_t *wstring)
+{
+#ifdef UNICODE
+    return _WideToUTF8(wstring);
+#else
+    return NULL;
+#endif
+}
--- a/rexx.c	Sun Nov 20 11:11:53 2011 -0600
+++ b/rexx.c	Wed Jul 25 00:05:29 2012 -0500
@@ -113,7 +113,8 @@
 TRUE = 1\r\n\
 FALSE = 0\r\n";
 
-unsigned long savedx = 0, savedy = 0, savedwidth = 0, savedheight = 0;
+long savedx = 0, savedy = 0;
+unsigned long savedwidth = 0, savedheight = 0;
 HWND windowhandle;
 
 RexxVar *root = NULL;
@@ -1182,7 +1183,7 @@
 	int len = str ? strlen(str) : 0;
 	char *newstr = NULL;
 
-	DosAllocMem(&newstr, len+1, PAG_READ|PAG_WRITE|PAG_COMMIT);
+	DosAllocMem((void **)&newstr, len+1, PAG_READ|PAG_WRITE|PAG_COMMIT);
 
 	if(newstr)
 		strncpy(newstr, str, len+1);
--- a/sfxace/makefile.vac	Sun Nov 20 11:11:53 2011 -0600
+++ b/sfxace/makefile.vac	Wed Jul 25 00:05:29 2012 -0500
@@ -47,7 +47,7 @@
 	 $(OBJECTS) dw.obj install.obj instsup.obj rexx.obj dirent.obj
 	 ..\install.def
 <<
-	rc -x2 ..\sfxos2.res sfxos2.exe
+	rc -x1 ..\sfxos2.res sfxos2.exe
 	lxlite sfxos2.exe
         copy sfxos2.exe ..\sfx.exe
 
--- a/win/dw.c	Sun Nov 20 11:11:53 2011 -0600
+++ b/win/dw.c	Wed Jul 25 00:05:29 2012 -0500
@@ -2,18 +2,25 @@
  * Dynamic Windows:
  *          A GTK like implementation of the Win32 GUI
  *
- * (C) 2000-2011 Brian Smith <brian@dbsoft.org>
- * (C) 2003-2011 Mark Hessling <m.hessling@qut.edu.au>
+ * (C) 2000-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2003-2011 Mark Hessling <mark@rexx.org>
  *
  */
+ 
+#ifdef AEROGLASS
+#define _WIN32_IE 0x0501
+#define WINVER 0x501
+#else
 #define _WIN32_IE 0x0500
 #define WINVER 0x500
+#endif
 #include <windows.h>
 #include <windowsx.h>
 #include <commctrl.h>
 #include <shlwapi.h>
 #include <shlobj.h>
 #include <userenv.h>
+#include <tchar.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -21,11 +28,33 @@
 #include <malloc.h>
 #include <io.h>
 #include <time.h>
+#define _USE_MATH_DEFINES
 #include <math.h>
 #include "dw.h"
 #ifdef BUILD_DLL
 #include "XBrowseForFolder.h"
 #endif
+#ifdef AEROGLASS
+#include <uxtheme.h>
+#endif
+#include <richedit.h>
+
+#define STATICCLASSNAME TEXT("STATIC")
+#define COMBOBOXCLASSNAME TEXT("COMBOBOX")
+#define LISTBOXCLASSNAME TEXT("LISTBOX")
+#define BUTTONCLASSNAME TEXT("BUTTON")
+#define POPUPMENUCLASSNAME TEXT("POPUPMENU")
+#define EDITCLASSNAME TEXT("EDIT")
+#define FRAMECLASSNAME TEXT("FRAME")
+#define SCROLLBARCLASSNAME TEXT("SCROLLBAR")
+
+#define ClassName TEXT("dynamicwindows")
+#define SplitbarClassName TEXT("dwsplitbar")
+#define ObjectClassName TEXT("dwobjectclass")
+#define BrowserClassName TEXT("dwbrowserclass")
+#define ScrollClassName TEXT("dwscrollclass")
+#define StatusbarClassName TEXT("dwstatusbar")
+#define DefaultFont NULL
 
 #ifdef GDIPLUS
 /* GDI+ Headers are not C compatible... so define what we need here instead */
@@ -60,15 +89,89 @@
   PropertyNotFound            = 19,
   PropertyNotSupported        = 20,
   ProfileNotFound             = 21 
-} Status;
-
-Status WINAPI GdipCreateBitmapFromFile(const WCHAR* filename, void **bitmap);
-Status WINAPI GdipCreateHBITMAPFromBitmap(void *bitmap, HBITMAP* hbmReturn, DWORD background);
-Status WINAPI GdipCreateHICONFromBitmap(void *bitmap, HICON *hbmReturn);
-Status WINAPI GdipDisposeImage(void *image);
-Status WINAPI GdipGetImagePixelFormat(void *image, INT *format);
-Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, void *output);
+} GpStatus;
+
+typedef enum {
+  UnitWorld,
+  UnitDisplay,
+  UnitPixel,
+  UnitPoint,
+  UnitInch,
+  UnitDocument,
+  UnitMillimeter
+} GpUnit;
+
+typedef enum  {
+  FlushIntentionFlush   = 0,
+  FlushIntentionSync    = 1 
+} GpFlushIntention;
+
+typedef enum {
+  QualityModeInvalid  = -1,
+  QualityModeDefault  = 0,
+  QualityModeLow      = 1,
+  QualityModeHigh     = 2
+} QualityMode;
+
+typedef enum  {
+  SmoothingModeInvalid     = QualityModeInvalid,
+  SmoothingModeDefault     = QualityModeDefault,
+  SmoothingModeHighSpeed   = QualityModeLow,
+  SmoothingModeHighQuality = QualityModeHigh,
+  SmoothingModeNone,
+  SmoothingModeAntiAlias
+} SmoothingMode;
+
+typedef void GpGraphics;
+typedef void GpPen;
+typedef void GpBrush;
+typedef void GpBitmap;
+typedef void GpImage;
+typedef POINT GpPoint;
+typedef DWORD ARGB;
+typedef float REAL;
+
+#define ALPHA_SHIFT 24
+#define RED_SHIFT   16
+#define GREEN_SHIFT 8
+#define BLUE_SHIFT  0
+#define ALPHA_MASK  ((ARGB) 0xff << ALPHA_SHIFT)
+
+#define MAKEARGB(a, r, g, b) \
+                (((ARGB) ((a) & 0xff) << ALPHA_SHIFT)| \
+                 ((ARGB) ((r) & 0xff) << RED_SHIFT)  | \
+                 ((ARGB) ((g) & 0xff) << GREEN_SHIFT)| \
+                 ((ARGB) ((b) & 0xff) << BLUE_SHIFT))
+
+/* Graphic conversion functions */
+GpStatus WINAPI GdipCreateBitmapFromFile(const WCHAR* filename, GpBitmap **bitmap);
+GpStatus WINAPI GdipCreateHBITMAPFromBitmap(GpBitmap *bitmap, HBITMAP* hbmReturn, DWORD background);
+GpStatus WINAPI GdipCreateHICONFromBitmap(GpBitmap *bitmap, HICON *hbmReturn);
+GpStatus WINAPI GdipDisposeImage(GpImage *image);
+GpStatus WINAPI GdipGetImagePixelFormat(GpImage *image, INT *format);
+/* Startup and Shutdown */
+GpStatus WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, void *output);
 VOID WINAPI GdiplusShutdown(ULONG_PTR token);
+/* Drawing functions */
+GpStatus WINAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
+GpStatus WINAPI GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics);
+GpStatus WINAPI GdipDeleteGraphics(GpGraphics *graphics);
+GpStatus WINAPI GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode);
+GpStatus WINAPI GdipCreatePen1(ARGB color, REAL width, GpUnit unit, GpPen **pen);
+GpStatus WINAPI GdipDeletePen(GpPen *pen);
+GpStatus WINAPI GdipCreateSolidFill(ARGB color, GpBrush **brush);
+GpStatus WINAPI GdipDeleteBrush(GpBrush *brush);
+GpStatus WINAPI GdipSetSolidFillColor(GpBrush *brush, ARGB color);
+GpStatus WINAPI GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1, INT x2, INT y2);
+GpStatus WINAPI GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, const GpPoint *points, INT count);
+GpStatus WINAPI GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height);
+GpStatus WINAPI GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height);
+GpStatus WINAPI GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle);
+GpStatus WINAPI GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, const GpPoint *points, INT count);
+GpStatus WINAPI GdipFillPolygon2I(GpGraphics *graphics, GpBrush *brush, const GpPoint *points, INT count);
+GpStatus WINAPI GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y, INT width, INT height);
+GpStatus WINAPI GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y, INT width, INT height);
+GpStatus WINAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention);
 
 /* Pixel format information */
 #define    PixelFormatIndexed      0x00010000 
@@ -101,13 +204,37 @@
 ULONG_PTR gdiplusToken; 
 #endif
 
+#ifdef AEROGLASS
+HRESULT (WINAPI *_DwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset) = 0;
+HRESULT (WINAPI *_DwmIsCompositionEnabled)(BOOL *pfEnabled) = 0;
+HTHEME (WINAPI *_OpenThemeData)(HWND hwnd, LPCWSTR pszClassList) = 0;
+HPAINTBUFFER (WINAPI *_BeginBufferedPaint)(HDC hdcTarget, const RECT *prcTarget, BP_BUFFERFORMAT dwFormat, BP_PAINTPARAMS *pPaintParams, HDC *phdc) = 0;
+HRESULT (WINAPI *_BufferedPaintSetAlpha)(HPAINTBUFFER hBufferedPaint, const RECT *prc, BYTE alpha) = 0;
+HRESULT (WINAPI *_DrawThemeTextEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, DWORD dwFlags, LPRECT pRect, const DTTOPTS *pOptions) = 0;
+HRESULT (WINAPI *_EndBufferedPaint)(HPAINTBUFFER hBufferedPaint, BOOL fUpdateTarget) = 0;
+HRESULT (WINAPI *_CloseThemeData)(HTHEME hTheme) = 0;
+BOOL _dw_composition = FALSE;
+COLORREF _dw_transparencykey = RGB(200,201,202);
+HANDLE hdwm = 0;
+#endif
+/* Aero related but separate functions and handles */
+HRESULT (WINAPI *_SetWindowTheme)(HWND hwnd, LPCWSTR pszSubAppName, LPCWSTR pszSubIdList) = 0;
+HANDLE huxtheme = 0;
+ 
+/* Needed for Rich Edit controls */
+HANDLE hrichedit = 0;
+
 /*
  * MinGW Is missing a bunch of definitions
  * so #define them here...
  */
 
-#if !defined( MIM_MENUDATA )
-# define MIM_MENUDATA 0x00000008
+#if !defined( _tstol )
+#if defined(UNICODE)
+# define _tstol _wtol
+#else
+# define _tstol atol
+#endif
 #endif
 #if !defined(PBS_MARQUEE)
 # define PBS_MARQUEE 0x08
@@ -119,7 +246,7 @@
 # define LVS_EX_DOUBLEBUFFER 0x10000
 #endif
 
-HWND popup = (HWND)NULL, DW_HWND_OBJECT = (HWND)NULL;
+HWND popup = (HWND)NULL, DW_HWND_OBJECT = (HWND)NULL, hwndTooltip = (HWND)0;
 
 HINSTANCE DWInstance = NULL;
 
@@ -143,7 +270,8 @@
  * an alternate temporary directory if TMP is not set, so we get the value
  * of TEMP and store it here.
  */
-static char _dw_alternate_temp_dir[MAX_PATH+1];
+static char _dw_alternate_temp_dir[MAX_PATH+1] = {0};
+static char _dw_exec_dir[MAX_PATH+1] = {0};
 
 int main(int argc, char *argv[]);
 
@@ -158,6 +286,10 @@
 DWORD _background;
 DWORD _hPen;
 DWORD _hBrush;
+#ifdef GDIPLUS
+DWORD _gpPen;
+DWORD _gpBrush;
+#endif
 
 BYTE _red[] = {   0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77,
            0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 };
@@ -168,12 +300,12 @@
 
 HBRUSH _colors[18];
 
-static int screenx, screeny;
 HFONT _DefaultFont = NULL;
 
 #if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
 LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 #endif
+LRESULT CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
 void _resize_notebook_page(HWND handle, int pageid);
 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
 int _lookup_icon(HWND handle, HICON hicon, int type);
@@ -181,6 +313,22 @@
 void _click_default(HWND handle);
 void _do_resize(Box *thisbox, int x, int y);
 
+/* Internal function to queue a window redraw */
+void _dw_redraw(HWND window, int skip)
+{
+    static HWND lastwindow = 0;
+    HWND redraw = lastwindow;
+    
+    if(skip && !window)
+        return;
+
+    lastwindow = window;
+    if(redraw != lastwindow && redraw)
+    {
+        dw_window_redraw(redraw);
+    }
+}
+
 typedef struct _sighandler
 {
    struct _sighandler   *next;
@@ -269,7 +417,7 @@
 
    argv = (char **)malloc(sizeof(char *) * ((*count)+1));
    argv[0] = malloc(260);
-   GetModuleFileName(DWInstance, argv[0], 260);
+   GetModuleFileNameA(DWInstance, argv[0], 260);
 
    argstart = tmp = start;
 
@@ -292,7 +440,7 @@
          else if(*tmp == ' ' && !inquotes)
          {
             *tmp = 0;
-            argv[loc] = strdup(argstart);
+            argv[loc] = _strdup(argstart);
 
             /* Push past any white space */
             while(*(tmp+1) == ' ')
@@ -310,7 +458,7 @@
          tmp++;
       }
       if(*argstart)
-         argv[loc] = strdup(argstart);
+         argv[loc] = _strdup(argstart);
    }
    argv[loc+1] = NULL;
    return argv;
@@ -330,6 +478,31 @@
 }
 #endif
 
+#ifdef UNICODE
+/* Macro and internal function to convert UTF8 to Unicode wide characters */
+#define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL)
+LPWSTR _myUTF8toWide(char *utf8string, void *outbuf)
+{
+   LPWSTR retbuf = outbuf;
+   
+   if(retbuf)
+      MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, retbuf, MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, NULL, 0) * sizeof(WCHAR));
+   return retbuf;
+}
+#define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
+char *_myWideToUTF8(LPWSTR widestring, void *outbuf)
+{
+   char *retbuf = outbuf;
+   
+   if(retbuf)
+      WideCharToMultiByte(CP_UTF8, 0, widestring, -1, retbuf, WideCharToMultiByte(CP_UTF8, 0, widestring, -1, NULL, 0, NULL, NULL), NULL, NULL);
+   return retbuf;
+}
+#else
+#define UTF8toWide(a) a
+#define WideToUTF8(a) a
+#endif
+
 DWORD GetDllVersion(LPCTSTR lpszDllName)
 {
 
@@ -392,7 +565,7 @@
 /* Section for loading files of types besides BMP and ICO and return HBITMAP or HICON */
 void *_dw_load_gpbitmap( char *filename )
 {
-   int found_ext = 0,i, wclen = (strlen(filename) + 6) * sizeof(wchar_t);
+   int i, wclen = (int)(strlen(filename) + 6) * sizeof(wchar_t);
    char *file = _alloca(strlen(filename) + 6);
    wchar_t *wfile = _alloca(wclen);
    void *image;
@@ -405,7 +578,7 @@
       if ( _access( file, 04 ) == 0 )
       {
          /* Convert to wide format */
-         MultiByteToWideChar(CP_ACP, 0, file, strlen(file)+1, wfile, wclen);
+         MultiByteToWideChar(CP_ACP, 0, file, (int)strlen(file)+1, wfile, wclen);
          if(!GdipCreateBitmapFromFile(wfile, &image))
              return image;
       }
@@ -540,26 +713,34 @@
 
    for(z=0;z<SIGNALMAX;z++)
    {
-      if(stricmp(signame, SignalTranslate[z].name) == 0)
+      if(_stricmp(signame, SignalTranslate[z].name) == 0)
          return SignalTranslate[z].message;
    }
    return 0L;
 }
 
-/* This function removes and handlers on windows and frees
- * the user memory allocated to it.
+/* This function removes any handlers on windows and frees
+ * the user memory and resources allocated to it.
  */
 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam)
 {
    ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
    HFONT oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
    HICON oldicon = (HICON)SendMessage(handle, WM_GETICON, 0, 0);
-   char tmpbuf[100];
-
+   TCHAR tmpbuf[100] = {0};
+   
+   TOOLINFO ti = { 0 };
+ 
+   ti.cbSize = sizeof(TOOLINFO);
+   ti.hwnd = handle;
+   ti.hinst = DWInstance;
+ 
+   SendMessage(hwndTooltip, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+      
    GetClassName(handle, tmpbuf, 99);
 
    /* Don't try to free memory from an OLE embedded IE */
-   if(strncmp(tmpbuf, "Internet Explorer_Server", 25) == 0)
+   if(_tcsncmp(tmpbuf, TEXT("Internet Explorer_Server"), 25) == 0)
       return TRUE;
 
    /* Delete font, icon and bitmap GDI objects in use */
@@ -568,39 +749,58 @@
    if(oldicon)
       DeleteObject(oldicon);
 
-   if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, STATICCLASSNAME, _tcslen(STATICCLASSNAME)+1)==0)
    {
       HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
 
       if(oldbitmap)
          DeleteObject(oldbitmap);
    }
-   if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0)
    {
       HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
+      HICON oldicon = (HICON)SendMessage(handle, BM_GETIMAGE, IMAGE_ICON, 0);
 
       if(oldbitmap)
          DeleteObject(oldbitmap);
-   }
-   else if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+      if(oldicon)
+         DestroyIcon(oldicon);
+   }
+#ifdef TOOLBAR   
+   /* Bitmap Buttons */
+   else if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+   {
+      HIMAGELIST imlist = (HIMAGELIST)SendMessage(handle, TB_GETIMAGELIST, 0, 0);
+      HIMAGELIST dimlist = (HIMAGELIST)SendMessage(handle, TB_GETDISABLEDIMAGELIST, 0, 0);
+      
+      SendMessage(handle, TB_SETIMAGELIST, 0, 0);
+      SendMessage(handle, TB_SETDISABLEDIMAGELIST, 0, 0);
+      
+      if(imlist)
+         ImageList_Destroy(imlist);
+      if(dimlist)
+         ImageList_Destroy(dimlist);
+   }
+#endif   
+   else if(_tcsnicmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1)==0)
    {
       Box *box = (Box *)thiscinfo;
 
       if(box && box->count && box->items)
          free(box->items);
    }
-   else if(strnicmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+   else if(_tcsnicmp(tmpbuf, SplitbarClassName, _tcslen(SplitbarClassName)+1)==0)
    {
       void *data = dw_window_get_data(handle, "_dw_percent");
 
       if(data)
          free(data);
    }
-   else if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)==0)
+   else if(_tcsnicmp(tmpbuf, WC_TREEVIEW, _tcslen(WC_TREEVIEW)+1)==0)
    {
       dw_tree_clear(handle);
    }
-   else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL)+1)==0) /* Notebook */
+   else if(_tcsnicmp(tmpbuf, WC_TABCONTROL, _tcslen(WC_TABCONTROL)+1)==0) /* Notebook */
    {
       NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
 
@@ -621,7 +821,7 @@
          free(array);
       }
    }
-   else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
+   else if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0)
    {
       /* for spinbuttons, we need to get the spinbutton's "buddy", the text window associated and destroy it */
       ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
@@ -634,7 +834,8 @@
 
    if(thiscinfo)
    {
-      SubclassWindow(handle, thiscinfo->pOldProc);
+      if(thiscinfo->pOldProc)
+         SetWindowLongPtr(handle, GWLP_WNDPROC, (LPARAM)(WNDPROC)thiscinfo->pOldProc);
 
       /* Delete the brush so as not to leak GDI objects */
       if(thiscinfo->hbrush)
@@ -701,7 +902,7 @@
  */
 int _validate_focus(HWND handle)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    if(!handle)
       return 0;
@@ -714,31 +915,31 @@
    /* These are the window classes which can
     * obtain input focus.
     */
-   if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1)==0 ||          /* Entryfield */
-      strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0 ||      /* Button */
-      strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0 ||  /* Combobox */
-      strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME)+1)==0 ||    /* List box */
-      strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0 ||            /* Spinbutton */
-      strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0 ||        /* Slider */
-      strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)== 0 ||             /* Container */
-      strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)== 0)               /* Tree */
+   if(_tcsnicmp(tmpbuf, EDITCLASSNAME, _tcslen(EDITCLASSNAME)+1)==0 ||          /* Entryfield */
+      _tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0 ||      /* Button */
+      _tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0 ||  /* Combobox */
+      _tcsnicmp(tmpbuf, LISTBOXCLASSNAME, _tcslen(LISTBOXCLASSNAME)+1)==0 ||    /* List box */
+      _tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0 ||            /* Spinbutton */
+      _tcsnicmp(tmpbuf, TRACKBAR_CLASS, _tcslen(TRACKBAR_CLASS)+1)==0 ||        /* Slider */
+      _tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW)+1)== 0 ||             /* Container */
+      _tcsnicmp(tmpbuf, WC_TREEVIEW, _tcslen(WC_TREEVIEW)+1)== 0)               /* Tree */
       return 1;
    return 0;
 }
 
 HWND _normalize_handle(HWND handle)
 {
-   char tmpbuf[100] = "";
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
-   if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) /* Spinner */
+   if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS))==0) /* Spinner */
    {
       ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
       if(cinfo && cinfo->buddy)
          return cinfo->buddy;
    }
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) /* Combobox */
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME))==0) /* Combobox */
    {
       ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
@@ -752,7 +953,7 @@
 {
    int z;
    static HWND lasthwnd, firsthwnd;
-    static int finish_searching;
+   static int finish_searching;
 
    /* Start is 2 when we have cycled completely and
     * need to set the focus to the last widget we found
@@ -823,11 +1024,11 @@
          }
          else
          {
-            char tmpbuf[100] = "";
+            TCHAR tmpbuf[100] = {0};
 
             GetClassName(box->items[z].hwnd, tmpbuf, 99);
 
-            if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            if(_tcsncmp(tmpbuf, SplitbarClassName, _tcslen(SplitbarClassName)+1)==0)
             {
                /* Then try the bottom or right box */
                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
@@ -851,7 +1052,7 @@
                      return 1;
                }
             }
-            else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) /* Notebook */
+            else if(_tcsnicmp(tmpbuf, WC_TABCONTROL, _tcslen(WC_TABCONTROL))==0) /* Notebook */
             {
                NotebookPage **array = (NotebookPage **)dw_window_get_data(box->items[z].hwnd, "_dw_array");
                int pageid = TabCtrl_GetCurSel(box->items[z].hwnd);
@@ -869,7 +1070,7 @@
                   }
                }
             }
-            else if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName))==0) /* Scroll Box */
+            else if(_tcsnicmp(tmpbuf, ScrollClassName, _tcslen(ScrollClassName))==0) /* Scroll Box */
             {
                 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box->items[z].hwnd, GWLP_USERDATA);
                 Box *scrollbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
@@ -887,7 +1088,7 @@
 {
    int z;
    static HWND lasthwnd, firsthwnd;
-    static int finish_searching;
+   static int finish_searching;
 
    /* Start is 2 when we have cycled completely and
     * need to set the focus to the last widget we found
@@ -958,11 +1159,11 @@
          }
          else
          {
-            char tmpbuf[100] = "";
+            TCHAR tmpbuf[100] = {0};
 
             GetClassName(box->items[z].hwnd, tmpbuf, 99);
 
-            if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            if(_tcsncmp(tmpbuf, SplitbarClassName, _tcslen(SplitbarClassName)+1)==0)
             {
                /* Try the top or left box */
                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
@@ -986,7 +1187,7 @@
                      return 1;
                }
             }
-            else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) /* Notebook */
+            else if(_tcsnicmp(tmpbuf, WC_TABCONTROL, _tcslen(WC_TABCONTROL))==0) /* Notebook */
             {
                NotebookPage **array = (NotebookPage **)dw_window_get_data(box->items[z].hwnd, "_dw_array");
                int pageid = TabCtrl_GetCurSel(box->items[z].hwnd);
@@ -1004,7 +1205,7 @@
                   }
                }
             }
-            else if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName))==0) /* Scroll Box */
+            else if(_tcsnicmp(tmpbuf, ScrollClassName, _tcslen(ScrollClassName))==0) /* Scroll Box */
             {
                 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box->items[z].hwnd, GWLP_USERDATA);
                 Box *scrollbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
@@ -1024,14 +1225,14 @@
 void _initial_focus(HWND handle)
 {
    Box *thisbox;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    if(!handle)
       return;
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, ClassName, strlen(ClassName))!=0)
+   if(_tcsnicmp(tmpbuf, ClassName, _tcslen(ClassName)+1)!=0)
       return;
 
 
@@ -1051,11 +1252,21 @@
    /* Find the toplevel window */
    while((box = GetParent(lastbox)))
    {
+      /* If it hasn't been packed yet.. */
+      if(box == DW_HWND_OBJECT)
+         return 0;
       lastbox = box;
    }
    if(lastbox)
-      return lastbox;
-   return handle;
+   {
+      TCHAR tmpbuf[100] = {0};
+      
+      GetClassName(lastbox, tmpbuf, 99);
+      
+      if(_tcsncmp(tmpbuf, ClassName, _tcslen(ClassName)+1)==0)
+         return lastbox;
+   }
+   return 0;
 }
 
 /* This function finds the current widget in the
@@ -1103,193 +1314,107 @@
          _focus_check_box_back(thisbox, handle, 2, 0);
    }
 }
-
 /* 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)
    {
-      char *text = dw_window_get_text(thisbox->grouphwnd);
-
-      thisbox->grouppady = 0;
-
-      if(text)
-      {
-         dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
-         dw_free(text);
-      }
-
-      if(thisbox->grouppady)
-         thisbox->grouppady += 3;
-      else
-         thisbox->grouppady = 6;
-
-      thisbox->grouppadx = 6;
-
-      (*usedx) += thisbox->grouppadx;
-      (*usedpadx) += thisbox->grouppadx;
-      (*usedy) += thisbox->grouppady;
-      (*usedpady) += thisbox->grouppady;
-   }
-
+      /* Only calculate the size on the first pass...
+       * use the cached values on second.
+       */
+      if(pass == 1)
+      {
+         char *text = dw_window_get_text(thisbox->grouphwnd);
+
+         thisbox->grouppady = 9;
+
+         if(text)
+         {
+            if(*text)
+               dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
+            dw_free(text);
+         }
+         /* If the string height is less than 9...
+          * set it to 9 anyway since that is the minimum.
+          */
+         if(thisbox->grouppady < 9)
+            thisbox->grouppady = 9;
+         
+         if(thisbox->grouppady)
+            thisbox->grouppady += 3;
+         else
+            thisbox->grouppady = 6;
+
+         thisbox->grouppadx = 6;
+      }
+
+      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;
-
-               /* 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;
+               
+               /* If the box has no contents but is expandable... default the size to 1 */
+               if(!thisbox->items[z].width && thisbox->items[z].hsize)
+                  thisbox->items[z].width = 1;
+               if(!thisbox->items[z].height && thisbox->items[z].vsize)
+                  thisbox->items[z].height = 1;
+               
+               (*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 = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-            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].pad*2) + thisbox->items[z].width;
-
          if(itemwidth > uxmax)
             uxmax = itemwidth;
+            
          if(thisbox->items[z].hsize != SIZEEXPAND)
          {
             if(itemwidth > upxmax)
@@ -1297,30 +1422,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
       {
-         if(thisbox->items[z].width == -1)
-         {
-            /* figure out how much space this item requires */
-            /* thisbox->items[z].width = */
-         }
-         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)
@@ -1330,150 +1442,109 @@
          }
          else
          {
-            if(thisbox->items[z].pad*2 > upymax)
-               upymax = thisbox->items[z].pad*2;
-         }
-      }
-      else
-      {
-         if(thisbox->items[z].height == -1)
-         {
-            /* figure out how much space this item requires */
-            /* thisbox->items[z].height = */
-         }
+            if(itempad > upymax)
+               upymax = itempad;
+         }
+         thisbox->minwidth += itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+            thisbox->usedpadx += itemwidth;
          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;
-            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)
-         {
-            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)
+            {
+               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)
             {
-               vectorx++;
-               vectory++;
+               int expandabley = thisbox->minheight - thisbox->usedpady;
+                
+               if(expandabley)
+                  height = (int)(((float)height / (float)expandabley) * (float)(y - thisbox->usedpady));
             }
-
-            /* 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;
-
+            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;
+            TCHAR tmpbuf[100] = {0};
+               
             GetClassName(handle, tmpbuf, 99);
 
-            if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+            if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(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)
+#ifdef TOOLBAR
+            /* Bitmap Buttons */
+            else if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+            {
+               SendMessage(handle, TB_SETBUTTONSIZE, 0, MAKELPARAM(width, height));
+
+               MoveWindow(handle, currentx + pad, currenty + pad, width, height, FALSE);
+            }
+#endif
+            else if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(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)
+            else if(_tcsncmp(tmpbuf, ScrollClassName, _tcslen(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;
@@ -1486,7 +1557,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;
@@ -1494,32 +1565,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 - 1;
                     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 - 1;
                     hsi.nPage = rect.right;
                     if(hsi.nPos > hsi.nMax)
                     {
@@ -1533,21 +1604,19 @@
                 /* Layout the content of the scrollbox */
                 _do_resize(thisbox, cx, cy);
             }
-            else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            else if(_tcsncmp(tmpbuf, SplitbarClassName, _tcslen(SplitbarClassName)+1)==0)
             {
                /* 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 && width > 0 && height > 0)
+                  _handle_splitbar_resize(handle, *percent, type, width, height);
             }
-            else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
+            else if(_tcsnicmp(tmpbuf, STATICCLASSNAME, _tcslen(STATICCLASSNAME)+1)==0)
             {
                /* Handle special case Vertically Center static text */
                ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
@@ -1555,45 +1624,56 @@
                if(cinfo && cinfo->vcenter)
                {
                   /* We are centered so calculate a new position */
-                  char tmpbuf[1024];
-                  int textheight, diff, total = height + vectory;
-
-                  GetWindowText(handle, tmpbuf, 1023);
+                  TCHAR tmpbuf[1024] = {0}, *thisbuf = tmpbuf;
+                  int textheight, diff, total = height;
+
+                  GetWindowText(handle, thisbuf, 1023);
 
                   /* Figure out how big the text is */
-                  dw_font_text_extents_get(handle, 0, tmpbuf, 0, &textheight);
+                  dw_font_text_extents_get(handle, 0, WideToUTF8(thisbuf), 0, &textheight);
 
                   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);
+               if(*depth)
+                  MoveWindow(handle, currentx + pad, currenty + pad, width, height, FALSE);
+               else /* FIXME: This is a hack to generate WM_PAINT messages for items on the top-level */
+                  SetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad, width, height, 0);
+
+               /* 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)--;
                   }
-
                }
             }
 
             /* Notebook dialog requires additional processing */
-            if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0)
+            if(_tcsncmp(tmpbuf, WC_TABCONTROL, _tcslen(WC_TABCONTROL))==0)
             {
                RECT rect;
                NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
@@ -1605,10 +1685,11 @@
                   TabCtrl_AdjustRect(handle,FALSE,&rect);
                   MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
                            rect.right - rect.left, rect.bottom-rect.top, FALSE);
+                  dw_window_redraw(array[pageid]->hwnd);
                }
             }
             /* 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(_tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW)+1)==0 && width > 10 && height > 10)
             {            
                 int index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_cursor"));
                 
@@ -1616,14 +1697,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);
-         }
-      }
-   }
-   return 0;
+               currenty += height + (pad * 2);
+         }
+      }
+   }
 }
 
 void _do_resize(Box *thisbox, int x, int y)
@@ -1632,19 +1713,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);
       }
    }
 }
@@ -1672,7 +1747,7 @@
    /*case SB_PAGEDOWN:*/
    case SB_PAGERIGHT:
       pos = si.nPos + si.nPage;
-      if(pos > (si.nMax - si.nPage) + 1)
+      if(pos > (int)(si.nMax - si.nPage) + 1)
          pos = (si.nMax - si.nPage) + 1;
       return pos;
    /*case SB_LINEUP:*/
@@ -1684,7 +1759,7 @@
    /*case SB_LINEDOWN:*/
    case SB_LINERIGHT:
       pos = si.nPos + 1;
-      if(pos > (si.nMax - si.nPage) + 1)
+      if(pos > (int)(si.nMax - si.nPage) + 1)
          pos = (si.nMax - si.nPage) + 1;
       return pos;
    }
@@ -1733,16 +1808,15 @@
       int is_checked;
       sprintf( buffer, "_dw_ischecked%d", id );
       is_checked = (int)dw_window_get_data(DW_HWND_OBJECT, buffer);
-      is_checked = (is_checked) ? 0 : 1;
-      dw_menu_item_set_check( window, id, is_checked );
+      is_checked = (is_checked) ? DW_MIS_UNCHECKED : DW_MIS_CHECKED;
+      dw_menu_item_set_state( window, id, is_checked );
    }
 }
 
 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */
-BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    int result = -1, taskbar = FALSE;
-   static int command_active = 0;
    SignalHandler *tmp = Root;
    void (*windowfunc)(PVOID);
    ULONG origmsg = msg;
@@ -1764,9 +1838,6 @@
 
    if (result == -1)
    {
-      /* Avoid infinite recursion */
-      command_active = 1;
-
       /* Find any callbacks for this function */
       while (tmp)
       {
@@ -1905,13 +1976,19 @@
                   break;
                case WM_CHAR:
                   {
-                     int (*keypressfunc)(HWND, char, int, int, void *) = tmp->signalfunction;
+                     int (*keypressfunc)(HWND, char, int, int, void *, char *) = tmp->signalfunction;
 
                      if(hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window)
                      {
                         int special = 0;
-                        char ch = 0;
-
+                        char *utf8 = NULL, ch[2] = {0};
+#ifdef UNICODE             
+                        WCHAR uc[2] = { 0 };
+                        
+                        uc[0] = (WCHAR)mp1;
+                        utf8 = WideToUTF8(uc);
+#endif                        
+                        
                         if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
                            special |= KC_SHIFT;
                         if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
@@ -1920,9 +1997,9 @@
                            special |= KC_ALT;
 
                         if(origmsg == WM_CHAR && mp1 < 128)
-                           ch = (char)mp1;
-
-                        result = keypressfunc(tmp->window, ch, mp1, special, tmp->data);
+                           ch[0] = (char)mp1;
+
+                        result = keypressfunc(tmp->window, ch[0], (int)mp1, special, tmp->data, utf8 ? utf8 : ch);
                         tmp = NULL;
                      }
                   }
@@ -1964,11 +2041,11 @@
                      {
                         NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2;
                         NMLISTVIEW FAR *lem=(NMLISTVIEW FAR *)mp2;
-                        char tmpbuf[100];
+                        TCHAR tmpbuf[100] = {0};
 
                         GetClassName(tem->hdr.hwndFrom, tmpbuf, 99);
 
-                        if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0)
+                        if(_tcsnicmp(tmpbuf, WC_TREEVIEW, _tcslen(WC_TREEVIEW))==0)
                         {
                            if(tem->hdr.code == TVN_SELCHANGED && tmp->message == TVN_SELCHANGED)
                            {
@@ -2005,7 +2082,7 @@
                               if(tmp->window == tem->hdr.hwndFrom)
                               {
                                  int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
-                                 HTREEITEM hti, last;
+                                 HTREEITEM hti;
                                  TVITEM tvi;
                                  TVHITTESTINFO thi;
                                  void **ptrs = NULL;
@@ -2018,7 +2095,6 @@
 
                                  MapWindowPoints(HWND_DESKTOP, tmp->window, &thi.pt, 1);
 
-                                 last = TreeView_GetSelection(tmp->window);
                                  hti = TreeView_HitTest(tmp->window, &thi);
 
                                  if(hti)
@@ -2036,7 +2112,7 @@
                               }
                            }
                         }
-                        else if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0)
+                        else if(_tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW)+1)==0)
                         {
                            if((lem->hdr.code == LVN_ITEMCHANGED && (lem->uChanged & LVIF_STATE)) && tmp->message == TVN_SELCHANGED)
                            {
@@ -2090,6 +2166,16 @@
                            tmp = NULL;
                         }
                      }
+                     else if(tmp->message == WM_VSCROLL)
+                     {
+                        NMUPDOWN FAR *tem=(NMUPDOWN FAR *)mp2;
+                        if(tmp->window == tem->hdr.hwndFrom && tem->hdr.code == UDN_DELTAPOS)
+                        {
+                           int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
+                           result = valuechangefunc(tmp->window, tem->iPos + tem->iDelta, tmp->data);
+                           tmp = NULL;
+                        }
+                     }
                   }
                   break;
                case WM_COMMAND:
@@ -2111,6 +2197,21 @@
                            tmp = NULL;
                         }
                      }
+#ifdef TOOLBAR                     
+                     else if (message == BN_CLICKED && tmp->message == WM_COMMAND && tmp->window == (HWND)mp2)
+                     {
+                        TCHAR tmpbuf[100] = {0};
+
+                        GetClassName((HWND)mp2, tmpbuf, 99);
+
+                        /* Make sure this isn't a button, because it will have already been handled */
+                        if (_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1) != 0)
+                        {
+                           result = clickfunc(tmp->window, tmp->data);
+                           tmp = NULL;
+                        }
+                     }
+#endif                     
                      else if (tmp->id && passthru == tmp->id)
                      {
                         HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window);
@@ -2136,7 +2237,7 @@
                case WM_HSCROLL:
                case WM_VSCROLL:
                   {
-                     char tmpbuf[100] = "";
+                     TCHAR tmpbuf[100] = {0};
                      HWND handle = (HWND)mp2;
                      int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
 
@@ -2145,7 +2246,7 @@
                          GetClassName(hWnd, tmpbuf, 99);
                      }
 
-                     if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
+                     if (_tcsnicmp(tmpbuf, TRACKBAR_CLASS, _tcslen(TRACKBAR_CLASS)+1)==0)
                      {
 
                         if (handle == tmp->window)
@@ -2161,7 +2262,7 @@
                            tmp = NULL;
                         }
                      }
-                     else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0)
+                     else if(_tcsnicmp(tmpbuf, SCROLLBARCLASSNAME, _tcslen(SCROLLBARCLASSNAME)+1)==0)
                      {
                         if(handle == tmp->window)
                         {
@@ -2184,12 +2285,47 @@
          if(tmp)
             tmp = tmp->next;
       }
-      command_active = 0;
    }
 
    /* Now that any handlers are done... do normal processing */
    switch( msg )
    {
+#ifdef AEROGLASS   
+   case WM_DWMCOMPOSITIONCHANGED:
+      {
+         LONG_PTR styleex = GetWindowLongPtr(hWnd, GWL_EXSTYLE);
+         
+         if(_DwmIsCompositionEnabled)
+            _DwmIsCompositionEnabled(&_dw_composition);
+         
+         /* If we are no longer compositing... disable layered windows */
+         if(!_dw_composition && (styleex & WS_EX_LAYERED))
+         {
+            MARGINS mar = {0};
+            
+            SetWindowLongPtr(hWnd, GWL_EXSTYLE, styleex & ~WS_EX_LAYERED);
+            if(_DwmExtendFrameIntoClientArea)
+               _DwmExtendFrameIntoClientArea(hWnd, &mar);
+         }
+      }
+      break;
+#endif
+#ifdef AEROGLASS1      
+   case WM_ERASEBKGND: 
+      if(_dw_composition && (GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED))
+      {
+         static HBRUSH hbrush = 0;
+         RECT rect;
+         
+         if(!hbrush)
+            hbrush = CreateSolidBrush(_dw_transparencykey);
+            
+         GetClientRect(hWnd, &rect);
+         FillRect((HDC)mp1, &rect, hbrush);
+         return TRUE;
+      }
+      break;
+#endif      
    case WM_PAINT:
       {
          PAINTSTRUCT ps;
@@ -2260,7 +2396,6 @@
    case WM_VSCROLL:
       {
          HWND handle = (HWND)mp2;
-         char tmpbuf[100];
          int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT;
 
          if(dw_window_get_data(handle, "_dw_scrollbar"))
@@ -2272,8 +2407,10 @@
          }
          else
          {
+            TCHAR tmpbuf[100] = {0};
+            
             GetClassName( hWnd, tmpbuf, 99 );
-            if ( strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1 ) == 0 )
+            if ( _tcsnicmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1 ) == 0 )
             {
                _HandleScroller(hWnd, bar, (int)HIWORD(mp1), (int)LOWORD(mp1));
             }
@@ -2318,74 +2455,16 @@
    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLORSCROLLBAR:
    case WM_CTLCOLORDLG:
-      {
-         ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
-         if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-         {
-            /* Handle foreground */
-            if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
-            {
-               if(thiscinfo->fore != DW_CLR_DEFAULT)
-               {
-                  SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
-                                       _green[thiscinfo->fore],
-                                       _blue[thiscinfo->fore]));
-               }
-            }
-            else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-            {
-               SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
-                                    DW_GREEN_VALUE(thiscinfo->fore),
-                                    DW_BLUE_VALUE(thiscinfo->fore)));
-            }
-            /* Handle background */
-            if(thiscinfo->back > -1 && thiscinfo->back < 18)
-            {
-               if(thiscinfo->back == DW_CLR_DEFAULT)
-               {
-                  HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
-
-                  SelectObject((HDC)mp1, hbr);
-                  return (LONG)hbr;
-               }
-               else
-               {
-                  SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
-                                     _green[thiscinfo->back],
-                                     _blue[thiscinfo->back]));
-                  if(thiscinfo->hbrush)
-                     DeleteObject(thiscinfo->hbrush);
-                  thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
-                                                 _green[thiscinfo->back],
-                                                 _blue[thiscinfo->back]));
-                  SelectObject((HDC)mp1, thiscinfo->hbrush);
-               }
-               return (LONG)thiscinfo->hbrush;
-            }
-            else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
-            {
-               SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
-                                     DW_GREEN_VALUE(thiscinfo->back),
-                                     DW_BLUE_VALUE(thiscinfo->back)));
-               if(thiscinfo->hbrush)
-                  DeleteObject(thiscinfo->hbrush);
-               thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
-                                              DW_GREEN_VALUE(thiscinfo->back),
-                                              DW_BLUE_VALUE(thiscinfo->back)));
-               SelectObject((HDC)mp1, thiscinfo->hbrush);
-               return (LONG)thiscinfo->hbrush;
-            }
-         }
-
-      }
-      break;
+      return _colorwndproc(hWnd, msg, mp1, mp2);
    }
    if(result != -1)
+   {
+      /* Make sure any queued redraws are handled */
+      _dw_redraw(0, FALSE);
+      /* Then finally return */
       return result;
-   else
-   {
-      return DefWindowProc(hWnd, msg, mp1, mp2);
-   }
+   }
+   return DefWindowProc(hWnd, msg, mp1, mp2);
 }
 
 VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
@@ -2393,7 +2472,7 @@
    _wndproc(hwnd, msg, (WPARAM)idEvent, 0);
 }
 
-BOOL CALLBACK _framewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _framewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    switch( msg )
    {
@@ -2408,16 +2487,22 @@
    case WM_MOUSEMOVE:
       _wndproc(hWnd, msg, mp1, mp2);
       break;
-#if 0
-   case WM_ERASEBKGND:
-      {
-         ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-         if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-            return FALSE;
+#ifdef AEROGLASS   
+   case WM_ERASEBKGND: 
+      if(_dw_composition && (GetWindowLongPtr(_toplevel_window(hWnd), GWL_EXSTYLE) & WS_EX_LAYERED))
+      {
+         static HBRUSH hbrush = 0;
+         RECT rect;
+         
+         if(!hbrush)
+            hbrush = CreateSolidBrush(_dw_transparencykey);
+            
+         GetClientRect(hWnd, &rect);
+         FillRect((HDC)mp1, &rect, hbrush);
+         return TRUE;
       }
       break;
-#endif
+#endif      
    case WM_PAINT:
       {
          ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
@@ -2491,9 +2576,9 @@
    return DefWindowProc(hWnd, msg, mp1, mp2);
 }
 
-BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-   BOOL rcode = TRUE;
+LRESULT CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   LRESULT rcode = TRUE;
 
    switch( msg )
    {
@@ -2529,7 +2614,7 @@
    return rcode;
 }
 
-BOOL CALLBACK _spinnerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _spinnerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    ColorInfo *cinfo;
 
@@ -2547,7 +2632,7 @@
       case WM_RBUTTONDOWN:
       case WM_KEYDOWN:
          {
-            BOOL ret;
+            LRESULT ret;
 
             if(!cinfo || !cinfo->pOldProc)
                ret = DefWindowProc(hWnd, msg, mp1, mp2);
@@ -2569,7 +2654,7 @@
       case WM_RBUTTONUP:
       case WM_KEYUP:
          {
-            BOOL ret;
+            LRESULT ret;
 
             if(!cinfo || !cinfo->pOldProc)
                ret = DefWindowProc(hWnd, msg, mp1, mp2);
@@ -2591,7 +2676,7 @@
          {
             if(mp1 == 100)
             {
-               BOOL ret;
+               LRESULT ret;
 
                if(cinfo && cinfo->buddy)
                   SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
@@ -2614,12 +2699,12 @@
          {
             if(cinfo->buddy)
             {
-               char tempbuf[100] = "";
+               TCHAR tempbuf[100] = { 0 };
                long position;
 
                GetWindowText(cinfo->buddy, tempbuf, 99);
 
-               position = atol(tempbuf);
+               position = _tstol(tempbuf);
 
                SendMessage(hWnd, UDM_SETPOS32, 0, (LPARAM)position);
             }
@@ -2635,14 +2720,14 @@
 
 void _click_default(HWND handle)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
    /* These are the window classes which can
     * obtain input focus.
     */
-   if (strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0)
+   if (_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0)
    {
       /* Generate click on default item */
       SignalHandler *tmp = Root;
@@ -2668,17 +2753,18 @@
       SetFocus(handle);
 }
 
-BOOL CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+/* Subclass function that will handle setting colors on controls */
+LRESULT CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    ColorInfo *cinfo;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
    WNDPROC pOldProc = 0;
-   int ret = -1;
+   LRESULT ret = -1;
 
    cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
 
    GetClassName(hWnd, tmpbuf, 99);
-   if(strcmp(tmpbuf, FRAMECLASSNAME) == 0)
+   if(_tcsncmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1) == 0)
       cinfo = &(((Box *)cinfo)->cinfo);
 
    if ( msg == WM_MOUSEMOVE || msg == WM_USER+2 )
@@ -2804,7 +2890,7 @@
 
                val = (long)SendMessage(cinfo->buddy, UDM_GETPOS32, 0, 0);
 
-               sprintf(tmpbuf, "%ld", val);
+               _sntprintf(tmpbuf, 99, TEXT("%ld"), val);
                SetWindowText(hWnd, tmpbuf);
             }
          }
@@ -2820,64 +2906,74 @@
             ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
             if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
             {
+               int thisback = thiscinfo->back;
+               
                /* Handle foreground */
-               if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
+               if(thiscinfo->fore != DW_CLR_DEFAULT)
                {
-                  if(thiscinfo->fore != DW_CLR_DEFAULT)
-                  {
-                     SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
-                                          _green[thiscinfo->fore],
-                                          _blue[thiscinfo->fore]));
-                  }
-               }
-               else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-               {
-                  SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
-                                       DW_GREEN_VALUE(thiscinfo->fore),
-                                       DW_BLUE_VALUE(thiscinfo->fore)));
+                  int fore = _internal_color(thiscinfo->fore);
+               
+                  SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(fore),
+                                       DW_GREEN_VALUE(fore),
+                                       DW_BLUE_VALUE(fore)));
                }
                /* Handle background */
-               if(thiscinfo->back > -1 && thiscinfo->back < 18)
+               if(thiscinfo->back == DW_RGB_TRANSPARENT)
+               {
+                  ColorInfo *parentcinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+                  
+                  if(parentcinfo && parentcinfo->back != -1)
+                     thisback = parentcinfo->back;
+               }
+               if(thisback == DW_CLR_DEFAULT)
                {
-                  if(thiscinfo->back == DW_CLR_DEFAULT)
-                  {
-                     HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
-
-                     SetBkColor((HDC)mp1, GetSysColor(COLOR_3DFACE));
-
-
-                     SelectObject((HDC)mp1, hbr);
-                     return (LONG)hbr;
-                  }
-                  else
-                  {
-                     SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
-                                        _green[thiscinfo->back],
-                                        _blue[thiscinfo->back]));
-                     if(thiscinfo->hbrush)
-                        DeleteObject(thiscinfo->hbrush);
-                     thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
-                                                    _green[thiscinfo->back],
-                                                    _blue[thiscinfo->back]));
-                     SelectObject((HDC)mp1, thiscinfo->hbrush);
-                  }
-                  return (LONG)thiscinfo->hbrush;
+                  HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
+
+                  SetBkColor((HDC)mp1, GetSysColor(COLOR_3DFACE));
+
+                  SelectObject((HDC)mp1, hbr);
+                  return (LONG)hbr;
                }
-               else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
+               else if(thisback != -1 && thisback != DW_RGB_TRANSPARENT)
                {
-                  SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
-                                     DW_GREEN_VALUE(thiscinfo->back),
-                                     DW_BLUE_VALUE(thiscinfo->back)));
+                  int back = _internal_color(thisback);
+                  
+                  SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(back),
+                                     DW_GREEN_VALUE(back),
+                                     DW_BLUE_VALUE(back)));
                   if(thiscinfo->hbrush)
                      DeleteObject(thiscinfo->hbrush);
-                  thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
-                                                 DW_GREEN_VALUE(thiscinfo->back),
-                                                 DW_BLUE_VALUE(thiscinfo->back)));
+                  thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(back),
+                                                 DW_GREEN_VALUE(back),
+                                                 DW_BLUE_VALUE(back)));
                   SelectObject((HDC)mp1, thiscinfo->hbrush);
                   return (LONG)thiscinfo->hbrush;
                }
             }
-
+ #ifdef AEROGLASS
+            switch(msg)
+            {
+               case WM_CTLCOLORSTATIC:
+               case WM_CTLCOLORBTN:
+               case WM_CTLCOLORDLG:
+                  {
+                     
+                     if((_dw_composition && GetWindowLongPtr(_toplevel_window(hWnd), GWL_EXSTYLE) & WS_EX_LAYERED) && 
+                        (!thiscinfo || (thiscinfo && (thiscinfo->back == -1 || thiscinfo->back == DW_RGB_TRANSPARENT))))
+                     {
+                        if(!(msg == WM_CTLCOLORSTATIC && SendMessage((HWND)mp2, STM_GETIMAGE, IMAGE_BITMAP, 0)))
+                        {
+                           SetBkColor((HDC)mp1, _dw_transparencykey);
+                           if(thiscinfo->hbrush)
+                              DeleteObject(thiscinfo->hbrush);
+                           thiscinfo->hbrush = CreateSolidBrush(_dw_transparencykey);
+                           SelectObject((HDC)mp1, thiscinfo->hbrush);
+                           return (LONG)thiscinfo->hbrush;
+                        }
+                     }
+                  }
+            }
+#endif
          }
          break;
       }
@@ -2893,7 +2989,7 @@
 }
 
 /* Window procedure for container/listview */
-BOOL CALLBACK _containerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _containerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    ContainerInfo *continfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
 
@@ -2907,7 +3003,7 @@
    case WM_PAINT:
        if(continfo->cinfo.pOldProc && (continfo->even != DW_RGB_TRANSPARENT || continfo->odd != DW_RGB_TRANSPARENT))
        {
-            RECT rectUpd, rectDestin, rect;
+            RECT rectUpd, rectDestin, rectThis, *rect = &rectThis;
             int iItems, iTop, i;
             COLORREF c;
 
@@ -2925,7 +3021,7 @@
             for(i=iTop; i<=(iTop+iItems+1); i++) 
             {
                 /* if row rectangle intersects update rectangle then it requires re-drawing */
-                if(ListView_GetItemRect(hWnd, i, &rect, LVIR_BOUNDS) && IntersectRect(&rectDestin, &rectUpd, &rect)) 
+                if(ListView_GetItemRect(hWnd, i, rect, LVIR_BOUNDS) && IntersectRect(&rectDestin, &rectUpd, rect)) 
                 {
                     /* change text background colour accordingly */
                     c = (i % 2) ? continfo->odd : continfo->even;
@@ -3047,10 +3143,10 @@
    return CallWindowProc(continfo->cinfo.pOldProc, hWnd, msg, mp1, mp2);
 }
 
-BOOL CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    ContainerInfo *cinfo;
-   int ret = -1;
+   LRESULT ret = -1;
 
    cinfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
 
@@ -3110,23 +3206,20 @@
 
 void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
 {
-   HWND handle1, handle2;
-   Box *tmp;
+   HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+   HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+
+   ShowWindow(handle1, SW_HIDE);
+   ShowWindow(handle2, SW_HIDE);
 
    if(type == DW_HORZ)
    {
       int newx = x;
       float ratio = (float)percent/(float)100.0;
-
-      handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-      handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-      tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
+      Box *tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
 
       newx = (int)((float)newx * ratio) - (SPLITBAR_WIDTH/2);
 
-      ShowWindow(handle1, SW_HIDE);
-      ShowWindow(handle2, SW_HIDE);
-
       MoveWindow(handle1, 0, 0, newx, y, FALSE);
       _do_resize(tmp, newx - 1, y - 1);
 
@@ -3143,24 +3236,18 @@
    {
       int newy = y;
       float ratio = (float)(100.0-percent)/(float)100.0;
-
-      handle1 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-      handle2 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-      tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
+      Box *tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
 
       newy = (int)((float)newy * ratio) - (SPLITBAR_WIDTH/2);
 
-      ShowWindow(handle1, SW_HIDE);
-      ShowWindow(handle2, SW_HIDE);
-
-      MoveWindow(handle1, 0, y - newy, x, newy, FALSE);
+      MoveWindow(handle2, 0, y - newy, x, newy, FALSE);
       _do_resize(tmp, x - 1, newy - 1);
 
-      tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
+      tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
 
       newy = y - newy - SPLITBAR_WIDTH;
 
-      MoveWindow(handle2, 0, 0, x, newy, FALSE);
+      MoveWindow(handle1, 0, 0, x, newy, FALSE);
       _do_resize(tmp, x - 1, newy - 1);
 
       dw_window_set_data(hwnd, "_dw_start", (void *)newy);
@@ -3171,7 +3258,7 @@
 }
 
 /* This handles any activity on the scrollbox */
-BOOL CALLBACK _scrollwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _scrollwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    switch (msg)
    {
@@ -3211,7 +3298,7 @@
             /*case SB_PAGEUP:*/
             case SB_PAGERIGHT:
                 si->nPos = si->nPos + si->nPage;
-                if(si->nPos > (si->nMax - si->nPage) + 1)
+                if(si->nPos > (int)(si->nMax - si->nPage) + 1)
                     si->nPos = (si->nMax - si->nPage) + 1;
                 break;
             /*case SB_LINEDOWN:*/
@@ -3223,7 +3310,7 @@
             /*case SB_LINEUP:*/
             case SB_LINERIGHT:
                 si->nPos = si->nPos + 1;
-                if(si->nPos > (si->nMax - si->nPage) + 1)
+                if(si->nPos > (int)(si->nMax - si->nPage) + 1)
                     si->nPos = (si->nMax - si->nPage) + 1;
                 break;
             }
@@ -3239,7 +3326,7 @@
 }
 
 /* This handles any activity on the splitbars (sizers) */
-BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    switch (msg)
    {
@@ -3318,13 +3405,13 @@
                   {
                      start = point.x - rect.left;
                      if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
-                        *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
+                        *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * (float)100.0;
                   }
                   else
                   {
                      start = point.y - rect.top;
                      if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
-                        *percent = ((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0;
+                        *percent = ((float)start / (float)(height - SPLITBAR_WIDTH)) * (float)100.0;
                   }
                   _handle_splitbar_resize(hwnd, *percent, type, width, height);
                }
@@ -3338,7 +3425,7 @@
 }
 
 /* This handles drawing the status text areas */
-BOOL CALLBACK _statuswndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _statuswndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    switch (msg)
    {
@@ -3359,7 +3446,7 @@
          PAINTSTRUCT ps;
          RECT rc;
          unsigned long cx, cy;
-         char tempbuf[1024] = "";
+         TCHAR tempbuf[1025] = { 0 };
          ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
          HFONT hfont = _acquire_font(hwnd, cinfo ? cinfo->fontname : NULL);
          HFONT oldfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
@@ -3385,18 +3472,159 @@
    return DefWindowProc(hwnd, msg, mp1, mp2);
 }
 
+#ifdef AEROGLASS
+/* Window procedure to handle drawing themed text when in composited mode */
+LRESULT CALLBACK _staticwndproc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
+{
+   ColorInfo *parentcinfo, *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+   WNDPROC pOldProc;
+
+   if (!cinfo)
+      return DefWindowProc(hwnd, msg, mp1, mp2);
+
+   /* Need the parent to do the check completely */
+   parentcinfo = (ColorInfo *)GetWindowLongPtr(GetParent(hwnd), GWLP_USERDATA);
+   
+   /* If we don't require themed drawing */
+   if(((cinfo->back != -1 && cinfo->back != DW_RGB_TRANSPARENT) || (parentcinfo && parentcinfo->back != -1)) 
+       || !_dw_composition || !(GetWindowLongPtr(_toplevel_window(hwnd), GWL_EXSTYLE) & WS_EX_LAYERED))
+      return _colorwndproc(hwnd, msg, mp1, mp2);
+   
+   pOldProc = cinfo->pOldProc;
+   
+   switch(msg)
+   {
+      case WM_PAINT:
+      {
+         PAINTSTRUCT ps;
+         HDC hdc = BeginPaint(hwnd, &ps);
+
+         if(hdc)
+         {
+            /* Figure out how to draw */
+            HDC hdcPaint = NULL;
+            RECT rcClient;
+            LONG_PTR dwStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
+            LONG_PTR dwStyleEx = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
+            HTHEME hTheme = _OpenThemeData(NULL, L"ControlPanelStyle"); 
+
+            GetClientRect(hwnd, &rcClient);
+            
+            if(hTheme)
+            {
+               /* Create an in memory image to draw to */
+               HPAINTBUFFER hBufferedPaint = _BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcPaint);
+               
+               if(hdcPaint)
+               {
+                  LONG_PTR dwStaticStyle = dwStyle & 0x1F;
+                  HFONT hFontOld = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
+                  int iLen = GetWindowTextLength(hwnd), fore = _internal_color(cinfo->fore);
+                  DTTOPTS DttOpts = { sizeof(DTTOPTS) };
+                  static HBRUSH hbrush = 0;
+                   
+                  /* Make sure we have a transparency brush */
+                  if(!hbrush)
+                     hbrush = CreateSolidBrush(_dw_transparencykey);
+            
+                  /* Fill the background with the transparency color */
+                  FillRect(hdcPaint, &rcClient, hbrush);
+                  _BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00);
+                  
+                  /* Setup how we will draw the text */
+                  DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE | DTT_TEXTCOLOR;
+                  DttOpts.crText = cinfo->fore == -1 ? RGB(255, 255, 255) : RGB(DW_RED_VALUE(fore), DW_GREEN_VALUE(fore), DW_BLUE_VALUE(fore));
+                  DttOpts.iGlowSize = 12;
+                  
+                  SetBkMode(hdcPaint, TRANSPARENT);
+
+                  if(hFontOld) 
+                     hFontOld = (HFONT)SelectObject(hdcPaint, hFontOld);
+
+                  /* Make sure there is text to draw */
+                  if(iLen)
+                  {
+                     LPWSTR szText = (LPWSTR)_alloca(sizeof(WCHAR)*(iLen+5));
+                     
+                     if(szText)
+                     {
+                        iLen = GetWindowTextW(hwnd, szText, iLen+5);
+                        if(iLen)
+                        {
+                           DWORD dwFlags = DT_WORDBREAK;
+                         
+                           switch (dwStaticStyle)
+                           {
+                              case SS_CENTER:
+                                 dwFlags |= DT_CENTER;
+                                 break;
+                              case SS_RIGHT:
+                                 dwFlags |= DT_RIGHT;
+                                 break;
+                              case SS_LEFTNOWORDWRAP:
+                                 dwFlags &= ~DT_WORDBREAK;
+                                 break;
+                           }
+
+                           if(dwStyle & SS_CENTERIMAGE)
+                           {
+                              dwFlags |= DT_VCENTER;
+                              dwFlags &= ~DT_WORDBREAK;
+                           }
+
+
+                           if(dwStyle & SS_ENDELLIPSIS)
+                              dwFlags |= DT_END_ELLIPSIS|DT_MODIFYSTRING;
+                           else if(dwStyle & SS_PATHELLIPSIS)
+                              dwFlags |= DT_PATH_ELLIPSIS|DT_MODIFYSTRING;
+                           else if(dwStyle & SS_WORDELLIPSIS)
+                              dwFlags |= DT_WORD_ELLIPSIS|DT_MODIFYSTRING;
+
+                           if (dwStyleEx&WS_EX_RIGHT)
+                              dwFlags |= DT_RIGHT;
+
+                           if(dwStyle & SS_NOPREFIX)
+                              dwFlags |= DT_NOPREFIX;
+                         
+                           /* Draw the text! */
+                           _DrawThemeTextEx(hTheme, hdcPaint, 0, 0, 
+                                            szText, -1, dwFlags, &rcClient, &DttOpts);
+                        }
+                     }
+                  }
+
+                  /* Cleanup */
+                  if (hFontOld)
+                     SelectObject(hdcPaint, hFontOld);
+                  _EndBufferedPaint(hBufferedPaint, TRUE);
+               }                
+               _CloseThemeData(hTheme);
+            }
+         }
+             
+         EndPaint(hwnd, &ps);
+         return TRUE;
+      }
+      break;
+   }
+    
+   if ( !pOldProc )
+      return DefWindowProc(hwnd, msg, mp1, mp2);
+   return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
+}
+#endif
+
 /* Function: _BtProc
  * Abstract: Subclass procedure for buttons
  */
 
-BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
-{
-   BubbleButton *bubble;
+LRESULT CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
+{
+   ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    WNDPROC pOldProc;
-
-   bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
-   if ( !bubble )
+   int retval = -1;
+
+   if ( !cinfo )
       return DefWindowProc(hwnd, msg, mp1, mp2);
 
    /* We must save a pointer to the old
@@ -3404,7 +3632,7 @@
     * handler attached here destroys this
     * window it will then be invalid.
     */
-   pOldProc = bubble->pOldProc;
+   pOldProc = cinfo->pOldProc;
 
    switch(msg)
    {
@@ -3415,8 +3643,7 @@
    case WM_CTLCOLORMSGBOX:
    case WM_CTLCOLORSCROLLBAR:
    case WM_CTLCOLORDLG:
-      _wndproc(hwnd, msg, mp1, mp2);
-      break;
+      return _colorwndproc(hwnd, msg, mp1, mp2);
    case WM_SETFOCUS:
       _wndproc(hwnd, msg, mp1, mp2);
       break;
@@ -3434,12 +3661,14 @@
                /* Make sure it's the right window, and the right ID */
                if(tmp->window == hwnd)
                {
-                  if(bubble->checkbox)
+                  int checkbox = DW_POINTER_TO_INT(dw_window_get_data(hwnd, "_dw_checkbox"));
+                  
+                  if(checkbox)
                      in_checkbox_handler = 1;
 
-                  clickfunc(tmp->window, tmp->data);
-
-                  if(bubble->checkbox)
+                  retval = clickfunc(tmp->window, tmp->data);
+
+                  if(checkbox)
                      in_checkbox_handler = 0;
                   tmp = NULL;
                }
@@ -3468,7 +3697,7 @@
                   /* Make sure it's the right window, and the right ID */
                   if(tmp->window == hwnd)
                   {
-                     clickfunc(tmp->window, tmp->data);
+                     retval = clickfunc(tmp->window, tmp->data);
                      tmp = NULL;
                   }
                }
@@ -3494,6 +3723,9 @@
       break;
    }
 
+   /* Make sure windows are up-to-date */
+   if(retval != -1)
+      _dw_redraw(0, FALSE);
    if ( !pOldProc )
       return DefWindowProc(hwnd, msg, mp1, mp2);
    return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
@@ -3528,29 +3760,25 @@
 
 void _create_tooltip(HWND handle, char *text)
 {
-    /* Create a tooltip. */
-    HWND hwndTT = CreateWindowEx(WS_EX_TOPMOST,
-        TOOLTIPS_CLASS, NULL,
-        WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
-        CW_USEDEFAULT, CW_USEDEFAULT,
-        CW_USEDEFAULT, CW_USEDEFAULT,
-        handle, NULL, DWInstance,NULL);
     TOOLINFO ti = { 0 };
-
-    SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
-
-    /* Set up "tool" information.
-     * In this case, the "tool" is the entire parent window.
-     */
+    
     ti.cbSize = sizeof(TOOLINFO);
-    ti.uFlags = TTF_SUBCLASS;
     ti.hwnd = handle;
     ti.hinst = DWInstance;
-    ti.lpszText = text;
-    GetClientRect(handle, &ti.rect);
-
-    /* Associate the tooltip with the "tool" window. */
-    SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+    
+    SendMessage(hwndTooltip, TTM_DELTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+    if(text)
+    {
+        /* Set up "tool" information.
+         * In this case, the "tool" is the entire parent window.
+         */
+        ti.uFlags = TTF_SUBCLASS;
+        ti.lpszText = UTF8toWide(text);
+        ti.rect.right = ti.rect.bottom = 2000;
+
+        /* Associate the tooltip with the "tool" window. */
+        SendMessage(hwndTooltip, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+    }
 }
 
 #ifndef GDIPLUS
@@ -3582,17 +3810,17 @@
       }
       if ( stricmp( file + len - 4, ".ico" ) == 0 )
       {
-         *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+         *icon = LoadImage(NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
          windowtype = BS_ICON;
       }
       else if ( stricmp( file + len - 4, ".bmp" ) == 0 )
       {
-         *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+         *hbitmap = (HBITMAP)LoadImage(NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
          windowtype = BS_BITMAP;
       }
       else if ( stricmp( file + len - 4, ".png" ) == 0 )
       {
-         *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+         *hbitmap = (HBITMAP)LoadImage(NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
          windowtype = BS_BITMAP;
       }
       free(file);
@@ -3603,7 +3831,7 @@
       strcat(file, ".ico");
       if (access(file, 04) == 0)
       {
-         *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+         *icon = LoadImage(NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
          windowtype = BS_ICON;
       }
       else
@@ -3612,7 +3840,7 @@
          strcat(file, ".bmp");
          if (access(file, 04) == 0)
          {
-            *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+            *hbitmap = (HBITMAP)LoadImage(NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
             windowtype = BS_BITMAP;
          }
       }
@@ -3627,6 +3855,16 @@
 {
     COLORREF foreground = RGB(128,128,128);
     COLORREF background = DW_RGB_TRANSPARENT;
+#ifdef GDIPLUS
+    ARGB gpfore = MAKEARGB(255, 128, 128, 128);
+    GpBrush *brush;
+    GpPen *pen;
+    
+    GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen);
+    TlsSetValue(_gpPen, (LPVOID)pen);
+    GdipCreateSolidFill(gpfore, &brush);
+    TlsSetValue(_gpBrush, (LPVOID)brush);
+#endif    
     TlsSetValue(_foreground, (LPVOID)foreground);
     TlsSetValue(_background, (LPVOID)background);
     TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
@@ -3649,12 +3887,31 @@
    struct GdiplusStartupInput si; 
 #endif
 
+   /* Setup the private data directory */
+   if(argc > 0 && argv[0])
+   {
+      char *pos = strrchr(argv[0], '\\');
+      
+      /* Just to be safe try the unix style */
+      if(!pos)
+         pos = strrchr(argv[0], '/');
+         
+      if(pos)
+         strncpy(_dw_exec_dir, argv[0], (size_t)(pos - argv[0]));
+   }
+   /* If that failed... just get the current directory */
+   if(!_dw_exec_dir[0])
+      GetCurrentDirectoryA(MAX_PATH, _dw_exec_dir);
+      
    /* Initialize our thread local storage */
    _foreground = TlsAlloc();
    _background = TlsAlloc();
    _hPen = TlsAlloc();
    _hBrush = TlsAlloc();
-   _init_thread();
+#ifdef GDIPLUS
+   _gpPen = TlsAlloc();
+   _gpBrush = TlsAlloc();
+#endif   
 
    icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icc.dwICC = ICC_WIN95_CLASSES|ICC_DATE_CLASSES;
@@ -3712,6 +3969,19 @@
 
    RegisterClass(&wc);
 
+   /* Register a status bar control */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS;
+   wc.lpfnWndProc = (WNDPROC)_statuswndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 32;
+   wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
+   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = StatusbarClassName;
+
+   RegisterClass(&wc);
+
 #if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
    /* Register HTML renderer class */
    memset(&wc, 0, sizeof(WNDCLASS));
@@ -3748,7 +4018,7 @@
     * packed into their correct parent.
     */
 
-   DW_HWND_OBJECT = CreateWindow(ObjectClassName, "", 0, 0, 0,
+   DW_HWND_OBJECT = CreateWindow(ObjectClassName, TEXT("HWND_OBJECT"), 0, 0, 0,
                           0, 0, HWND_DESKTOP, NULL, DWInstance, NULL);
 
    if(!DW_HWND_OBJECT)
@@ -3757,6 +4027,12 @@
       exit(1);
    }
    
+   /* Create a tooltip. */
+   hwndTooltip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, DW_HWND_OBJECT, NULL, DWInstance,NULL);
+
+   SetWindowPos(hwndTooltip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
    /* Create empty box data */
    SetWindowLongPtr(DW_HWND_OBJECT, GWLP_USERDATA, (LONG_PTR)calloc(sizeof(Box), 1));
 
@@ -3781,13 +4057,6 @@
    {
       strncpy( _dw_alternate_temp_dir, alttmpdir, MAX_PATH );
    }
-   /*
-    * Get screen size. Used to make calls to dw_screen_width()
-    * and dw_screen-height() quicker, but to alos limit the
-    * default size of windows.
-    */
-   screenx = GetSystemMetrics(SM_CXSCREEN);
-   screeny = GetSystemMetrics(SM_CYSCREEN);
 
 #ifdef GDIPLUS
    /* Setup GDI+ */
@@ -3797,9 +4066,43 @@
    si.SuppressExternalCodecs = FALSE;
    GdiplusStartup(&gdiplusToken, &si, NULL);
 #endif
+   
+   /* GDI+ Needs to be initialized before calling _init_thread(); */
+   _init_thread();
+
+   if((huxtheme = LoadLibrary(TEXT("uxtheme"))))
+      _SetWindowTheme = (HRESULT (WINAPI *)(HWND, LPCWSTR, LPCWSTR ))GetProcAddress(huxtheme, "SetWindowTheme");
+#ifdef AEROGLASS
+   /* Attempt to load the Desktop Window Manager and Theme library */
+   if(huxtheme && (hdwm = LoadLibrary(TEXT("dwmapi"))))
+   {
+      _DwmExtendFrameIntoClientArea = (HRESULT (WINAPI *)(HWND, const MARGINS *))GetProcAddress(hdwm, "DwmExtendFrameIntoClientArea");
+      if((_DwmIsCompositionEnabled = (HRESULT (WINAPI *)(BOOL *))GetProcAddress(hdwm, "DwmIsCompositionEnabled")))
+         _DwmIsCompositionEnabled(&_dw_composition);
+      _OpenThemeData = (HTHEME (WINAPI *)(HWND, LPCWSTR))GetProcAddress(huxtheme, "OpenThemeData");
+      _BeginBufferedPaint = (HPAINTBUFFER (WINAPI *)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *))GetProcAddress(huxtheme, "BeginBufferedPaint");
+      _BufferedPaintSetAlpha = (HRESULT (WINAPI *)(HPAINTBUFFER, const RECT *, BYTE))GetProcAddress(huxtheme, "BufferedPaintSetAlpha");
+      _DrawThemeTextEx = (HRESULT (WINAPI *)(HTHEME, HDC, int, int, LPCWSTR, int, DWORD, LPRECT, const DTTOPTS *))GetProcAddress(huxtheme, "DrawThemeTextEx");
+      _EndBufferedPaint = (HRESULT (WINAPI *)(HPAINTBUFFER, BOOL))GetProcAddress(huxtheme, "EndBufferedPaint");
+      _CloseThemeData = (HRESULT (WINAPI *)(HTHEME))GetProcAddress(huxtheme, "CloseThemeData");
+   }
+   /* In case of error close the library if needed */
+   else if(hdwm)
+   {
+      FreeLibrary(hdwm);
+      hdwm = 0;
+   }
+#endif
+#ifdef RICHEDIT
+   /* Attempt to load rich edit library */
+   if(!(hrichedit = LoadLibrary("riched20")))
+      hrichedit = LoadLibrary("riched32");
+#endif      
    return 0;
 }
 
+static int _dw_main_running = FALSE;
+
 /*
  * Runs a message loop for Dynamic Windows.
  */
@@ -3808,8 +4111,14 @@
    MSG msg;
 
    _dwtid = dw_thread_id();
-
-   while(GetMessage(&msg, NULL, 0, 0))
+   /* Make sure any queued redraws are handled */
+   _dw_redraw(0, FALSE);
+
+   /* Set the running flag to TRUE */
+   _dw_main_running = TRUE;
+   
+   /* Run the loop until the flag is unset... or error */
+   while(_dw_main_running && GetMessage(&msg, NULL, 0, 0))
    {
       if(msg.hwnd == NULL && msg.message == WM_TIMER)
          _wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
@@ -3822,6 +4131,14 @@
 }
 
 /*
+ * Causes running dw_main() to return.
+ */
+void API dw_main_quit(void)
+{
+    _dw_main_running = FALSE;
+}
+
+/*
  * Runs a message loop for Dynamic Windows, for a period of milliseconds.
  * Parameters:
  *           milliseconds: Number of milliseconds to run the loop for.
@@ -3952,13 +4269,13 @@
 void API dw_debug(char *format, ...)
 {
    va_list args;
-   char outbuf[1025] = {0};
+   char outbuf[1025] = {0}, *thisbuf = outbuf;
 
    va_start(args, format);
    vsnprintf(outbuf, 1024, format, args);
    va_end(args);
    
-   OutputDebugString(outbuf);
+   OutputDebugString(UTF8toWide(thisbuf));
 }
 
 /*
@@ -3971,14 +4288,14 @@
 int API dw_messagebox(char *title, int flags, char *format, ...)
 {
    va_list args;
-   char outbuf[1024];
+   char outbuf[1025] = { 0 }, *thisbuf = outbuf;
    int rc;
 
    va_start(args, format);
    vsnprintf(outbuf, 1024, format, args);
    va_end(args);
 
-   rc = MessageBox(HWND_DESKTOP, outbuf, title, flags);
+   rc = MessageBox(HWND_DESKTOP, UTF8toWide(thisbuf), UTF8toWide(title), flags);
    if(rc == IDOK)
       return DW_MB_RETURN_OK;
    else if(rc == IDYES)
@@ -4027,7 +4344,16 @@
  */
 int API dw_window_show(HWND handle)
 {
-   int rc = ShowWindow(handle, SW_SHOW);
+   int rc;
+   RECT rect;
+   
+   GetClientRect(handle, &rect);
+   
+   /* If the client area is 0x0 then call the autosize routine */
+   if((rect.bottom - rect.top) == 0 || (rect.right - rect.left) == 0)
+      dw_window_set_size(handle, 0, 0);
+      
+   rc = ShowWindow(handle, SW_SHOW);
    SetFocus(handle);
    _initial_focus(handle);
    return rc;
@@ -4050,49 +4376,33 @@
  */
 int API dw_window_destroy(HWND handle)
 {
-   HWND parent = GetParent(handle);
-   Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);
-   HMENU menu = GetMenu(handle);
-
+   HWND parent;
+   HMENU menu;
+
+   /* Handle special case for menu handle */
+   if(handle < (HWND)65536)
+   {
+      char buffer[31] = {0};
+      ULONG id = (ULONG)handle;
+      
+      _snprintf(buffer, 30, "_dw_id%ld", id);
+      menu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      
+      if(menu && IsMenu(menu))
+         return dw_menu_delete_item((HMENUI)menu, id);
+      return DW_ERROR_UNKNOWN;
+   }
+   
+   parent = GetParent(handle);
+   menu = GetMenu(handle);
+   
    if(menu)
       _free_menu_data(menu);
 
    /* If it is a desktop window let WM_DESTROY handle it */
    if(parent != HWND_DESKTOP)
    {
-      /* If the parent box has items... 
-       * try to remove it from the layout 
-       */
-      if(thisbox && thisbox->count)
-      {
-         int z, index = -1;
-         Item *tmpitem, *thisitem = thisbox->items;
-
-         for(z=0;z<thisbox->count;z++)
-         {
-            if(thisitem[z].hwnd == handle)
-               index = z;
-         }
-
-         if(index == -1)
-            return 0;
-
-         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-         /* Copy all but the current entry to the new list */
-         for(z=0;z<index;z++)
-         {
-            tmpitem[z] = thisitem[z];
-         }
-         for(z=index+1;z<thisbox->count;z++)
-         {
-            tmpitem[z-1] = thisitem[z];
-         }
-
-         thisbox->items = tmpitem;
-         free(thisitem);
-         thisbox->count--;
-      }
+      dw_box_unpack(handle);
       _free_window_memory(handle, 0);
       EnumChildWindows(handle, _free_window_memory, 0);
    }
@@ -4120,21 +4430,6 @@
    }
 }
 
-int instring(char *text, char *buffer)
-{
-   int z, len = strlen(text), buflen = strlen(buffer);
-
-   if(buflen > len)
-   {
-      for(z=0;z<=(buflen-len);z++)
-      {
-         if(memcmp(text, &buffer[z], len) == 0)
-            return z;
-      }
-   }
-   return 0;
-}
-
 /*
  * Changes a window's parent to newparent.
  * Parameters:
@@ -4148,20 +4443,19 @@
 
 LOGFONT _get_logfont(HDC hdc, char *fontname)
 {
-   int Italic, Bold;
-   char *myFontName;
-   int z, size = 9;
+   char  *Italic, *Bold, *myFontName = strchr(fontname, '.');
+   int size = atoi(fontname);
    LOGFONT lf = {0};
 
-   for(z=0;z<strlen(fontname);z++)
-   {
-      if(fontname[z]=='.')
-         break;
-   }
-   size = atoi(fontname);
-   lf.lfHeight = -MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
-   Italic = instring(" Italic", &fontname[z+1]);
-   Bold = instring(" Bold", &fontname[z+1]);
+   /* If we found a '.' use the location after the . */
+   if(myFontName)
+       myFontName = _strdup(++myFontName);
+   else /* Otherwise use the whole fontname and default size of 9 */
+       myFontName = _strdup(fontname);
+
+   lf.lfHeight = -MulDiv(size ? size : 9, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+   Italic = strstr(myFontName, " Italic");
+   Bold = strstr(myFontName, " Bold");
    lf.lfWidth = 0;
    lf.lfEscapement = 0;
    lf.lfOrientation = 0;
@@ -4174,15 +4468,11 @@
    lf.lfClipPrecision = 0;
    lf.lfQuality = DEFAULT_QUALITY;
    lf.lfPitchAndFamily = DEFAULT_PITCH | FW_DONTCARE;
-   /*
-    * remove any font modifiers
-    */
-   myFontName = strdup(&fontname[z+1]);
    if(Italic)
-      myFontName[Italic] = 0;
+      *Italic = 0;
    if(Bold)
-      myFontName[Bold] = 0;
-   strncpy(lf.lfFaceName, myFontName, sizeof(lf.lfFaceName)-1);
+      *Bold = 0;
+   _tcsncpy(lf.lfFaceName, UTF8toWide(myFontName), (sizeof(lf.lfFaceName)/sizeof(TCHAR))-1);
    free(myFontName);
    return lf;
 }
@@ -4242,6 +4532,324 @@
     }
 }
 
+/* Internal function to return a pointer to an item struct
+ * with information about the packing information regarding object.
+ */
+Item *_box_item(HWND handle)
+{
+   HWND parent = GetParent(handle);
+   Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);   
+   
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != HWND_DESKTOP)
+   {
+      if(thisbox && thisbox->count)
+      {
+         int z;
+         Item *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               return &thisitem[z];
+         }
+      }
+   }
+   return NULL;
+}
+
+/* Internal function to calculate the widget's required size..
+ * These are the general rules for widget sizes:
+ * 
+ * Render/Unspecified: 1x1
+ * Scrolled(Container,Tree,MLE): Guessed size clamped to min and max in dw.h
+ * Entryfield/Combobox/Spinbutton: 150x(maxfontheight)
+ * Spinbutton: 50x(maxfontheight)
+ * Text/Status: (textwidth)x(textheight)
+ * Ranged: 100x14 or 14x100 for vertical.
+ * Buttons/Bitmaps: Size of text or image and border.
+ */
+void _control_size(HWND handle, int *width, int *height)
+{
+   int thiswidth = 1, thisheight = 1, extrawidth = 0, extraheight = 0;
+   char *buf = dw_window_get_text(handle);
+   TCHAR tmpbuf[100] = {0};
+   static char testtext[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+   HBITMAP hbm = 0;
+   HICON hic = 0;
+   ICONINFO ii = {0};
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* If we have a string... 
+    * calculate the size with the current font.
+    */
+   if(buf)
+   {
+      if(*buf)
+         dw_font_text_extents_get(handle, NULL, buf, &thiswidth, &thisheight);
+      dw_free(buf);
+   }
+   
+   /* Attempt to get icon from classes that can have them */
+   if(_tcsnicmp(tmpbuf, STATICCLASSNAME, _tcslen(STATICCLASSNAME)+1) == 0)
+      hic = (HICON)SendMessage(handle, STM_GETIMAGE, IMAGE_ICON, 0);
+   else if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1) == 0)
+      hic = (HICON)SendMessage(handle, BM_GETIMAGE, IMAGE_ICON, 0);
+      
+   /* If we got an icon, pull out the internal bitmap */
+   if(hic)
+   {
+      if(GetIconInfo(hic, &ii))
+         hbm = ii.hbmMask ? ii.hbmMask : ii.hbmColor;
+   }
+   
+   /* If we weren't able to get the bitmap from the icon... */
+   if(!hbm)
+   {
+       /* Attempt to get bitmap from classes that can have them */
+      if(_tcsnicmp(tmpbuf, STATICCLASSNAME, _tcslen(STATICCLASSNAME)+1) == 0)
+         hbm = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
+      else if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1) == 0)
+         hbm = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
+   }
+   
+   /* If we got an image... set the sizes appropriately */
+   if(hbm)
+   {
+      BITMAP bmi = { 0 };
+      
+      GetObject(hbm, sizeof(BITMAP), &bmi);
+      thiswidth = bmi.bmWidth;
+      thisheight = bmi.bmHeight;
+   }
+   
+   /* Combobox */
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1) == 0)
+   {
+      dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+      thiswidth = 150;
+      extraheight = 4;
+      if(thisheight < 18)
+        thisheight = 18;
+   }
+   /* Ranged: Percent, Slider, Scrollbar */
+   else if(_tcsnicmp(tmpbuf, PROGRESS_CLASS, _tcslen(PROGRESS_CLASS)+1) == 0 || 
+           _tcsnicmp(tmpbuf, TRACKBAR_CLASS, _tcslen(TRACKBAR_CLASS)+1) == 0 ||
+           _tcsnicmp(tmpbuf, SCROLLBARCLASSNAME, _tcslen(SCROLLBARCLASSNAME)+1) == 0)
+   {
+      if(_tcsnicmp(tmpbuf, SCROLLBARCLASSNAME, _tcslen(SCROLLBARCLASSNAME)+1) == 0 &&
+        GetWindowLong(handle, GWL_STYLE) & SBS_VERT)
+      {
+         /* Vertical */
+         thiswidth = GetSystemMetrics(SM_CXVSCROLL);
+         thisheight = 100;
+      }
+      else
+      {
+         /* Horizontal */
+         thiswidth = 100;
+         thisheight = GetSystemMetrics(SM_CYHSCROLL);
+      }
+   }
+   /* Spinbuttons */
+   else if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1) == 0)
+   {
+      dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+      thiswidth = 50;
+      extraheight = 6;
+   }
+#ifdef TOOLBAR   
+   /* Bitmap Buttons */
+   else if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+   {
+      HIMAGELIST imlist = (HIMAGELIST)SendMessage(handle, TB_GETIMAGELIST, 0, 0);
+      int minsize = 24;
+      
+      if(imlist)
+         ImageList_GetIconSize(imlist, &thiswidth, &thisheight);
+
+      /* If we are flat the size can be smaller */
+      if(GetWindowLong(handle, GWL_STYLE) & TBSTYLE_FLAT)
+         minsize = 20;
+      else
+      {
+         thiswidth += 4;
+         thisheight += 4;
+      }
+         
+      if(thiswidth < minsize)
+         thiswidth = minsize;
+      if(thisheight < minsize)
+         thisheight = minsize;
+   }
+#endif   
+   /* Listbox */
+   else if(_tcsnicmp(tmpbuf, LISTBOXCLASSNAME, _tcslen(LISTBOXCLASSNAME)+1) == 0)
+   {
+      char buf[1025] = {0};
+      int x, count = dw_listbox_count(handle);
+      int basicwidth = thiswidth = GetSystemMetrics(SM_CXVSCROLL) + 8;
+      
+      thisheight = 8;
+      
+      for(x=0;x<count;x++)
+      {
+         int height, width = 0;
+         
+         dw_listbox_get_text(handle, x, buf, 1024);
+         
+         if(strlen(buf))
+            dw_font_text_extents_get(handle, NULL, buf, &width, &height);
+         else
+            dw_font_text_extents_get(handle, NULL, testtext, NULL, &height);
+        
+         width += basicwidth;
+         
+         if(width > thiswidth)
+            thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width;
+         thisheight += height;
+      }
+      
+      if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+         thiswidth = _DW_SCROLLED_MIN_WIDTH;
+      if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+         thisheight = _DW_SCROLLED_MIN_HEIGHT;
+      if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+         thisheight = _DW_SCROLLED_MAX_HEIGHT;
+   }
+   /* Entryfields and MLE */
+   else if(_tcsnicmp(tmpbuf, EDITCLASSNAME, _tcslen(EDITCLASSNAME)+1) == 0 ||
+           _tcsnicmp(tmpbuf, RICHEDIT_CLASS, _tcslen(RICHEDIT_CLASS)+1) == 0)
+   {
+      LONG style = GetWindowLong(handle, GWL_STYLE);
+      if((style & ES_MULTILINE))
+      {
+         unsigned long bytes;
+         int height, width;
+         char *buf, *ptr;
+         int basicwidth;
+         
+         if(style & ES_AUTOHSCROLL)
+            thisheight = GetSystemMetrics(SM_CYHSCROLL) + 8;
+         else 
+            thisheight = 8;
+         basicwidth = thiswidth = GetSystemMetrics(SM_CXVSCROLL) + 8;
+         
+         dw_mle_get_size(handle, &bytes, NULL);
+         
+         ptr = buf = _alloca(bytes + 2);
+         dw_mle_export(handle, buf, 0, (int)bytes);
+         buf[bytes] = 0;
+         strcat(buf, "\n");
+         
+         /* MLE */
+         while((ptr = strstr(buf, "\n")))
+         {
+            ptr[0] = 0;
+            width = 0;
+            if(strlen(buf))
+               dw_font_text_extents_get(handle, NULL, buf, &width, &height);
+            else
+               dw_font_text_extents_get(handle, NULL, testtext, NULL, &height);
+            
+            width += basicwidth;
+            
+            if(!(style & ES_AUTOHSCROLL) && width > _DW_SCROLLED_MAX_WIDTH)
+            {
+               thiswidth = _DW_SCROLLED_MAX_WIDTH;
+               thisheight += height * (width / _DW_SCROLLED_MAX_WIDTH);
+            }
+            else
+            {
+               if(width > thiswidth)
+                  thiswidth = width > _DW_SCROLLED_MAX_WIDTH ? _DW_SCROLLED_MAX_WIDTH : width;
+            }
+            thisheight += height;
+            buf = &ptr[1];
+         }
+         
+         if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+            thiswidth = _DW_SCROLLED_MIN_WIDTH;
+         if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+            thisheight = _DW_SCROLLED_MIN_HEIGHT;
+         if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+            thisheight = _DW_SCROLLED_MAX_HEIGHT;
+      }
+      else
+      {
+         /* Entryfield */
+         dw_font_text_extents_get(handle, NULL, testtext, NULL, &thisheight);
+         thiswidth = 150;
+         extraheight = 6;
+      }
+   }
+   /* Container */
+   else if(_tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW)+1)== 0)
+   {
+      DWORD result = ListView_ApproximateViewRect(handle, _DW_SCROLLED_MAX_WIDTH, _DW_SCROLLED_MAX_HEIGHT, -1);
+      
+      thiswidth = LOWORD(result);
+      thisheight = HIWORD(result);
+      
+      if(thiswidth > _DW_SCROLLED_MAX_WIDTH)
+         thiswidth = _DW_SCROLLED_MAX_WIDTH;
+      if(thiswidth < _DW_SCROLLED_MIN_WIDTH)
+         thiswidth = _DW_SCROLLED_MIN_WIDTH;
+      if(thisheight < _DW_SCROLLED_MIN_HEIGHT)
+         thisheight = _DW_SCROLLED_MIN_HEIGHT;
+      if(thisheight > _DW_SCROLLED_MAX_HEIGHT)
+         thisheight = _DW_SCROLLED_MAX_HEIGHT;
+   }
+   /* Tree */
+   else if(_tcsnicmp(tmpbuf, WC_TREEVIEW, _tcslen(WC_TREEVIEW)+1)== 0)
+   {
+      thiswidth = (int)((_DW_SCROLLED_MAX_WIDTH + _DW_SCROLLED_MIN_WIDTH)/2);
+      thisheight = (int)((_DW_SCROLLED_MAX_HEIGHT + _DW_SCROLLED_MIN_HEIGHT)/2);
+   }
+   /* Buttons */
+   else if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1) == 0)
+   {
+      ULONG style = GetWindowLong(handle, GWL_STYLE);
+      
+      /* Bitmap buttons */
+      if(hbm)
+      {
+         extrawidth = 5;
+         extraheight = 5;
+      }
+      /* Checkbox or radio button */
+      else if(style & BS_AUTOCHECKBOX || style & BS_AUTORADIOBUTTON)
+      {
+         extrawidth = 24;
+         extraheight = 4;
+      }
+      /* Text buttons */
+      else
+      {
+         extrawidth = 8;
+         extraheight = 8;
+      }
+   }
+   else if(_tcsnicmp(tmpbuf, StatusbarClassName, _tcslen(StatusbarClassName)+1) == 0)
+   {
+      extrawidth = 4;
+      extraheight = 2;
+   }
+
+   /* Set the requested sizes */    
+   if(width)
+      *width = thiswidth + extrawidth;
+   if(height)
+      *height = thisheight + extraheight;
+      
+   /* Free temporary bitmaps */
+   if(ii.hbmColor)
+      DeleteObject(ii.hbmColor);
+   if(ii.hbmMask);
+      DeleteObject(ii.hbmMask);
+}
+
 /*
  * Sets the font used by a specified window (widget) handle.
  * Parameters:
@@ -4252,12 +4860,12 @@
 {
     HFONT hfont, oldfont;
     ColorInfo *cinfo;
-    char tmpbuf[100];
+    TCHAR tmpbuf[100] = {0};
 
     cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
     GetClassName(handle, tmpbuf, 99);
-    if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+    if ( _tcsnicmp( tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1) == 0 )
     {
         /* groupbox */
         Box *thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
@@ -4271,7 +4879,7 @@
     oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
     hfont = _acquire_font(handle, fontname);
 
-    if (fontname)
+    if(hfont && fontname)
     {
         if(cinfo)
         {
@@ -4291,10 +4899,25 @@
             SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
         }
     }
-    SendMessage(handle, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
-    if(oldfont)
-        DeleteObject(oldfont);
-   return 0;
+    /* If we changed the font... */
+    if(hfont)
+    {
+       Item *item = _box_item(handle);
+       
+       SendMessage(handle, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
+       if(oldfont)
+          DeleteObject(oldfont);
+        
+       /* Check to see if any of the sizes need to be recalculated */
+       if(item && (item->origwidth == -1 || item->origheight == -1))
+       {
+          _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+          /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+       }
+       return DW_ERROR_NONE;
+    }
+   return DW_ERROR_UNKNOWN;
 }
 
 /* Allows the user to choose a font using the system's font chooser dialog.
@@ -4332,7 +4955,7 @@
             italic = " Italic";
          height = MulDiv(abs(lf.lfHeight), 72,  GetDeviceCaps (hdc, LOGPIXELSY));
          ReleaseDC(NULL, hdc);
-         _snprintf( str, 100, "%d.%s%s%s", height, lf.lfFaceName, bold, italic );
+         _snprintf( str, 100, "%d.%s%s%s", height, WideToUTF8(lf.lfFaceName), bold, italic );
       }
    }
    return str;
@@ -4352,10 +4975,10 @@
    char *italic = "";
    LOGFONT lf = { 0 };
    Box *thisbox;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
-   if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+   if ( _tcsnicmp( tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1) == 0 )
    {
       /* groupbox */
       thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
@@ -4398,13 +5021,13 @@
 {
    ColorInfo *cinfo;
    Box *thisbox;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0)
+   if(_tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW))==0)
    {
       cinfo->fore = fore = _internal_color(fore);
       cinfo->back = back = _internal_color(back);
@@ -4421,7 +5044,7 @@
       InvalidateRgn(handle, NULL, TRUE);
       return TRUE;
    }
-   else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)) == 0 )
+   else if ( _tcsnicmp( tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)) == 0 )
    {
       /* groupbox */
       thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
@@ -4511,44 +5134,47 @@
    HWND hwndframe;
    Box *newbox = calloc(sizeof(Box), 1);
    ULONG flStyleEx = 0;
-
-   newbox->pad = 0;
+#ifdef AEROGLASS
+   MARGINS mar = {-1};
+   
+   if(_dw_composition && (flStyle & DW_FCF_COMPOSITED))
+      flStyleEx = WS_EX_LAYERED;
+#endif
+
    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;
 
-   if(flStyle & DW_FCF_TASKLIST)
-   {
-      ULONG newflags = (flStyle | WS_CLIPCHILDREN) & ~DW_FCF_TASKLIST;
-
-      hwndframe = CreateWindowEx(flStyleEx, ClassName, title, newflags, CW_USEDEFAULT, CW_USEDEFAULT,
-                           CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
+   if(flStyle & DW_FCF_TASKLIST ||
+      flStyle & WS_VSCROLL /* This is deprecated and should go away in version 3? */)
+   {
+      hwndframe = CreateWindowEx(flStyleEx, ClassName, UTF8toWide(title), (flStyle | WS_CLIPCHILDREN) & 0xffdf0000, CW_USEDEFAULT, CW_USEDEFAULT,
+                           0, 0, hwndOwner, NULL, DWInstance, NULL);
    }
    else
    {
       flStyleEx |= WS_EX_TOOLWINDOW;
 
-      hwndframe = CreateWindowEx(flStyleEx, ClassName, title, flStyle | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT,
-                           CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
+      hwndframe = CreateWindowEx(flStyleEx, ClassName, UTF8toWide(title), (flStyle | WS_CLIPCHILDREN) & 0xffff0000, CW_USEDEFAULT, CW_USEDEFAULT,
+                           0, 0, hwndOwner, NULL, DWInstance, NULL);
    }
    SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
 
    if(hwndOwner)
       SetParent(hwndframe, hwndOwner);
 
+#ifdef AEROGLASS
+   /* Attempt to enable Aero glass background on the entire window */
+   if(_DwmExtendFrameIntoClientArea && _dw_composition && (flStyle & DW_FCF_COMPOSITED))
+   {
+      SetLayeredWindowAttributes(hwndframe, _dw_transparencykey, 0, LWA_COLORKEY);
+      _DwmExtendFrameIntoClientArea(hwndframe, &mar);
+   }
+#endif
+
    return hwndframe;
 }
 
@@ -4570,7 +5196,7 @@
    newbox->cinfo.fore = newbox->cinfo.back = -1;
 
    hwndframe = CreateWindow(FRAMECLASSNAME,
-                      "",
+                      NULL,
                       WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                       0,0,0,0,
                       DW_HWND_OBJECT,
@@ -4601,7 +5227,7 @@
     cinfo->fore = cinfo->back = -1;
 
     hwndframe = CreateWindow(ScrollClassName,
-                      "",
+                      NULL,
                       WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
                       0,0,0,0,
                       DW_HWND_OBJECT,
@@ -4687,7 +5313,7 @@
    newbox->cinfo.fore = newbox->cinfo.back = -1;
 
    hwndframe = CreateWindow(FRAMECLASSNAME,
-                      "",
+                      NULL,
                       WS_VISIBLE | WS_CHILD,
                       0,0,0,0,
                       DW_HWND_OBJECT,
@@ -4696,7 +5322,7 @@
                       NULL);
 
    newbox->grouphwnd = CreateWindow(BUTTONCLASSNAME,
-                            title,
+                            UTF8toWide(title),
                             WS_CHILD | BS_GROUPBOX |
                             WS_VISIBLE | WS_CLIPCHILDREN,
                             0,0,0,0,
@@ -4723,8 +5349,8 @@
    ccs.hWindowMenu = NULL;
    ccs.idFirstChild = 0;
 
-   hwndframe = CreateWindow("MDICLIENT",
-                      "",
+   hwndframe = CreateWindow(TEXT("MDICLIENT"),
+                      NULL,
                       WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
                       0,0,0,0,
                       DW_HWND_OBJECT,
@@ -4743,7 +5369,7 @@
 {
 #if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
    return CreateWindow(BrowserClassName,
-                  "",
+                  NULL,
                   WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
                   0,0,0,0,
                   DW_HWND_OBJECT,
@@ -4819,7 +5445,7 @@
 HWND API dw_bitmap_new(ULONG id)
 {
    return CreateWindow(STATICCLASSNAME,
-                  "",
+                  NULL,
                   SS_BITMAP | SS_CENTERIMAGE | WS_VISIBLE |
                   WS_CHILD | WS_CLIPCHILDREN,
                   0,0,0,0,
@@ -4845,7 +5471,7 @@
       flags = TCS_BOTTOM;
 
    tmp = CreateWindow(WC_TABCONTROL,
-                  "",
+                  NULL,
                   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | flags,
                   0,0,0,0,
                   DW_HWND_OBJECT,
@@ -5022,8 +5648,8 @@
       mii.hSubMenu = (HMENU)submenu;
    else
       mii.hSubMenu = 0;
-   mii.dwTypeData = menutitle;
-   mii.cch = strlen(menutitle);
+   mii.dwTypeData = UTF8toWide(menutitle);
+   mii.cch = (UINT)_tcslen(mii.dwTypeData);
 
    InsertMenuItem(mymenu, 65535, TRUE, &mii);
 
@@ -5183,26 +5809,31 @@
 }
 
 /*
- * INCOMPLETE
  * Deletes the menu item specified
  * Parameters:
  *       menu: The handle to the  menu in which the item was appended.
  *       id: Menuitem id.
- */
-void API dw_menu_delete_item(HMENUI menux, unsigned long id)
+ * Returns: 
+ *       DW_ERROR_NONE (0) on success or DW_ERROR_UNKNOWN on failure.
+ */
+int API dw_menu_delete_item(HMENUI menux, unsigned long id)
 {
    HMENU mymenu = (HMENU)menux;
 
    if ( IsWindow(menux) && !IsMenu(mymenu) )
       mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
 
-   if ( DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 )
-   {
-      char lasterror[257];
-      FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), lasterror, 256, NULL);
-      fprintf(stderr, "Error deleting menu: %s", lasterror);
-   }
-   DrawMenuBar(menux);
+   if ( mymenu == 0 || DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 )
+      return DW_ERROR_UNKNOWN;
+   
+   /* If the ID was autogenerated it is safe to remove it */
+   if(id >= 30000)
+      dw_signal_disconnect_by_window((HWND)id);
+      
+   /* Make sure the menu is redrawn if needed */
+   if( (HMENU)menux != mymenu )
+      DrawMenuBar(menux);
+   return DW_ERROR_NONE;
 }
 
 /*
@@ -5238,7 +5869,7 @@
 HWND API dw_container_new(ULONG id, int multi)
 {
    HWND tmp = CreateWindow(WC_LISTVIEW,
-                     "",
+                     NULL,
                      WS_VISIBLE | WS_CHILD |
                      (multi ? 0 : LVS_SINGLESEL) |
                      LVS_REPORT | LVS_SHOWSELALWAYS |
@@ -5257,7 +5888,7 @@
       return NULL;
    }
 
-   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
+   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _containerwndproc);
    cinfo->cinfo.fore = cinfo->cinfo.back = -1;
    cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
 
@@ -5281,7 +5912,7 @@
 HWND API dw_tree_new(ULONG id)
 {
    HWND tmp = CreateWindow(WC_TREEVIEW,
-                     "",
+                     NULL,
                      WS_VISIBLE | WS_CHILD |
                      TVS_HASLINES | TVS_SHOWSELALWAYS |
                      TVS_HASBUTTONS | TVS_LINESATROOT |
@@ -5300,7 +5931,7 @@
       return NULL;
    }
 
-   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
+   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _treewndproc);
    cinfo->cinfo.fore = cinfo->cinfo.back = -1;
    cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
 
@@ -5347,16 +5978,24 @@
 HWND API dw_text_new(char *text, ULONG id)
 {
    HWND tmp = CreateWindow(STATICCLASSNAME,
-                     text,
-                     SS_NOPREFIX |
-                     BS_TEXT | WS_VISIBLE |
+                     UTF8toWide(text),
+                     SS_NOPREFIX | SS_NOTIFY | WS_VISIBLE |
                      WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
                      (HMENU)id,
                      DWInstance,
                      NULL);
+#ifdef AEROGLASS
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   cinfo->back = cinfo->fore = -1;
+
+   cinfo->pOldProc = SubclassWindow(tmp, _staticwndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+#endif                     
    dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_DEFAULT, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -5368,17 +6007,15 @@
  */
 HWND API dw_status_text_new(char *text, ULONG id)
 {
-   HWND tmp = CreateWindow(ObjectClassName,
-                     text,
-                     BS_TEXT | WS_VISIBLE |
-                     WS_CHILD | WS_CLIPCHILDREN,
+   HWND tmp = CreateWindow(StatusbarClassName,
+                     UTF8toWide(text),
+                     WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
                      (HMENU)id,
                      DWInstance,
                      NULL);
    dw_window_set_font(tmp, DefaultFont);
-   SubclassWindow(tmp, _statuswndproc);
    return tmp;
 }
 
@@ -5391,8 +6028,8 @@
 {
 
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-                       EDITCLASSNAME,
-                       "",
+                       hrichedit ? RICHEDIT_CLASS : EDITCLASSNAME,
+                       NULL,
                        WS_VISIBLE | WS_BORDER |
                        WS_VSCROLL | ES_MULTILINE |
                        ES_WANTRETURN | WS_CHILD |
@@ -5410,7 +6047,7 @@
       return NULL;
    }
 
-   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
+   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _treewndproc);
    cinfo->cinfo.fore = cinfo->cinfo.back = -1;
    cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
 
@@ -5429,7 +6066,7 @@
 {
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
                        EDITCLASSNAME,
-                       text,
+                       UTF8toWide(text),
                        ES_WANTRETURN | WS_CHILD |
                        WS_BORDER | ES_AUTOHSCROLL |
                        WS_VISIBLE | WS_CLIPCHILDREN,
@@ -5458,7 +6095,7 @@
 {
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
                        EDITCLASSNAME,
-                       text,
+                       UTF8toWide(text),
                        ES_WANTRETURN | WS_CHILD |
                        ES_PASSWORD | WS_BORDER | WS_VISIBLE |
                        ES_AUTOHSCROLL | WS_CLIPCHILDREN,
@@ -5484,7 +6121,7 @@
    if(cinfo)
    {
       cinfo->buddy = handle;
-      cinfo->pOldProc = (WNDPROC)SubclassWindow(handle, _colorwndproc);
+      cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
       SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
    }
    return FALSE;
@@ -5499,7 +6136,7 @@
 HWND API dw_combobox_new(char *text, ULONG id)
 {
    HWND tmp = CreateWindow(COMBOBOXCLASSNAME,
-                     text,
+                     UTF8toWide(text),
                      WS_CHILD | CBS_DROPDOWN | WS_VSCROLL |
                      WS_CLIPCHILDREN | CBS_AUTOHSCROLL | WS_VISIBLE,
                      0,0,0,0,
@@ -5524,10 +6161,11 @@
    cinfo2->back = cinfo->back = -1;
    cinfo2->combo = cinfo->combo = tmp;
    EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo2);
-
+   cinfo->buddy = cinfo2->buddy;
+   
    SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_font(tmp, DefaultFont);
-   SetWindowText(tmp, text);
+   SetWindowText(tmp, UTF8toWide(text));
    return tmp;
 }
 
@@ -5539,10 +6177,10 @@
  */
 HWND API dw_button_new(char *text, ULONG id)
 {
-   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
 
    HWND tmp = CreateWindow(BUTTONCLASSNAME,
-                     text,
+                     UTF8toWide(text),
                      WS_CHILD | BS_PUSHBUTTON |
                      WS_VISIBLE | WS_CLIPCHILDREN,
                      0,0,0,0,
@@ -5550,14 +6188,100 @@
                      (HMENU)id,
                      DWInstance,
                      NULL);
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_font(tmp, DefaultFont);
    return tmp;
 }
 
+#ifdef TOOLBAR
+/* Internal function to create a grayscale bitmap from a color one */
+void _to_grayscale(HBITMAP hbm, int width, int height)
+{
+   HDC hdc = CreateCompatibleDC(NULL);
+   if (hdc) 
+   {
+      HBITMAP hbmPrev = SelectBitmap(hdc, hbm);
+      int x, y;
+
+      for(y=0;y<height;y++)
+      {
+         for(x=0;x<width;x++)
+         {
+            COLORREF c = GetPixel(hdc, x, y);
+            /* Use half-values then add 127 to make it look washed out */
+            int luma = (int)(GetRValue(c)*0.15 + GetGValue(c)*0.3+ GetBValue(c)*0.06) + 127;
+
+            SetPixel(hdc, x, y, RGB(luma,luma,luma));
+         }
+      }
+      SelectBitmap(hdc, hbmPrev);
+      DeleteDC(hdc);
+   }
+}
+
+/* Internal function to create a toolbar based button */
+HWND _create_toolbar(char *text, ULONG id, HICON icon, HBITMAP hbitmap)
+{
+   HWND tmp;
+   HIMAGELIST imlist, dimlist;
+   BITMAP bmi = { 0 };
+   TBBUTTON tbButtons[] = {    
+   { MAKELONG(0, 0), id, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
+   };
+   
+   /* Get the bitmap from either the icon or bitmap itself */
+   if(hbitmap)
+   {
+      GetObject(hbitmap, sizeof(BITMAP), &bmi);
+      imlist = ImageList_Create(bmi.bmWidth, bmi.bmHeight, ILC_COLOR32, 1, 0);
+      ImageList_Add(imlist, hbitmap, NULL);
+      dimlist = ImageList_Create(bmi.bmWidth, bmi.bmHeight, ILC_COLOR32, 1, 0);
+      _to_grayscale(hbitmap, bmi.bmWidth, bmi.bmHeight);
+      ImageList_Add(dimlist, hbitmap, NULL);
+      DeleteObject(hbitmap);
+   }
+   else if(icon)
+   {
+      ICONINFO iconinfo;
+      
+      GetIconInfo(icon, &iconinfo);
+      GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bmi);
+      imlist = ImageList_Create(bmi.bmWidth, bmi.bmHeight, ILC_COLOR32 | ILC_MASK, 1, 0);
+      ImageList_AddIcon(imlist, icon);
+      dimlist = ImageList_Create(bmi.bmWidth, bmi.bmHeight, ILC_COLOR32 | ILC_MASK, 1, 0);
+      _to_grayscale(iconinfo.hbmColor, bmi.bmWidth, bmi.bmHeight);
+      ImageList_Add(dimlist, iconinfo.hbmColor, iconinfo.hbmMask);
+      DeleteObject(iconinfo.hbmColor);
+      DeleteObject(iconinfo.hbmMask);
+      DestroyIcon(icon);
+   }
+   else
+      return 0;
+
+   /* Create the toolbar */
+   tmp = CreateWindowEx(0L, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_AUTOSIZE | CCS_NORESIZE | 
+                        CCS_NOPARENTALIGN | CCS_NODIVIDER, 0, 0, 100, 30, DW_HWND_OBJECT, (HMENU)id, DWInstance, NULL);
+                         
+   /* Disable visual styles by default */
+   if(_SetWindowTheme)
+      _SetWindowTheme(tmp, L"", L"");
+
+   /* Insert the single bitmap and button into the toolbar */
+   SendMessage(tmp, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
+   SendMessage(tmp, TB_SETBUTTONSIZE, 0, MAKELPARAM(bmi.bmWidth, bmi.bmHeight));
+   SendMessage(tmp, TB_SETPADDING, 0, 0);
+   SendMessage(tmp, TB_SETIMAGELIST, 0, (LPARAM)imlist);
+   SendMessage(tmp, TB_SETDISABLEDIMAGELIST, 0, (LPARAM)dimlist);
+   SendMessage(tmp, TB_ADDBUTTONS, 1, (LONG) &tbButtons);
+   
+   _create_tooltip(tmp, text);
+   return tmp;
+}
+#endif
+
 /*
  * Create a new bitmap button window (widget) to be packed.
  * Parameters:
@@ -5567,12 +6291,20 @@
 HWND API dw_bitmapbutton_new(char *text, ULONG id)
 {
    HWND tmp;
-   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-   HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
-   HICON icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+   HICON icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, 0);
+   HBITMAP hbitmap = icon ? 0 : LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+#ifdef TOOLBAR
+   if(tmp = _create_toolbar(text, id, icon, hbitmap))
+   {
+      cinfo->fore = cinfo->back = -1;
+      SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+      return tmp;
+   }
+#endif
 
    tmp = CreateWindow(BUTTONCLASSNAME,
-                  "",
+                  NULL,
                   WS_CHILD | BS_PUSHBUTTON |
                   WS_VISIBLE | WS_CLIPCHILDREN |
                   (icon ? BS_ICON : BS_BITMAP),
@@ -5582,10 +6314,10 @@
                   DWInstance,
                   NULL);
 
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
 
    _create_tooltip(tmp, text);
 
@@ -5612,12 +6344,12 @@
 HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
 {
    HWND tmp;
-   BubbleButton *bubble;
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
    HBITMAP hbitmap = 0;
    HANDLE hicon = 0;
    int windowtype = 0;
 
-   if (!(bubble = calloc(1, sizeof(BubbleButton))))
+   if (!cinfo)
       return 0;
 
 #ifdef GDIPLUS
@@ -5632,8 +6364,16 @@
    windowtype = _dw_get_image_handle(filename, &hicon, &hbitmap);
 #endif
 
+#ifdef TOOLBAR
+   if(tmp = _create_toolbar(text, id, hicon, hbitmap))
+   {
+      cinfo->fore = cinfo->back = -1;
+      SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+      return tmp;
+   }
+#endif
    tmp = CreateWindow( BUTTONCLASSNAME,
-                       "",
+                       NULL,
                        windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE,
                        0,0,0,0,
                        DW_HWND_OBJECT,
@@ -5641,10 +6381,10 @@
                        DWInstance,
                        NULL);
 
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
 
    _create_tooltip(tmp, text);
 
@@ -5671,15 +6411,16 @@
 HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len)
 {
    HWND tmp;
-   BubbleButton *bubble;
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
    HBITMAP hbitmap = 0;
    HANDLE hicon = 0;
    char *file;
    FILE *fp;
    int windowtype = BS_BITMAP;
 
-   if ( !(bubble = calloc(1, sizeof(BubbleButton))) )
+   if (!cinfo)
       return 0;
+
    file = _tempnam( _dw_alternate_temp_dir, "dw" );
    if ( file != NULL )
    {
@@ -5695,26 +6436,34 @@
             hbitmap = _dw_load_bitmap(file, NULL);
 #else
          if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
-            hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+            hbitmap = (HBITMAP)LoadImage( NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
          else /* otherwise its assumed to be an ico */
          {
-            hicon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+            hicon = LoadImage( NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
             windowtype = BS_ICON;
          }
 #endif
       }
       else
       {
-         unlink( file );
+         _unlink( file );
          free( file );
          return 0;
       }
-      unlink( file );
+      _unlink( file );
       free( file );
    }
 
+#ifdef TOOLBAR
+   if(tmp = _create_toolbar(text, id, hicon, hbitmap))
+   {
+      cinfo->fore = cinfo->back = -1;
+      SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+      return tmp;
+   }
+#endif
    tmp = CreateWindow( BUTTONCLASSNAME,
-                       "",
+                       NULL,
                        WS_CHILD | BS_PUSHBUTTON |
                        windowtype | WS_CLIPCHILDREN |
                        WS_VISIBLE,
@@ -5724,10 +6473,10 @@
                        DWInstance,
                        NULL );
 
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow( tmp, _BtProc );
-
-   SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)bubble );
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow( tmp, _BtProc );
+
+   SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)cinfo );
 
    _create_tooltip(tmp, text);
 
@@ -5752,7 +6501,7 @@
 {
    HWND buddy = CreateWindowEx(WS_EX_CLIENTEDGE,
                         EDITCLASSNAME,
-                        text,
+                        UTF8toWide(text),
                         WS_CHILD | WS_BORDER | WS_VISIBLE |
                         ES_NUMBER | WS_CLIPCHILDREN,
                         0,0,0,0,
@@ -5806,7 +6555,7 @@
 HWND API dw_radiobutton_new(char *text, ULONG id)
 {
    HWND tmp = CreateWindow(BUTTONCLASSNAME,
-                     text,
+                     UTF8toWide(text),
                      WS_CHILD | BS_AUTORADIOBUTTON |
                      WS_CLIPCHILDREN | WS_VISIBLE,
                      0,0,0,0,
@@ -5814,11 +6563,12 @@
                      (HMENU)id,
                      DWInstance,
                      NULL);
-   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_DEFAULT, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -5833,7 +6583,7 @@
 HWND API dw_slider_new(int vertical, int increments, ULONG id)
 {
    HWND tmp = CreateWindow(TRACKBAR_CLASS,
-                     "",
+                     NULL,
                      WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
                      (vertical ? TBS_VERT : TBS_HORZ),
                      0,0,0,0,
@@ -5861,7 +6611,7 @@
 HWND API dw_scrollbar_new(int vertical, ULONG id)
 {
    HWND tmp = CreateWindow(SCROLLBARCLASSNAME,
-                     "",
+                     NULL,
                      WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
                      (vertical ? SBS_VERT : SBS_HORZ),
                      0,0,0,0,
@@ -5887,7 +6637,7 @@
 HWND API dw_percent_new(ULONG id)
 {
    return CreateWindow(PROGRESS_CLASS,
-                  "",
+                  NULL,
                   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                   0,0,0,0,
                   DW_HWND_OBJECT,
@@ -5904,9 +6654,9 @@
  */
 HWND API dw_checkbox_new(char *text, ULONG id)
 {
-   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
    HWND tmp = CreateWindow(BUTTONCLASSNAME,
-                     text,
+                     UTF8toWide(text),
                      WS_CHILD | BS_AUTOCHECKBOX |
                      BS_TEXT | WS_CLIPCHILDREN | WS_VISIBLE,
                      0,0,0,0,
@@ -5914,11 +6664,11 @@
                      (HMENU)id,
                      DWInstance,
                      NULL);
-   bubble->checkbox = 1;
-   bubble->cinfo.fore = bubble->cinfo.back = -1;
-   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_data(tmp, "_dw_checkbox", DW_INT_TO_POINTER(1));
    dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_DEFAULT, DW_RGB_TRANSPARENT);
    return tmp;
 }
 
@@ -5932,7 +6682,7 @@
 {
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
                        LISTBOXCLASSNAME,
-                       "",
+                       NULL,
                        WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
                        WS_CHILD | LBS_HASSTRINGS |
                        LBS_NOTIFY | WS_BORDER  | WS_CLIPCHILDREN |
@@ -5952,7 +6702,7 @@
 
    cinfo->cinfo.fore = cinfo->cinfo.back = -1;
    cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
-   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
+   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _containerwndproc);
 
    SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_font(tmp, DefaultFont);
@@ -6031,6 +6781,19 @@
       DeleteObject(oldbitmap);
    else if(icon && oldicon)
       DeleteObject(oldicon);
+
+   /* If we changed the bitmap... */
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+   }
 }
 
 /*
@@ -6053,12 +6816,7 @@
    char *file;
    FILE *fp;
 
-   if ( id )
-   {
-      hbitmap = LoadBitmap( DWInstance, MAKEINTRESOURCE(id) );
-      icon = LoadImage( DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED );
-   }
-   else if (data)
+   if (data)
    {
       file = _tempnam( _dw_alternate_temp_dir, "dw" );
       if ( file != NULL )
@@ -6072,23 +6830,28 @@
             hbitmap = _dw_load_bitmap(file, NULL);
 #else
             if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
-               hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+               hbitmap = (HBITMAP)LoadImage( NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
             else /* otherwise its assumed to be an ico */
-               icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+               icon = LoadImage( NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
 #endif
          }
          else
          {
-            unlink( file );
+            _unlink( file );
             free( file );
             return;
          }
-         unlink( file );
+         _unlink( file );
          free( file );
       }
       if (icon == 0 && hbitmap == 0)
          return;
    }
+   else if ( id )
+   {
+      hbitmap = LoadBitmap( DWInstance, MAKEINTRESOURCE(id) );
+      icon = LoadImage( DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED );
+   }
 
    if ( icon )
    {
@@ -6125,28 +6888,55 @@
 void API dw_window_set_text(HWND handle, char *text)
 {
    Box *thisbox;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0}, *wtext = UTF8toWide(text);
 
    GetClassName(handle, tmpbuf, 99);
 
-   SetWindowText(handle, text);
+   SetWindowText(handle, wtext);
 
    /* Combobox */
-   if ( strnicmp( tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1) == 0 )
+   if ( _tcsnicmp( tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1) == 0 )
       SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0));
-   else if ( strnicmp( tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1) == 0 )
+   else if ( _tcsnicmp( tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1) == 0 )
    {
       ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
       if( cinfo && cinfo->buddy )
-         SetWindowText( cinfo->buddy, text );
-   }
-   else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+         SetWindowText( cinfo->buddy, wtext );
+   }
+   else if ( _tcsnicmp( tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1) == 0 )
    {
       /* groupbox */
       thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
       if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
-         SetWindowText( thisbox->grouphwnd, text );
-   }
+         SetWindowText( thisbox->grouphwnd, wtext );
+   }
+   /* If we changed the text... */
+   {
+      Item *item = _box_item(handle);
+       
+      /* Check to see if any of the sizes need to be recalculated */
+      if(item && (item->origwidth == -1 || item->origheight == -1))
+      {
+         _control_size(handle, item->origwidth == -1 ? &item->width : NULL, item->origheight == -1 ? &item->height : NULL); 
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(handle), TRUE);
+      }
+   }
+}
+
+/*
+ * Sets the text used for a given window's floating bubble help.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       bubbletext: The text in the floating bubble tooltip.
+ */
+void API dw_window_set_tooltip(HWND handle, char *bubbletext)
+{
+    ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+    
+    if(cinfo && cinfo->buddy)
+        _create_tooltip(cinfo->buddy, bubbletext);
+    _create_tooltip(handle, bubbletext);
 }
 
 /*
@@ -6158,12 +6948,13 @@
  */
 char * API dw_window_get_text(HWND handle)
 {
-   char tmpbuf[100], *tempbuf;
+   char *retbuf = NULL;
+   TCHAR *tempbuf, tmpbuf[100] = { 0 };
    int len;
 
    GetClassName(handle, tmpbuf, 99);
 
-   if ( strnicmp( tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1) == 0 )
+   if ( _tcsnicmp( tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1) == 0 )
    {
       ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
@@ -6173,12 +6964,19 @@
         return NULL;
    }
 
-   len = GetWindowTextLength(handle);
-   tempbuf = calloc(1, len + 2);
-
-   GetWindowText(handle, tempbuf, len + 1);
-
-   return tempbuf;
+   /* Figure out the wide length, allocate a temp buffer
+    * and fill it with the current text.
+    */
+   len = GetWindowTextLength(handle) + 1;
+   if((tempbuf = _alloca(len * sizeof(TCHAR))))
+      GetWindowText(handle, tempbuf, len);
+   
+   /* Figure out the UTF8 length, allocate a return buffer
+    * and fill it with the UTF8 text and return it.
+    */
+   if(tempbuf && (retbuf = WideToUTF8(tempbuf)))
+      retbuf = _strdup(retbuf);
+   return retbuf;
 }
 
 /*
@@ -6256,7 +7054,7 @@
 void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
 {
    Box *thisbox = NULL;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
       /*
        * If you try and pack an item into itself VERY bad things can happen; like at least an
@@ -6269,9 +7067,9 @@
    }
 
    GetClassName(box, tmpbuf, 99);
-
+   
    /* If we are in a scrolled box... extract the interal box */
-   if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+   if(_tcsnicmp(tmpbuf, ScrollClassName, _tcslen(ScrollClassName)+1)==0)
    {
         ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
         if(cinfo)
@@ -6280,7 +7078,7 @@
             thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
         }
    }
-   else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+   else //if(_tcsnicmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1)==0)
        thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
    if(thisbox)
    {
@@ -6288,12 +7086,14 @@
       Item *tmpitem, *thisitem = thisbox->items;
 
       /* Do some sanity bounds checking */
+      if(!thisitem)
+          thisbox->count = 0;
       if(index < 0)
         index = 0;
       if(index > thisbox->count)
         index = thisbox->count;
 
-      tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
+      tmpitem = calloc(sizeof(Item), (thisbox->count+1));
 
       for(z=0;z<thisbox->count;z++)
       {
@@ -6310,49 +7110,49 @@
       if(hsize && !width)
          width = 1;
 
-      if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+      if(_tcsnicmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1)==0)
          tmpitem[index].type = TYPEBOX;
-      else if(strnicmp(tmpbuf, "SysMonthCal32", 13)==0)
-      {
-         RECT rc;
-         MonthCal_GetMinReqRect(item, &rc);
-         width = 1 + rc.right - rc.left;
-         height = 1 + rc.bottom - rc.top;
-         tmpitem[index].type = TYPEITEM;
-      }
       else
       {
-         if ( width == 0 && hsize == FALSE )
-            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-         if ( height == 0 && vsize == FALSE )
-            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-         tmpitem[index].type = TYPEITEM;
+         if(_tcsnicmp(tmpbuf, TEXT("SysMonthCal32"), 13)==0)
+         {
+            RECT rc;
+            MonthCal_GetMinReqRect(item, &rc);
+            width = 1 + rc.right - rc.left;
+            height = 1 + rc.bottom - rc.top;
+            tmpitem[index].type = TYPEITEM;
+         }
+         else
+         {
+            if ( width == 0 && hsize == FALSE )
+               dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
+            if ( height == 0 && vsize == FALSE )
+               dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
+
+            tmpitem[index].type = TYPEITEM;
+         }
       }
 
       tmpitem[index].hwnd = item;
       tmpitem[index].origwidth = tmpitem[index].width = width;
       tmpitem[index].origheight = tmpitem[index].height = height;
       tmpitem[index].pad = pad;
-      if(hsize)
-         tmpitem[index].hsize = SIZEEXPAND;
-      else
-         tmpitem[index].hsize = SIZESTATIC;
-
-      if(vsize)
-         tmpitem[index].vsize = SIZEEXPAND;
-      else
-         tmpitem[index].vsize = SIZESTATIC;
+      tmpitem[index].hsize = hsize ? SIZEEXPAND : SIZESTATIC;
+      tmpitem[index].vsize = vsize ? SIZEEXPAND : SIZESTATIC;
+    
+      /* If either of the parameters are -1 ... calculate the size */
+      if(width == -1 || height == -1)
+         _control_size(item, width == -1 ? &tmpitem[index].width : NULL, height == -1 ? &tmpitem[index].height : NULL);
 
       thisbox->items = tmpitem;
 
-      if(thisbox->count)
+      if(thisitem)
          free(thisitem);
 
       thisbox->count++;
 
       SetParent(item, box);
-      if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
+      if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0)
       {
          ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(item, GWLP_USERDATA);
 
@@ -6363,14 +7163,147 @@
             SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0);
          }
       }
-   }
+#ifdef TOOLBAR      
+      else if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+      {
+#ifdef AEROGLASS	  
+         if(!(_dw_composition && (GetWindowLongPtr(_toplevel_window(box), GWL_EXSTYLE) & WS_EX_LAYERED)))
+#endif		 
+         { 
+            /* Enable double buffering if our window isn't composited */
+            SendMessage(item, TB_SETEXTENDEDSTYLE, 0, (LPARAM)TBSTYLE_EX_DOUBLEBUFFER);
+         }
+      }
+#endif      
+      /* Queue a redraw on the top-level window */
+      _dw_redraw(_toplevel_window(box), TRUE);
+   }
+}
+
+/*
+ * Remove windows (widgets) from the box they are packed into.
+ * Parameters:
+ *       handle: Window handle of the packed item to be removed.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_box_unpack(HWND handle)
+{
+   HWND parent = GetParent(handle);
+   
+   if(handle && parent != HWND_DESKTOP)
+   {
+      Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);
+      
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+      if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem = NULL, *thisitem = thisbox->items;
+
+         if(!thisitem)
+             thisbox->count = 0;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return DW_ERROR_GENERAL;
+
+         if(thisbox->count > 1)
+         {
+            tmpitem = calloc(sizeof(Item), (thisbox->count-1));
+
+            /* Copy all but the current entry to the new list */
+            for(z=0;z<index;z++)
+            {
+               tmpitem[z] = thisitem[z];
+            }
+            for(z=index+1;z<thisbox->count;z++)
+            {
+               tmpitem[z-1] = thisitem[z];
+            }
+         }
+
+         thisbox->items = tmpitem;
+         if(thisitem)
+            free(thisitem);
+         if(tmpitem)
+            thisbox->count--;
+         else
+            thisbox->count = 0;
+
+         SetParent(handle, DW_HWND_OBJECT);
+         /* Queue a redraw on the top-level window */
+         _dw_redraw(_toplevel_window(parent), TRUE);
+         return DW_ERROR_NONE;
+      }
+   }
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Remove windows (widgets) from a box at an arbitrary location.
+ * Parameters:
+ *       box: Window handle of the box to be removed from.
+ *       index: 0 based index of packed items.
+ * Returns:
+ *       Handle to the removed item on success, 0 on failure or padding.
+ */
+HWND API dw_box_unpack_at_index(HWND box, int index)
+{
+   Box *thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+   
+   /* Try to remove it from the layout */
+   if(thisbox && index > -1 && index < thisbox->count)
+   {
+      int z;
+      Item *tmpitem = NULL, *thisitem = thisbox->items;
+      HWND handle = thisitem[index].hwnd;
+
+      if(thisbox->count > 1)
+      {
+         tmpitem = calloc(sizeof(Item), (thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+      }
+
+      thisbox->items = tmpitem;
+      if(thisitem)
+         free(thisitem);
+      if(tmpitem)
+         thisbox->count--;
+      else
+         thisbox->count = 0;
+
+      /* If it isn't padding, reset the parent */
+      if(handle)
+         SetParent(handle, DW_HWND_OBJECT);
+      /* Queue a redraw on the top-level window */
+      _dw_redraw(_toplevel_window(box), TRUE);
+      return handle;
+   }
+   return 0;
 }
 
 /*
  * Pack windows (widgets) into a box at an arbitrary location.
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       index: 0 based index of packed items.
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
@@ -6387,7 +7320,7 @@
  * Pack windows (widgets) into a box from the start (or top).
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
  *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
@@ -6406,7 +7339,7 @@
  * Pack windows (widgets) into a box from the end (or bottom).
  * Parameters:
  *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
+ *       item: Window handle of the item to pack.
  *       width: Width in pixels of the item or -1 to be self determined.
  *       height: Height in pixels of the item or -1 to be self determined.
  *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
@@ -6419,6 +7352,36 @@
 }
 
 /*
+ * 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.
+ */
+void _get_window_for_size(HWND handle, unsigned long *width, unsigned long *height)
+{
+   Box *thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   
+   if(thisbox)
+   {
+      int depth = 0;
+      DWORD dwStyle = GetWindowLong(handle, GWL_STYLE);
+      DWORD dwExStyle = GetWindowLong(handle, GWL_EXSTYLE);
+      HMENU menu = GetMenu(handle) ;
+      RECT rc = { 0 } ;
+     
+      /* Calculate space requirements */
+      _resize_box(thisbox, &depth, *width, *height, 1);
+      
+      rc.right = thisbox->minwidth;
+      rc.bottom = thisbox->minheight;
+      
+      /* Take into account the window border and menu here */
+      AdjustWindowRectEx(&rc, dwStyle, menu ? TRUE : FALSE, dwExStyle);
+      
+      if ( *width < 1 ) *width = rc.right - rc.left;
+      if ( *height < 1 ) *height = rc.bottom - rc.top;
+   }
+}
+
+/*
  * Sets the size of a given window (widget).
  * Parameters:
  *          handle: Window (widget) handle.
@@ -6427,22 +7390,56 @@
  */
 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 :-(
-    */
-   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;
-   SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
+   /* Attempt to auto-size */
+   if ( width < 1 || height < 1 )
+      _get_window_for_size(handle, &width, &height);
+   
+   /* Finally set the size */
+   SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
+}
+
+/*
+ * Gets the size the system thinks the widget should be.
+ * Parameters:
+ *       handle: Window handle of the item to be back.
+ *       width: Width in pixels of the item or NULL if not needed.
+ *       height: Height in pixels of the item or NULL if not needed.
+ */
+void API dw_window_get_preferred_size(HWND handle, int *width, int *height)
+{
+   TCHAR tmpbuf[100] = {0};
+
+   GetClassName(handle, tmpbuf, 99);
+   
+   if(_tcsnicmp(tmpbuf, ClassName, _tcslen(ClassName)+1) == 0)
+   {
+      unsigned long thiswidth = 0, thisheight = 0;
+      
+      /* Get the size with the border */
+      _get_window_for_size(handle, &thiswidth, &thisheight);
+      
+      /* Return what was requested */
+      if(width) *width = (int)thiswidth;
+      if(height) *height = (int)thisheight;
+   }
+   else if(_tcsnicmp(tmpbuf, FRAMECLASSNAME, _tcslen(FRAMECLASSNAME)+1) == 0)
+   {
+      Box *thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+      
+      if(thisbox)
+      {
+         int depth = 0;
+         
+         /* Calculate space requirements */
+         _resize_box(thisbox, &depth, 0, 0, 1);
+         
+         /* Return what was requested */
+         if(width) *width = thisbox->minwidth;
+         if(height) *height = thisbox->minheight;
+      }
+   }
+   else
+      _control_size(handle, width, height);
 }
 
 /*
@@ -6450,7 +7447,7 @@
  */
 int API dw_screen_width(void)
 {
-   return screenx;
+   return GetSystemMetrics(SM_CXSCREEN);
 }
 
 /*
@@ -6458,7 +7455,7 @@
  */
 int API dw_screen_height(void)
 {
-   return screeny;
+   return GetSystemMetrics(SM_CYSCREEN);
 }
 
 /* This should return the current color depth */
@@ -6474,6 +7471,75 @@
    return bpp;
 }
 
+/*
+ * Sets the gravity of a given window (widget).
+ * Gravity controls which corner of the screen and window the position is relative to.
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          horz: DW_GRAV_LEFT (default), DW_GRAV_RIGHT or DW_GRAV_CENTER.
+ *          vert: DW_GRAV_TOP (default), DW_GRAV_BOTTOM or DW_GRAV_CENTER.
+ */
+void API dw_window_set_gravity(HWND handle, int horz, int vert)
+{
+   dw_window_set_data(handle, "_dw_grav_horz", DW_INT_TO_POINTER(horz));
+   dw_window_set_data(handle, "_dw_grav_vert", DW_INT_TO_POINTER(vert));
+}
+
+/* Convert the coordinates based on gravity */
+void _handle_gravity(HWND handle, long *x, long *y, unsigned long width, unsigned long height)
+{
+   int horz = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_grav_horz"));
+   int vert = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_grav_vert"));
+   
+   /* Do any gravity calculations */
+   if(horz || vert)
+   {
+      long newx = *x, newy = *y;
+   
+      /* Handle horizontal center gravity */
+      if((horz & 0xf) == DW_GRAV_CENTER)
+         newx += ((dw_screen_width() / 2) - (width / 2));
+      /* Handle right gravity */
+      else if((horz & 0xf) == DW_GRAV_RIGHT)
+         newx = dw_screen_width() - width - *x;
+      /* Handle vertical center gravity */
+      if((vert & 0xf) == DW_GRAV_CENTER)
+         newy += ((dw_screen_height() / 2) - (height / 2));
+      else if((vert & 0xf) == DW_GRAV_BOTTOM)
+         newy = dw_screen_height() - height - *y;
+        
+      /* Save the new values */
+      *x = newx;
+      *y = newy;
+      
+       /* Adjust the values to avoid Taskbar if requested */
+       if((horz | vert) & DW_GRAV_OBSTACLES)
+       {
+         POINT pt = { 0, 0 };
+         HMONITOR mon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
+         MONITORINFO mi;
+         
+         mi.cbSize = sizeof(MONITORINFO);
+         
+         GetMonitorInfo(mon, &mi);
+         
+         if(horz & DW_GRAV_OBSTACLES)
+         {
+            if((horz & 0xf) == DW_GRAV_LEFT)
+               *x += (mi.rcWork.left - mi.rcMonitor.left);
+            else if((horz & 0xf) == DW_GRAV_RIGHT)
+               *x -= (mi.rcMonitor.right - mi.rcWork.right);
+         }
+         if(vert & DW_GRAV_OBSTACLES)
+         {
+            if((vert & 0xf) == DW_GRAV_TOP)
+               *y += (mi.rcWork.top - mi.rcMonitor.top);
+            else if((vert & 0xf) == DW_GRAV_BOTTOM)
+               *y -= (mi.rcMonitor.bottom - mi.rcWork.bottom);
+         }
+      }
+   }            
+}
 
 /*
  * Sets the position of a given window (widget).
@@ -6484,6 +7550,17 @@
  */
 void API dw_window_set_pos(HWND handle, long x, long y)
 {
+   unsigned long width, height;
+   RECT rect;
+
+   GetClientRect(handle, &rect);
+
+   /* Can't position an unsized window, so attempt to auto-size */
+   if((rect.bottom - rect.top) == 0 || (rect.right - rect.left) == 0)
+      dw_window_set_size(handle, 0, 0);
+
+   dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+   _handle_gravity(handle, &x, &y, width, height);
    SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
 }
 
@@ -6498,26 +7575,13 @@
  */
 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 :-(
-    */
-   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;
-   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
+   /* Attempt to auto-size */
+   if ( width < 1 || height < 1 )
+      _get_window_for_size(handle, &width, &height);
+   
+   _handle_gravity(handle, &x, &y, width, height);
+   /* Finally set the size */
+   SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_NOACTIVATE);
 }
 
 /*
@@ -6571,7 +7635,11 @@
 {
    ULONG tmp, currentstyle;
    ColorInfo *cinfo;
-   
+   TCHAR tmpbuf[100] = {0};
+
+   if(!handle)
+      return;
+
    if(handle < (HWND)65536)
    {
       char buffer[31] = {0};
@@ -6586,31 +7654,83 @@
       return;
    }
    
+   GetClassName(handle, tmpbuf, 99);
+
    currentstyle = GetWindowLong(handle, GWL_STYLE);
    cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
+#ifdef TOOLBAR
+   /* Bitmap Buttons */
+   if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+   {
+      ULONG thisstyle = (TBSTYLE_FLAT | TBSTYLE_TRANSPARENT);
+      
+      if(mask & DW_BS_NOBORDER)
+      {
+         SetWindowLong(handle, GWL_STYLE, (style & DW_BS_NOBORDER) ? (currentstyle | thisstyle) : (currentstyle & ~thisstyle));
+
+         /* Enable or disable visual themese */
+         if(_SetWindowTheme)
+            _SetWindowTheme(handle, (style & DW_BS_NOBORDER) ? NULL : L"", (style & DW_BS_NOBORDER) ? NULL : L"");
+            
+         return;
+      }
+   }
+#endif
+   
    tmp = currentstyle | mask;
    tmp ^= mask;
    tmp |= style;
 
-   /* We are using SS_NOPREFIX as a VCENTER flag */
-   if(tmp & SS_NOPREFIX)
-   {
-
-      if(cinfo)
-         cinfo->vcenter = 1;
-      else
-      {
-         cinfo = calloc(1, sizeof(ColorInfo));
-         cinfo->fore = cinfo->back = -1;
-         cinfo->vcenter = 1;
-
-         cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
-         SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
-      }
-   }
-   else if(cinfo)
-      cinfo->vcenter = 0;
+   if(_tcsnicmp(tmpbuf, ClassName, _tcslen(ClassName)+1)==0)
+   {
+      tmp = tmp & 0xffff0000;
+#ifdef AEROGLASS      
+      if(mask & DW_FCF_COMPOSITED && _DwmExtendFrameIntoClientArea && _dw_composition)
+      {
+         LONG_PTR styleex = GetWindowLongPtr(handle, GWL_EXSTYLE);
+         
+         if(style & DW_FCF_COMPOSITED)
+         {
+            MARGINS mar = {-1};
+            
+            /* Attempt to enable Aero glass background on the entire window */
+            SetWindowLongPtr(handle, GWL_EXSTYLE, styleex | WS_EX_LAYERED);
+            SetLayeredWindowAttributes(handle, _dw_transparencykey, 0, LWA_COLORKEY);
+            _DwmExtendFrameIntoClientArea(handle, &mar);
+         }
+         else
+         {
+            MARGINS mar = {0};
+            
+            /* Remove Aero Glass */
+            SetWindowLongPtr(handle, GWL_EXSTYLE, styleex & ~WS_EX_LAYERED);
+            _DwmExtendFrameIntoClientArea(handle, &mar);
+         }
+      }
+#endif      
+   }
+   else
+   {
+      /* We are using SS_NOPREFIX as a VCENTER flag */
+      if(tmp & SS_NOPREFIX)
+      {
+
+         if(cinfo)
+            cinfo->vcenter = 1;
+         else
+         {
+            cinfo = calloc(1, sizeof(ColorInfo));
+            cinfo->fore = cinfo->back = -1;
+            cinfo->vcenter = 1;
+
+            cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
+            SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
+         }
+      }
+      else if(cinfo)
+         cinfo->vcenter = 0;
+   }
 
    SetWindowLong(handle, GWL_STYLE, tmp);
 }
@@ -6663,7 +7783,7 @@
             array[z]->realid = refid;
             array[z]->item.mask = TCIF_TEXT;
             array[z]->item.iImage = -1;
-            array[z]->item.pszText = "";
+            array[z]->item.pszText = TEXT("");
             TabCtrl_InsertItem(handle, z, &(array[z]->item));
             return refid;
          }
@@ -6693,7 +7813,7 @@
    if(pageid > -1 && array[pageid])
    {
       array[pageid]->item.mask = TCIF_TEXT;
-      array[pageid]->item.pszText = text;
+      array[pageid]->item.pszText = UTF8toWide(text);
       TabCtrl_SetItem(handle, pageid, &(array[pageid]->item));
       _resize_notebook_page(handle, pageid);
    }
@@ -6732,7 +7852,6 @@
       HWND tmpbox = dw_box_new(DW_VERT, 0);
 
       dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
-      SubclassWindow(tmpbox, _wndproc);
       if(array[pageid]->hwnd)
          dw_window_destroy(array[pageid]->hwnd);
       array[pageid]->hwnd = tmpbox;
@@ -6851,18 +7970,18 @@
  */
 void API dw_listbox_append(HWND handle, char *text)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       SendMessage(handle,
                CB_ADDSTRING,
-               0, (LPARAM)text);
+               0, (LPARAM)UTF8toWide(text));
    else
       SendMessage(handle,
                LB_ADDSTRING,
-               0, (LPARAM)text);
+               0, (LPARAM)UTF8toWide(text));
 }
 
 /*
@@ -6874,19 +7993,19 @@
  */
 void API dw_listbox_list_append(HWND handle, char **text, int count)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
    int listbox_type;
    int i;
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       listbox_type = CB_ADDSTRING;
    else
       listbox_type = LB_ADDSTRING;
 
    for(i=0;i<count;i++)
-      SendMessage(handle,(WPARAM)listbox_type,0,(LPARAM)text[i]);
+      SendMessage(handle,(WPARAM)listbox_type,0,(LPARAM)UTF8toWide(text[i]));
 }
 
 /*
@@ -6898,18 +8017,18 @@
  */
 void API dw_listbox_insert(HWND handle, char *text, int pos)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       SendMessage(handle,
                CB_INSERTSTRING,
-               pos, (LPARAM)text);
+               pos, (LPARAM)UTF8toWide(text));
    else
       SendMessage(handle,
                LB_INSERTSTRING,
-               pos, (LPARAM)text);
+               pos, (LPARAM)UTF8toWide(text));
 }
 
 /*
@@ -6919,11 +8038,11 @@
  */
 void API dw_listbox_clear(HWND handle)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
    {
       char *buf = dw_window_get_text(handle);
 
@@ -6950,11 +8069,11 @@
  */
 void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
    {
       SendMessage(handle,  CB_DELETESTRING, (WPARAM)index, 0);
       SendMessage(handle, CB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer);
@@ -6979,31 +8098,35 @@
  */
 void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
 {
-   char tmpbuf[100];
-   int len;
+   TCHAR tmpbuf[100] = {0}, *wbuffer;
+   unsigned int len;
+
+   buffer[0] = 0;
 
    if(!buffer || !length)
       return;
 
-   buffer[0] = 0;
-
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
    {
       len = (int)SendMessage(handle, CB_GETLBTEXTLEN, (WPARAM)index, 0);
 
-      if(len < length && len != CB_ERR)
-         SendMessage(handle,
-                  CB_GETLBTEXT, (WPARAM)index, (LPARAM)buffer);
+      if(len != CB_ERR && (wbuffer = _alloca((len+1)*sizeof(TCHAR))))
+      {
+         SendMessage(handle, CB_GETLBTEXT, (WPARAM)index, (LPARAM)wbuffer);
+         strncpy(buffer, WideToUTF8(wbuffer), length);
+      }
    }
    else
    {
       len = (int)SendMessage(handle, LB_GETTEXTLEN, (WPARAM)index, 0);
 
-      if(len < length && len != LB_ERR)
-         SendMessage(handle,
-                  LB_GETTEXT, (WPARAM)index, (LPARAM)buffer);
+      if(len != LB_ERR && (wbuffer = _alloca((len+1)*sizeof(TCHAR))))
+      {
+         SendMessage(handle, LB_GETTEXT, (WPARAM)index, (LPARAM)wbuffer);
+         strncpy(buffer, WideToUTF8(wbuffer), length);
+      }
    }
 }
 
@@ -7014,11 +8137,11 @@
  */
 int API dw_listbox_selected(HWND handle)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       return (unsigned int)SendMessage(handle,
                                CB_GETCURSEL,
                                0, 0);
@@ -7037,12 +8160,12 @@
 int API dw_listbox_selected_multi(HWND handle, int where)
 {
    int *array, count, z;
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
    /* This doesn't work on comboboxes */
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       return -1;
 
    count = (int)SendMessage(handle, LB_GETSELCOUNT, 0, 0);
@@ -7080,11 +8203,11 @@
  */
 void API dw_listbox_select(HWND handle, int index, int state)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       SendMessage(handle, CB_SETCURSEL, (WPARAM)index, 0);
    else
    {
@@ -7102,11 +8225,11 @@
  */
 void API dw_listbox_delete(HWND handle, int index)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       SendMessage(handle, CB_DELETESTRING, (WPARAM)index, 0);
    else
       SendMessage(handle, LB_DELETESTRING, (WPARAM)index, 0);
@@ -7119,11 +8242,11 @@
  */
 int API dw_listbox_count(HWND handle)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       return (int)SendMessage(handle,
                         CB_GETCOUNT,0L, 0L);
 
@@ -7139,12 +8262,12 @@
  */
 void API dw_listbox_set_top(HWND handle, int top)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
    /* This doesn't work on comboboxes */
-   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   if(_tcsnicmp(tmpbuf, COMBOBOXCLASSNAME, _tcslen(COMBOBOXCLASSNAME)+1)==0)
       return;
 
    SendMessage(handle, LB_SETTOPINDEX, (WPARAM)top, 0);
@@ -7160,19 +8283,19 @@
 unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
 {
    int textlen, len = GetWindowTextLength(handle);
-   char *tmpbuf;
+   TCHAR *tmpbuf, *srcbuf = UTF8toWide(buffer);
 
    if(startpoint < 0)
       startpoint = 0;
 
-   if(!buffer || (textlen = strlen(buffer)) < 1)
+   if(!buffer || (textlen = (int)_tcslen(srcbuf)) < 1)
       return startpoint;
 
-   tmpbuf = calloc(1, len + textlen + startpoint + 2);
+   tmpbuf = calloc(sizeof(TCHAR), len + textlen + startpoint + 2);
 
    if(len)
    {
-      char *dest, *start;
+      TCHAR *dest, *start;
       int copylen = len - startpoint;
 
       GetWindowText(handle, tmpbuf, len+1);
@@ -7181,9 +8304,9 @@
       start = &tmpbuf[startpoint];
 
       if(copylen > 0)
-         memcpy(dest, start, copylen);
-   }
-   memcpy(&tmpbuf[startpoint], buffer, textlen);
+         memcpy(dest, start, copylen*sizeof(TCHAR));
+   }
+   memcpy(&tmpbuf[startpoint], srcbuf, textlen*sizeof(TCHAR));
 
    SetWindowText(handle, tmpbuf);
 
@@ -7202,7 +8325,7 @@
 void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
 {
    int max, len = GetWindowTextLength(handle);
-   char *tmpbuf = calloc(1, len+2);
+   TCHAR *tmpbuf = calloc(sizeof(TCHAR), len+2);
 
    if(len)
       GetWindowText(handle, tmpbuf, len+1);
@@ -7213,7 +8336,7 @@
    {
       max = MIN(length, len - startpoint);
 
-      memcpy(buffer, &tmpbuf[startpoint], max);
+      memcpy(buffer, WideToUTF8(&tmpbuf[startpoint]), max);
       buffer[max] = '\0';
    }
 
@@ -7245,13 +8368,13 @@
 void API dw_mle_delete(HWND handle, int startpoint, int length)
 {
    int len = GetWindowTextLength(handle);
-   char *tmpbuf = calloc(1, len+2);
+   TCHAR *tmpbuf = calloc(sizeof(TCHAR), len+2);
 
    GetWindowText(handle, tmpbuf, len+1);
 
    if(startpoint + length < len)
    {
-      strcpy(&tmpbuf[startpoint], &tmpbuf[startpoint+length]);
+      _tcscpy(&tmpbuf[startpoint], &tmpbuf[startpoint+length]);
 
       SetWindowText(handle, tmpbuf);
    }
@@ -7266,7 +8389,7 @@
  */
 void API dw_mle_clear(HWND handle)
 {
-   SetWindowText(handle, "");
+   SetWindowText(handle, TEXT(""));
 }
 
 /*
@@ -7300,13 +8423,21 @@
  */
 void API dw_mle_set_word_wrap(HWND handle, int state)
 {
-   /* If ES_AUTOHSCROLL is not set and there is not
+   /* If ES_AUTOHSCROLL is not set and there is no
     * horizontal scrollbar it word wraps.
     */
    if(state)
       dw_window_set_style(handle, 0, ES_AUTOHSCROLL);
    else
       dw_window_set_style(handle, ES_AUTOHSCROLL, ES_AUTOHSCROLL);
+   /* If it is a rich edit control use the rich edit message */
+   if(hrichedit)
+   {
+      if(state)
+         SendMessage(handle, EM_SETOPTIONS, (WPARAM)ECOOP_AND, (LPARAM)~ECO_AUTOHSCROLL);
+      else
+         SendMessage(handle, EM_SETOPTIONS, (WPARAM)ECOOP_OR, (LPARAM)ECO_AUTOHSCROLL);
+   }
 }
 
 /*
@@ -7332,18 +8463,19 @@
 int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
 {
    int len = GetWindowTextLength(handle);
-   char *tmpbuf = calloc(1, len+2);
+   TCHAR *tmpbuf = calloc(sizeof(TCHAR), len+2);
+   TCHAR *searchtext = UTF8toWide(text);
    int z, textlen, retval = 0;
 
    GetWindowText(handle, tmpbuf, len+1);
 
-   textlen = strlen(text);
+   textlen = (int)strlen(text);
 
    if(flags & DW_MLE_CASESENSITIVE)
    {
       for(z=point;z<(len-textlen) && !retval;z++)
       {
-         if(strncmp(&tmpbuf[z], text, textlen) == 0)
+         if(_tcsncmp(&tmpbuf[z], searchtext, textlen) == 0)
             retval = z + textlen;
       }
    }
@@ -7351,7 +8483,7 @@
    {
       for(z=point;z<(len-textlen) && !retval;z++)
       {
-         if(strnicmp(&tmpbuf[z], text, textlen) == 0)
+         if(_tcsnicmp(&tmpbuf[z], searchtext, textlen) == 0)
             retval = z + textlen;
       }
    }
@@ -7506,10 +8638,10 @@
  */
 void API dw_spinbutton_set_pos(HWND handle, long position)
 {
-   char tmpbuf[101] = {0};
+   TCHAR tmpbuf[101] = {0};
    ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
 
-   _snprintf(tmpbuf, 100, "%ld", position);
+   _sntprintf(tmpbuf, 100, TEXT("%ld"), position);
 
    if(cinfo && cinfo->buddy)
       SetWindowText(cinfo->buddy, tmpbuf);
@@ -7565,15 +8697,13 @@
 /* This function unchecks all radiobuttons on a box */
 BOOL CALLBACK _uncheck_radios(HWND handle, LPARAM lParam)
 {
-   char tmpbuf[100];
+   TCHAR tmpbuf[100] = {0};
 
    GetClassName(handle, tmpbuf, 99);
 
-   if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
-   {
-      BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-      if(bubble && !bubble->checkbox)
+   if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0)
+   {
+      if(!dw_window_get_data(handle, "_dw_checkbox"))
          SendMessage(handle, BM_SETCHECK, 0, 0);
    }
    return TRUE;
@@ -7586,9 +8716,7 @@
  */
 void API dw_checkbox_set(HWND handle, int value)
 {
-   BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-   if(bubble && !bubble->checkbox)
+   if(!dw_window_get_data(handle, "_dw_checkbox"))
    {
       HWND parent = GetParent(handle);
 
@@ -7619,9 +8747,9 @@
    ptrs[1] = itemdata;
 
    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
-   tvi.pszText = title;
+   tvi.pszText = UTF8toWide(title);
    tvi.lParam = (LONG)ptrs;
-   tvi.cchTextMax = strlen(title);
+   tvi.cchTextMax = (int)_tcslen(tvi.pszText);
    tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
 
    tvins.item = tvi;
@@ -7653,9 +8781,9 @@
    ptrs[1] = itemdata;
 
    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
-   tvi.pszText = title;
+   tvi.pszText = UTF8toWide(title);
    tvi.lParam = (LONG)ptrs;
-   tvi.cchTextMax = strlen(title);
+   tvi.cchTextMax = (int)_tcslen(tvi.pszText);
    tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
 
    tvins.item = tvi;
@@ -7690,8 +8818,8 @@
       ptrs[0] = title;
 
       tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
-      tvi.pszText = title;
-      tvi.cchTextMax = strlen(title);
+      tvi.pszText = UTF8toWide(title);
+      tvi.cchTextMax = (int)_tcslen(tvi.pszText);
       tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
       tvi.hItem = (HTREEITEM)item;
 
@@ -7757,7 +8885,7 @@
    tvi.hItem = item;
 
    if(TreeView_GetItem(handle, &tvi))
-      return tvi.pszText;
+      return _strdup(WideToUTF8(tvi.pszText));
     return NULL;
 }
 
@@ -7780,9 +8908,7 @@
  */
 void API dw_tree_item_select(HWND handle, HTREEITEM item)
 {
-   dw_window_set_data(handle, "_dw_select_item", (void *)1);
    TreeView_SelectItem(handle, item);
-   dw_window_set_data(handle, "_dw_select_item", (void *)0);
 }
 
 /* Delete all tree subitems */
@@ -7904,8 +9030,8 @@
       if(titles[z])
       {
          lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
-         lvc.pszText = titles[z];
-         lvc.cchTextMax = strlen(titles[z]);
+         lvc.pszText = UTF8toWide(titles[z]);
+         lvc.cchTextMax = (int)_tcslen(lvc.pszText);
          if(flags[z] & DW_CFA_RIGHT)
             lvc.fmt = LVCFMT_RIGHT;
          else if(flags[z] & DW_CFA_CENTER)
@@ -7922,6 +9048,19 @@
 }
 
 /*
+ * Configures the main filesystem column title for localization.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          title: The title to be displayed in the main column.
+ */
+void API dw_filesystem_set_column_title(HWND handle, char *title)
+{
+    char *newtitle = _strdup(title ? title : "");
+
+    dw_window_set_data(handle, "_dw_coltitle", newtitle);
+}
+
+/*
  * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
  * Parameters:
  *          handle: Handle to the container to be configured.
@@ -7931,10 +9070,11 @@
  */
 int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
 {
+   char *coltitle = (char *)dw_window_get_data(handle, "_dw_coltitle");
    LV_COLUMN lvc;
 
    lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
-   lvc.pszText = "Filename";
+   lvc.pszText = coltitle ? UTF8toWide(coltitle) : TEXT("Filename");
    lvc.cchTextMax = 8;
    lvc.fmt = 0;
    if(!count)
@@ -7944,6 +9084,11 @@
    lvc.iSubItem = count;
    SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)0, (LPARAM)&lvc);
    dw_container_setup(handle, flags, titles, count, -1);
+   if(coltitle)
+   {
+      dw_window_set_data(handle, "_dw_coltitle", NULL);
+      free(coltitle);
+   }
    return DW_ERROR_NONE;
 }
 
@@ -7991,7 +9136,7 @@
          return 0;
       }
    }
-   icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+   icon = LoadImage(NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
    free(file);
    return (HICN)icon;
 #endif
@@ -8023,16 +9168,16 @@
 #ifdef GDIPLUS
          icon = _dw_load_icon(file);
 #else
-         icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+         icon = LoadImage( NULL, UTF8toWide(file), IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
 #endif
       }
       else
       {
-         unlink( file );
+         _unlink( file );
          free( file );
          return 0;
       }
-      unlink( file );
+      _unlink( file );
       free( file );
    }
    return (HICN)icon;
@@ -8063,7 +9208,7 @@
    lvi.iSubItem = 0;
    /* Insert at the end */
    lvi.iItem = 1000000;
-   lvi.pszText = "";
+   lvi.pszText = TEXT("");
    lvi.cchTextMax = 1;
    lvi.iImage = -1;
 
@@ -8082,7 +9227,12 @@
 {
    int z;
    static HWND lasthwnd = NULL;
-
+   HIMAGELIST himl;
+
+   /* We can't add an invalid handle */
+   if(!hicon)
+      return -1;
+      
    if(!hSmall || !hLarge)
    {
       hSmall = ImageList_Create(16, 16, ILC_COLOR16 | ILC_MASK, ICON_INDEX_LIMIT, 0);
@@ -8097,12 +9247,12 @@
          ImageList_AddIcon(hLarge, hicon);
          if(type)
          {
-            TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+            himl = TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
          }
          else
          {
-            ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-            ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+            himl = ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+            himl = ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
          }
          lasthwnd = handle;
          return z;
@@ -8114,14 +9264,14 @@
          {
             if(type)
             {
-               TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+               himl = TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
             }
             else
             {
-               ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-               ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+               himl = ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+               himl = ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
             }
-                lasthwnd = handle;
+            lasthwnd = handle;
          }
          return z;
       }
@@ -8151,8 +9301,8 @@
    lvi.iItem = row + item;
    lvi.iSubItem = 0;
    lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE | LVIF_TEXT;
-   lvi.pszText = filename;
-   lvi.cchTextMax = strlen(filename);
+   lvi.pszText = UTF8toWide(filename);
+   lvi.cchTextMax = (int)_tcslen(lvi.pszText);
    lvi.iImage = _lookup_icon(handle, (HICON)icon, 0);
 
    ListView_SetItem(handle, &lvi);
@@ -8186,7 +9336,7 @@
    ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
    ULONG *flags;
    LV_ITEM lvi;
-   char textbuffer[101] = {0}, *destptr = textbuffer;
+   TCHAR textbuffer[101] = {0};
    int item = 0;
 
    if(pointer)
@@ -8194,7 +9344,7 @@
       item = (int)dw_window_get_data(handle, "_dw_insertitem");
    }
 
-   if(!cinfo || !cinfo->flags || !data)
+   if(!cinfo || !cinfo->flags)
       return;
 
    flags = cinfo->flags;
@@ -8202,38 +9352,42 @@
    lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT;
    lvi.iItem = row + item;
    lvi.iSubItem = column;
+   lvi.pszText = textbuffer;
+   lvi.cchTextMax = 0;
 
    if(flags[column] & DW_CFA_BITMAPORICON)
    {
-      HICON hicon = *((HICON *)data);
-
       lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE;
       lvi.pszText = NULL;
-      lvi.cchTextMax = 0;
-
-      lvi.iImage = _lookup_icon(handle, hicon, 0);
-   }
-   else if(flags[column] & DW_CFA_STRING)
+      
+      if(data)
+      {
+         HICON hicon = *((HICON *)data);
+
+         lvi.iImage = _lookup_icon(handle, hicon, 0);
+      }
+      else
+         lvi.iImage = -1;
+   }
+   else if(flags[column] & DW_CFA_STRING && data)
    {
       char *tmp = *((char **)data);
 
       if(!tmp)
          tmp = "";
 
-      lvi.pszText = tmp;
-      lvi.cchTextMax = strlen(tmp);
-      destptr = tmp;
-   }
-   else if(flags[column] & DW_CFA_ULONG)
+      lvi.pszText = UTF8toWide(tmp);
+      lvi.cchTextMax = (int)_tcslen(lvi.pszText);
+   }
+   else if(flags[column] & DW_CFA_ULONG && data)
    {
       ULONG tmp = *((ULONG *)data);
 
-      _snprintf(textbuffer, 100, "%lu", tmp);
-
-      lvi.pszText = textbuffer;
-      lvi.cchTextMax = strlen(textbuffer);
-   }
-   else if(flags[column] & DW_CFA_DATE)
+      _sntprintf(textbuffer, 100, TEXT("%lu"), tmp);
+
+      lvi.cchTextMax = (int)_tcslen(textbuffer);
+   }
+   else if(flags[column] & DW_CFA_DATE && data)
    {
       struct tm curtm;
       CDATE cdate = *((CDATE *)data);
@@ -8248,17 +9402,12 @@
           curtm.tm_mday = (cdate.day >= 0 && cdate.day < 32) ? cdate.day : 1;
           curtm.tm_mon = (cdate.month > 0 && cdate.month < 13) ? cdate.month - 1 : 0;
           curtm.tm_year = cdate.year - 1900;
-          strftime(textbuffer, 100, "%x", &curtm);
-      }
-      else
-      {
-          textbuffer[0] = 0;
-      }
-
-      lvi.pszText = textbuffer;
-      lvi.cchTextMax = strlen(textbuffer);
-   }
-   else if(flags[column] & DW_CFA_TIME)
+          _tcsftime(textbuffer, 100, TEXT("%x"), &curtm);
+      }
+
+      lvi.cchTextMax = (int)_tcslen(textbuffer);
+   }
+   else if(flags[column] & DW_CFA_TIME && data)
    {
       struct tm curtm;
       CTIME ctime = *((CTIME *)data);
@@ -8267,10 +9416,9 @@
       curtm.tm_min = (ctime.minutes >= 0 && ctime.minutes < 60) ? ctime.minutes : 0;
       curtm.tm_sec = (ctime.seconds >= 0 && ctime.seconds < 60) ? ctime.seconds : 0;
 
-      strftime(textbuffer, 100, "%X", &curtm);
-
-      lvi.pszText = textbuffer;
-      lvi.cchTextMax = strlen(textbuffer);
+      _tcsftime(textbuffer, 100, TEXT("%X"), &curtm);
+
+      lvi.cchTextMax = (int)_tcslen(textbuffer);
    }
 
    ListView_SetItem(handle, &lvi);
@@ -8658,9 +9806,10 @@
    }
    else if(cinfo && cinfo->columns > 1)
    {
-      int z, index;
       ULONG *flags = cinfo->flags, *columns = calloc(sizeof(ULONG), cinfo->columns);
-      char *text = malloc(1024);
+      TCHAR *text = calloc(sizeof(TCHAR), 1024);
+      unsigned int z;
+      int index;
 
       /* Initialize with sizes of column labels */
       for(z=0;z<cinfo->columns;z++)
@@ -8690,33 +9839,26 @@
       {
          for(z=0;z<cinfo->columns;z++)
          {
-            LV_ITEM lvi;
-
-            memset(&lvi, 0, sizeof(LV_ITEM));
-
-            lvi.iItem = index;
-            lvi.iSubItem = z;
-            lvi.mask = LVIF_TEXT;
-            lvi.cchTextMax = 1023;
-            lvi.pszText = text;
-
-            if(ListView_GetItem(handle, &lvi))
-            {
-               int width = ListView_GetStringWidth(handle, lvi.pszText);
-               if(width > columns[z])
-               {
-                  if(z == 0)
-                     columns[z] = width + 20;
-                  else
-                     columns[z] = width;
-               }
-            }
+            unsigned int width;
+            
+            ListView_GetItemText(handle, index, z, text, 1023);
+            width = ListView_GetStringWidth(handle, text);
+
+            /* Figure extra space for the icon for the first column */
+            if(z == 0)
+               width += 20;
+
+            if(width > columns[z])
+               columns[z] = width;
          }
 
          index = ListView_GetNextItem(handle, index, LVNI_ALL);
       }
 
-      /* Set the new sizes */
+      /* Set the new sizes... Microsoft says we need to add
+       * padding to the calculated sized but does not give 
+       * a value.  Trial and error shows that 16 works for us.
+       */
       for(z=0;z<cinfo->columns;z++)
          ListView_SetColumnWidth(handle, z, columns[z] + 16);
 
@@ -8743,7 +9885,7 @@
    tnid.uCallbackMessage = WM_USER+2;
    tnid.hIcon = (HICON)icon;
    if(bubbletext)
-      strncpy(tnid.szTip, bubbletext, sizeof(tnid.szTip));
+      _tcsncpy(tnid.szTip, UTF8toWide(bubbletext), sizeof(tnid.szTip));
    else
       tnid.szTip[0] = 0;
 
@@ -8778,9 +9920,9 @@
 {
    Box *newbox = calloc(sizeof(Box), 1);
    HWND tmp = CreateWindow(ObjectClassName,
-                     "",
+                     NULL,
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-                     0,0,screenx,screeny,
+                     0,0,0,0,
                      DW_HWND_OBJECT,
                      (HMENU)id,
                      DWInstance,
@@ -8806,9 +9948,22 @@
    HPEN hPen = TlsGetValue(_hPen);
    HBRUSH hBrush = TlsGetValue(_hBrush);
    COLORREF foreground;
+#ifdef GDIPLUS
+   GpBrush *brush = TlsGetValue(_gpBrush);
+   GpPen *pen = TlsGetValue(_gpPen);
+   ARGB gpfore;
+#endif
 
    value = _internal_color(value);
    foreground = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
+#ifdef GDIPLUS
+   gpfore = MAKEARGB(255, DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
+   
+   GdipDeletePen(pen);
+   GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen);
+   TlsSetValue(_gpPen, (LPVOID)pen);
+   GdipSetSolidFillColor(brush, gpfore);
+#endif    
 
    DeleteObject(hPen);
    DeleteObject(hBrush);
@@ -8873,6 +10028,12 @@
  */
 void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
 {
+#ifdef GDIPLUS
+   /* There doesn't seem to be an equivalent to SetPixel in GDI+ ... 
+    * so instead we call dw_draw_rect() with 1 for width and height.
+    */
+   dw_draw_rect(handle, pixmap, DW_DRAW_FILL | DW_DRAW_NOAA, x, y, 1, 1);
+#else   
    HDC hdcPaint;
 
    if(handle)
@@ -8885,6 +10046,7 @@
    SetPixel(hdcPaint, x, y, (COLORREF)TlsGetValue(_foreground));
    if(!pixmap)
       ReleaseDC(handle, hdcPaint);
+#endif      
 }
 
 /* Draw a line on a window (preferably a render window).
@@ -8898,6 +10060,21 @@
  */
 void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
 {
+#ifdef GDIPLUS
+   GpGraphics *graphics = NULL;
+   GpPen *pen = TlsGetValue(_gpPen);
+   
+   if(handle)
+      GdipCreateFromHWND(handle, &graphics);
+   else if(pixmap)
+      GdipCreateFromHDC(pixmap->hdc, &graphics);
+   else
+      return;
+   
+   GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
+   GdipDrawLineI(graphics, pen, x1, y1, x2, y2);
+   GdipDeleteGraphics(graphics);
+#else
    HDC hdcPaint;
    HPEN oldPen;
 
@@ -8918,6 +10095,40 @@
    SetPixel(hdcPaint, x2, y2, (COLORREF)TlsGetValue(_foreground));
    if(!pixmap)
       ReleaseDC(handle, hdcPaint);
+#endif
+}
+
+/* Internal function to generate POINT arrays used by Windows APIs */
+POINT *_makePoints(int *npoints, int *x, int *y)
+{
+   POINT *points;
+   int i;
+   
+   /*
+    * Allocate enough space for the number of points supplied plus 1.
+    * Under windows, unless the first and last points are the same
+    * the polygon won't be closed
+    */
+   points = (POINT *)malloc( ((*npoints)+1) * sizeof(POINT) );
+   
+   if(points)
+   {
+      for ( i = 0 ; i < *npoints ; i++ )
+      {
+         points[i].x = x[i];
+         points[i].y = y[i];
+      }
+      if ( !( points[0].x == points[(*npoints)-1].x
+      &&   points[0].y == points[(*npoints)-1].y ) )
+      {
+         /* set the last point to be the same as the first point... */
+         points[*npoints].x = points[0].x;
+         points[*npoints].y = points[0].y;
+         /* ... and increment the number of points */
+         (*npoints)++;
+      }
+   }
+   return points;
 }
 
 /* Draw a closed polygon on a window (preferably a render window).
@@ -8931,58 +10142,75 @@
  */
 void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y)
 {
-   HDC hdcPaint;
-   HBRUSH oldBrush;
-   HPEN oldPen;
    POINT *points = NULL;
-   int i;
-
-   if ( handle )
-      hdcPaint = GetDC( handle );
-   else if ( pixmap )
-      hdcPaint = pixmap->hdc;
-   else
+   
+   /* Sanity check */
+   if(npoints < 1)
       return;
-   if ( npoints )
-   {
-      /*
-       * Allocate enough space for the number of points supplied plus 1.
-       * Under windows, unless the first and last points are the same
-       * the polygon won't be closed
-       */
-      points = (POINT *)malloc( (npoints+1) * sizeof(POINT) );
-      /*
-       * should check for NULL pointer return!
-       */
-      for ( i = 0 ; i < npoints ; i++ )
-      {
-         points[i].x = x[i];
-         points[i].y = y[i];
-      }
-      if ( !( points[0].x == points[npoints-1].x
-      &&   points[0].y == points[npoints-1].y ) )
-      {
-         /* set the last point to be the same as the first point... */
-         points[npoints].x = points[0].x;
-         points[npoints].y = points[0].y;
-         /* ... and increment the number of points */
-         npoints++;
-      }
-   }
-   else
-      return;
-
-   oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) );
-   oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) );
-   if ( flags & DW_DRAW_FILL )
-      Polygon( hdcPaint, points, npoints );
-   else
-      Polyline( hdcPaint, points, npoints );
-   SelectObject( hdcPaint, oldBrush );
-   SelectObject( hdcPaint, oldPen );
-   if ( !pixmap )
-      ReleaseDC( handle, hdcPaint );
-   free(points);
+
+#ifdef GDIPLUS
+   {
+      GpGraphics *graphics = NULL;
+      
+      if(handle)
+         GdipCreateFromHWND(handle, &graphics);
+      else if(pixmap)
+         GdipCreateFromHDC(pixmap->hdc, &graphics);
+      else
+         return;
+      
+      /* Enable antialiasing if the DW_DRAW_NOAA flag isn't set */
+      if(!(flags & DW_DRAW_NOAA))
+        GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
+  
+      if((points = _makePoints(&npoints, x, y)))
+      {
+         if(flags & DW_DRAW_FILL)
+         {
+            GpBrush *brush = TlsGetValue(_gpBrush);
+            
+            GdipFillPolygon2I(graphics, brush, points, npoints);
+         }
+         else
+         {
+            GpPen *pen = TlsGetValue(_gpPen);
+            
+            GdipDrawPolygonI(graphics, pen, points, npoints);
+         }
+      }
+      GdipDeleteGraphics(graphics);
+   }
+#else
+   {
+      HDC hdcPaint;
+      
+      if ( handle )
+         hdcPaint = GetDC( handle );
+      else if ( pixmap )
+         hdcPaint = pixmap->hdc;
+      else 
+         return;
+
+      if((points = _makePoints(&npoints, x, y)))
+      {
+         HBRUSH oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) );
+         HPEN oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) );
+      
+         if ( flags & DW_DRAW_FILL )
+            Polygon( hdcPaint, points, npoints );
+         else
+            Polyline( hdcPaint, points, npoints );
+            
+         SelectObject( hdcPaint, oldBrush );
+         SelectObject( hdcPaint, oldPen );
+      }
+      
+      if ( !pixmap )
+         ReleaseDC( handle, hdcPaint );
+   }
+#endif   
+   if(points)
+      free(points);
 }
 
 /* Draw a rectangle on a window (preferably a render window).
@@ -8997,6 +10225,34 @@
  */
 void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
 {
+#ifdef GDIPLUS
+   GpGraphics *graphics = NULL;
+   
+   if(handle)
+      GdipCreateFromHWND(handle, &graphics);
+   else if(pixmap)
+      GdipCreateFromHDC(pixmap->hdc, &graphics);
+   else
+      return;
+   
+   /* Enable antialiasing if the DW_DRAW_NOAA flag isn't set */
+   if(!(flags & DW_DRAW_NOAA))
+     GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
+     
+   if(flags & DW_DRAW_FILL)
+   {
+      GpBrush *brush = TlsGetValue(_gpBrush);
+   
+      GdipFillRectangleI(graphics, brush, x, y, width, height);
+   }
+   else
+   {
+      GpPen *pen = TlsGetValue(_gpPen);
+      
+      GdipDrawRectangleI(graphics, pen, x, y, width, height);
+   }
+   GdipDeleteGraphics(graphics);
+#else
    HDC hdcPaint;
    RECT Rect;
 
@@ -9014,6 +10270,7 @@
       FrameRect(hdcPaint, &Rect, TlsGetValue(_hBrush));
    if(!pixmap)
       ReleaseDC(handle, hdcPaint);
+#endif   
 }
 
 /* Draw an arc on a window (preferably a render window).
@@ -9031,12 +10288,58 @@
  */
 void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
 {
+#ifdef GDIPLUS
+   GpGraphics *graphics = NULL;
+   GpPen *pen = TlsGetValue(_gpPen);
+   
+   if(handle)
+      GdipCreateFromHWND(handle, &graphics);
+   else if(pixmap)
+      GdipCreateFromHDC(pixmap->hdc, &graphics);
+   else
+      return;
+   
+   /* Enable antialiasing if the DW_DRAW_NOAA flag isn't set */
+   if(!(flags & DW_DRAW_NOAA))
+     GdipSetSmoothingMode(graphics, SmoothingModeAntiAlias);
+  
+   if(flags & DW_DRAW_FULL)
+   {
+      if(flags & DW_DRAW_FILL)
+      {
+         GpBrush *brush = TlsGetValue(_gpBrush);
+      
+         GdipFillEllipseI(graphics, brush, x1 < x2 ? x1 : x2, y1 < y2 ? y1 : y2, abs(x1-x2), abs(y1-y2));
+      }
+      else
+         GdipDrawEllipseI(graphics, pen, x1 < x2 ? x1 : x2, y1 < y2 ? y1 : y2, abs(x1-x2), abs(y1-y2));
+   }
+   else
+   {
+      double a1 = atan2((y1-yorigin), (x1-xorigin));
+      double a2 = atan2((y2-yorigin), (x2-xorigin));
+      double dx = xorigin - x1;
+      double dy = yorigin - y1;
+      double r = sqrt(dx*dx + dy*dy);
+      double sweep;
+      int ri = (int)r;
+      
+      /* Convert to degrees */
+      a1 *= (180.0 / M_PI);
+      a2 *= (180.0 / M_PI);
+      sweep = fabs(a1 - a2);
+      
+      GdipDrawArcI(graphics, pen, xorigin-ri, yorigin-ri, ri*2, ri*2, (REAL)a1, (REAL)sweep);
+   }
+   GdipDeleteGraphics(graphics);
+#else  
    HDC hdcPaint;
    HBRUSH oldBrush;
    HPEN oldPen;
    double dx = xorigin - x1;
    double dy = yorigin - y1;
    double r = sqrt(dx*dx + dy*dy);
+   int ri = (int)r;
 
    if(handle)
       hdcPaint = GetDC(handle);
@@ -9053,13 +10356,42 @@
    if(flags & DW_DRAW_FULL)
       Ellipse(hdcPaint, x1, y1, x2, y2);
    else
-      Arc(hdcPaint, xorigin-r, yorigin-r, xorigin+r, yorigin+r, x2, y2, x1, y1);
+      Arc(hdcPaint, xorigin-ri, yorigin-ri, xorigin+ri, yorigin+ri, x2, y2, x1, y1);
    SelectObject( hdcPaint, oldBrush );
    SelectObject( hdcPaint, oldPen );
 
    if(!pixmap)
       ReleaseDC(handle, hdcPaint);
-}
+#endif   
+}
+
+#ifdef GDIPLUS
+/* Internal function to increase or decrease coordinates/sizes
+ * by the difference of the screen DPI (96) and the context DPI.
+ */
+void _convert_dpi(HDC hdc, int *x, int *y, int mult)
+{
+   int ratiox = (int)GetDeviceCaps(hdc, LOGPIXELSX)/96;
+   int ratioy = (int)GetDeviceCaps(hdc, LOGPIXELSY)/96;
+   if(ratiox > 1 && ratioy > 1)
+   {
+      if(mult)
+      {
+         if(x)
+            *x *= ratiox;
+         if(y)
+            *y *= ratioy;
+      }
+      else
+      {
+         if(x)
+            *x /= ratiox;
+         if(y)
+            *y /= ratioy;
+      }
+   }
+}
+#endif
 
 /* Draw text on a window (preferably a render window).
  * Parameters:
@@ -9076,6 +10408,7 @@
    HFONT hFont = 0, oldFont = 0;
    ColorInfo *cinfo = NULL;
    COLORREF background;
+   TCHAR *wtext = UTF8toWide(text);
 
    if(handle)
       hdc = GetDC(handle);
@@ -9108,7 +10441,10 @@
       SetBkMode(hdc, OPAQUE);
       SetBkColor(hdc, background);
    }
-   TextOut(hdc, x, y, text, strlen(text));
+#ifdef GDIPLUS
+   _convert_dpi(hdc, &x, &y, TRUE);
+#endif
+   TextOut(hdc, x, y, wtext, (int)_tcslen(wtext));
    if(oldFont)
       SelectObject(hdc, oldFont);
    if(mustdelete)
@@ -9131,6 +10467,7 @@
    int mustdelete = 0;
    HFONT hFont = NULL, oldFont;
    SIZE sz;
+   TCHAR *wtext = UTF8toWide(text);
 
    if(handle)
       hdc = GetDC(handle);
@@ -9160,7 +10497,7 @@
    }
    oldFont = SelectObject(hdc, hFont);
 
-   GetTextExtentPoint32(hdc, text, strlen(text), &sz);
+   GetTextExtentPoint32(hdc, wtext, (int)_tcslen(wtext), &sz);
 
    if(width)
       *width = sz.cx;
@@ -9168,6 +10505,10 @@
    if(height)
       *height = sz.cy;
 
+#ifdef GDIPLUS
+   _convert_dpi(hdc, width, height, FALSE);
+#endif
+
    SelectObject(hdc, oldFont);
    if(mustdelete)
       DeleteObject(hFont);
@@ -9308,7 +10649,7 @@
       }
    }
 
-   pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+   pixmap->hbm = (HBITMAP)LoadImage(NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    pixmap->depth = _read_bitmap_header(file);
 #endif
 
@@ -9370,18 +10711,18 @@
 #ifdef GDIPLUS
          pixmap->hbm = _dw_load_bitmap(file, NULL);
 #else
-         pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+         pixmap->hbm = (HBITMAP)LoadImage( NULL, UTF8toWide(file), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
          pixmap->depth = _read_bitmap_header(file);
 #endif
       }
       else
       {
-         unlink( file );
+         _unlink( file );
          free( file );
          free( pixmap );
          return NULL;
       }
-      unlink( file );
+      _unlink( file );
       free( file );
    }
 
@@ -9567,6 +10908,14 @@
        sheight = height;
    }
 
+#ifdef GDIPLUS
+   /* Do conversion on all the coordinates */
+   _convert_dpi(hdcdest, &xdest, &ydest, TRUE);
+   _convert_dpi(hdcdest, &width, &height, TRUE);
+   _convert_dpi(hdcsrc, &xsrc, &ysrc, TRUE);
+   _convert_dpi(hdcsrc, &swidth, &sheight, TRUE);
+#endif
+   
    /* If it is a 32bpp bitmap (with alpha) use AlphaBlend unless it fails */
    if ( srcp && srcp->depth == 32 && AlphaBlend( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, bf ) )
    {
@@ -9635,7 +10984,7 @@
    if(!handle)
       return DW_ERROR_UNKNOWN;
 
-   *handle = LoadLibrary(name);
+   *handle = LoadLibrary(UTF8toWide(name));
    return (NULL == *handle);
 }
 
@@ -9810,7 +11159,7 @@
    sa.lpSecurityDescriptor = &_dwsd;
    sa.bInheritHandle = FALSE;
 
-   return CreateEvent(&sa, TRUE, FALSE, name);
+   return CreateEvent(&sa, TRUE, FALSE, UTF8toWide(name));
 }
 
 /* Destroy this semaphore.
@@ -9820,7 +11169,7 @@
  */
 HEV API dw_named_event_get(char *name)
 {
-   return OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
+   return OpenEvent(EVENT_ALL_ACCESS, FALSE, UTF8toWide(name));
 }
 
 /* Resets the event semaphore so threads who call wait
@@ -9901,7 +11250,7 @@
    sa.lpSecurityDescriptor = &_dwsd;
    sa.bInheritHandle = FALSE;
 
-   handle = CreateFileMapping((HANDLE)0xFFFFFFFF, &sa, PAGE_READWRITE, 0, size, name);
+   handle = CreateFileMapping((HANDLE)0xFFFFFFFF, &sa, PAGE_READWRITE, 0, size, UTF8toWide(name));
 
    if(!handle)
       return 0;
@@ -9926,7 +11275,7 @@
  */
 HSHM API dw_named_memory_get(void **dest, int size, char *name)
 {
-   HSHM handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
+   HSHM handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, UTF8toWide(name));
 
    if(!handle)
       return 0;
@@ -9964,6 +11313,10 @@
    void **tmp = (void **)data;
    HPEN hPen;
    HBRUSH hBrush;
+#ifdef GDIPLUS
+   GpBrush *brush;
+   GpPen *pen;
+#endif       
 
    _init_thread();
 
@@ -9975,6 +11328,12 @@
        DeleteObject(hPen);
    if((hBrush = TlsGetValue(_hBrush)))
        DeleteObject(hBrush);
+#ifdef GDIPLUS
+   if((brush = TlsGetValue(_gpBrush)))
+      GdipDeleteBrush(brush);
+   if((pen = TlsGetValue(_gpPen)))
+      GdipDeletePen(pen);
+#endif       
 }
 
 /*
@@ -10028,6 +11387,12 @@
 void API dw_exit(int exitcode)
 {
    OleUninitialize();
+#ifdef AEROGLASS
+   /* Free any in use libraries */
+   FreeLibrary(hdwm);
+#endif   
+   FreeLibrary(huxtheme);
+   DestroyWindow(hwndTooltip);
    exit(exitcode);
 }
 
@@ -10043,7 +11408,7 @@
 HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
 {
    HWND tmp = CreateWindow(SplitbarClassName,
-                     "",
+                     NULL,
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
@@ -10087,7 +11452,8 @@
 
    dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
 
-   _handle_splitbar_resize(handle, percent, type, width, height);
+   if(width > 0 && height > 0)
+      _handle_splitbar_resize(handle, percent, type, width, height);
 }
 
 /*
@@ -10120,7 +11486,7 @@
    MONTHDAYSTATE mds[3];
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
                            MONTHCAL_CLASS,
-                           "",
+                           NULL,
                            WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | MCS_DAYSTATE,
                            0,0,0,0,
                            DW_HWND_OBJECT,
@@ -10232,20 +11598,26 @@
 char * API dw_clipboard_get_text(void)
 {
    HANDLE handle;
-   char *tmp, *ret = NULL;
+   char *ret = NULL;
+   TCHAR *tmp;
+#ifdef UNICODE
+   int type = CF_UNICODETEXT;
+#else   
+   int type = CF_TEXT;
+#endif
 
    if ( !OpenClipboard( NULL ) )
       return ret;
 
-   if ( ( handle = GetClipboardData( CF_TEXT) ) == NULL )
+   if ( ( handle = GetClipboardData(type) ) == NULL )
    {
       CloseClipboard();
       return ret;
    }
 
-   if ( (tmp = GlobalLock(handle)) && strlen(tmp) )
-   {
-        ret = strdup(tmp);
+   if ( (tmp = GlobalLock(handle)) && _tcslen(tmp) )
+   {
+        ret = _strdup(WideToUTF8(tmp));
         GlobalUnlock(handle);
    }
    CloseClipboard();
@@ -10261,6 +11633,20 @@
 {
    HGLOBAL ptr1;
    LPTSTR ptr2;
+   TCHAR *buf;
+#ifdef UNICODE
+   int type = CF_UNICODETEXT;
+   char *src = calloc(len + 1, 1);
+
+   memcpy(src, str, len);
+   buf = UTF8toWide(src);
+   free(src);
+   len = (int)_tcslen(buf);
+#else   
+   int type = CF_TEXT;
+   
+   buf = str;
+#endif
 
    if ( !OpenClipboard( NULL ) )
       return;
@@ -10272,16 +11658,14 @@
 
    ptr2 = GlobalLock( ptr1 );
 
-   memcpy( (char *)ptr2, str, len + 1);
+   memcpy(ptr2, buf, (len + 1) * sizeof(TCHAR));
    GlobalUnlock( ptr1 );
    EmptyClipboard();
 
-   SetClipboardData( CF_TEXT, ptr1 );
+   SetClipboardData( type, ptr1 );
 
    CloseClipboard();
    GlobalFree( ptr1 );
-
-   return;
 }
 
 /*
@@ -10311,8 +11695,10 @@
          strcpy(env->osName, "Windows XP");
       else if(env->MajorVersion == 6 && env->MinorVersion == 0)
          strcpy(env->osName, "Windows Vista");
-      else if(env->MajorVersion == 6 && env->MinorVersion > 0)
+      else if(env->MajorVersion == 6 && env->MinorVersion == 1)
          strcpy(env->osName, "Windows 7");
+      else if(env->MajorVersion == 6 && env->MinorVersion > 1)
+         strcpy(env->osName, "Windows 8");
       else
          strcpy(env->osName, "Windows NT");
 
@@ -10336,14 +11722,14 @@
 }
 
 /* Helper to make sure all /s are \s */
-void _to_dos(char *dst, char *src)
+void _to_dos(TCHAR *dst, TCHAR *src)
 {
    int x = 0;
    
    while(src[x])
    {
-      if(src[x] == '/')
-         dst[x] = '\\';
+      if(src[x] == TEXT('/'))
+         dst[x] = TEXT('\\');
       else
          dst[x] = src[x];
       x++;
@@ -10351,6 +11737,8 @@
    dst[x] = 0;
 }
 
+#define BROWSEBUFSIZE 1000
+
 /*
  * Opens a file dialog and queries user selection.
  * Parameters:
@@ -10365,27 +11753,28 @@
  */
 char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
 {
-   OPENFILENAME of;
-   char filenamebuf[1001] = {0};
-   char filterbuf[1001] = {0};
+   OPENFILENAME of = {0};
+   TCHAR filenamebuf[BROWSEBUFSIZE+1] = {0}, *fbuf = filenamebuf;
+   TCHAR filterbuf[BROWSEBUFSIZE+1] = {0};
+   TCHAR *exten = UTF8toWide(ext);
+   TCHAR *dpath = UTF8toWide(defpath);
    int rc;
 
    if ( flags == DW_DIRECTORY_OPEN )
    {
    /* If we aren't building a DLL, use the more simple browser */
 #ifndef BUILD_DLL
-      BROWSEINFO bi;
+      BROWSEINFO bi = {0};
       TCHAR szDir[MAX_PATH];
       LPITEMIDLIST pidl;
       LPMALLOC pMalloc;
 
       if (SUCCEEDED(SHGetMalloc(&pMalloc)))
       {
-         ZeroMemory(&bi,sizeof(bi));
          bi.hwndOwner = NULL;
          bi.pszDisplayName = 0;
          bi.pidlRoot = 0;
-         bi.lpszTitle = title;
+         bi.lpszTitle = UTF8toWide(title);
          bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
          bi.lpfn = NULL; /*BrowseCallbackProc*/
 
@@ -10394,31 +11783,31 @@
          {
             if (SHGetPathFromIDList(pidl,szDir))
             {
-               strncpy(filenamebuf,szDir,1000);
+               _tcsncpy(filenamebuf,szDir,BROWSEBUFSIZE);
             }
 
-            // In C++: pMalloc->Free(pidl); pMalloc->Release();
+            /* In C++: pMalloc->Free(pidl); pMalloc->Release(); */
             pMalloc->lpVtbl->Free(pMalloc,pidl);
             pMalloc->lpVtbl->Release(pMalloc);
-            return strdup(filenamebuf);
+            return _strdup(WideToUTF8(filenamebuf));
          }
       }
 #else
      if ( XBrowseForFolder( NULL,
-                            (LPCTSTR)defpath,
+                            (LPCTSTR)dpath,
                             -1,
-                            (LPCTSTR)title,
+                            (LPCTSTR)UTF8toWide(title),
                             (LPTSTR)filenamebuf,
-                            1000,
+                            BROWSEBUFSIZE,
                             FALSE ) )
      {
-        return strdup( filenamebuf );
+        return _strdup( WideToUTF8(fbuf) );
      }
 #endif
    }
    else
    {
-      DWORD att = defpath ? GetFileAttributes(defpath) : INVALID_FILE_ATTRIBUTES;
+      DWORD att = defpath ? GetFileAttributes(UTF8toWide(defpath)) : INVALID_FILE_ATTRIBUTES;
       
       if (ext)
       {
@@ -10427,15 +11816,16 @@
           * and format of filter is eg: "c files (*.c)\0*.c\0All Files\0*.*\0\0"
           */
          int len;
-         char *ptr = filterbuf;
-         memset( filterbuf, 0, sizeof(filterbuf) );
-         len = sprintf( ptr, "%s Files (*.%s)", ext, ext );
-         ptr = ptr + len + 1; // past first \0
-         len = sprintf( ptr, "*.%s", ext );
-         ptr = ptr + len + 1; // past next \0
-         len = sprintf( ptr, "All Files" );
-         ptr = ptr + len + 1; // past next \0
-         len = sprintf( ptr, "*.*" );
+         TCHAR *ptr = filterbuf;
+         TCHAR *start = filterbuf;
+
+         len = _sntprintf( ptr, BROWSEBUFSIZE - (ptr - start), TEXT("%s Files (*.%s)"), exten, exten );
+         ptr = ptr + len + 1; /* past first \0 */
+         len = _sntprintf( ptr, BROWSEBUFSIZE - (ptr - start), TEXT("*.%s"), exten );
+         ptr = ptr + len + 1; /* past next \0 */
+         len = _sntprintf( ptr, BROWSEBUFSIZE - (ptr - start), TEXT("All Files") );
+         ptr = ptr + len + 1; /* past next \0 */
+         len = _sntprintf( ptr, BROWSEBUFSIZE - (ptr - start), TEXT("*.*") );
       }
 
       memset( &of, 0, sizeof(OPENFILENAME) );
@@ -10443,16 +11833,16 @@
       of.lStructSize = sizeof(OPENFILENAME);
       of.hwndOwner = HWND_DESKTOP;
       of.hInstance = DWInstance;
-      of.lpstrTitle = title;
-      of.lpstrInitialDir = ".";
+      of.lpstrTitle = UTF8toWide(title);
+      of.lpstrInitialDir = TEXT(".");
       if(att != INVALID_FILE_ATTRIBUTES && (att & FILE_ATTRIBUTE_DIRECTORY))
-        of.lpstrInitialDir = defpath;
+        of.lpstrInitialDir = dpath;
       else if(defpath)
-        _to_dos(filenamebuf, defpath);
+        _to_dos(filenamebuf, dpath);
       of.lpstrFile = filenamebuf;
       of.lpstrFilter = filterbuf;
       of.nFilterIndex = 1;
-      of.nMaxFile = 1000;
+      of.nMaxFile = BROWSEBUFSIZE;
       /*of.lpstrDefExt = ext;*/
       of.Flags = OFN_NOCHANGEDIR;
 
@@ -10468,7 +11858,7 @@
       }
 
       if (rc)
-         return strdup(of.lpstrFile);
+         return _strdup(WideToUTF8(of.lpstrFile));
    }
    return NULL;
 }
@@ -10503,7 +11893,8 @@
    }
    newparams[count] = NULL;
 
-   retcode = _spawnvp(P_NOWAIT, program, (const char * const *)newparams);
+   /* Why does this return intptr_t ... can the PID exceed an integer value? */
+   retcode = (int)_spawnvp(P_NOWAIT, program, (const char * const *)newparams);
 
    for(z=0;z<count;z++)
    {
@@ -10529,7 +11920,7 @@
       int len, z;
 
       browseurl = &url[7];
-      len = strlen(browseurl);
+      len = (int)strlen(browseurl);
 
       for(z=0;z<len;z++)
       {
@@ -10540,7 +11931,7 @@
       }
    }
 
-   retcode = (int)ShellExecute(NULL, "open", browseurl, NULL, NULL, SW_SHOWNORMAL);
+   retcode = (int)ShellExecute(NULL, TEXT("open"), UTF8toWide(browseurl), NULL, NULL, SW_SHOWNORMAL);
    if(retcode<33 && retcode != 2)
       return DW_ERROR_UNKNOWN;
    return DW_ERROR_NONE;
@@ -10591,7 +11982,7 @@
     }
 
     print->di.cbSize = sizeof(DOCINFO);
-    print->di.lpszDocName = jobname ? jobname : "Dynamic Windows Print Job";
+    print->di.lpszDocName = jobname ? UTF8toWide(jobname) : TEXT("Dynamic Windows Print Job");
     return print;
 }
 
@@ -10607,7 +11998,7 @@
 {
     DWPrint *p = print;
     HPIXMAP pixmap;
-    int x, result = DW_ERROR_UNKNOWN;
+    int x, width, height, result = DW_ERROR_UNKNOWN;
     
     if(!p)
         return result;
@@ -10615,13 +12006,21 @@
     if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
         return result;
 
-    pixmap->width = GetDeviceCaps(p->pd.hDC, HORZRES); 
-    pixmap->height = GetDeviceCaps(p->pd.hDC, VERTRES);
-
-    pixmap->hbm = CreateCompatibleBitmap(p->pd.hDC, pixmap->width, pixmap->height);
+    width = GetDeviceCaps(p->pd.hDC, HORZRES); 
+    height = GetDeviceCaps(p->pd.hDC, VERTRES);
+
+    pixmap->hbm = CreateCompatibleBitmap(p->pd.hDC, width, height);
     pixmap->hdc = p->pd.hDC;
     pixmap->transcolor = DW_RGB_TRANSPARENT;
 
+#ifdef GDIPLUS
+   /* Convert the size based on the DPI */
+   _convert_dpi(pixmap->hdc, &width, &height, FALSE);
+#endif
+
+    pixmap->width = width;
+    pixmap->height = height;
+
     SelectObject(pixmap->hdc, pixmap->hbm);
 
     /* Start the job */
@@ -10667,7 +12066,7 @@
  */
 char * API dw_user_dir(void)
 {
-    static char _user_dir[1024] = "";
+    static char _user_dir[1024] = {0};
 
     if(!_user_dir[0])
     {
@@ -10677,9 +12076,11 @@
         if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
         {
             DWORD BufSize = 1024;
-
-            GetUserProfileDirectory(hToken, _user_dir, &BufSize);
+            TCHAR TmpBuf[1024], *Buf = TmpBuf;
+
+            GetUserProfileDirectory(hToken, Buf, &BufSize);
             CloseHandle(hToken);
+            strncpy(_user_dir, WideToUTF8(Buf), 1023);
         }
         /* If it fails set it to the root directory */
         if(!_user_dir[0])
@@ -10691,6 +12092,15 @@
 }
 
 /*
+ * Returns a pointer to a static buffer which containes the
+ * private application data directory. 
+ */
+char * API dw_app_dir(void)
+{
+    return _dw_exec_dir;
+}
+
+/*
  * Call a function from the window (widget)'s context.
  * Parameters:
  *       handle: Window handle of the widget.
@@ -10712,7 +12122,7 @@
 
    while(tmp)
    {
-      if(stricmp(tmp->varname, varname) == 0)
+      if(_stricmp(tmp->varname, varname) == 0)
          return tmp;
       tmp = tmp->next;
    }
@@ -10733,7 +12143,7 @@
       new = malloc(sizeof(UserData));
       if(new)
       {
-         new->varname = strdup(varname);
+         new->varname = _strdup(varname);
          new->data = data;
 
          new->next = NULL;
@@ -10763,7 +12173,7 @@
 
    while(tmp)
    {
-      if(all || stricmp(tmp->varname, varname) == 0)
+      if(all || _stricmp(tmp->varname, varname) == 0)
       {
          if(!prev)
          {
@@ -10862,7 +12272,10 @@
 {
    if(sigfunc)
    {
-      int timerid = SetTimer(NULL, 0, interval, _TimerProc);
+      /* Warning: This seems to return UINT_PTR on some systems...
+       * which may exceed the storage of int that our API uses.
+       */
+      int timerid = (int)SetTimer(NULL, 0, interval, _TimerProc);
 
       if(timerid)
       {
@@ -10927,7 +12340,7 @@
 
    if (window && signame && sigfunc)
    {
-      if (stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
+      if (_stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
          window = _normalize_handle(window);
 
       if ((message = _findsigmessage(signame)) != 0)
@@ -11061,3 +12474,38 @@
       }
    }
 }
+
+/*
+ * Converts a UTF-8 encoded string into a wide string.
+ * Parameters:
+ *       utf8string: UTF-8 encoded source string.
+ * Returns:
+ *       Wide string that needs to be freed with dw_free()
+ *       or NULL on failure.
+ */
+wchar_t * API dw_utf8_to_wchar(char *utf8string)
+{
+ #ifdef UNICODE
+    return _myUTF8toWide(utf8string, malloc(MultiByteToWideChar(CP_UTF8, 0, utf8string, -1, NULL, 0) * sizeof(WCHAR)));
+#else
+    return NULL;
+#endif    
+}
+
+/*
+ * Converts a wide string into a UTF-8 encoded string.
+ * Parameters:
+ *       wstring: Wide source string.
+ * Returns:
+ *       UTF-8 encoded string that needs to be freed with dw_free()
+ *       or NULL on failure.
+ */
+char * API dw_wchar_to_utf8(wchar_t *wstring)
+{
+#ifdef UNICODE
+    return _myWideToUTF8(wstring, malloc(WideCharToMultiByte(CP_UTF8, 0, wstring, -1, NULL, 0, NULL, NULL)));
+#else
+    return NULL;
+#endif
+}
+