changeset 13:2c122663858c default tip

Update OS/2 and Windows Dynamic Windows... change for using ace 2.0
author Brian Smith <brian@dbsoft.org>
date Thu, 26 Sep 2019 17:40:21 -0500
parents 840ef4182857
children
files dw.h os2/dw.c win/dw.c
diffstat 3 files changed, 2015 insertions(+), 1015 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Wed Sep 26 23:31:24 2012 -0500
+++ b/dw.h	Thu Sep 26 17:40:21 2019 -0500
@@ -1,11 +1,11 @@
-/* $Id: dw.h 1804 2012-09-24 23:24:25Z bsmith $ */
+/* $Id: dw.h 2001 2019-09-16 19:12:39Z bsmith $ */
 
 #ifndef _H_DW
 #define _H_DW
 
 /* Dynamic Windows version numbers */
-#define DW_MAJOR_VERSION 2
-#define DW_MINOR_VERSION 4
+#define DW_MAJOR_VERSION 3
+#define DW_MINOR_VERSION 0
 #define DW_SUB_VERSION 0
 
 #if !defined(__PHOTON__)
@@ -143,6 +143,8 @@
 #define DW_FCF_AUTOICON          FCF_AUTOICON
 #define DW_FCF_MAXIMIZE          WS_MAXIMIZED
 #define DW_FCF_MINIMIZE          WS_MINIMIZED
+#define DW_FCF_TEXTURED          0
+#define DW_FCF_FULLSCREEN        0
 
 #define DW_CFA_BITMAPORICON      CFA_BITMAPORICON
 #define DW_CFA_STRING            CFA_STRING
@@ -159,6 +161,8 @@
 #define DW_CRA_SELECTED          CRA_SELECTED
 #define DW_CRA_CURSORED          CRA_CURSORED
 
+#define DW_CR_RETDATA            (1 << 10)
+
 #define DW_LS_MULTIPLESEL        LS_MULTIPLESEL
 
 #define DW_LIT_NONE              -1
@@ -255,6 +259,36 @@
 
 extern HAB dwhab;
 extern HMQ dwhmq;
+
+#include <stdio.h>
+
+/* Mostly safe but slow snprintf() for compilers that don't have it... 
+ * like VisualAge.  So we can write safe code and still use VAC to test.
+ */
+#if defined(__IBMC__) && !defined(snprintf)
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+static int _dw_snprintf(char *str, size_t size, const char *format, ...)
+{
+   va_list args;
+   char *outbuf = calloc(1, size + strlen(format) + 1024);
+   int retval = -1;
+
+   if(outbuf)
+   {
+      va_start(args, format);
+      vsprintf(outbuf, format, args);
+      va_end(args);
+      retval = strlen(outbuf);
+      strncpy(str, outbuf, size);
+      free(outbuf);
+   }
+   return retval;
+}
+#define snprintf _dw_snprintf
+#endif
+
 #endif
 
 #if defined(__MAC__)
@@ -353,6 +387,8 @@
 #define DW_FCF_AUTOICON          0
 #define DW_FCF_MAXIMIZE          0
 #define DW_FCF_MINIMIZE          0
+#define DW_FCF_TEXTURED          (1 << 8) /* NSTexturedBackgroundWindowMask */
+#define DW_FCF_FULLSCREEN        (1 << 4)
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -369,6 +405,8 @@
 #define DW_CRA_SELECTED          1
 #define DW_CRA_CURSORED          (1 << 1)
 
+#define DW_CR_RETDATA            (1 << 10)
+
 #define DW_LS_MULTIPLESEL        1
 
 #define DW_LIT_NONE              -1
@@ -483,6 +521,7 @@
 
 /* Windows specific section */
 #if defined(__WIN32__) || defined(WINNT)
+#include <winsock2.h>
 #include <windows.h>
 #include <commctrl.h>
 
@@ -492,6 +531,7 @@
 # else
 #  define API _cdecl
 #endif
+#define DWSIGNAL _cdecl
 #endif
 
 #define DW_DT_LEFT               SS_LEFTNOWORDWRAP
@@ -529,6 +569,8 @@
 #define DW_FCF_MAXIMIZE          WS_MAXIMIZE
 #define DW_FCF_MINIMIZE          WS_MINIMIZE
 #define DW_FCF_COMPOSITED        1
+#define DW_FCF_TEXTURED          0
+#define DW_FCF_FULLSCREEN        (1 << 2)
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -545,6 +587,8 @@
 #define DW_CRA_SELECTED          LVNI_SELECTED
 #define DW_CRA_CURSORED          LVNI_FOCUSED
 
+#define DW_CR_RETDATA            (1 << 10)
+
 #define DW_LS_MULTIPLESEL        LBS_MULTIPLESEL
 
 #define DW_LIT_NONE              -1
@@ -638,6 +682,7 @@
 typedef struct _box {
 #if defined(__WIN32__) || defined(WINNT)
    ColorInfo cinfo;
+   int fullscreen;
 #elif defined(__OS2__) || defined(__EMX__)
    PFNWP oldproc;
    UserData *root;
@@ -791,6 +836,8 @@
 #define DW_FCF_AUTOICON          (Ph_WM_RENDER_ASICON | ~Ph_WM_RENDER_ASAPP)
 #define DW_FCF_MAXIMIZE          0
 #define DW_FCF_MINIMIZE          0
+#define DW_FCF_TEXTURED          0
+#define DW_FCF_FULLSCREEN        0
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -807,6 +854,8 @@
 #define DW_CRA_SELECTED          1
 #define DW_CRA_CURSORED          (1 << 1)
 
+#define DW_CR_RETDATA            (1 << 10)
+
 #define DW_LS_MULTIPLESEL        1
 
 #define DW_LIT_NONE              -1
@@ -924,6 +973,7 @@
 
 #else
 /* GTK Specific section */
+#define _GNU_SOURCE
 #include <gtk/gtk.h>
 #ifdef GDK_WINDOWING_X11
 # include <gdk/gdkx.h>
@@ -973,6 +1023,8 @@
 #define DW_FCF_MAXIMIZE          (1 << 19)
 #define DW_FCF_MINIMIZE          (1 << 20)
 #define DW_FCF_CLOSEBUTTON       (1 << 21)
+#define DW_FCF_TEXTURED          0
+#define DW_FCF_FULLSCREEN        (1 << 22)
 
 #define DW_CFA_BITMAPORICON      1
 #define DW_CFA_STRING            (1 << 1)
@@ -989,6 +1041,8 @@
 #define DW_CRA_SELECTED          1
 #define DW_CRA_CURSORED          (1 << 1)
 
+#define DW_CR_RETDATA            (1 << 10)
+
 #define DW_LS_MULTIPLESEL        1
 
 #define DW_LIT_NONE              -1
@@ -1350,11 +1404,19 @@
 #define DW_RGB(a, b, c) (0xF0000000 | (a) | (b) << 8 | (c) << 16)
 #endif
 
+/* Menu convenience paramaters */
 #define DW_MENU_SEPARATOR ""
 #define DW_NOMENU 0
 #define DW_MENU_AUTO 0
 #define DW_MENU_POPUP (unsigned long)-1
 
+/* Convenience parameters for various types */
+#define DW_NOHWND 0
+#define DW_NOHTIMER 0
+#define DW_NOHPRINT 0
+#define DW_NOHPIXMAP 0
+#define DW_NOHICN 0
+
 #define DW_PERCENT_INDETERMINATE ((unsigned int)-1)
 
 /* Return value error codes */
@@ -1381,17 +1443,33 @@
 #define DW_DRAW_FULL       (1 << 1)
 #define DW_DRAW_NOAA       (1 << 2)
 
+/* MLE Completion flags */
+#define DW_MLE_COMPLETE_TEXT      1
+#define DW_MLE_COMPLETE_DASH      (1 << 1)
+#define DW_MLE_COMPLETE_QUOTE     (1 << 2)
+
 /* Macro for casting resource IDs to HICN */
 #define DW_RESOURCE(a) (a < 65536 ? (HICN)a : (HICN)0)
 
 #include <limits.h>
 /* Macros for converting from INT/UINT to and from POINTER without compiler warnings */
-#if LONG_MAX > INT_MAX
+#if _MSC_VER > 1500 || (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 30100 || defined(__has_extension)
+#include <stdint.h>
+/* There has got to be a better way to check for the intptr_t type....
+ * for now just include valid versions of Visual C and GCC plus clang.
+ */
+#define DW_INT_TO_POINTER(a) ((void *)(intptr_t)a)
+#define DW_POINTER_TO_INT(a) ((int)(intptr_t)a)
+#define DW_UINT_TO_POINTER(a) ((void *)(uintptr_t)a)
+#define DW_POINTER_TO_UINT(a) ((unsigned int)(uintptr_t)a)
+#elif ULONG_MAX > UINT_MAX
+/* If no intptr_t... ULONG is often bigger than UINT */
 #define DW_INT_TO_POINTER(a) ((void *)(long)a)
 #define DW_POINTER_TO_INT(a) ((int)(long)a)
 #define DW_UINT_TO_POINTER(a) ((void *)(unsigned long)a)
 #define DW_POINTER_TO_UINT(a) ((unsigned int)(unsigned long)a)
 #else
+/* Otherwise just fall back to standard casts */
 #define DW_INT_TO_POINTER(a) ((void *)a)
 #define DW_POINTER_TO_INT(a) ((int)a)
 #define DW_UINT_TO_POINTER(a) ((void *)a)
@@ -1407,7 +1485,9 @@
 #define API
 #endif
 
+#ifndef DWSIGNAL
 #define DWSIGNAL API
+#endif
 
 /* Constants for sizing scrolled widgets */
 #define _DW_SCROLLED_MIN_WIDTH   100
@@ -1437,20 +1517,20 @@
 #endif
 
 /* Visual C */
-#if defined(_MSC_VER) 
+#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) 
+#  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 
+#  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))
@@ -1568,6 +1648,7 @@
 void API dw_mle_set_visible(HWND handle, int line);
 void API dw_mle_set_editable(HWND handle, int state);
 void API dw_mle_set_word_wrap(HWND handle, int state);
+void API dw_mle_set_auto_complete(HWND handle, int state);
 int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags);
 void API dw_spinbutton_set_pos(HWND handle, long position);
 void API dw_spinbutton_set_limits(HWND handle, long upper, long lower);
@@ -1598,8 +1679,8 @@
 void API dw_container_set_column_width(HWND handle, int column, int width);
 void API dw_container_set_row_title(void *pointer, int row, char *title);
 void API dw_container_change_row_title(HWND handle, int row, char *title);
-#define dw_container_set_row_data(a, b, c) dw_container_set_row_title(a, b, (char *)c)
-#define dw_container_change_row_data(a, b, c) dw_container_change_row_title(a, b, (char *)c)
+void API dw_container_set_row_data(void *pointer, int row, void *data);
+void API dw_container_change_row_data(HWND handle, int row, void *data);
 void API dw_container_insert(HWND handle, void *pointer, int rowcount);
 void API dw_container_clear(HWND handle, int redraw);
 void API dw_container_delete(HWND handle, int rowcount);
@@ -1607,7 +1688,9 @@
 char * API dw_container_query_next(HWND handle, unsigned long flags);
 void API dw_container_scroll(HWND handle, int direction, long rows);
 void API dw_container_cursor(HWND handle, char *text);
+void API dw_container_cursor_by_data(HWND handle, void *data);
 void API dw_container_delete_row(HWND handle, char *text);
+void API dw_container_delete_row_by_data(HWND handle, void *data);
 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);
@@ -1660,6 +1743,7 @@
 void API dw_thread_end(void);
 DWTID API dw_thread_id(void);
 void API dw_exit(int exitcode);
+void API dw_shutdown(void);
 HWND API dw_render_new(unsigned long id);
 void API dw_color_foreground_set(unsigned long value);
 void API dw_color_background_set(unsigned long value);
@@ -1703,6 +1787,7 @@
 int API dw_timer_connect(int interval, void *sigfunc, void *data);
 void API dw_timer_disconnect(int id);
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data);
+void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data);
 void API dw_signal_disconnect_by_window(HWND window);
 void API dw_signal_disconnect_by_data(HWND window, void *data);
 void API dw_signal_disconnect_by_name(HWND window, char *signame);
@@ -1729,5 +1814,8 @@
 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);
+/* Exported for language bindings */
+void API _dw_init_thread(void);
+void API _dw_deinit_thread(void);
 
 #endif
--- a/os2/dw.c	Wed Sep 26 23:31:24 2012 -0500
+++ b/os2/dw.c	Thu Sep 26 17:40:21 2019 -0500
@@ -2,7 +2,7 @@
  * Dynamic Windows:
  *          A GTK like implementation of the PM GUI
  *
- * (C) 2000-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2000-2019 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>
@@ -65,7 +65,7 @@
 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, int *depth);
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height, int *depth, unsigned long backrgb);
 void _free_menu_data(HWND menu);
 BOOL (API_FUNC _WinQueryDesktopWorkArea)(HWND hwndDesktop, PWRECT pwrcWorkArea) = 0;
 /* PMPrintf support for dw_debug() */
@@ -166,6 +166,7 @@
    HWND window;
    int id;
    void *signalfunction;
+   void *discfunction;
    void *data;
 
 } SignalHandler;
@@ -216,7 +217,7 @@
 
 /* This function adds a signal handler callback into the linked list.
  */
-void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *discfunc, void *data)
 {
    SignalHandler *new = malloc(sizeof(SignalHandler));
 
@@ -224,6 +225,7 @@
    new->window = window;
    new->id = id;
    new->signalfunction = signalfunction;
+   new->discfunction = discfunc;
    new->data = data;
    new->next = NULL;
 
@@ -431,6 +433,14 @@
    HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled");
    HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon");
 
+   /* For safety purposes, reset all the window data */
+   dw_window_set_data(handle, "_dw_bitmap", NULL);
+   dw_window_set_data(handle, "_dw_hps", NULL);
+   dw_window_set_data(handle, "_dw_hdc", NULL);
+   dw_window_set_data(handle, "_dw_hpixmap", NULL);
+   dw_window_set_data(handle, "_dw_hpixmap_disabled", NULL);
+   dw_window_set_data(handle, "_dw_button_icon", NULL);
+   
    if(icon)
       WinDestroyPointer(icon);
 
@@ -610,14 +620,46 @@
       strncmp(tmpbuf, "#37", 4)==0 || /* Container */
       strncmp(tmpbuf, "#38", 4)== 0)  /* Slider */
       return 1;
+   if(strncmp(tmpbuf, "#40", 4)==0)   /* Notebook */
+      return 2;
    return 0;
 }
 
-int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem)
+#define _DW_DIRECTION_FORWARD -1
+#define _DW_DIRECTION_BACKWARD 1
+
+int _focus_check_box(Box *box, HWND handle, int start, int direction, HWND defaultitem);
+
+/* Internal comparision function */
+int _focus_comp(int direction, int z, int end)
+{
+   if(direction == _DW_DIRECTION_FORWARD)
+      return z > -1;
+   return z < end;
+}
+int _focus_notebook(HWND hwnd, HWND handle, int start, int direction, HWND defaultitem)
+{
+   Box *notebox;
+   HWND page = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND,
+                         (MPARAM)dw_notebook_page_get(hwnd), 0);
+
+   if(page)
+   {
+      notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
+
+      if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, direction, defaultitem))
+         return 1;
+   }
+   return 0;
+}
+
+int _focus_check_box(Box *box, HWND handle, int start, int direction, HWND defaultitem)
 {
    int z;
    static HWND lasthwnd, firsthwnd;
    static int finish_searching;
+   int beg = (direction == _DW_DIRECTION_FORWARD) ? box->count-1 : 0;
+   int end = (direction == _DW_DIRECTION_FORWARD) ? -1 : box->count;
 
    /* Start is 2 when we have cycled completely and
     * need to set the focus to the last widget we found
@@ -641,17 +683,22 @@
       firsthwnd = 0;
    }
 
-   for(z=box->count-1;z>-1;z--)
+   for(z=beg;_focus_comp(direction, z, end);z+=direction)
    {
       if(box->items[z].type == TYPEBOX)
       {
          Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
 
-         if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+         if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
             return 1;
       }
       else
       {
+         int type = _validate_focus(box->items[z].hwnd);
+         
+         /* Special case notebook, can focus and contains items */
+         if(type == 2 && direction == _DW_DIRECTION_FORWARD && _focus_notebook(box->items[z].hwnd, handle, start, direction, defaultitem)) 
+            return 1;
          if(box->items[z].hwnd == handle)
          {
             if(lasthwnd == handle && firsthwnd)
@@ -681,10 +728,10 @@
                }
             }
 
+            lasthwnd = box->items[z].hwnd;
+            
             if(!firsthwnd)
-               firsthwnd = box->items[z].hwnd;
-
-            lasthwnd = box->items[z].hwnd;
+               firsthwnd = lasthwnd;
          }
          else
          {
@@ -694,38 +741,24 @@
             if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
             {
                /* Then try the bottom or right box */
-               HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-
-               /* Try the top or left box */
-               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
+                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, (direction == _DW_DIRECTION_FORWARD) ? "_dw_bottomright" : "_dw_topleft");
 
                if(mybox)
                {
                   Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
 
-                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
                      return 1;
                }
-            }
-            else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
-            {
-               Box *notebox;
-               HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
-                                     (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
-
-               if(page)
+
+               /* Try the top or left box */
+               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, (direction == _DW_DIRECTION_FORWARD) ? "_dw_topleft" : "_dw_bottomright");
+
+               if(mybox)
                {
-                  notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
-
-                  if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem))
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
                      return 1;
                }
             }
@@ -738,147 +771,15 @@
                 {
                     Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
 
-                    if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
+                    if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
                         return 1;
                 }
             }
          }
-      }
-   }
-   return 0;
-}
-
-int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem)
-{
-   int z;
-   static HWND lasthwnd, firsthwnd;
-    static int finish_searching;
-
-   /* Start is 2 when we have cycled completely and
-    * need to set the focus to the last widget we found
-    * that was valid.
-    */
-   if(start == 2)
-   {
-      if(lasthwnd)
-         WinSetFocus(HWND_DESKTOP, lasthwnd);
-      return 0;
-   }
-
-   /* Start is 1 when we are entering the function
-    * for the first time, it is zero when entering
-    * the function recursively.
-    */
-   if(start == 1)
-   {
-      lasthwnd = handle;
-      finish_searching = 0;
-      firsthwnd = 0;
-   }
-
-   for(z=0;z<box->count;z++)
-   {
-      if(box->items[z].type == TYPEBOX)
-      {
-         Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER);
-
-         if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+         /* Special case notebook, can focus and contains items */
+         if(type == 2 && direction == _DW_DIRECTION_BACKWARD && _focus_notebook(box->items[z].hwnd, handle, start, direction, defaultitem)) 
             return 1;
       }
-      else
-      {
-         if(box->items[z].hwnd == handle)
-         {
-            if(lasthwnd == handle && firsthwnd)
-               WinSetFocus(HWND_DESKTOP, firsthwnd);
-            else if(lasthwnd == handle && !firsthwnd)
-               finish_searching = 1;
-            else
-               WinSetFocus(HWND_DESKTOP, lasthwnd);
-
-            /* If we aren't looking for the last handle,
-             * return immediately.
-             */
-            if(!finish_searching)
-               return 1;
-         }
-         if(_validate_focus(box->items[z].hwnd))
-         {
-            /* Start is 3 when we are looking for the
-             * first valid item in the layout.
-             */
-            if(start == 3)
-            {
-               if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd))
-               {
-                  WinSetFocus(HWND_DESKTOP, box->items[z].hwnd);
-                  return 1;
-               }
-            }
-
-            if(!firsthwnd)
-               firsthwnd = box->items[z].hwnd;
-
-            lasthwnd = box->items[z].hwnd;
-         }
-         else
-         {
-            char tmpbuf[100] = {0};
-
-            WinQueryClassName(box->items[z].hwnd, 99, (PCH)tmpbuf);
-            if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-            {
-               /* Try the top or left box */
-               HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-
-               /* Then try the bottom or right box */
-               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-            }
-            else if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */
-            {
-               Box *notebox;
-               HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND,
-                                     (MPARAM)dw_notebook_page_get(box->items[z].hwnd), 0);
-
-               if(page)
-               {
-                  notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
-
-                  if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-            }
-            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0) /* Scrollbox */
-            {
-                /* Get the box window handle */
-                HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_box");
-
-                if(mybox)
-                {
-                    Box *scrollbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-                    if(scrollbox && _focus_check_box_back(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
-                        return 1;
-                }
-            }
-         }
-      }
    }
    return 0;
 }
@@ -898,14 +799,14 @@
       return 1;
 
    if(thisbox)
-      _focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
+      _focus_check_box(thisbox, handle, 3, _DW_DIRECTION_FORWARD, thisbox->defaultitem);
    return 0;
 }
 
 /* This function finds the current widget in the
  * layout and moves the current focus to the next item.
  */
-void _shift_focus(HWND handle)
+void _shift_focus(HWND handle, int direction)
 {
    Box *thisbox;
    HWND box, lastbox = _toplevel_window(handle);
@@ -918,29 +819,8 @@
 
    if(thisbox)
    {
-      if(_focus_check_box(thisbox, handle, 1, 0)  == 0)
-         _focus_check_box(thisbox, handle, 2, 0);
-   }
-}
-
-/* This function finds the current widget in the
- * layout and moves the current focus to the next item.
- */
-void _shift_focus_back(HWND handle)
-{
-   Box *thisbox;
-   HWND box, lastbox = _toplevel_window(handle);
-
-   box = WinWindowFromID(lastbox, FID_CLIENT);
-   if(box)
-      thisbox = WinQueryWindowPtr(box, QWP_USER);
-   else
-      thisbox = WinQueryWindowPtr(lastbox, QWP_USER);
-
-   if(thisbox)
-   {
-      if(_focus_check_box_back(thisbox, handle, 1, 0)  == 0)
-         _focus_check_box_back(thisbox, handle, 2, 0);
+      if(_focus_check_box(thisbox, handle, 1, direction, 0)  == 0)
+         _focus_check_box(thisbox, handle, 2, direction, 0);
    }
 }
 
@@ -2615,9 +2495,9 @@
       if(SHORT1FROMMP(mp2) == '\t')
       {
          if(CHARMSG(&msg)->fs & KC_SHIFT)
-            _shift_focus_back(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
          else
-            _shift_focus(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
          return FALSE;
       }
       else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
@@ -2869,9 +2749,9 @@
       if(SHORT1FROMMP(mp2) == '\t')
       {
          if(CHARMSG(&msg)->fs & KC_SHIFT)
-            _shift_focus_back(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
          else
-            _shift_focus(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
          return FALSE;
       }
       else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
@@ -3282,8 +3162,9 @@
                {
                case CN_ENTER:
                   {
-                     int (API_FUNC containerselectfunc)(HWND, char *, void *) = (int (API_FUNC)(HWND, char *, void *))tmp->signalfunction;
+                     int (API_FUNC containerselectfunc)(HWND, char *, void *, void *) = (int (API_FUNC)(HWND, char *, void *, void *))tmp->signalfunction;
                      char *text = NULL;
+                     void *data = NULL;
 
                      if(mp2)
                      {
@@ -3291,12 +3172,15 @@
 
                         pre = ((PNOTIFYRECORDENTER)mp2)->pRecord;
                         if(pre)
-                           text = (char *)pre->pszIcon;
+                        {
+                            text = (char *)pre->pszIcon;
+                            data = (void *)pre->pszText;
+                        }
                      }
 
                      if(tmp->window == notifyhwnd)
                      {
-                        result = containerselectfunc(tmp->window, text, tmp->data);
+                        result = containerselectfunc(tmp->window, text, tmp->data, data);
                         tmp = NULL;
                      }
                   }
@@ -3375,14 +3259,16 @@
                         {
                            if(tmp->window == pre->hwndCnr)
                            {
+                              /* PCNRITEM for Tree PRECORDCORE for Container */
                               PCNRITEM pci = (PCNRITEM)pre->pRecord;
+                              PRECORDCORE prc = pre->pRecord;
 
                               if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
                               {
                                  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);
+                                    result = treeselectfunc(tmp->window, 0, (char *)prc->pszIcon, tmp->data, (void *)prc->pszText);
                                  else
                                  {
                                     if(lasthcnr == tmp->window && lastitem == (HWND)pci)
@@ -3825,9 +3711,9 @@
       if(SHORT1FROMMP(mp2) == '\t')
       {
          if(CHARMSG(&msg)->fs & KC_SHIFT)
-            _shift_focus_back(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
          else
-            _shift_focus(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
          return FALSE;
       }
       break;
@@ -4292,20 +4178,20 @@
          if(SHORT1FROMMP(mp2) == '\t')
          {
             if(CHARMSG(&msg)->fs & KC_SHIFT)
-               _shift_focus_back(hwnd);
+               _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
             else
-               _shift_focus(hwnd);
+               _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
             WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
             return FALSE;
          }
          else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_LEFT || CHARMSG(&msg)->vkey == VK_UP))
          {
-            _shift_focus_back(hwnd);
+            _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
             return FALSE;
          }
          else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN))
          {
-            _shift_focus(hwnd);
+            _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
             return FALSE;
          }
       }
@@ -4391,9 +4277,9 @@
       if(SHORT1FROMMP(mp2) == '\t')
       {
          if(CHARMSG(&msg)->fs & KC_SHIFT)
-            _shift_focus_back(hwnd);
+            _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
          else
-            _shift_focus(hwnd);
+            _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
          return FALSE;
       }
       break;
@@ -4407,6 +4293,45 @@
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
 }
 
+MRESULT EXPENTRY _NotebookProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hwnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_PAINT:
+      if(!WinSendMsg(hwnd, BKM_QUERYPAGECOUNT, 0, (MPARAM)BKA_END))
+      {
+         HPS hpsPaint;
+         RECTL rclPaint;
+
+         hpsPaint = WinBeginPaint(hwnd, 0, &rclPaint);
+         WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+         WinEndPaint(hpsPaint);
+      }
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
+         else
+            _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
+         return FALSE;
+      }
+      break;
+   }
+   
+   if(oldproc)
+      return oldproc(hwnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
 #ifdef UNICODE
 /* Internal function to detect the active keyboard layout */
 UniChar *_detect_keyb(void)
@@ -4712,6 +4637,9 @@
    QMSG qmsg;
    void *tmp;
 
+   if(!dialog)
+      return NULL;
+
    while (WinGetMsg(dwhab, &qmsg, 0, 0, 0))
    {
       if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
@@ -6007,6 +5935,7 @@
 {
    ULONG flags;
    HWND tmp;
+   WindowData *blah = calloc(1, sizeof(WindowData));
 
    if(top)
       flags = BKS_MAJORTABTOP;
@@ -6035,6 +5964,8 @@
       WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB));
    }
 
+   blah->oldproc = WinSubclassWindow(tmp, _NotebookProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
    dw_window_set_font(tmp, DefaultFont);
    return tmp;
 }
@@ -6743,6 +6674,29 @@
    return tmp;
 }
 
+/* Internal function to create a disabled version of a pixmap */
+HPIXMAP _create_disabled(HWND handle, HPIXMAP pixmap)
+{
+    /* Create a disabled style pixmap */
+    HPIXMAP disabled = dw_pixmap_new(handle, pixmap->width, pixmap->height, dw_color_depth_get());
+    LONG fore = _foreground;
+    int z, j, lim;
+
+    dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
+
+    dw_color_foreground_set(DW_CLR_PALEGRAY);
+    lim = pixmap->width/2;
+    for(j=0;j<pixmap->height;j++)
+    {
+        int mod = j%2;
+
+        for(z=0;z<lim;z++)
+            dw_draw_point(0, disabled, (z*2)+mod, j);
+    }
+    _foreground = fore;
+    return disabled;
+}
+
 /*
  * Create a new bitmap button window (widget) to be packed from a file.
  * Parameters:
@@ -6772,8 +6726,7 @@
 
    if(file && (pixmap = calloc(1,sizeof(struct _hpixmap))))
    {
-      int z, j, lim, len;
-      LONG fore;
+      int z, len;
 
       strcpy(file, filename);
 
@@ -6786,7 +6739,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, &pixmap->depth);
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth, DW_CLR_DEFAULT);
          }
       }
       else
@@ -6802,7 +6755,7 @@
                 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))
+                   _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth, DW_CLR_DEFAULT))
                     break;
             }
          }
@@ -6815,21 +6768,7 @@
       }
       else
       {
-         /* Create a disabled style pixmap */
-         disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get());
-         dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
-
-         fore = _foreground;
-         dw_color_foreground_set(DW_CLR_PALEGRAY);
-         lim = pixmap->width/2;
-         for(j=0;j<pixmap->height;j++)
-         {
-            int mod = j%2;
-
-            for(z=0;z<lim;z++)
-               dw_draw_point(0, disabled, (z*2)+mod, j);
-         }
-         _foreground = fore;
+          disabled = _create_disabled(tmp, pixmap);
       }
    }
 
@@ -6880,8 +6819,6 @@
 
    if((pixmap = calloc(1, sizeof(struct _hpixmap))) != NULL)
    {
-      int z, j, lim;
-      LONG fore;
       file = tmpnam( NULL );
       if ( file != NULL )
       {
@@ -6890,7 +6827,7 @@
          {
             fwrite( data, 1, len, fp );
             fclose( fp );
-            if(!_load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
+            if(!_load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth, DW_CLR_DEFAULT))
             {
                icon = WinLoadFileIcon((PSZ)file, FALSE);
             }
@@ -6910,21 +6847,7 @@
       }
       else
       {
-         /* Create a disabled style pixmap */
-         disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth_get());
-         dw_pixmap_bitblt(0, disabled, 0, 0, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
-
-         fore = _foreground;
-         dw_color_foreground_set(DW_CLR_PALEGRAY);
-         lim = pixmap->width/2;
-         for(j=0;j<pixmap->height;j++)
-         {
-            int mod = j%2;
-
-            for(z=0;z<lim;z++)
-               dw_draw_point(0, disabled, (z*2)+mod, j);
-         }
-         _foreground = fore;
+          disabled = _create_disabled(tmp, pixmap);
       }
    }
 
@@ -7151,6 +7074,94 @@
    WinSendMsg(handle, WM_SETICON, (MPARAM)hptr, 0);
 }
 
+/* Code from GBM to convert to 24bpp if it isn't currently */
+static int _To24Bit(GBM *gbm, GBMRGB *gbmrgb, BYTE **ppbData)
+{
+    unsigned long stride     = (((unsigned long)gbm -> w * gbm -> bpp + 31)/32) * 4;
+    unsigned long new_stride = (((unsigned long)gbm -> w * 3 + 3) & ~3);
+    unsigned long bytes;
+    int y;
+    unsigned char *pbDataNew;
+
+    if ( gbm -> bpp == 24 )
+    {
+        return ( TRUE );
+    }
+
+    bytes = new_stride * gbm -> h;
+    /* Allocate a buffer to store the image */
+    if(DosAllocMem((PPVOID)&pbDataNew, (ULONG)bytes, PAG_READ | PAG_WRITE | PAG_COMMIT) != NO_ERROR)
+    {
+        return ( FALSE );
+    }
+
+    for ( y = 0; y < gbm -> h; y++ )
+    {
+        unsigned char *src = *ppbData + y * stride;
+        unsigned char *dest = pbDataNew + y * new_stride;
+        int   x;
+
+        switch ( gbm -> bpp )
+        {
+        case 1:
+            {
+                unsigned char  c = 0;
+                for ( x = 0; x < gbm -> w; x++ )
+                {
+                    if ( (x & 7) == 0 )
+                        c = *src++;
+                    else
+                        c <<= 1;
+
+                    *dest++ = gbmrgb [(c & 0x80) != 0].b;
+                    *dest++ = gbmrgb [(c & 0x80) != 0].g;
+                    *dest++ = gbmrgb [(c & 0x80) != 0].r;
+                }
+            }
+            break;
+
+        case 4:
+            for ( x = 0; x + 1 < gbm -> w; x += 2 )
+            {
+                unsigned char c = *src++;
+
+                *dest++ = gbmrgb [c >> 4].b;
+                *dest++ = gbmrgb [c >> 4].g;
+                *dest++ = gbmrgb [c >> 4].r;
+                *dest++ = gbmrgb [c & 15].b;
+                *dest++ = gbmrgb [c & 15].g;
+                *dest++ = gbmrgb [c & 15].r;
+            }
+
+            if ( x < gbm -> w )
+            {
+                unsigned char c = *src;
+
+                *dest++ = gbmrgb [c >> 4].b;
+                *dest++ = gbmrgb [c >> 4].g;
+                *dest++ = gbmrgb [c >> 4].r;
+            }
+            break;
+
+        case 8:
+            for ( x = 0; x < gbm -> w; x++ )
+            {
+                unsigned char c = *src++;
+
+                *dest++ = gbmrgb [c].b;
+                *dest++ = gbmrgb [c].g;
+                *dest++ = gbmrgb [c].r;
+            }
+            break;
+        }
+    }
+    DosFreeMem(*ppbData);
+    *ppbData = pbDataNew;
+    gbm->bpp = 24;
+
+    return ( TRUE );
+}
+
 /* 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.
@@ -7161,7 +7172,7 @@
 /* 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, int *depth)
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height, int *depth, unsigned long backrgb)
 {
     PBITMAPINFOHEADER2 pBitmapInfoHeader;
     /* pointer to the first byte of bitmap data  */
@@ -7176,7 +7187,7 @@
     {
         int fd, z, err = -1, ft = 0;
         GBM gbm;
-        GBMRGB *gbmrgb;
+        GBMRGB *gbmrgb = NULL;
         ULONG byteswidth;
 
         /* Try to open the file */
@@ -7193,8 +7204,27 @@
 
         for(z=0;z<ft;z++)
         {
+            /* Using CLR_PALEGRAY as a default alpha background... we can
+             * change this to use WinQuerySysColor() later, but pale gray is
+             * already hardcoded elsewhere so just continue using it here.
+             */
+            char options[101] = "back_rgb=52224_52224_52224";
+
+            /* Ask the control if it has another color set */
+            if(backrgb == DW_CLR_DEFAULT && handle)
+            {
+                RGB rgb = {0};
+
+                if(WinQueryPresParam(handle, PP_BACKGROUNDCOLOR, PP_BACKGROUNDCOLORINDEX, NULL, sizeof(rgb), &rgb, QPF_NOINHERIT | QPF_PURERGBCOLOR | QPF_ID2COLORINDEX))
+                    sprintf(options, "back_rgb=%d_%d_%d", rgb.bRed * 256, rgb.bGreen * 256, rgb.bBlue * 256);
+            }
+            else if(backrgb & DW_RGB_COLOR)
+            {
+                sprintf(options, "back_rgb=%d_%d_%d", (int)DW_RED_VALUE(backrgb) * 256, (int)DW_GREEN_VALUE(backrgb) * 256, (int)DW_BLUE_VALUE(backrgb) * 256);
+            }
+
             /* Read the file header */
-            if((err = _gbm_read_header(file, fd, z, &gbm, "")) == 0)
+            if((err = _gbm_read_header(file, fd, z, &gbm, options)) == 0)
                 break;
         }
 
@@ -7211,7 +7241,7 @@
         /* if less than 24-bit, then have palette */
         if(gbm.bpp < 24)
         {
-            gbmrgb = alloca(sizeof(GBMRGB));
+            gbmrgb = alloca(sizeof(GBMRGB) * 256);
             /* Read the palette from the file */
             if((err = _gbm_read_palette(fd, z, &gbm, gbmrgb)) != 0)
             {
@@ -7222,8 +7252,6 @@
                 return 0;
             }
         }
-        else
-            gbmrgb = NULL;
 
         /* Save the dimension for return */
         *width = gbm.w;
@@ -7249,6 +7277,18 @@
         /* Close the file */
         _gbm_io_close(fd);
 
+        /* Convert to 24bpp for use in the application */
+        if(_To24Bit(&gbm, gbmrgb, &BitmapFileBegin))
+            *depth = 24;
+        else
+        {
+#ifdef DEBUG
+            dw_debug("GBM: Failed 24bpp conversion \"%s\"\n", file);
+#endif
+            DosFreeMem(BitmapFileBegin);
+            return 0;
+        }
+
         pBitmapInfoHeader = alloca(sizeof(BITMAPINFOHEADER2));
         memset(pBitmapInfoHeader, 0, sizeof(BITMAPINFOHEADER2));
         pBitmapInfoHeader->cbFix     = sizeof(BITMAPINFOHEADER2);
@@ -7364,6 +7404,65 @@
     return 1;
 }
 
+/* Internal function to change the button bitmap */
+void _dw_window_set_bitmap(HWND handle, HBITMAP hbm, HDC hdc, HPS hps, unsigned long width, unsigned long height, int depth, HPOINTER icon)
+{
+   char tmpbuf[100] = {0};
+
+   WinQueryClassName(handle, 99, (PCH)tmpbuf);
+
+   /* Button */
+   if(strncmp(tmpbuf, "#3", 3)==0)
+   {
+       WNDPARAMS   wp = {0};
+       BTNCDATA    bcd = {0};
+       RECTL       rect;
+
+       wp.fsStatus = WPM_CTLDATA;
+       wp.pCtlData = &bcd;
+       wp.cbCtlData = bcd.cb = sizeof(BTNCDATA);
+
+       /* Clear any existing icon */
+       WinSendMsg(handle, WM_SETWINDOWPARAMS, (MPARAM)&wp, NULL);
+
+       if(icon)
+       {
+           dw_window_set_data(handle, "_dw_button_icon", DW_POINTER(icon));
+       }
+       else
+       {
+           HPIXMAP disabled, pixmap = calloc(1,sizeof(struct _hpixmap));
+
+           pixmap->hbm = hbm;
+           pixmap->hdc = hdc;
+           pixmap->hps = hps;
+           pixmap->width = width;
+           pixmap->height = height;
+           disabled = _create_disabled(handle, pixmap);
+
+           dw_window_set_data(handle, "_dw_hpixmap", DW_POINTER(pixmap));
+           dw_window_set_data(handle, "_dw_hpixmap_disabled", DW_POINTER(disabled));
+       }
+       dw_window_set_data(handle, "_dw_bitmapbutton", DW_POINTER(1));
+       /* Make sure we invalidate the button so it redraws */
+       WinQueryWindowRect(handle, &rect);
+       WinInvalidateRect(handle, &rect, TRUE);
+   }
+   
+   /* 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);
+      }
+   }
+}
+
 /*
  * Sets the bitmap used for a given static window.
  * Parameters:
@@ -7376,8 +7475,12 @@
  */
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
 {
-   HBITMAP hbm;
-   HPS     hps;
+   HBITMAP hbm = 0;
+   HPS     hps = 0;
+   HDC     hdc = 0;
+   HPOINTER icon = 0;
+   unsigned long width = 0, height = 0;
+   int depth = 0;
 
    /* Destroy any old bitmap data */
    _free_bitmap(handle);
@@ -7387,13 +7490,11 @@
    {
       hps = WinGetPS( handle );
       hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+      WinReleasePS(hps);
    }
    else if ( filename )
    {
-      HDC hdc = 0;
-      unsigned long width, height;
       char *file = alloca(strlen(filename) + 6);
-      int depth;
 
       if(!file)
          return;
@@ -7403,22 +7504,38 @@
       /* check if we can read from this file (it exists and read permission) */
       if(access(file, 04) != 0)
       {
-          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;
-          }
+         /* Try with .ico extension first...*/
+         strcat(file, ".ico");
+         if(access(file, 04) == 0)
+            icon = WinLoadFileIcon((PSZ)file, FALSE);
+         else
+         {
+             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, DW_CLR_DEFAULT))
+                     break;
+             }
+         }
       }
       else
-          _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth);
-
-      if(!hdc)
+      {
+         int len = strlen( file );
+         if(len > 4)
+         {
+            if(stricmp(file + len - 4, ".ico") == 0)
+               icon = WinLoadFileIcon((PSZ)file, FALSE);
+            else
+               _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth, DW_CLR_DEFAULT);
+         }
+      }
+
+      if(!hdc && !icon)
          return;
 
       dw_window_set_data(handle, "_dw_hps", (void *)hps);
@@ -7429,22 +7546,9 @@
    else
       return;
 
-   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);
-      }
-   }
+
+   _dw_window_set_bitmap(handle, hbm, hdc, hps, width, height, depth, icon);
 }
 
 /*
@@ -7480,7 +7584,7 @@
          {
             fwrite( data, 1, len, fp );
             fclose( fp );
-            if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth))
+            if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height, &depth, DW_CLR_DEFAULT))
             {
                /* can't use ICO ? */
                unlink( file );
@@ -7505,13 +7609,14 @@
    {
       hps = WinGetPS( handle );
       hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+      WinReleasePS(hps);
    }
    else
       return;
 
-   if ( id )
-      WinReleasePS(hps);
    dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+
+   _dw_window_set_bitmap(handle, hbm, hdc, hps, width, height, depth, 0);
 }
 
 /*
@@ -8284,8 +8389,12 @@
  */
 unsigned long API dw_notebook_page_new(HWND handle, ULONG flags, int front)
 {
-   return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L,
-                      MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST));
+   ULONG retval = (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L,
+                                    MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), front ? BKA_FIRST : BKA_LAST));
+   RECTL rect;
+   WinQueryWindowRect(handle, &rect);
+   WinInvalidateRect(handle, &rect, TRUE);
+   return retval;
 }
 
 /*
@@ -8298,10 +8407,13 @@
 {
    HWND pagehwnd = (HWND)WinSendMsg(handle, BKM_QUERYPAGEWINDOWHWND,
                                     MPFROMLONG(pageid), 0L);
+   RECTL rect;
    WinSendMsg(handle, BKM_DELETEPAGE,
             MPFROMLONG(pageid),  (MPARAM)BKA_SINGLE);
    if(pagehwnd)
       dw_window_destroy(pagehwnd);
+   WinQueryWindowRect(handle, &rect);
+   WinInvalidateRect(handle, &rect, TRUE);
 }
 
 /*
@@ -8704,6 +8816,16 @@
 }
 
 /*
+ * Sets the word auto complete state of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: Bitwise combination of DW_MLE_COMPLETE_TEXT/DASH/QUOTE
+ */
+void API dw_mle_set_auto_complete(HWND handle, int state)
+{
+}
+
+/*
  * Sets the current cursor position of an MLE box.
  * Parameters:
  *          handle: Handle to the MLE to be positioned.
@@ -9073,8 +9195,8 @@
    PCNRITEM pci = (PCNRITEM)item;
 
    handle = handle; /* keep compiler happy */
-   if(pci)
-      return (char *)pci->rc.pszIcon;
+   if(pci && pci->rc.pszIcon)
+      return strdup((char *)pci->rc.pszIcon);
    return NULL;
 }
 
@@ -9367,8 +9489,35 @@
    return WinLoadPointer(HWND_DESKTOP,module,id);
 }
 
+#if 0
+/* Internal function to create pointer/icon masks */
+void _create_mask(HPIXMAP src, HPIXMAP mask, unsigned long backrgb)
+{
+    LONG maskcolor = (DW_RED_VALUE(backrgb) << 16) | (DW_GREEN_VALUE(backrgb) << 8) | DW_BLUE_VALUE(backrgb);
+    int x, y;
+
+    for(x=0; x < src->width; x++)
+    {
+        for(y=0; y < src->height; y++)
+        {
+            POINTL pt = {x, y};
+            LONG color = GpiQueryPel(src->hps, &pt);
+
+            dw_debug("Mask color %x (%dx%d) %x\n", (int)maskcolor, x, y, (int)color);
+            if(color == maskcolor)
+            {
+                GpiSetColor(mask->hps, CLR_WHITE);
+                GpiSetPel(mask->hps, &pt);
+                pt.y = y + src->height;
+                GpiSetPel(mask->hps, &pt);
+            }
+        }
+    }
+}
+#endif
+
 /* Internal function to create an icon from an existing pixmap */
-HICN _create_icon(HPIXMAP src)
+HICN _create_icon(HPIXMAP src, unsigned long backrgb)
 {
     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);
@@ -9385,6 +9534,14 @@
     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);
+#if 0
+    /* If we have a background color... create masks */
+    if(backrgb & DW_RGB_COLOR)
+    {
+        _create_mask(pntr, mask, backrgb);
+        _create_mask(minipntr, minimask, backrgb);
+    }
+#endif
     _foreground = oldcol;
 
     /* Assemble the Pointer Info structure */
@@ -9393,7 +9550,7 @@
     pi.hbmMiniPointer = minimask->hbm;
     pi.hbmMiniColor = minipntr->hbm;
 
-    /* Destroy the pixmaps but not the bitmaps */
+    /* Destroy the temporary pixmaps */
     mask->hbm = pntr->hbm = minimask->hbm = minipntr->hbm = 0;
     dw_pixmap_destroy(mask);
     dw_pixmap_destroy(pntr);
@@ -9416,6 +9573,7 @@
    char *file = alloca(strlen(filename) + 6);
    HPIXMAP src = alloca(sizeof(struct _hpixmap));
    HICN icon = 0;
+   unsigned long defcol = DW_RGB(204, 204, 204);
 
    if(!file || !src)
       return 0;
@@ -9438,15 +9596,15 @@
            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))
+              _load_bitmap_file(file, hwndApp, &src->hbm, &src->hdc, &src->hps, &src->width, &src->height, &src->depth, defcol))
            {
-               icon = _create_icon(src);
+               icon = _create_icon(src, defcol);
                break;
            }
        }
    }
-   else if(_load_bitmap_file(file, hwndApp, &src->hbm, &src->hdc, &src->hps, &src->width, &src->height, &src->depth))
-       icon = _create_icon(src);
+   else if(_load_bitmap_file(file, hwndApp, &src->hbm, &src->hdc, &src->hps, &src->width, &src->height, &src->depth, defcol))
+       icon = _create_icon(src, defcol);
    /* Free temporary resources if in use */
    if(icon)
    {
@@ -9647,13 +9805,19 @@
    WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
    ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
    int z, count = 0;
-
+   char *oldtitle = (char *)temp->pszIcon;
+   
    if(!flags)
       return;
 
    while(flags[count])
       count++;
 
+   /* Empty and free the title memory */
+   temp->pszIcon = temp->pszText = NULL;
+   if(oldtitle)
+        free(oldtitle);
+        
    /* Figure out the offsets to the items in the struct */
    for(z=0;z<count;z++)
    {
@@ -9867,6 +10031,7 @@
    PRECORDCORE temp;
    int z, currentcount;
    CNRINFO cnr;
+   char *newtitle;
 
    if(!ci)
       return;
@@ -9883,9 +10048,8 @@
    for(z=0;z<(row-currentcount);z++)
       temp = temp->preccNextRecord;
 
-   temp->pszIcon = (PSZ)title;
-   temp->pszName = (PSZ)title;
-   temp->pszText = (PSZ)title;
+   newtitle = title ? strdup(title) : NULL;
+   temp->pszName = temp->pszIcon = (PSZ)newtitle;
 }
 
 /*
@@ -9904,9 +10068,70 @@
    {
       if(count == row)
       {
-         pCore->pszIcon = (PSZ)title;
-         pCore->pszName = (PSZ)title;
-         pCore->pszText = (PSZ)title;
+         char *oldtitle = (char *)pCore->pszIcon;
+         char *newtitle = title ? strdup(title) : NULL;
+         pCore->pszName = pCore->pszIcon = (PSZ)newtitle;
+
+         WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
+         
+         if(oldtitle)
+            free(oldtitle);
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      count++;
+   }
+}
+
+/*
+ * Sets the data of a row in the container.
+ * Parameters:
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          row: Zero based row of data being set.
+ *          data: Data pointer.
+ */
+void API dw_container_set_row_data(void *pointer, int row, void *data)
+{
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+   PRECORDCORE temp;
+   int z, currentcount;
+   CNRINFO cnr;
+
+   if(!ci)
+      return;
+
+   temp = (PRECORDCORE)ci->data;
+
+   z = 0;
+
+   if(!_dw_send_msg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
+      return;
+
+   currentcount = cnr.cRecords;
+
+   for(z=0;z<(row-currentcount);z++)
+      temp = temp->preccNextRecord;
+
+   temp->pszText = (PSZ)data;
+}
+
+/*
+ * Changes the data of a row already inserted in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          row: Zero based row of data being set.
+ *          data: Data pointer.
+ */
+void API dw_container_change_row_data(HWND handle, int row, void *data)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int count = 0;
+
+   while(pCore)
+   {
+      if(count == row)
+      {
+         pCore->pszText = (PSZ)data;
 
          WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
          return;
@@ -10076,7 +10301,9 @@
             if(pCore->flRecordAttr & flags)
             {
                dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-               return (char *)pCore->pszIcon;
+               if(flags & DW_CR_RETDATA)
+                  return (char *)pCore->pszText;
+               return pCore->pszIcon ? strdup((char *)pCore->pszIcon) : NULL;
             }
             pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
          }
@@ -10084,7 +10311,9 @@
       else
       {
          dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-         return (char *)pCore->pszIcon;
+         if(flags & DW_CR_RETDATA)
+            return (char *)pCore->pszText;
+         return pCore->pszIcon ? strdup((char *)pCore->pszIcon) : NULL;
       }
    }
    return NULL;
@@ -10113,7 +10342,9 @@
             if(pCore->flRecordAttr & flags)
             {
                dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-               return (char *)pCore->pszIcon;
+               if(flags & DW_CR_RETDATA)
+                  return (char *)pCore->pszText;
+               return pCore->pszIcon ? strdup((char *)pCore->pszIcon) : NULL;
             }
 
             pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
@@ -10122,7 +10353,9 @@
       else
       {
          dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
-         return (char *)pCore->pszIcon;
+         if(flags & DW_CR_RETDATA)
+            return (char *)pCore->pszText;
+         return pCore->pszIcon ? strdup((char *)pCore->pszIcon) : NULL;
       }
    }
     return NULL;
@@ -10138,11 +10371,10 @@
 {
    RECTL viewport, item;
    PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
 
    while(pCore)
    {
-      if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      if(pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0)
       {
          QUERYRECORDRECT qrr;
          int scrollpixels = 0, midway;
@@ -10176,11 +10408,69 @@
 void API dw_container_delete_row(HWND handle, char *text)
 {
    PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
+
+   while(pCore)
+   {
+      if(pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0)
+      {
+         WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+}
+
+/*
+ * Cursors the item with the data speficied, and scrolls to that item.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       data:  Data usually returned by dw_container_query().
+ */
+void API dw_container_cursor_by_data(HWND handle, void *data)
+{
+   RECTL viewport, item;
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
 
    while(pCore)
    {
-      if((textcomp && pCore->pszIcon && strcmp((char *)pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      if((void *)pCore->pszText == data)
+      {
+         QUERYRECORDRECT qrr;
+         int scrollpixels = 0, midway;
+
+         qrr.cb = sizeof(QUERYRECORDRECT);
+         qrr.pRecord = pCore;
+         qrr.fRightSplitWindow = 0;
+         qrr.fsExtent = CMA_TEXT;
+
+         WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(TRUE, CRA_CURSORED));
+         WinSendMsg(handle, CM_QUERYVIEWPORTRECT, (MPARAM)&viewport, MPFROM2SHORT(CMA_WORKSPACE, FALSE));
+         WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
+
+         midway = (viewport.yTop - viewport.yBottom)/2;
+         scrollpixels = viewport.yTop - (item.yTop + midway);
+
+         WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL),  MPFROMLONG(scrollpixels));
+         return;
+      }
+
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+}
+
+/*
+ * Deletes the item with the data speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       data:  Data usually returned by dw_container_query().
+ */
+void API dw_container_delete_row_by_data(HWND handle, void *data)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(pCore)
+   {
+      if((void *)pCore->pszText == data)
       {
          WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_FREE | CMA_INVALIDATE));
          return;
@@ -10965,7 +11255,7 @@
            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))
+              _load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth, DW_CLR_DEFAULT))
                break;
        }
    }
@@ -11011,7 +11301,7 @@
       {
          fwrite( data, 1, len, fp );
          fclose( fp );
-         if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth))
+         if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height, &pixmap->depth, DW_CLR_DEFAULT))
          {
             /* can't use ICO ? */
             unlink( file );
@@ -11631,28 +11921,81 @@
    return 0;
 }
 
-/*
- * Encapsulate the message queues on OS/2.
- */
-void _dwthreadstart(void *data)
+/* 
+ * Generally an internal function called from a newly created
+ * thread to setup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they create threads that require access to Dynamic Windows.
+ */
+void **_dw_init_thread2(void)
 {
    HAB thishab = WinInitialize(0);
    HMQ thishmq = WinCreateMsgQueue(thishab, 0);
-   void (API_FUNC threadfunc)(void *) = NULL;
-   void **tmp = (void **)data;
+   void **threadinfo = (void **)malloc(sizeof(void *) * 2);
+
+   threadinfo[0] = (void *)thishab;
+   threadinfo[1] = (void *)thishmq;
+   
+#ifndef __WATCOMC__
+   *_threadstore() = (void *)threadinfo;
+#endif
 
 #ifdef UNICODE
    /* Set the codepage to 1208 (UTF-8) */
    WinSetCp(thishmq, 1208);
 #endif
+   return threadinfo;
+}
+
+void API _dw_init_thread(void)
+{
+   _dw_init_thread2();
+}
+
+/* 
+ * Generally an internal function called from a terminating
+ * thread to cleanup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they exit threads that require access to Dynamic Windows.
+ */
+void _dw_deinit_thread2(void **threadinfo)
+{
+#ifndef __WATCOMC__
+   if(!threadinfo)
+      threadinfo = (void **)*_threadstore();
+#endif
+	
+   if(threadinfo)
+   {
+      HAB thishab = (HAB)threadinfo[0];
+      HMQ thishmq = (HMQ)threadinfo[1];
+      
+      WinDestroyMsgQueue(thishmq);
+      WinTerminate(thishab);
+      free(threadinfo);
+   }
+}
+
+void API _dw_deinit_thread(void)
+{
+   _dw_deinit_thread2(NULL);
+}
+
+/*
+ * Encapsulate the message queues on OS/2.
+ */
+void _dwthreadstart(void *data)
+{
+   void (API_FUNC threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+   void **threadinfo = _dw_init_thread2();
 
    threadfunc = (void (API_FUNC)(void *))tmp[0];
    threadfunc(tmp[1]);
 
    free(tmp);
 
-   WinDestroyMsgQueue(thishmq);
-   WinTerminate(thishab);
+   _dw_deinit_thread2(threadinfo);
 }
 
 /*
@@ -11684,6 +12027,7 @@
  */
 void API dw_thread_end(void)
 {
+   _dw_deinit_thread();
    _endthread();
 }
 
@@ -11697,10 +12041,8 @@
 
 /*
  * Cleanly terminates a DW session, should be signal handler safe.
- * Parameters:
- *       exitcode: Exit code reported to the operating system.
- */
-void API dw_exit(int exitcode)
+ */
+void API dw_shutdown(void)
 {
    /* Destroy the menu message window */
    dw_window_destroy(hwndApp);
@@ -11713,7 +12055,10 @@
 
    /* Deinit the GBM */
    if(_gbm_deinit)
+   {
        _gbm_deinit();
+       _gbm_deinit = NULL;
+   }
 
 #ifdef UNICODE
    /* Free the conversion object */
@@ -11731,7 +12076,16 @@
    DosFreeModule(pmprintf);
    DosFreeModule(pmmerge);
    DosFreeModule(gbm);
-   
+}
+
+/*
+ * Cleanly terminates a DW session, should be signal handler safe.
+ * Parameters:
+ *       exitcode: Exit code reported to the operating system.
+ */
+void API dw_exit(int exitcode)
+{
+   dw_shutdown();
    /* And finally exit */
    exit(exitcode);
 }
@@ -13073,7 +13427,7 @@
 
       if(timerid)
       {
-         _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data);
+         _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, NULL, data);
          return timerid;
       }
    }
@@ -13130,6 +13484,20 @@
  */
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
 {
+    dw_signal_connect_data(window, signame, sigfunc, NULL, data);
+}
+
+/*
+ * Add a callback to a window event with a closure callback.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       signame: A string pointer identifying which signal to be hooked.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       discfunc: The pointer to the function called when this handler is removed.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data)
+{
    ULONG message = 0, id = 0;
 
    if(window && signame && sigfunc)
@@ -13154,7 +13522,7 @@
                window = owner;
             }
          }
-         _new_signal(message, window, id, sigfunc, data);
+         _new_signal(message, window, id, sigfunc, discfunc, data);
       }
    }
 }
@@ -13176,6 +13544,13 @@
    {
       if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message)
       {
+         void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
          if(prev)
          {
             prev->next = tmp->next;
@@ -13210,6 +13585,13 @@
    {
       if((window < 65536 && tmp->id == window) || tmp->window == window)
       {
+         void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
          if(prev)
          {
             prev->next = tmp->next;
@@ -13245,6 +13627,13 @@
    {
       if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data)
       {
+         void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
          if(prev)
          {
             prev->next = tmp->next;
--- a/win/dw.c	Wed Sep 26 23:31:24 2012 -0500
+++ b/win/dw.c	Thu Sep 26 17:40:21 2019 -0500
@@ -2,7 +2,7 @@
  * Dynamic Windows:
  *          A GTK like implementation of the Win32 GUI
  *
- * (C) 2000-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2000-2019 Brian Smith <brian@dbsoft.org>
  * (C) 2003-2011 Mark Hessling <mark@rexx.org>
  *
  */
@@ -14,6 +14,7 @@
 #define _WIN32_IE 0x0500
 #define WINVER 0x500
 #endif
+#include <winsock2.h>
 #include <windows.h>
 #include <windowsx.h>
 #include <commctrl.h>
@@ -207,6 +208,7 @@
 #ifdef AEROGLASS
 HRESULT (WINAPI *_DwmExtendFrameIntoClientArea)(HWND hWnd, const MARGINS *pMarInset) = 0;
 HRESULT (WINAPI *_DwmIsCompositionEnabled)(BOOL *pfEnabled) = 0;
+HRESULT (WINAPI *_DwmSetWindowAttribute)(HWND, DWORD, LPCVOID, DWORD) = 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;
@@ -223,6 +225,7 @@
  
 /* Needed for Rich Edit controls */
 HANDLE hrichedit = 0;
+HANDLE hmsftedit = 0;
 
 /*
  * MinGW Is missing a bunch of definitions
@@ -263,6 +266,9 @@
 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif
 
+#define _DW_DATA_TYPE_STRING  0
+#define _DW_DATA_TYPE_POINTER 1
+
 /*
  * For the dw*from_data() functions, a temporary file is required to write
  * the contents of the image to so it can be loaded by the Win32 API
@@ -302,7 +308,7 @@
 
 HFONT _DefaultFont = NULL;
 
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
 LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 #endif
 LRESULT CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
@@ -336,6 +342,7 @@
    HWND window;
    int id;
    void *signalfunction;
+   void *discfunction;
    void *data;
 
 } SignalHandler;
@@ -665,9 +672,217 @@
 }
 #endif
 
+#ifdef AEROGLASS
+/* Set _DW_DARK_MODE_ALLOWED to FALSE to disable dark mode.
+ * Set _DW_DARK_MODE_ALLOWED to TRUE for basic dark mode.
+ * Set _DW_DARK_MODE_ALLOWED to 2 for full dark mode.
+ */
+int _DW_DARK_MODE_ALLOWED = TRUE;
+int _DW_DARK_MODE_SUPPORTED = FALSE;
+int _DW_DARK_MODE_ENABLED = FALSE;
+
+typedef enum IMMERSIVE_HC_CACHE_MODE
+{
+   IHCM_USE_CACHED_VALUE,
+   IHCM_REFRESH
+} IMMERSIVE_HC_CACHE_MODE;
+
+typedef enum _PreferredAppMode
+{
+   _Default,
+   _AllowDark,
+   _ForceDark,
+   _ForceLight,
+   _Max
+} _PreferredAppMode;
+
+int CompareStringOrdinal(LPCWCH lpString1, int cchCount1, LPCWCH lpString2, int cchCount2, BOOL bIgnoreCase);
+HTHEME (WINAPI * _OpenNcThemeData)(HWND, LPCWSTR) = NULL; 
+VOID (WINAPI * _RefreshImmersiveColorPolicyState)(VOID) = NULL; 
+BOOL (WINAPI * _GetIsImmersiveColorUsingHighContrast)(IMMERSIVE_HC_CACHE_MODE) = NULL; 
+BOOL (WINAPI * _ShouldAppsUseDarkMode)(VOID) = NULL; 
+BOOL (WINAPI * _AllowDarkModeForWindow)(HWND, BOOL) = NULL;
+BOOL (WINAPI * _AllowDarkModeForApp)(BOOL) = NULL; 
+_PreferredAppMode (WINAPI * _SetPreferredAppMode)(_PreferredAppMode) = NULL; 
+BOOL (WINAPI * _IsDarkModeAllowedForWindow)(HWND) = NULL; 
+BOOL (WINAPI * _ShouldSystemUseDarkMode)(VOID) = NULL; 
+
+BOOL IsHighContrast(VOID)
+{
+   HIGHCONTRASTW highContrast = { sizeof(highContrast) };
+   if(SystemParametersInfoW(SPI_GETHIGHCONTRAST, sizeof(highContrast), &highContrast, FALSE))
+      return highContrast.dwFlags & HCF_HIGHCONTRASTON;
+   return FALSE;
+}
+
+void _dw_init_dark_mode(void)
+{
+   if(_DW_DARK_MODE_ALLOWED && dwVersion && huxtheme)
+   {
+      /* Dark mode is introduced in Windows 10 (1809) build 17763 */
+      if(LOBYTE(LOWORD(dwVersion)) >= 10 && HIWORD(dwVersion) >= 17763)
+      {
+         _OpenNcThemeData = (HTHEME (WINAPI *)(HWND, LPCWSTR))GetProcAddress(huxtheme, MAKEINTRESOURCEA(49));
+         _RefreshImmersiveColorPolicyState = (VOID (WINAPI *)(VOID))GetProcAddress(huxtheme, MAKEINTRESOURCEA(104));
+         _GetIsImmersiveColorUsingHighContrast = (BOOL (WINAPI *)(IMMERSIVE_HC_CACHE_MODE))GetProcAddress(huxtheme, MAKEINTRESOURCEA(106));
+         _ShouldAppsUseDarkMode = (BOOL (WINAPI *)(VOID))GetProcAddress(huxtheme, MAKEINTRESOURCEA(132));
+         _AllowDarkModeForWindow = (BOOL (WINAPI *)(HWND, BOOL))GetProcAddress(huxtheme, MAKEINTRESOURCEA(133));
+         if(HIWORD(dwVersion) < 18334)
+            _AllowDarkModeForApp = (BOOL (WINAPI *)(BOOL))GetProcAddress(huxtheme, MAKEINTRESOURCEA(135));
+         else
+            _SetPreferredAppMode = (_PreferredAppMode (WINAPI *)(_PreferredAppMode))GetProcAddress(huxtheme, MAKEINTRESOURCEA(135));
+         _IsDarkModeAllowedForWindow = (BOOL (WINAPI *)(HWND))GetProcAddress(huxtheme, MAKEINTRESOURCEA(137));
+         _ShouldSystemUseDarkMode = (BOOL (WINAPI *)(VOID))GetProcAddress(huxtheme, MAKEINTRESOURCEA(138));
+      }
+      /* Make sure we were able to load all the Dark Mode functions */
+      if(_OpenNcThemeData && _RefreshImmersiveColorPolicyState && _ShouldAppsUseDarkMode && _AllowDarkModeForWindow &&
+         (_AllowDarkModeForApp || _SetPreferredAppMode) && _IsDarkModeAllowedForWindow && _DwmSetWindowAttribute)
+      {
+         _DW_DARK_MODE_SUPPORTED = TRUE;
+         if(_AllowDarkModeForApp)
+            _AllowDarkModeForApp(TRUE);
+         else
+            _SetPreferredAppMode(_AllowDark);
+         _RefreshImmersiveColorPolicyState();
+         _DW_DARK_MODE_ENABLED = _ShouldAppsUseDarkMode() && !IsHighContrast();
+      }
+   }
+}
+
+BOOL _CanThemeWindow(HWND window)
+{
+   TCHAR tmpbuf[100] = {0};
+   LONG_PTR style = GetWindowLongPtr(window, GWL_STYLE);
+   
+   GetClassName(window, tmpbuf, 99);
+
+   /* Some controls don't display properly with visual styles enabled */
+   if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1) == 0 && 
+      (style & (BS_AUTOCHECKBOX | BS_CHECKBOX | BS_RADIOBUTTON)))
+      return FALSE;
+#ifdef TOOLBAR
+   else if(_tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0)
+   {
+     /* If we aren't in full dark mode */
+      if(_DW_DARK_MODE_ALLOWED != 2)
+      {
+         /* Enable or disable visual themes */
+         if(_SetWindowTheme)
+            _SetWindowTheme(window, (style & TBSTYLE_FLAT) ? L"" : NULL, (style & TBSTYLE_FLAT) ? L"" : NULL);
+      }
+      return FALSE;
+   }
+#endif
+   return TRUE;
+}
+
+BOOL AllowDarkModeForWindow(HWND window, BOOL allow)
+{
+   if(_DW_DARK_MODE_SUPPORTED)
+   {
+      if(_CanThemeWindow(window))
+      {
+         if(_DW_DARK_MODE_ALLOWED == 2)
+         {
+            if(_DW_DARK_MODE_ENABLED)
+               _SetWindowTheme(window, L"DarkMode_Explorer", NULL);
+            else
+               _SetWindowTheme(window, L"Explorer", NULL);
+         }
+      }
+      return _AllowDarkModeForWindow(window, allow);
+   }
+   return FALSE;
+}
+
+BOOL IsColorSchemeChangeMessage(LPARAM lParam)
+{
+   BOOL is = FALSE;
+   if(lParam && CompareStringOrdinal((LPCWCH)lParam, -1, L"ImmersiveColorSet", -1, TRUE) == CSTR_EQUAL)
+   {
+      _RefreshImmersiveColorPolicyState();
+      is = TRUE;
+   }
+   _GetIsImmersiveColorUsingHighContrast(IHCM_REFRESH);
+   return is;
+}
+
+void RefreshTitleBarThemeColor(HWND window)
+{
+   BOOL dark = FALSE;
+   if (_IsDarkModeAllowedForWindow(window) && _ShouldAppsUseDarkMode() && !IsHighContrast())
+      dark = TRUE;
+   _DwmSetWindowAttribute(window, 19, &dark, sizeof(dark));
+}
+
+/* Call this on a window to apply the style */
+BOOL CALLBACK _dw_set_child_window_theme(HWND window, LPARAM lParam)
+{
+   if(_DW_DARK_MODE_SUPPORTED)
+   {
+      AllowDarkModeForWindow(window, _DW_DARK_MODE_ENABLED);
+      SendMessageW(window, WM_THEMECHANGED, 0, 0);
+   }
+   return TRUE;
+}
+#endif
+
+/* Special wrappers for GetSysColor*() since they currently don't support 
+ * dark mode, we will have to return modified colors when dark mode is enabled.
+ */
+DWORD _DW_GetSysColor(int nIndex)
+{
+   DWORD retval = GetSysColor(nIndex);
+#ifdef AEROGLASS
+   if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED)
+   {
+      const COLORREF darkBkColor = 0x383838;
+      const COLORREF darkTextColor = 0xFFFFFF;
+   
+      switch(nIndex)
+      {
+         case COLOR_3DFACE:
+         case COLOR_WINDOW:
+            retval = darkBkColor;
+         break;
+         case COLOR_WINDOWTEXT:
+            retval = darkTextColor;
+         break;
+      }
+   }
+#endif
+   return retval;
+}
+
+HBRUSH _DW_GetSysColorBrush(int nIndex)
+{
+   HBRUSH retval = GetSysColorBrush(nIndex);
+#ifdef AEROGLASS
+   static HBRUSH darkBkColorBrush = 0;
+   
+   if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED)
+   {
+      if(!darkBkColorBrush)
+         darkBkColorBrush = CreateSolidBrush(0x383838);
+
+      switch(nIndex)
+      {
+         case COLOR_3DFACE:
+         case COLOR_WINDOW:
+            retval = darkBkColorBrush;
+         break;
+         case COLOR_WINDOWTEXT:
+            retval = _colors[DW_CLR_WHITE];
+         break;
+      }
+   }
+#endif
+   return retval;
+}
+
 /* This function adds a signal handler callback into the linked list.
  */
-void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *discfunc, void *data)
 {
    SignalHandler *new = malloc(sizeof(SignalHandler));
 
@@ -675,6 +890,7 @@
    new->window = window;
    new->id = id;
    new->signalfunction = signalfunction;
+   new->discfunction = discfunc;
    new->data = data;
    new->next = NULL;
 
@@ -917,6 +1133,9 @@
     */
    if(_tcsnicmp(tmpbuf, EDITCLASSNAME, _tcslen(EDITCLASSNAME)+1)==0 ||          /* Entryfield */
       _tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0 ||      /* Button */
+#ifdef TOOLBAR      
+      _tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0 ||  /* Toolbar */
+#endif      
       _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 */
@@ -924,6 +1143,9 @@
       _tcsnicmp(tmpbuf, WC_LISTVIEW, _tcslen(WC_LISTVIEW)+1)== 0 ||             /* Container */
       _tcsnicmp(tmpbuf, WC_TREEVIEW, _tcslen(WC_TREEVIEW)+1)== 0)               /* Tree */
       return 1;
+   /* Special case for the notebook, can get focus and contains other items */
+   if(_tcsnicmp(tmpbuf, WC_TABCONTROL, _tcslen(WC_TABCONTROL))==0)              /* Notebook */
+      return 2;
    return 0;
 }
 
@@ -949,11 +1171,47 @@
    return handle;
 }
 
-int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem)
+#define _DW_DIRECTION_FORWARD -1
+#define _DW_DIRECTION_BACKWARD 1
+
+int _focus_check_box(Box *box, HWND handle, int start, int direction, HWND defaultitem);
+
+/* Internal comparision function */
+int _focus_comp(int direction, int z, int end)
+{
+   if(direction == _DW_DIRECTION_FORWARD)
+      return z > -1;
+   return z < end;
+}
+
+int _focus_notebook(HWND hwnd, HWND handle, int start, int direction, HWND defaultitem)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(hwnd, "_dw_array");
+   int pageid = TabCtrl_GetCurSel(hwnd);
+
+   if(pageid > -1 && array && array[pageid])
+   {
+      Box *notebox;
+
+      if(array[pageid]->hwnd)
+      {
+         notebox = (Box *)GetWindowLongPtr(array[pageid]->hwnd, GWLP_USERDATA);
+
+         if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, direction, defaultitem))
+            return 1;
+      }
+   }
+   return 0;
+}
+
+/* Handle box focus traversal in either direction */
+int _focus_check_box(Box *box, HWND handle, int start, int direction, HWND defaultitem)
 {
    int z;
    static HWND lasthwnd, firsthwnd;
    static int finish_searching;
+   int beg = (direction == _DW_DIRECTION_FORWARD) ? box->count-1 : 0;
+   int end = (direction == _DW_DIRECTION_FORWARD) ? -1 : box->count;
 
    /* Start is 2 when we have cycled completely and
     * need to set the focus to the last widget we found
@@ -977,17 +1235,22 @@
       firsthwnd = 0;
    }
 
-   for(z=box->count-1;z>-1;z--)
+   for(z=beg;_focus_comp(direction, z, end);z+=direction)
    {
       if(box->items[z].type == TYPEBOX)
       {
          Box *thisbox = (Box *)GetWindowLongPtr(box->items[z].hwnd, GWLP_USERDATA);
 
-         if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+         if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
             return 1;
       }
       else
       {
+         int type = _validate_focus(box->items[z].hwnd);
+         
+         /* Special case notebook, can focus and contains items */
+         if(type == 2 && direction == _DW_DIRECTION_FORWARD && _focus_notebook(box->items[z].hwnd, handle, start, direction, defaultitem)) 
+            return 1;
          if(box->items[z].hwnd == handle)
          {
             if(lasthwnd == handle && firsthwnd)
@@ -1003,7 +1266,7 @@
             if(!finish_searching)
                return 1;
          }
-         if(_validate_focus(box->items[z].hwnd))
+         if(type > 0)
          {
             /* Start is 3 when we are looking for the
              * first valid item in the layout.
@@ -1017,13 +1280,14 @@
                }
             }
 
+            lasthwnd = _normalize_handle(box->items[z].hwnd);
+            
             if(!firsthwnd)
-               firsthwnd = _normalize_handle(box->items[z].hwnd);
-
-            lasthwnd = _normalize_handle(box->items[z].hwnd);
+               firsthwnd = lasthwnd;
          }
          else
          {
+            /* Handle controls that contain other items */
             TCHAR tmpbuf[100] = {0};
 
             GetClassName(box->items[z].hwnd, tmpbuf, 99);
@@ -1031,43 +1295,25 @@
             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");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
-
-                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-
-               /* Try the top or left box */
-               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_topleft");
+               HWND mybox = (HWND)dw_window_get_data(box->items[z].hwnd, (direction == _DW_DIRECTION_FORWARD) ? "_dw_bottomright" : "_dw_topleft");
 
                if(mybox)
                {
                   Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
 
-                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
                      return 1;
                }
-            }
-            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);
-
-               if(pageid > -1 && array && array[pageid])
+
+               /* Try the top or left box */
+               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, (direction == _DW_DIRECTION_FORWARD) ? "_dw_topleft" : "_dw_bottomright");
+
+               if(mybox)
                {
-                  Box *notebox;
-
-                  if(array[pageid]->hwnd)
-                  {
-                     notebox = (Box *)GetWindowLongPtr(array[pageid]->hwnd, GWLP_USERDATA);
-
-                     if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-                        return 1;
-                  }
+                  Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
+
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
+                     return 1;
                }
             }
             else if(_tcsnicmp(tmpbuf, ScrollClassName, _tcslen(ScrollClassName))==0) /* Scroll Box */
@@ -1075,146 +1321,14 @@
                 ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box->items[z].hwnd, GWLP_USERDATA);
                 Box *scrollbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
 
-                if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
+                if(scrollbox && _focus_check_box(scrollbox, handle, start == 3 ? 3 : 0, direction, defaultitem))
                    return 1;
             }
          }
-      }
-   }
-   return 0;
-}
-
-int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem)
-{
-   int z;
-   static HWND lasthwnd, firsthwnd;
-   static int finish_searching;
-
-   /* Start is 2 when we have cycled completely and
-    * need to set the focus to the last widget we found
-    * that was valid.
-    */
-   if(start == 2)
-   {
-      if(lasthwnd)
-         SetFocus(lasthwnd);
-      return 0;
-   }
-
-   /* Start is 1 when we are entering the function
-    * for the first time, it is zero when entering
-    * the function recursively.
-    */
-   if(start == 1)
-   {
-      lasthwnd = handle;
-      finish_searching = 0;
-      firsthwnd = 0;
-   }
-
-   for(z=0;z<box->count;z++)
-   {
-      if(box->items[z].type == TYPEBOX)
-      {
-         Box *thisbox = (Box *)GetWindowLongPtr(box->items[z].hwnd, GWLP_USERDATA);
-
-         if(thisbox && _focus_check_box_back(thisbox, handle, start == 3 ? 3 : 0, defaultitem))
+         /* Special case notebook, can focus and contains items */
+         if(type == 2 && direction == _DW_DIRECTION_BACKWARD && _focus_notebook(box->items[z].hwnd, handle, start, direction, defaultitem)) 
             return 1;
       }
-      else
-      {
-         if(box->items[z].hwnd == handle)
-         {
-            if(lasthwnd == handle && firsthwnd)
-               SetFocus(firsthwnd);
-            else if(lasthwnd == handle && !firsthwnd)
-               finish_searching = 1;
-            else
-               SetFocus(lasthwnd);
-
-            /* If we aren't looking for the last handle,
-             * return immediately.
-             */
-            if(!finish_searching)
-               return 1;
-         }
-         if(_validate_focus(box->items[z].hwnd))
-         {
-            /* Start is 3 when we are looking for the
-             * first valid item in the layout.
-             */
-            if(start == 3)
-            {
-               if(!defaultitem || (defaultitem && box->items[z].hwnd == defaultitem))
-               {
-                  SetFocus(_normalize_handle(box->items[z].hwnd));
-                  return 1;
-               }
-            }
-
-            if(!firsthwnd)
-               firsthwnd = _normalize_handle(box->items[z].hwnd);
-
-            lasthwnd = _normalize_handle(box->items[z].hwnd);
-         }
-         else
-         {
-            TCHAR tmpbuf[100] = {0};
-
-            GetClassName(box->items[z].hwnd, tmpbuf, 99);
-
-            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");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
-
-                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-
-               /* Then try the bottom or right box */
-               mybox = (HWND)dw_window_get_data(box->items[z].hwnd, "_dw_bottomright");
-
-               if(mybox)
-               {
-                  Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
-
-                  if(splitbox && _focus_check_box_back(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-                     return 1;
-               }
-            }
-            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);
-
-               if(pageid > -1 && array && array[pageid])
-               {
-                  Box *notebox;
-
-                  if(array[pageid]->hwnd)
-                  {
-                     notebox = (Box *)GetWindowLongPtr(array[pageid]->hwnd, GWLP_USERDATA);
-
-                     if(notebox && _focus_check_box_back(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-                        return 1;
-                  }
-               }
-            }
-            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);
-
-                if(scrollbox && _focus_check_box_back(scrollbox, handle, start == 3 ? 3 : 0, defaultitem))
-                   return 1;
-            }
-         }
-      }
    }
    return 0;
 }
@@ -1241,7 +1355,7 @@
 
    if(thisbox)
    {
-      _focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
+      _focus_check_box(thisbox, handle, 3, _DW_DIRECTION_FORWARD, thisbox->defaultitem);
    }
 }
 
@@ -1249,6 +1363,9 @@
 {
    HWND box, lastbox = GetParent(handle);
 
+   if(!lastbox)
+      lastbox = handle;
+      
    /* Find the toplevel window */
    while((box = GetParent(lastbox)))
    {
@@ -1272,7 +1389,7 @@
 /* This function finds the current widget in the
  * layout and moves the current focus to the next item.
  */
-void _shift_focus(HWND handle)
+void _shift_focus(HWND handle, int direction)
 {
    Box *thisbox;
 
@@ -1287,33 +1404,11 @@
    thisbox = (Box *)GetWindowLongPtr(lastbox, GWLP_USERDATA);
    if(thisbox)
    {
-      if(_focus_check_box(thisbox, handle, 1, 0)  == 0)
-         _focus_check_box(thisbox, handle, 2, 0);
-   }
-}
-
-/* This function finds the current widget in the
- * layout and moves the current focus to the next item.
- */
-void _shift_focus_back(HWND handle)
-{
-   Box *thisbox;
-
-   HWND box, lastbox = GetParent(handle);
-
-   /* Find the toplevel window */
-   while((box = GetParent(lastbox)))
-   {
-      lastbox = box;
-   }
-
-   thisbox = (Box *)GetWindowLongPtr(lastbox, GWLP_USERDATA);
-   if(thisbox)
-   {
-      if(_focus_check_box_back(thisbox, handle, 1, 0)  == 0)
-         _focus_check_box_back(thisbox, handle, 2, 0);
-   }
-}
+      if(_focus_check_box(thisbox, handle, 1, direction, 0)  == 0)
+         _focus_check_box(thisbox, handle, 2, direction, 0);
+   }
+}
+
 /* This function calculates how much space the widgets and boxes require
  * and does expansion as necessary.
  */
@@ -1608,7 +1703,7 @@
             {
                /* 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 type = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_type"));
 
                MoveWindow(handle, currentx + pad, currenty + pad,
                         width, height, FALSE);
@@ -1802,12 +1897,12 @@
    char buffer[40];
    int checkable;
    sprintf( buffer, "_dw_checkable%d", id );
-   checkable = (int)dw_window_get_data(DW_HWND_OBJECT, buffer);
+   checkable = DW_POINTER_TO_INT(dw_window_get_data(DW_HWND_OBJECT, buffer));
    if ( checkable )
    {
       int is_checked;
       sprintf( buffer, "_dw_ischecked%d", id );
-      is_checked = (int)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      is_checked = DW_POINTER_TO_INT(dw_window_get_data(DW_HWND_OBJECT, buffer));
       is_checked = (is_checked) ? DW_MIS_UNCHECKED : DW_MIS_CHECKED;
       dw_menu_item_set_state( window, id, is_checked );
    }
@@ -1818,7 +1913,7 @@
 {
    int result = -1, taskbar = FALSE;
    SignalHandler *tmp = Root;
-   void (*windowfunc)(PVOID);
+   void (DWSIGNAL *windowfunc)(PVOID);
    ULONG origmsg = msg;
 
    /* Deal with translating some messages */
@@ -1849,7 +1944,7 @@
                   {
                      if (!hWnd)
                      {
-                        int (*timerfunc)(void *) = tmp->signalfunction;
+                        int (DWSIGNAL *timerfunc)(void *) = tmp->signalfunction;
                         if (tmp->id == (int)mp1)
                         {
                            if (!timerfunc(tmp->data))
@@ -1864,7 +1959,7 @@
                   break;
                case WM_SETFOCUS:
                   {
-                     int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
+                     int (DWSIGNAL *setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
 
                      if(hWnd == tmp->window)
                      {
@@ -1875,7 +1970,7 @@
                   break;
                case WM_SIZE:
                   {
-                     int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
+                     int (DWSIGNAL *sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
                      if(hWnd == tmp->window)
                      {
                         result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data);
@@ -1885,7 +1980,7 @@
                   break;
                case WM_LBUTTONDOWN:
                   {
-                     int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+                     int (DWSIGNAL *buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
 
                      if(hWnd == tmp->window)
                      {
@@ -1920,7 +2015,7 @@
                   break;
                case WM_LBUTTONUP:
                   {
-                     int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+                     int (DWSIGNAL *buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
 
                      if(hWnd == tmp->window)
                      {
@@ -1956,7 +2051,7 @@
                case WM_MOUSEMOVE:
                   {
                      POINTS pts = MAKEPOINTS(mp2);
-                     int (*motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+                     int (DWSIGNAL *motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
 
                      if(hWnd == tmp->window)
                      {
@@ -1976,7 +2071,7 @@
                   break;
                case WM_CHAR:
                   {
-                     int (*keypressfunc)(HWND, char, int, int, void *, char *) = tmp->signalfunction;
+                     int (DWSIGNAL *keypressfunc)(HWND, char, int, int, void *, char *) = tmp->signalfunction;
 
                      if(hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window)
                      {
@@ -1986,7 +2081,7 @@
                         WCHAR uc[2] = { 0 };
                         
                         uc[0] = (WCHAR)mp1;
-                        utf8 = WideToUTF8(uc);
+                        utf8 = WideToUTF8(&uc[0]);
 #endif                        
                         
                         if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
@@ -2006,7 +2101,7 @@
                   break;
                case WM_CLOSE:
                   {
-                     int (*closefunc)(HWND, void *) = tmp->signalfunction;
+                     int (DWSIGNAL *closefunc)(HWND, void *) = tmp->signalfunction;
 
                      if(hWnd == tmp->window)
                      {
@@ -2019,7 +2114,7 @@
                   {
                      PAINTSTRUCT ps;
                      DWExpose exp;
-                     int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction;
+                     int (DWSIGNAL *exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction;
 
                      if ( hWnd == tmp->window )
                      {
@@ -2051,18 +2146,18 @@
                            {
                               if(tmp->window == tem->hdr.hwndFrom && !dw_window_get_data(tmp->window, "_dw_select_item"))
                               {
-                                 int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = tmp->signalfunction;
+                                 int (DWSIGNAL *treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = tmp->signalfunction;
                                  TVITEM tvi;
-                                 void **ptrs;
-
-                                 tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+                                 TCHAR textbuf[1025] = {0}, *textptr = textbuf;
+
+                                 tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT;
                                  tvi.hItem = tem->itemNew.hItem;
+                                 tvi.pszText = textbuf;
+                                 tvi.cchTextMax = 1024;
 
                                  TreeView_GetItem(tmp->window, &tvi);
 
-                                 ptrs = (void **)tvi.lParam;
-                                 if(ptrs)
-                                    result = treeselectfunc(tmp->window, tem->itemNew.hItem, (char *)ptrs[0], tmp->data, (void *)ptrs[1]);
+                                 result = treeselectfunc(tmp->window, tem->itemNew.hItem, WideToUTF8(textptr), tmp->data, (void *)tvi.lParam);
 
                                  tmp = NULL;
                               }
@@ -2071,7 +2166,7 @@
                            {
                               if(tmp->window == tem->hdr.hwndFrom && tem->action == TVE_EXPAND)
                               {
-                                 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = tmp->signalfunction;
+                                 int (DWSIGNAL *treeexpandfunc)(HWND, HTREEITEM, void *) = tmp->signalfunction;
 
                                  result = treeexpandfunc(tmp->window, tem->itemNew.hItem, tmp->data);
                                  tmp = NULL;
@@ -2081,12 +2176,13 @@
                            {
                               if(tmp->window == tem->hdr.hwndFrom)
                               {
-                                 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
+                                 int (DWSIGNAL *containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
                                  HTREEITEM hti;
                                  TVITEM tvi;
                                  TVHITTESTINFO thi;
-                                 void **ptrs = NULL;
+                                 void *itemdata = NULL;
                                  LONG x, y;
+                                 TCHAR textbuf[1025] = {0}, *textptr = textbuf;
 
                                  dw_pointer_query_pos(&x, &y);
 
@@ -2099,15 +2195,17 @@
 
                                  if(hti)
                                  {
-                                    tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+                                    tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_TEXT;
                                     tvi.hItem = hti;
+                                    tvi.pszText = textbuf;
+                                    tvi.cchTextMax = 1024;
 
                                     TreeView_GetItem(tmp->window, &tvi);
                                     TreeView_SelectItem(tmp->window, hti);
 
-                                    ptrs = (void **)tvi.lParam;
+                                    itemdata = (void *)tvi.lParam;
                                  }
-                                 containercontextfunc(tmp->window, ptrs ? (char *)ptrs[0] : NULL, x, y, tmp->data, ptrs ? ptrs[1] : NULL);
+                                 containercontextfunc(tmp->window, WideToUTF8(textptr), x, y, tmp->data, itemdata);
                                  tmp = NULL;
                               }
                            }
@@ -2127,18 +2225,17 @@
 
                                  if(iItem > -1)
                                  {
-                                    int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction;
+                                    int (DWSIGNAL *treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction;
+                                    void **params;
 
                                     lvi.iItem = iItem;
                                     lvi.mask = LVIF_PARAM;
 
                                     ListView_GetItem(tmp->window, &lvi);
 
-                                    /* Seems to be having lParam as 1 which really sucks */
-                                    if(lvi.lParam < 100)
-                                       lvi.lParam = 0;
-
-                                    treeselectfunc(tmp->window, 0, (char *)lvi.lParam, tmp->data, 0);
+                                    params = (void **)lvi.lParam;
+
+                                    treeselectfunc(tmp->window, 0, params ? (char *)params[_DW_DATA_TYPE_STRING] : NULL, tmp->data, params ? params[_DW_DATA_TYPE_POINTER] : NULL);
                                     tmp = NULL;
                                  }
                               }
@@ -2150,7 +2247,7 @@
                         NMHDR FAR *tem=(NMHDR FAR *)mp2;
                         if(tmp->window == tem->hwndFrom && tem->code == tmp->message)
                         {
-                           int (*switchpagefunc)(HWND, unsigned long, void *) = tmp->signalfunction;
+                           int (DWSIGNAL *switchpagefunc)(HWND, unsigned long, void *) = tmp->signalfunction;
                            unsigned long num=dw_notebook_page_get(tem->hwndFrom);
                            result = switchpagefunc(tem->hwndFrom, num, tmp->data);
                            tmp = NULL;
@@ -2161,7 +2258,7 @@
                         NMLISTVIEW FAR *tem=(NMLISTVIEW FAR *)mp2;
                         if(tmp->window == tem->hdr.hwndFrom && tem->hdr.code == tmp->message)
                         {
-                           int (*columnclickfunc)(HWND, int, void *) = tmp->signalfunction;
+                           int (DWSIGNAL *columnclickfunc)(HWND, int, void *) = tmp->signalfunction;
                            result = columnclickfunc(tem->hdr.hwndFrom, tem->iSubItem, tmp->data);
                            tmp = NULL;
                         }
@@ -2171,7 +2268,7 @@
                         NMUPDOWN FAR *tem=(NMUPDOWN FAR *)mp2;
                         if(tmp->window == tem->hdr.hwndFrom && tem->hdr.code == UDN_DELTAPOS)
                         {
-                           int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
+                           int (DWSIGNAL *valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
                            result = valuechangefunc(tmp->window, tem->iPos + tem->iDelta, tmp->data);
                            tmp = NULL;
                         }
@@ -2180,16 +2277,16 @@
                   break;
                case WM_COMMAND:
                   {
-                     int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+                     int (DWSIGNAL *clickfunc)(HWND, void *) = tmp->signalfunction;
                      HWND command;
                      ULONG passthru = (ULONG)LOWORD(mp1);
-                     ULONG message = HIWORD(mp1);
-
-                     command = (HWND)passthru;
+                     ULONG message = (ULONG)HIWORD(mp1);
+
+                     command = (HWND)(uintptr_t)passthru;
 
                      if (message == LBN_SELCHANGE || message == CBN_SELCHANGE)
                      {
-                        int (*listboxselectfunc)(HWND, int, void *) = tmp->signalfunction;
+                        int (DWSIGNAL *listboxselectfunc)(HWND, int, void *) = tmp->signalfunction;
 
                         if (tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2)
                         {
@@ -2222,13 +2319,13 @@
                            /*
                             * Call the user supplied callback
                             */
-                           result = clickfunc((HWND)tmp->id, tmp->data);
+                           result = clickfunc((HWND)(uintptr_t)tmp->id, tmp->data);
                            tmp = NULL;
                         }
                      } /* this fires for checkable menu items */
                      else if ( tmp->window < (HWND)65536 && command == tmp->window && tmp->message != WM_TIMER )
                      {
-                        _dw_toggle_checkable_menu_item( popup ? popup : tmp->window, (int)tmp->data );
+                        _dw_toggle_checkable_menu_item( popup ? popup : tmp->window, DW_POINTER_TO_INT(tmp->data) );
                         result = clickfunc(popup ? popup : tmp->window, tmp->data);
                         tmp = NULL;
                      }
@@ -2239,7 +2336,7 @@
                   {
                      TCHAR tmpbuf[100] = {0};
                      HWND handle = (HWND)mp2;
-                     int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
+                     int (DWSIGNAL *valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
 
                      if(!GetClassName(handle, tmpbuf, 99))
                      {
@@ -2309,8 +2406,20 @@
          }
       }
       break;
+   case WM_SETTINGCHANGE:
+   {
+      if(_DW_DARK_MODE_SUPPORTED && IsColorSchemeChangeMessage(mp2))
+      {
+         _DW_DARK_MODE_ENABLED = _ShouldAppsUseDarkMode() && !IsHighContrast();
+
+         RefreshTitleBarThemeColor(hWnd);
+         _dw_set_child_window_theme(hWnd, 0);
+         EnumChildWindows(hWnd, _dw_set_child_window_theme, 0);
+      }
+   }
+   break;
 #endif
-#ifdef AEROGLASS1      
+#ifdef AEROGLASS1
    case WM_ERASEBKGND: 
       if(_dw_composition && (GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED))
       {
@@ -2325,7 +2434,7 @@
          return TRUE;
       }
       break;
-#endif      
+#endif
    case WM_PAINT:
       {
          PAINTSTRUCT ps;
@@ -2390,6 +2499,28 @@
 
             _resize_notebook_page(tem->hwndFrom, num);
          }
+         else if(tem->code == LVN_DELETEITEM)
+         {
+            NMLISTVIEW FAR *lem=(NMLISTVIEW FAR *)mp2;
+            LV_ITEM lvi;
+            void **params;
+
+            memset(&lvi, 0, sizeof(LV_ITEM));
+
+            lvi.iItem = lem->iItem;
+            lvi.mask = LVIF_PARAM;
+
+            ListView_GetItem(lem->hdr.hwndFrom, &lvi);
+            params = (void **)lvi.lParam;
+
+            /* Free row data */
+            if(params)
+            {
+               if(params[_DW_DATA_TYPE_STRING])
+                  free(params[_DW_DATA_TYPE_STRING]);
+               free(params);
+            }
+         }
       }
       break;
    case WM_HSCROLL:
@@ -2487,7 +2618,14 @@
    case WM_MOUSEMOVE:
       _wndproc(hWnd, msg, mp1, mp2);
       break;
-#ifdef AEROGLASS   
+#ifdef AEROGLASS
+   case WM_THEMECHANGED:
+      if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_SUPPORTED)
+      {
+         SetClassLongPtr(hWnd, GCLP_HBRBACKGROUND, (LONG_PTR)_DW_GetSysColorBrush(COLOR_3DFACE));
+         InvalidateRect(hWnd, NULL, TRUE);
+      }
+      break;
    case WM_ERASEBKGND: 
       if(_dw_composition && (GetWindowLongPtr(_toplevel_window(hWnd), GWL_EXSTYLE) & WS_EX_LAYERED))
       {
@@ -2727,7 +2865,11 @@
    /* These are the window classes which can
     * obtain input focus.
     */
-   if (_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0)
+   if (_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0
+#ifdef TOOLBAR      
+    || _tcsnicmp(tmpbuf, TOOLBARCLASSNAME, _tcslen(TOOLBARCLASSNAME)+1) == 0
+#endif
+      )
    {
       /* Generate click on default item */
       SignalHandler *tmp = Root;
@@ -2740,7 +2882,7 @@
             /* Make sure it's the right window, and the right ID */
             if (tmp->window == handle)
             {
-               int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+               int (DWSIGNAL *clickfunc)(HWND, void *) = tmp->signalfunction;
                clickfunc(tmp->window, tmp->data);
                tmp = NULL;
             }
@@ -2835,20 +2977,20 @@
             if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
             {
                if (cinfo->combo)
-                  _shift_focus_back(cinfo->combo);
+                  _shift_focus(cinfo->combo, _DW_DIRECTION_BACKWARD);
                else if(cinfo->buddy)
-                  _shift_focus_back(cinfo->buddy);
+                  _shift_focus(cinfo->buddy, _DW_DIRECTION_BACKWARD);
                else
-                  _shift_focus_back(hWnd);
+                  _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
             }
             else
             {
                if (cinfo->combo)
-                  _shift_focus(cinfo->combo);
+                  _shift_focus(cinfo->combo, _DW_DIRECTION_FORWARD);
                else if(cinfo->buddy)
-                  _shift_focus(cinfo->buddy);
+                  _shift_focus(cinfo->buddy, _DW_DIRECTION_FORWARD);
                else
-                  _shift_focus(hWnd);
+                  _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
             }
             return FALSE;
          }
@@ -2858,6 +3000,7 @@
             if ( cinfo->clickdefault )
             {
                _click_default(cinfo->clickdefault);
+               return (LRESULT)TRUE;
             }
             else
             {
@@ -2870,6 +3013,7 @@
                if ( mycinfo && mycinfo->clickdefault )
                {
                   _click_default( mycinfo->clickdefault );
+                  return (LRESULT)TRUE;
                }
             }
          }
@@ -2904,6 +3048,18 @@
       case WM_CTLCOLORDLG:
          {
             ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
+            
+            if(msg == WM_CTLCOLORBTN)
+            {
+               /* Groupbox color info is on the frame window it is attached to */
+               if(GetWindowLongPtr((HWND)mp2, GWL_STYLE) & BS_GROUPBOX)
+               {
+                  Box *framebox = (Box *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+                  if(framebox)
+                     thiscinfo = &framebox->cinfo;
+               }
+            }
+            
             if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
             {
                int thisback = thiscinfo->back;
@@ -2912,11 +3068,15 @@
                if(thiscinfo->fore != DW_CLR_DEFAULT)
                {
                   int fore = _internal_color(thiscinfo->fore);
-               
+
                   SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(fore),
                                        DW_GREEN_VALUE(fore),
                                        DW_BLUE_VALUE(fore)));
                }
+#ifdef AEROGLASS
+               else if(thiscinfo->fore == DW_CLR_DEFAULT && _DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED)
+                  SetTextColor((HDC)mp1, _DW_GetSysColor(COLOR_WINDOWTEXT));
+#endif
                /* Handle background */
                if(thiscinfo->back == DW_RGB_TRANSPARENT)
                {
@@ -2927,12 +3087,12 @@
                }
                if(thisback == DW_CLR_DEFAULT)
                {
-                  HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
-
-                  SetBkColor((HDC)mp1, GetSysColor(COLOR_3DFACE));
+                  HBRUSH hbr = _DW_GetSysColorBrush(COLOR_3DFACE);
+
+                  SetBkColor((HDC)mp1, _DW_GetSysColor(COLOR_3DFACE));
 
                   SelectObject((HDC)mp1, hbr);
-                  return (LONG)hbr;
+                  return (LRESULT)(intptr_t)hbr;
                }
                else if(thisback != -1 && thisback != DW_RGB_TRANSPARENT)
                {
@@ -2947,10 +3107,11 @@
                                                  DW_GREEN_VALUE(back),
                                                  DW_BLUE_VALUE(back)));
                   SelectObject((HDC)mp1, thiscinfo->hbrush);
-                  return (LONG)thiscinfo->hbrush;
+                  return (LRESULT)(intptr_t)thiscinfo->hbrush;
                }
             }
  #ifdef AEROGLASS
+            /* First handle the transparent or layered cases */
             switch(msg)
             {
                case WM_CTLCOLORSTATIC:
@@ -2968,11 +3129,44 @@
                               DeleteObject(thiscinfo->hbrush);
                            thiscinfo->hbrush = CreateSolidBrush(_dw_transparencykey);
                            SelectObject((HDC)mp1, thiscinfo->hbrush);
-                           return (LONG)thiscinfo->hbrush;
+                           return (LRESULT)thiscinfo->hbrush;
                         }
                      }
                   }
             }
+            /* Second we handle the dark mode cases */
+            switch(msg)
+            {
+               case WM_CTLCOLORSTATIC:
+               case WM_CTLCOLORLISTBOX:
+               case WM_CTLCOLORBTN:
+               case WM_CTLCOLOREDIT:
+               case WM_CTLCOLORMSGBOX:
+               case WM_CTLCOLORSCROLLBAR:
+               case WM_CTLCOLORDLG:
+               {
+                  if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED)
+                  {
+                     ColorInfo *parentcinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+                     int thisback = thiscinfo ? thiscinfo->back : -1;
+                     
+                     if(thisback == DW_RGB_TRANSPARENT && parentcinfo)
+                        thisback = parentcinfo->back;
+
+                     if(!thiscinfo || (thiscinfo && (thiscinfo->fore == DW_CLR_DEFAULT || thiscinfo->fore == -1)))
+                        SetTextColor((HDC)mp1, _DW_GetSysColor(COLOR_WINDOWTEXT));
+                     if(!thiscinfo || (thiscinfo && (thisback == DW_CLR_DEFAULT || thisback == -1 || thisback == DW_RGB_TRANSPARENT)))
+                     {
+                        HBRUSH hbr = _DW_GetSysColorBrush(COLOR_3DFACE);
+
+                        SetBkColor((HDC)mp1, _DW_GetSysColor(COLOR_3DFACE));
+
+                        SelectObject((HDC)mp1, hbr);
+                        return (LRESULT)(intptr_t)hbr;
+                     }
+                  }
+               }
+            }
 #endif
          }
          break;
@@ -3000,12 +3194,47 @@
    case WM_MOUSEMOVE:
       _wndproc(hWnd, msg, mp1, mp2);
       break;
+#ifdef AEROGLASS
+   case WM_THEMECHANGED:
+      if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_SUPPORTED)
+      {
+         if(!continfo || continfo->cinfo.back == -1 || continfo->cinfo.back == DW_CLR_DEFAULT)
+         {
+            COLORREF bk = _DW_GetSysColor(COLOR_WINDOW);
+
+            ListView_SetBkColor(hWnd, bk);
+            ListView_SetTextBkColor(hWnd, bk);
+         }
+         if(!continfo || continfo->cinfo.fore == -1 || continfo->cinfo.fore == DW_CLR_DEFAULT)
+            ListView_SetTextColor(hWnd, _DW_GetSysColor(COLOR_WINDOWTEXT));
+      }
+      break;
+#endif
    case WM_PAINT:
        if(continfo->cinfo.pOldProc && (continfo->even != DW_RGB_TRANSPARENT || continfo->odd != DW_RGB_TRANSPARENT))
        {
             RECT rectUpd, rectDestin, rectThis, *rect = &rectThis;
             int iItems, iTop, i;
-            COLORREF c;
+            COLORREF c, odd, even;
+            unsigned long temp = _internal_color(continfo->odd);
+            
+            /* Create the colors based on the current theme */
+            if(continfo->odd == DW_CLR_DEFAULT)
+            {
+#ifdef AEROGLASS
+               if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED)
+                  odd = RGB(100,100,100);
+               else
+#endif              
+                  odd = RGB(230, 230, 230);
+            }
+            else 
+                  odd = RGB(DW_RED_VALUE(temp), DW_GREEN_VALUE(temp), DW_BLUE_VALUE(temp));
+            temp = _internal_color(continfo->even);
+            if(continfo->even == DW_CLR_DEFAULT)
+               even = DW_RGB_TRANSPARENT;
+            else
+               even = RGB(DW_RED_VALUE(temp), DW_GREEN_VALUE(temp), DW_BLUE_VALUE(temp));
 
             /* Load the default background color for the first pass */
             ListView_SetTextBkColor(hWnd, continfo->cinfo.back != -1 ? continfo->cinfo.back : ListView_GetBkColor(hWnd));
@@ -3024,7 +3253,7 @@
                 if(ListView_GetItemRect(hWnd, i, rect, LVIR_BOUNDS) && IntersectRect(&rectDestin, &rectUpd, rect)) 
                 {
                     /* change text background colour accordingly */
-                    c = (i % 2) ? continfo->odd : continfo->even;
+                    c = (i % 2) ? odd : even;
 
                     if(c != DW_RGB_TRANSPARENT)
                     {
@@ -3043,13 +3272,14 @@
       {
          LV_ITEM lvi;
          int iItem;
+         void **params = NULL;
 
          if(LOWORD(mp1) == '\t')
          {
             if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-               _shift_focus_back(hWnd);
+               _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
             else
-               _shift_focus(hWnd);
+               _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
             return FALSE;
          }
 
@@ -3066,6 +3296,7 @@
             lvi.mask = LVIF_PARAM;
 
             ListView_GetItem(hWnd, &lvi);
+            params = (void **)lvi.lParam;
          }
 
          {
@@ -3075,13 +3306,9 @@
             {
                if(tmp->message == NM_DBLCLK && tmp->window == hWnd)
                {
-                  int (*containerselectfunc)(HWND, char *, void *) = tmp->signalfunction;
-
-                  /* Seems to be having lParam as 1 which really sucks */
-                  if(lvi.lParam < 100)
-                     lvi.lParam = 0;
-
-                  containerselectfunc(tmp->window, (char *)lvi.lParam, tmp->data);
+                  int (DWSIGNAL *containerselectfunc)(HWND, char *, void *, void *) = tmp->signalfunction;
+
+                  containerselectfunc(tmp->window, params ? params[_DW_DATA_TYPE_STRING] : NULL, tmp->data, params ? params[_DW_DATA_TYPE_POINTER] : NULL);
                   tmp = NULL;
                }
                if(tmp)
@@ -3093,16 +3320,17 @@
    case WM_CONTEXTMENU:
       {
          SignalHandler *tmp = Root;
-
+         void **params = NULL;
          while(tmp)
          {
             if(tmp->message == NM_RCLICK && tmp->window == hWnd)
             {
-               int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
+               int (DWSIGNAL *containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
                LONG x,y;
                LV_ITEM lvi;
                int iItem;
                LVHITTESTINFO lhi;
+               TCHAR textbuf[1025] = {0};
 
                dw_pointer_query_pos(&x, &y);
 
@@ -3118,17 +3346,16 @@
                if(iItem > -1)
                {
                   lvi.iItem = iItem;
-                  lvi.mask = LVIF_PARAM;
+                  lvi.pszText = textbuf;
+                  lvi.cchTextMax = 1024;
+                  lvi.mask = LVIF_PARAM | LVIF_TEXT;
 
                   ListView_GetItem(tmp->window, &lvi);
                   ListView_SetSelectionMark(tmp->window, iItem);
+                  params = (void **)lvi.lParam;
                }
 
-               /* Seems to be having lParam as 1 which really sucks */
-               if(lvi.lParam < 100)
-                  lvi.lParam = 0;
-
-               containercontextfunc(tmp->window, (char *)lvi.lParam, x, y, tmp->data, NULL);
+               containercontextfunc(tmp->window, params ? params[_DW_DATA_TYPE_STRING] : NULL, x, y, tmp->data, (void *)lvi.lParam);
                tmp = NULL;
             }
             if(tmp)
@@ -3143,7 +3370,7 @@
    return CallWindowProc(continfo->cinfo.pOldProc, hWnd, msg, mp1, mp2);
 }
 
-LRESULT CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+LRESULT CALLBACK _simplewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
 {
    ContainerInfo *cinfo;
    LRESULT ret = -1;
@@ -3160,9 +3387,9 @@
       if(ret != TRUE && LOWORD(mp1) == '\t')
       {
          if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-            _shift_focus_back(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_BACKWARD);
          else
-            _shift_focus(hWnd);
+            _shift_focus(hWnd, _DW_DIRECTION_FORWARD);
          return FALSE;
       }
       break;
@@ -3177,6 +3404,25 @@
    return ret;
 }
 
+LRESULT CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+#ifdef AEROGLASS
+   if(msg == WM_THEMECHANGED)
+   {
+      if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_SUPPORTED)
+      {
+         ContainerInfo *continfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+         
+         if(!continfo || continfo->cinfo.back == -1 || continfo->cinfo.back == DW_CLR_DEFAULT)
+            TreeView_SetBkColor(hWnd, _DW_GetSysColor(COLOR_WINDOW));
+         if(!continfo || continfo->cinfo.fore == -1 || continfo->cinfo.fore == DW_CLR_DEFAULT)
+            TreeView_SetTextColor(hWnd, _DW_GetSysColor(COLOR_WINDOWTEXT));
+      }
+   }
+#endif
+   return _simplewndproc(hWnd, msg, mp1, mp2);
+}
+
 void _changebox(Box *thisbox, int percent, int type)
 {
    int z;
@@ -3230,7 +3476,7 @@
       MoveWindow(handle2, x - newx, 0, newx, y, FALSE);
       _do_resize(tmp, newx - 1, y - 1);
 
-      dw_window_set_data(hwnd, "_dw_start", (void *)newx);
+      dw_window_set_data(hwnd, "_dw_start", DW_INT_TO_POINTER(newx));
    }
    else
    {
@@ -3250,7 +3496,7 @@
       MoveWindow(handle1, 0, 0, x, newy, FALSE);
       _do_resize(tmp, x - 1, newy - 1);
 
-      dw_window_set_data(hwnd, "_dw_start", (void *)newy);
+      dw_window_set_data(hwnd, "_dw_start", DW_INT_TO_POINTER(newy));
    }
 
    ShowWindow(handle1, SW_SHOW);
@@ -3333,21 +3579,26 @@
    case WM_ACTIVATE:
    case WM_SETFOCUS:
       return FALSE;
-
+#ifdef AEROGLASS
+   case WM_THEMECHANGED:
+      if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_SUPPORTED)
+         InvalidateRect(hwnd, NULL, TRUE);
+      break;
+#endif
    case WM_PAINT:
       {
          PAINTSTRUCT ps;
          HDC hdcPaint;
-         int type = (int)dw_window_get_data(hwnd, "_dw_type");
-         int start = (int)dw_window_get_data(hwnd, "_dw_start");
+         int type = DW_POINTER_TO_INT(dw_window_get_data(hwnd, "_dw_type"));
+         int start = DW_POINTER_TO_INT(dw_window_get_data(hwnd, "_dw_start"));
 
          BeginPaint(hwnd, &ps);
 
          if((hdcPaint = GetDC(hwnd)) != NULL)
          {
             unsigned long cx, cy;
-            HBRUSH oldBrush = SelectObject(hdcPaint, GetSysColorBrush(COLOR_3DFACE));
-            HPEN oldPen = SelectObject(hdcPaint, CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DFACE)));
+            HBRUSH oldBrush = SelectObject(hdcPaint, _DW_GetSysColorBrush(COLOR_3DFACE));
+            HPEN oldPen = SelectObject(hdcPaint, CreatePen(PS_SOLID, 1, _DW_GetSysColor(COLOR_3DFACE)));
 
             dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
 
@@ -3377,7 +3628,7 @@
    case WM_MOUSEMOVE:
       {
          float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
-         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int type = DW_POINTER_TO_INT(dw_window_get_data(hwnd, "_dw_type"));
          int start;
 
          if(type == DW_HORZ)
@@ -3440,6 +3691,12 @@
          InvalidateRgn(hwnd, NULL, TRUE);
          return ret;
       }
+#ifdef AEROGLASS
+   case WM_THEMECHANGED:
+      if(_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_SUPPORTED)
+         InvalidateRect(hwnd, NULL, TRUE);
+      break;
+#endif
    case WM_PAINT:
       {
          HDC hdcPaint;
@@ -3457,10 +3714,40 @@
          hdcPaint = BeginPaint(hwnd, &ps);
          if(hfont)
             oldfont = (HFONT)SelectObject(hdcPaint, hfont);
-         rc.top = rc.left = 0;
-         rc.right = cx;
-         rc.bottom = cy;
-         DrawStatusText(hdcPaint, &rc, tempbuf, 0);
+         
+         SetRect(&rc, 0, 0, cx, cy);
+         
+         /* If we are in full dark mode, or we have custom colors selected...
+          * we will draw the status window ourselves... otherwise DrawStatusText()
+          */
+         if(
+#ifdef AEROGLASS
+            (_DW_DARK_MODE_ALLOWED == 2 && _DW_DARK_MODE_ENABLED) ||
+#endif
+            (cinfo && cinfo->fore != -1 && cinfo->fore != DW_CLR_DEFAULT &&
+             cinfo->back !=- -1 && cinfo->back != DW_CLR_DEFAULT))
+         {
+            ULONG fore = (cinfo && (cinfo->fore != -1 && cinfo->fore != DW_CLR_DEFAULT)) ? _internal_color(cinfo->fore) : DW_RGB_TRANSPARENT;
+            ULONG back = (cinfo && (cinfo->back != -1 && cinfo->back != DW_CLR_DEFAULT)) ? _internal_color(cinfo->back) : DW_RGB_TRANSPARENT;
+            HBRUSH hbrback, hbrfore;
+            hbrfore = fore != DW_RGB_TRANSPARENT ? CreateSolidBrush(RGB(DW_RED_VALUE(fore), DW_GREEN_VALUE(fore), DW_BLUE_VALUE(fore))) : NULL;
+            hbrback = back != DW_RGB_TRANSPARENT ? CreateSolidBrush(RGB(DW_RED_VALUE(back), DW_GREEN_VALUE(back), DW_BLUE_VALUE(back))) : NULL;
+            /* Fill with the background color */
+            FillRect(hdcPaint, &rc, hbrback ? hbrback : _DW_GetSysColorBrush(COLOR_3DFACE));
+            /* Dwaw a border around it */
+            FrameRect(hdcPaint, &rc, hbrfore ? hbrfore : _DW_GetSysColorBrush(COLOR_WINDOWTEXT));
+            SetRect(&rc, 3, 1, cx -1, cy - 1);
+            SetTextColor(hdcPaint, fore != DW_RGB_TRANSPARENT ? RGB(DW_RED_VALUE(fore), DW_GREEN_VALUE(fore), DW_BLUE_VALUE(fore)) : _DW_GetSysColor(COLOR_WINDOWTEXT));
+            SetBkMode(hdcPaint, TRANSPARENT);
+            /* Draw the text in the middle */
+            ExtTextOut(hdcPaint, 3, 1, ETO_CLIPPED, &rc, tempbuf, (UINT)_tcslen(tempbuf), NULL);
+            if(hbrfore)
+               DeleteObject(hbrfore);
+            if(hbrback)
+               DeleteObject(hbrback);
+         }
+         else
+            DrawStatusText(hdcPaint, &rc, tempbuf, 0);
          if(hfont && oldfont)
             SelectObject(hdcPaint, oldfont);
          if(hfont)
@@ -3656,7 +3943,7 @@
          {
             if(tmp->message == WM_COMMAND)
             {
-               int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+               int (DWSIGNAL *clickfunc)(HWND, void *) = tmp->signalfunction;
 
                /* Make sure it's the right window, and the right ID */
                if(tmp->window == hwnd)
@@ -3692,7 +3979,7 @@
             {
                if(tmp->message == WM_COMMAND)
                {
-                  int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+                  int (DWSIGNAL *clickfunc)(HWND, void *) = tmp->signalfunction;
 
                   /* Make sure it's the right window, and the right ID */
                   if(tmp->window == hwnd)
@@ -3708,18 +3995,18 @@
          if(LOWORD(mp1) == '\t')
          {
             if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-               _shift_focus_back(hwnd);
+               _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
             else
-               _shift_focus(hwnd);
+               _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
             return FALSE;
          }
       }
       break;
    case WM_KEYDOWN:
       if(mp1 == VK_LEFT || mp1 == VK_UP)
-         _shift_focus_back(hwnd);
+         _shift_focus(hwnd, _DW_DIRECTION_BACKWARD);
       if(mp1 == VK_RIGHT || mp1 == VK_DOWN)
-         _shift_focus(hwnd);
+         _shift_focus(hwnd, _DW_DIRECTION_FORWARD);
       break;
    }
 
@@ -3850,27 +4137,6 @@
 }
 #endif
 
-/* Initialize thread local values to the defaults */
-void _init_thread(void)
-{
-    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));
-    TlsSetValue(_hBrush, CreateSolidBrush(foreground));
-}
-
 /*
  * Initializes the Dynamic Windows engine.
  * Parameters:
@@ -3920,6 +4186,37 @@
 
    memset(lookup, 0, sizeof(HICON) * ICON_INDEX_LIMIT);
 
+   /* We need the version to check capability like up-down controls */
+   dwVersion = GetVersion();
+   dwComctlVer = GetDllVersion(TEXT("comctl32.dll"));
+
+   /* We need to initialize dark mode, and thus the aero/theme subsystems before registering our window classes */
+   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");
+      _DwmSetWindowAttribute = (HRESULT (WINAPI *)(HWND, DWORD, LPCVOID, DWORD))GetProcAddress(hdwm, "DwmSetWindowAttribute");
+      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");
+      _dw_init_dark_mode();
+   }
+   /* In case of error close the library if needed */
+   else if(hdwm)
+   {
+      FreeLibrary(hdwm);
+      hdwm = 0;
+   }
+#endif
+
    /* Register the generic Dynamic Windows class */
    memset(&wc, 0, sizeof(WNDCLASS));
    wc.style = CS_DBLCLKS;
@@ -3962,7 +4259,7 @@
    wc.lpfnWndProc = (WNDPROC)_framewndproc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 32;
-   wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
+   wc.hbrBackground = (HBRUSH)_DW_GetSysColorBrush(COLOR_3DFACE);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = FRAMECLASSNAME;
@@ -3975,14 +4272,14 @@
    wc.lpfnWndProc = (WNDPROC)_statuswndproc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 32;
-   wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
+   wc.hbrBackground = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = StatusbarClassName;
 
    RegisterClass(&wc);
 
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
    /* Register HTML renderer class */
    memset(&wc, 0, sizeof(WNDCLASS));
    wc.lpfnWndProc = (WNDPROC)_browserWindowProc;
@@ -4036,10 +4333,6 @@
    /* Create empty box data */
    SetWindowLongPtr(DW_HWND_OBJECT, GWLP_USERDATA, (LONG_PTR)calloc(sizeof(Box), 1));
 
-   /* We need the version to check capability like up-down controls */
-   dwVersion = GetVersion();
-   dwComctlVer = GetDllVersion(TEXT("comctl32.dll"));
-
    /* Initialize Security for named events and memory */
    InitializeSecurityDescriptor(&_dwsd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&_dwsd, TRUE, (PACL) NULL, FALSE);
@@ -4067,36 +4360,16 @@
    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
+   /* GDI+ Needs to be initialized before calling _dw_init_thread(); */
+   _dw_init_thread();
+
 #ifdef RICHEDIT
-   /* Attempt to load rich edit library */
-   if(!(hrichedit = LoadLibrary("riched20")))
-      hrichedit = LoadLibrary("riched32");
+   /* Attempt to load rich edit library: 4.1, 3/2.0 and 1.0 */
+   if(!(hmsftedit = LoadLibrary(TEXT("msftedit"))))
+   {
+      if(!(hrichedit = LoadLibrary(TEXT("riched20"))))
+         hrichedit = LoadLibrary(TEXT("riched32"));
+   }
 #endif      
    return 0;
 }
@@ -4242,6 +4515,9 @@
    MSG msg;
    void *tmp;
 
+   if(!dialog)
+      return NULL;
+
    while (GetMessage(&msg,NULL,0,0))
    {
       if(msg.hwnd == NULL && msg.message == WM_TIMER)
@@ -4347,6 +4623,17 @@
    int rc;
    RECT rect;
    
+#ifdef AEROGLASS
+   if(_DW_DARK_MODE_SUPPORTED)
+   {
+      /* Try to enable dark mode support if our OS supports it */
+      _dw_set_child_window_theme(handle, 0);
+      EnumChildWindows(handle, _dw_set_child_window_theme, 0);
+      if(GetParent(handle) == HWND_DESKTOP)
+         RefreshTitleBarThemeColor(handle);
+   }
+#endif
+   
    GetClientRect(handle, &rect);
    
    /* If the client area is 0x0 then call the autosize routine */
@@ -4383,7 +4670,7 @@
    if(handle < (HWND)65536)
    {
       char buffer[31] = {0};
-      ULONG id = (ULONG)handle;
+      ULONG id = (ULONG)(uintptr_t)handle;
       
       _snprintf(buffer, 30, "_dw_id%ld", id);
       menu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
@@ -4726,7 +5013,8 @@
    }
    /* Entryfields and MLE */
    else if(_tcsnicmp(tmpbuf, EDITCLASSNAME, _tcslen(EDITCLASSNAME)+1) == 0 ||
-           _tcsnicmp(tmpbuf, RICHEDIT_CLASS, _tcslen(RICHEDIT_CLASS)+1) == 0)
+           _tcsnicmp(tmpbuf, RICHEDIT_CLASS, _tcslen(RICHEDIT_CLASS)+1) == 0 ||
+           _tcsnicmp(tmpbuf, MSFTEDIT_CLASS, _tcslen(MSFTEDIT_CLASS)+1) == 0)
    {
       LONG style = GetWindowLong(handle, GWL_STYLE);
       if((style & ES_MULTILINE))
@@ -5008,7 +5296,7 @@
             italic = " Italic";
          height = MulDiv(abs(lf.lfHeight), 72,  GetDeviceCaps (hdc, LOGPIXELSY));
          ReleaseDC(handle, 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 );
       }
    }
    if ( oldfont )
@@ -5117,13 +5405,13 @@
  */
 void API dw_window_set_pointer(HWND handle, int pointertype)
 {
-   HCURSOR cursor = pointertype < 65536 ? LoadCursor(NULL, MAKEINTRESOURCE(pointertype)) : (HCURSOR)pointertype;
+   HCURSOR cursor = pointertype < 65536 ? LoadCursor(NULL, MAKEINTRESOURCE(pointertype)) : (HCURSOR)(intptr_t)pointertype;
 
    if(!pointertype)
       dw_window_set_data(handle, "_dw_cursor", 0);
     else
    {
-      dw_window_set_data(handle, "_dw_cursor", (void *)cursor);
+      dw_window_set_data(handle, "_dw_cursor", DW_POINTER(cursor));
       SetCursor(cursor);
    }
 }
@@ -5337,7 +5625,12 @@
                             DWInstance,
                             NULL);
 
+   /* Disable visual styles by default */
+   if(_SetWindowTheme)
+      _SetWindowTheme(newbox->grouphwnd, L"", L"");
+
    SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
+   newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc);
    dw_window_set_font(hwndframe, DefaultFont);
    return hwndframe;
 }
@@ -5360,7 +5653,7 @@
                       WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
                       0,0,0,0,
                       DW_HWND_OBJECT,
-                      (HMENU)id,
+                      (HMENU)(uintptr_t)id,
                       DWInstance,
                       &ccs);
    return hwndframe;
@@ -5373,13 +5666,13 @@
  */
 HWND API dw_html_new(unsigned long id)
 {
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
    return CreateWindow(BrowserClassName,
                   NULL,
                   WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
                   0,0,0,0,
                   DW_HWND_OBJECT,
-                  (HMENU)id,
+                  (HMENU)(uintptr_t)id,
                   DWInstance,
                   NULL);
 #else
@@ -5388,7 +5681,7 @@
 #endif
 }
 
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
 void _dw_html_action(HWND hwnd, int action);
 int _dw_html_raw(HWND hwnd, char *string);
 int _dw_html_url(HWND hwnd, char *url);
@@ -5402,7 +5695,7 @@
  */
 void API dw_html_action(HWND handle, int action)
 {
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
    _dw_html_action(handle, action);
 #endif
 }
@@ -5418,7 +5711,7 @@
  */
 int API dw_html_raw(HWND handle, char *string)
 {
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
    return _dw_html_raw(handle, string);
 #else
    return DW_ERROR_GENERAL;
@@ -5436,7 +5729,7 @@
  */
 int API dw_html_url(HWND handle, char *url)
 {
-#if (defined(BUILD_DLL) || defined(BUILD_HTML)) && !defined(__MINGW32__)
+#if (defined(BUILD_DLL) || defined(BUILD_HTML))
    return _dw_html_url(handle, url);
 #else
    return DW_ERROR_GENERAL;
@@ -5456,7 +5749,7 @@
                   WS_CHILD | WS_CLIPCHILDREN,
                   0,0,0,0,
                   DW_HWND_OBJECT,
-                  (HMENU)id,
+                  (HMENU)(uintptr_t)id,
                   DWInstance,
                   NULL);
 }
@@ -5472,6 +5765,7 @@
    ULONG flags = 0;
    HWND tmp;
    NotebookPage **array = calloc(256, sizeof(NotebookPage *));
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
 
    if(!top)
       flags = TCS_BOTTOM;
@@ -5481,9 +5775,12 @@
                   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | flags,
                   0,0,0,0,
                   DW_HWND_OBJECT,
-                  (HMENU)id,
+                  (HMENU)(uintptr_t)id,
                   DWInstance,
                   NULL);
+   cinfo->fore = cinfo->back = -1;
+   cinfo->pOldProc = SubclassWindow(tmp, _simplewndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_data(tmp, "_dw_array", (void *)array);
    dw_window_set_font(tmp, DefaultFont);
    return tmp;
@@ -5660,13 +5957,13 @@
    InsertMenuItem(mymenu, 65535, TRUE, &mii);
 
    _snprintf(buffer, 30, "_dw_id%ld", id);
-   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)mymenu );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, DW_POINTER(mymenu) );
    _snprintf(buffer, 30, "_dw_checkable%ld", id);
-   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)check );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, DW_INT_TO_POINTER(check) );
    _snprintf(buffer, 30, "_dw_ischecked%ld", id);
-   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)is_checked );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, DW_INT_TO_POINTER(is_checked) );
    _snprintf(buffer, 30, "_dw_isdisabled%ld", id);
-   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)is_disabled );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, DW_INT_TO_POINTER(is_disabled) );
 
    if (submenu)
    {
@@ -5681,7 +5978,7 @@
 
    if (IsWindow(menux) && !IsMenu((HMENU)menux))
       DrawMenuBar(menux);
-   return (HWND)id;
+   return (HWND)(uintptr_t)id;
 }
 
 /*
@@ -5718,7 +6015,7 @@
     * Keep our internal state consistent
     */
    _snprintf( buffer, 30, "_dw_ischecked%ld", id );
-   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)check );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, DW_INT_TO_POINTER(check) );
 }
 
 /*
@@ -5741,9 +6038,9 @@
       mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
 
    _snprintf( buffer1, 30, "_dw_ischecked%ld", id );
-   check = (int)dw_window_get_data( DW_HWND_OBJECT, buffer1 );
+   check = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer1 ));
    _snprintf( buffer2, 30, "_dw_isdisabled%ld", id );
-   disabled = (int)dw_window_get_data( DW_HWND_OBJECT, buffer2 );
+   disabled = DW_POINTER_TO_INT(dw_window_get_data( DW_HWND_OBJECT, buffer2 ));
 
    memset( &mii, 0, sizeof(mii) );
 
@@ -5810,8 +6107,8 @@
    /*
     * Keep our internal checked state consistent
     */
-   dw_window_set_data( DW_HWND_OBJECT, buffer1, (void *)check );
-   dw_window_set_data( DW_HWND_OBJECT, buffer2, (void *)disabled );
+   dw_window_set_data( DW_HWND_OBJECT, buffer1, DW_INT_TO_POINTER(check) );
+   dw_window_set_data( DW_HWND_OBJECT, buffer2, DW_INT_TO_POINTER(disabled) );
 }
 
 /*
@@ -5834,7 +6131,7 @@
    
    /* If the ID was autogenerated it is safe to remove it */
    if(id >= 30000)
-      dw_signal_disconnect_by_window((HWND)id);
+      dw_signal_disconnect_by_window((HWND)(uintptr_t)id);
       
    /* Make sure the menu is redrawn if needed */
    if( (HMENU)menux != mymenu )
@@ -5883,7 +6180,7 @@
                      WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
@@ -5925,7 +6222,7 @@
                      WS_BORDER | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
@@ -5989,7 +6286,7 @@
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
 #ifdef AEROGLASS
@@ -6018,7 +6315,7 @@
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    dw_window_set_font(tmp, DefaultFont);
@@ -6034,7 +6331,7 @@
 {
 
    HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-                       hrichedit ? RICHEDIT_CLASS : EDITCLASSNAME,
+                       hmsftedit ? MSFTEDIT_CLASS : (hrichedit ? RICHEDIT_CLASS : EDITCLASSNAME),
                        NULL,
                        WS_VISIBLE | WS_BORDER |
                        WS_VSCROLL | ES_MULTILINE |
@@ -6042,7 +6339,7 @@
                        WS_CLIPCHILDREN,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
    ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
@@ -6053,7 +6350,7 @@
       return NULL;
    }
 
-   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _treewndproc);
+   cinfo->cinfo.pOldProc = SubclassWindow(tmp, _simplewndproc);
    cinfo->cinfo.fore = cinfo->cinfo.back = -1;
    cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
 
@@ -6078,7 +6375,7 @@
                        WS_VISIBLE | WS_CLIPCHILDREN,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
    ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
@@ -6107,7 +6404,7 @@
                        ES_AUTOHSCROLL | WS_CLIPCHILDREN,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
    ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
@@ -6147,7 +6444,7 @@
                      WS_CLIPCHILDREN | CBS_AUTOHSCROLL | WS_VISIBLE,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo));
@@ -6191,7 +6488,7 @@
                      WS_VISIBLE | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    cinfo->fore = cinfo->back = -1;
@@ -6235,7 +6532,7 @@
    HIMAGELIST imlist, dimlist;
    BITMAP bmi = { 0 };
    TBBUTTON tbButtons[] = {    
-   { MAKELONG(0, 0), id, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
+   { MAKELONG(0, 0), id, TBSTATE_ENABLED, TBSTYLE_BUTTON}
    };
    
    /* Get the bitmap from either the icon or bitmap itself */
@@ -6269,8 +6566,8 @@
 
    /* 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);
-                         
+                        CCS_NOPARENTALIGN | CCS_NODIVIDER, 0, 0, 100, 30, DW_HWND_OBJECT, (HMENU)(uintptr_t)id, DWInstance, NULL);
+
    /* Disable visual styles by default */
    if(_SetWindowTheme)
       _SetWindowTheme(tmp, L"", L"");
@@ -6281,7 +6578,7 @@
    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);
+   SendMessage(tmp, TB_ADDBUTTONS, 1, (LPARAM) &tbButtons);
    
    _create_tooltip(tmp, text);
    return tmp;
@@ -6301,9 +6598,10 @@
    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))
+   if((tmp = _create_toolbar(text, id, icon, hbitmap)))
    {
       cinfo->fore = cinfo->back = -1;
+      cinfo->pOldProc = SubclassWindow(tmp, _simplewndproc);
       SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
       return tmp;
    }
@@ -6316,7 +6614,7 @@
                   (icon ? BS_ICON : BS_BITMAP),
                   0,0,0,0,
                   DW_HWND_OBJECT,
-                  (HMENU)id,
+                  (HMENU)(uintptr_t)id,
                   DWInstance,
                   NULL);
 
@@ -6371,9 +6669,10 @@
 #endif
 
 #ifdef TOOLBAR
-   if(tmp = _create_toolbar(text, id, hicon, hbitmap))
+   if((tmp = _create_toolbar(text, id, hicon, hbitmap)))
    {
       cinfo->fore = cinfo->back = -1;
+      cinfo->pOldProc = SubclassWindow(tmp, _simplewndproc);
       SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
       return tmp;
    }
@@ -6383,7 +6682,7 @@
                        windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
 
@@ -6461,9 +6760,10 @@
    }
 
 #ifdef TOOLBAR
-   if(tmp = _create_toolbar(text, id, hicon, hbitmap))
+   if((tmp = _create_toolbar(text, id, hicon, hbitmap)))
    {
       cinfo->fore = cinfo->back = -1;
+      cinfo->pOldProc = SubclassWindow(tmp, _simplewndproc);
       SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
       return tmp;
    }
@@ -6475,7 +6775,7 @@
                        WS_VISIBLE,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL );
 
@@ -6523,7 +6823,7 @@
                        UDS_WRAP | UDS_NOTHOUSANDS | WS_VISIBLE,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
    ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
@@ -6560,16 +6860,22 @@
  */
 HWND API dw_radiobutton_new(char *text, ULONG id)
 {
+   ColorInfo *cinfo;
    HWND tmp = CreateWindow(BUTTONCLASSNAME,
                      UTF8toWide(text),
                      WS_CHILD | BS_AUTORADIOBUTTON |
                      WS_CLIPCHILDREN | WS_VISIBLE,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
-   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   /* Disable visual styles by default */
+   if(_SetWindowTheme)
+      _SetWindowTheme(tmp, L"", L"");
+
+   cinfo = calloc(1, sizeof(ColorInfo));
    cinfo->fore = cinfo->back = -1;
    cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
    SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
@@ -6594,7 +6900,7 @@
                      (vertical ? TBS_VERT : TBS_HORZ),
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
@@ -6603,7 +6909,7 @@
 
    cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
    SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-   SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(0, increments-1));
+   SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, MAKELPARAM(0, increments-1));
    return tmp;
 }
 
@@ -6622,7 +6928,7 @@
                      (vertical ? SBS_VERT : SBS_HORZ),
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
@@ -6647,7 +6953,7 @@
                   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                   0,0,0,0,
                   DW_HWND_OBJECT,
-                  (HMENU)id,
+                  (HMENU)(uintptr_t)id,
                   DWInstance,
                   NULL);
 }
@@ -6667,9 +6973,14 @@
                      BS_TEXT | WS_CLIPCHILDREN | WS_VISIBLE,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
+
+   /* Disable visual styles by default */
+   if(_SetWindowTheme)
+      _SetWindowTheme(tmp, L"", L"");
+
    cinfo->pOldProc = SubclassWindow(tmp, _BtProc);
    SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
    dw_window_set_data(tmp, "_dw_checkbox", DW_INT_TO_POINTER(1));
@@ -6695,7 +7006,7 @@
                        WS_VSCROLL | (multi ? LBS_MULTIPLESEL : 0) ,
                        0,0,0,0,
                        DW_HWND_OBJECT,
-                       (HMENU)id,
+                       (HMENU)(uintptr_t)id,
                        DWInstance,
                        NULL);
    ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
@@ -6723,7 +7034,7 @@
  */
 void API dw_window_set_icon(HWND handle, HICN icon)
 {
-   int iicon = (int)icon;
+   int iicon = DW_POINTER_TO_INT(icon);
    HICON hicon = iicon < 65536 ? LoadIcon(DWInstance, MAKEINTRESOURCE(iicon)) : (HICON)icon;
 
    SendMessage(handle, WM_SETICON,
@@ -6731,6 +7042,86 @@
             (LPARAM) hicon);
 }
 
+/* Internal function to set bitmap for the next two functions */
+void _dw_window_set_bitmap(HWND handle, HICON icon, HBITMAP hbitmap)
+{
+   HBITMAP oldbitmap = 0;
+   HANDLE oldicon = 0;
+   TCHAR tmpbuf[100] = {0};
+   
+   if (!icon && !hbitmap)
+      return;
+
+   GetClassName(handle, tmpbuf, 99);
+  
+   if(_tcsnicmp(tmpbuf, BUTTONCLASSNAME, _tcslen(BUTTONCLASSNAME)+1)==0)
+   {
+      oldbitmap = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
+      oldicon = (HICON)SendMessage(handle, BM_GETIMAGE, IMAGE_ICON, 0);
+      SendMessage(handle, BM_SETIMAGE,
+               (icon ? (WPARAM)IMAGE_ICON : (WPARAM)IMAGE_BITMAP),
+               (icon ? (LPARAM)icon : (LPARAM)hbitmap));
+   }
+#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);
+      BITMAP bmi = { 0 };
+     
+      if(hbitmap)
+      {
+         GetObject(hbitmap, sizeof(BITMAP), &bmi);
+         ImageList_Replace(imlist, 0, hbitmap, NULL);
+         _to_grayscale(hbitmap, bmi.bmWidth, bmi.bmHeight);
+         ImageList_Replace(dimlist, 0, hbitmap, NULL);
+         DeleteObject(hbitmap);
+      }
+      else if(icon)
+      {
+         ICONINFO iconinfo;
+         
+         GetIconInfo(icon, &iconinfo);
+         GetObject(iconinfo.hbmColor, sizeof(BITMAP), &bmi);
+         ImageList_ReplaceIcon(imlist, 0, icon);
+         _to_grayscale(iconinfo.hbmColor, bmi.bmWidth, bmi.bmHeight);
+         ImageList_Replace(dimlist, 0, iconinfo.hbmColor, iconinfo.hbmMask);
+         DeleteObject(iconinfo.hbmColor);
+         DeleteObject(iconinfo.hbmMask);
+         DestroyIcon(icon);
+      }
+      InvalidateRect(handle, NULL, FALSE);
+   }
+#endif   
+   else
+   {
+      oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
+      oldicon = (HICON)SendMessage(handle, STM_GETIMAGE, IMAGE_ICON, 0);
+      SendMessage(handle, STM_SETIMAGE,
+               (icon ? (WPARAM)IMAGE_ICON : (WPARAM)IMAGE_BITMAP),
+               (icon ? (LPARAM)icon : (LPARAM)hbitmap));
+   }
+
+   if(oldbitmap)
+      DeleteObject(oldbitmap);
+   if(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);
+      }
+   }
+}
+
 /*
  * Sets the bitmap used for a given static window.
  * Parameters:
@@ -6744,9 +7135,7 @@
 void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
 {
    HBITMAP hbitmap = 0;
-   HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
    HANDLE icon = 0;
-   HANDLE oldicon = (HICON)SendMessage(handle, STM_GETIMAGE, IMAGE_ICON, 0);
 
    if(id)
    {
@@ -6760,46 +7149,9 @@
 #else
       _dw_get_image_handle(filename, &icon, &hbitmap);
 #endif
-      if (icon == 0 && hbitmap == 0)
-         return;
-   }
-
-   if(icon)
-   {
-      SendMessage(handle, BM_SETIMAGE,
-               (WPARAM) IMAGE_ICON,
-               (LPARAM) icon);
-      SendMessage(handle, STM_SETIMAGE,
-               (WPARAM) IMAGE_ICON,
-               (LPARAM) icon);
-   }
-   else if(hbitmap)
-   {
-      SendMessage(handle, BM_SETIMAGE,
-               (WPARAM) IMAGE_BITMAP,
-               (LPARAM) hbitmap);
-      SendMessage(handle, STM_SETIMAGE,
-               (WPARAM) IMAGE_BITMAP,
-               (LPARAM) hbitmap);
-   }
-
-   if(hbitmap && oldbitmap)
-      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);
-      }
-   }
+   }
+   
+   _dw_window_set_bitmap(handle, icon, hbitmap);
 }
 
 /*
@@ -6816,9 +7168,7 @@
 void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len)
 {
    HBITMAP hbitmap=0;
-   HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
    HICON icon=0;
-   HICON oldicon = (HICON)SendMessage(handle, STM_GETIMAGE, IMAGE_ICON, 0);
    char *file;
    FILE *fp;
 
@@ -6859,29 +7209,7 @@
       icon = LoadImage( DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED );
    }
 
-   if ( icon )
-   {
-      SendMessage( handle, BM_SETIMAGE,
-                   (WPARAM) IMAGE_ICON,
-                   (LPARAM) icon );
-      SendMessage( handle, STM_SETIMAGE,
-                   (WPARAM) IMAGE_ICON,
-                   (LPARAM) icon );
-   }
-   else if ( hbitmap )
-   {
-      SendMessage( handle, BM_SETIMAGE,
-                   (WPARAM) IMAGE_BITMAP,
-                   (LPARAM) hbitmap );
-      SendMessage( handle, STM_SETIMAGE,
-                   (WPARAM) IMAGE_BITMAP,
-                   (LPARAM) hbitmap );
-   }
-
-   if( hbitmap && oldbitmap )
-      DeleteObject( oldbitmap );
-   else if ( icon && oldicon )
-      DeleteObject( oldicon );
+   _dw_window_set_bitmap(handle, icon, hbitmap);
 }
 
 
@@ -7008,7 +7336,7 @@
    {
       char buffer[31] = {0};
       HMENU mymenu;
-      ULONG id = (ULONG)handle;
+      ULONG id = (ULONG)(uintptr_t)handle;
       
       _snprintf(buffer, 30, "_dw_id%ld", id);
       mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
@@ -7031,7 +7359,7 @@
    {
       char buffer[31] = {0};
       HMENU mymenu;
-      ULONG id = (ULONG)handle;
+      ULONG id = (ULONG)(uintptr_t)handle;
       
       _snprintf(buffer, 30, "_dw_id%ld", id);
       mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
@@ -7169,6 +7497,9 @@
 
       thisbox->count++;
 
+#ifdef AEROGLASS
+      AllowDarkModeForWindow(item, _DW_DARK_MODE_ENABLED);
+#endif
       SetParent(item, box);
       if(_tcsnicmp(tmpbuf, UPDOWN_CLASS, _tcslen(UPDOWN_CLASS)+1)==0)
       {
@@ -7662,7 +7993,7 @@
    {
       char buffer[31] = {0};
       HMENU mymenu;
-      ULONG id = (ULONG)handle;
+      ULONG id = (ULONG)(uintptr_t)handle;
       
       _snprintf(buffer, 30, "_dw_id%ld", id);
       mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
@@ -7700,7 +8031,10 @@
    tmp ^= mask;
    tmp |= style & mask;
 
-   if(_tcsnicmp(tmpbuf, ClassName, _tcslen(ClassName)+1)==0)
+   /* Drop out for status bar, it currently doesn't accept styles on Windows */
+   if(_tcsnicmp(tmpbuf, StatusbarClassName, _tcslen(StatusbarClassName)+1)==0)
+      return;
+   else if(_tcsnicmp(tmpbuf, ClassName, _tcslen(ClassName)+1)==0)
    {
       tmp = tmp & 0xffff0000;
 #ifdef AEROGLASS      
@@ -7730,7 +8064,6 @@
    }
    else if(_tcsnicmp(tmpbuf, STATICCLASSNAME, _tcslen(STATICCLASSNAME)+1)==0)
    {
-      static ULONG halign = (SS_LEFTNOWORDWRAP | SS_RIGHT | SS_CENTER);
       ULONG thismask = mask & ~(DW_DT_VCENTER | DW_DT_WORDBREAK);
       ULONG thisstyle = style & ~(DW_DT_VCENTER | DW_DT_WORDBREAK);
       ULONG type = style & mask & 0xFL;
@@ -8469,7 +8802,7 @@
    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(hrichedit || hmsftedit)
    {
       if(state)
          SendMessage(handle, EM_SETOPTIONS, (WPARAM)ECOOP_AND, (LPARAM)~ECO_AUTOHSCROLL);
@@ -8479,6 +8812,16 @@
 }
 
 /*
+ * Sets the word auto complete state of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: Bitwise combination of DW_MLE_COMPLETE_TEXT/DASH/QUOTE
+ */
+void API dw_mle_set_auto_complete(HWND handle, int state)
+{
+}
+
+/*
  * Sets the current cursor position of an MLE box.
  * Parameters:
  *          handle: Handle to the MLE to be positioned.
@@ -8486,7 +8829,7 @@
  */
 void API dw_mle_set_cursor(HWND handle, int point)
 {
-   SendMessage(handle, EM_SETSEL, 0, MAKELONG(point,point));
+   SendMessage(handle, EM_SETSEL, 0, MAKELPARAM(point,point));
    SendMessage(handle, EM_SCROLLCARET, 0, 0);
 }
 
@@ -8645,7 +8988,7 @@
  */
 void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
 {
-   dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
+   dw_window_set_data(handle, "_dw_scrollbar_value", DW_UINT_TO_POINTER(position));
    SendMessage(handle, SBM_SETPOS, (WPARAM)position, (LPARAM)TRUE);
 }
 
@@ -8779,14 +9122,10 @@
    TVITEM tvi;
    TVINSERTSTRUCT tvins;
    HTREEITEM hti;
-   void **ptrs= malloc(sizeof(void *) * 2);
-
-   ptrs[0] = title;
-   ptrs[1] = itemdata;
 
    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
    tvi.pszText = UTF8toWide(title);
-   tvi.lParam = (LONG)ptrs;
+   tvi.lParam = (LPARAM)itemdata;
    tvi.cchTextMax = (int)_tcslen(tvi.pszText);
    tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
 
@@ -8813,14 +9152,10 @@
    TVITEM tvi;
    TVINSERTSTRUCT tvins;
    HTREEITEM hti;
-   void **ptrs= malloc(sizeof(void *) * 2);
-
-   ptrs[0] = title;
-   ptrs[1] = itemdata;
 
    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
    tvi.pszText = UTF8toWide(title);
-   tvi.lParam = (LONG)ptrs;
+   tvi.lParam = (LPARAM)itemdata;
    tvi.cchTextMax = (int)_tcslen(tvi.pszText);
    tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
 
@@ -8844,17 +9179,12 @@
 void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon)
 {
    TVITEM tvi;
-   void **ptrs;
 
    tvi.mask = TVIF_HANDLE;
    tvi.hItem = item;
 
    if(TreeView_GetItem(handle, &tvi))
    {
-
-      ptrs = (void **)tvi.lParam;
-      ptrs[0] = title;
-
       tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
       tvi.pszText = UTF8toWide(title);
       tvi.cchTextMax = (int)_tcslen(tvi.pszText);
@@ -8875,16 +9205,12 @@
 void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
 {
    TVITEM tvi;
-   void **ptrs;
-
-   tvi.mask = TVIF_HANDLE;
+
+   tvi.mask = TVIF_HANDLE | TVIF_PARAM;
    tvi.hItem = item;
-
-   if(TreeView_GetItem(handle, &tvi))
-   {
-      ptrs = (void **)tvi.lParam;
-      ptrs[1] = itemdata;
-   }
+   tvi.lParam = (LPARAM)itemdata;
+
+   TreeView_SetItem(handle, &tvi);
 }
 
 /*
@@ -8896,15 +9222,13 @@
 void * API dw_tree_item_get_data(HWND handle, HTREEITEM item)
 {
    TVITEM tvi;
-   void **ptrs;
 
    tvi.mask = TVIF_HANDLE | TVIF_PARAM;
    tvi.hItem = item;
 
    if(TreeView_GetItem(handle, &tvi))
    {
-      ptrs = (void **)tvi.lParam;
-      return ptrs[1];
+      return (void *)tvi.lParam;
    }
    return NULL;
 }
@@ -8918,12 +9242,15 @@
 char * API dw_tree_get_title(HWND handle, HTREEITEM item)
 {
    TVITEM tvi;
-
-   tvi.mask = TVIF_HANDLE;
+   TCHAR textbuf[1025] = {0}, *textptr = textbuf;
+
+   tvi.mask = TVIF_HANDLE | TVIF_TEXT;
    tvi.hItem = item;
+   tvi.pszText = textptr;
+   tvi.cchTextMax = 1024;
 
    if(TreeView_GetItem(handle, &tvi))
-      return _strdup(WideToUTF8(tvi.pszText));
+      return _strdup(WideToUTF8(textptr));
     return NULL;
 }
 
@@ -8949,22 +9276,6 @@
    TreeView_SelectItem(handle, item);
 }
 
-/* Delete all tree subitems */
-void _dw_tree_item_delete_recursive(HWND handle, HTREEITEM node)
-{
-   HTREEITEM hti;
-
-   hti = TreeView_GetChild(handle, node);
-
-   while(hti)
-   {
-      HTREEITEM lastitem = hti;
-
-      hti = TreeView_GetNextSibling(handle, hti);
-      dw_tree_item_delete(handle, lastitem);
-   }
-}
-
 /*
  * Removes all nodes from a tree.
  * Parameters:
@@ -8972,18 +9283,9 @@
  */
 void API dw_tree_clear(HWND handle)
 {
-   HTREEITEM hti = TreeView_GetRoot(handle);
-
-   dw_window_set_data(handle, "_dw_select_item", (void *)1);
-   while(hti)
-   {
-      HTREEITEM lastitem = hti;
-
-      _dw_tree_item_delete_recursive(handle, hti);
-      hti = TreeView_GetNextSibling(handle, hti);
-      dw_tree_item_delete(handle, lastitem);
-   }
-   dw_window_set_data(handle, "_dw_select_item", (void *)0);
+   dw_window_set_data(handle, "_dw_select_item", DW_INT_TO_POINTER(1));
+   TreeView_DeleteAllItems(handle);
+   dw_window_set_data(handle, "_dw_select_item", NULL);
 }
 
 /*
@@ -9016,22 +9318,7 @@
  */
 void API dw_tree_item_delete(HWND handle, HTREEITEM item)
 {
-   TVITEM tvi;
-   void **ptrs=NULL;
-
-   if(item == TVI_ROOT || !item)
-      return;
-
-   tvi.mask = TVIF_HANDLE;
-   tvi.hItem = item;
-
-   if(TreeView_GetItem(handle, &tvi))
-      ptrs = (void **)tvi.lParam;
-
-   _dw_tree_item_delete_recursive(handle, item);
    TreeView_DeleteItem(handle, item);
-   if(ptrs)
-      free(ptrs);
 }
 
 /*
@@ -9254,7 +9541,7 @@
    item = ListView_InsertItem(handle, &lvi);
    for(z=1;z<rowcount;z++)
       ListView_InsertItem(handle, &lvi);
-   dw_window_set_data(handle, "_dw_insertitem", (void *)item);
+   dw_window_set_data(handle, "_dw_insertitem", DW_INT_TO_POINTER(item));
    return (void *)handle;
 }
 
@@ -9265,7 +9552,6 @@
 {
    int z;
    static HWND lasthwnd = NULL;
-   HIMAGELIST himl;
 
    /* We can't add an invalid handle */
    if(!hicon)
@@ -9285,12 +9571,12 @@
          ImageList_AddIcon(hLarge, hicon);
          if(type)
          {
-            himl = TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+            TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
          }
          else
          {
-            himl = ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-            himl = ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+            ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+            ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
          }
          lasthwnd = handle;
          return z;
@@ -9302,12 +9588,12 @@
          {
             if(type)
             {
-               himl = TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+               TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
             }
             else
             {
-               himl = ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-               himl = ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+               ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+               ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
             }
             lasthwnd = handle;
          }
@@ -9333,7 +9619,7 @@
 
    if(pointer)
    {
-      item = (int)dw_window_get_data(handle, "_dw_insertitem");
+      item = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_insertitem"));
    }
 
    lvi.iItem = row + item;
@@ -9379,7 +9665,7 @@
 
    if(pointer)
    {
-      item = (int)dw_window_get_data(handle, "_dw_insertitem");
+      item = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_insertitem"));
    }
 
    if(!cinfo || !cinfo->flags)
@@ -9557,25 +9843,14 @@
 void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor)
 {
     ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-    unsigned long temp = _internal_color(oddcolor);
-    COLORREF even, odd = RGB(DW_RED_VALUE(temp), DW_GREEN_VALUE(temp), DW_BLUE_VALUE(temp));
-    temp = _internal_color(evencolor);
-    even = RGB(DW_RED_VALUE(temp), DW_GREEN_VALUE(temp), DW_BLUE_VALUE(temp));
 
     /* Drop out on error */
     if(!cinfo)
         return;
 
     /* Create new brushes or remove if transparent */
-    if(oddcolor != DW_RGB_TRANSPARENT)
-        cinfo->odd = (oddcolor == DW_CLR_DEFAULT ? RGB(230, 230, 230) : odd);
-    else 
-        cinfo->odd = oddcolor;
-
-    if(evencolor != DW_RGB_TRANSPARENT)
-        cinfo->even = (evencolor == DW_CLR_DEFAULT ? DW_RGB_TRANSPARENT : even);
-    else 
-        cinfo->even = evencolor;
+    cinfo->odd = oddcolor;
+    cinfo->even = evencolor;
 }
 
 /*
@@ -9591,24 +9866,51 @@
 }
 
 /* Internal version that handles both types */
-void _dw_container_set_row_title(HWND handle, void *pointer, int row, char *title)
+void _dw_container_set_row_data(HWND handle, void *pointer, int row, int type, void *data)
 {
    LV_ITEM lvi;
    int item = 0;
 
    if(pointer)
    {
-      item = (int)dw_window_get_data(handle, "_dw_insertitem");
-   }
-
+      item = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_insertitem"));
+   }
+
+   memset(&lvi, 0, sizeof(LV_ITEM));
+   
    lvi.iItem = row + item;
-   lvi.iSubItem = 0;
    lvi.mask = LVIF_PARAM;
-   lvi.lParam = (LPARAM)title;
-
-   if(!ListView_SetItem(handle, &lvi) && lvi.lParam)
-      lvi.lParam = 0;
-
+   
+   if(ListView_GetItem(handle, &lvi))
+   {
+      void **params = (void **)lvi.lParam;
+      void *newparam = data;
+      
+      /* Make sure we have our pointer array... */
+      if(!params)
+      {
+         /* If not allocate it */
+         params = (void **)calloc(2, sizeof(void *));
+         lvi.lParam = (LPARAM)params;
+         ListView_SetItem(handle, &lvi);
+      }
+      /* If type string, we need to duplicate the string...
+       * freeing any existing string.
+       */
+      if(type == _DW_DATA_TYPE_STRING)
+      {
+         void *oldparam = params[type];
+         
+         params[type] = NULL;
+         
+         if(oldparam)
+            free(oldparam);
+         if(newparam)
+            newparam = _strdup((char *)newparam);
+      }
+      /* Set the new data in the pointer array */
+      params[type] = newparam;
+   }
 }
 
 /*
@@ -9620,7 +9922,7 @@
  */
 void API dw_container_set_row_title(void *pointer, int row, char *title)
 {
-   _dw_container_set_row_title(pointer, pointer, row, title);
+   _dw_container_set_row_data(pointer, pointer, row, _DW_DATA_TYPE_STRING, title);
 }
 
 /*
@@ -9632,7 +9934,31 @@
  */
 void API dw_container_change_row_title(HWND handle, int row, char *title)
 {
-   _dw_container_set_row_title(handle, NULL, row, title);
+   _dw_container_set_row_data(handle, NULL, row, _DW_DATA_TYPE_STRING, title);
+}
+
+/*
+ * Sets the data of a row in the container.
+ * Parameters:
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          row: Zero based row of data being set.
+ *          data: Data pointer.
+ */
+void API dw_container_set_row_data(void *pointer, int row, void *data)
+{
+   _dw_container_set_row_data(pointer, pointer, row, _DW_DATA_TYPE_POINTER, data);
+}
+
+/*
+ * Changes the data of a row already inserted in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          row: Zero based row of data being set.
+ *          data: Data pointer.
+ */
+void API dw_container_change_row_data(HWND handle, int row, void *data)
+{
+   _dw_container_set_row_data(handle, NULL, row, _DW_DATA_TYPE_POINTER, data);
 }
 
 /*
@@ -9666,7 +9992,7 @@
  */
 void API dw_container_delete(HWND handle, int rowcount)
 {
-   int z, _index = (int)dw_window_get_data(handle, "_dw_index");
+   int z, _index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_index"));
 
    for(z=0;z<rowcount;z++)
    {
@@ -9675,7 +10001,7 @@
    if(rowcount > _index)
       dw_window_set_data(handle, "_dw_index", 0);
    else
-      dw_window_set_data(handle, "_dw_index", (void *)(_index - rowcount));
+      dw_window_set_data(handle, "_dw_index", DW_INT_TO_POINTER((_index - rowcount)));
 }
 
 /*
@@ -9711,9 +10037,15 @@
 {
    LV_ITEM lvi;
    int _index = ListView_GetNextItem(handle, -1, flags);
+   void **params;
+   int type = _DW_DATA_TYPE_STRING;
+   char *retval = NULL;
 
    if(_index == -1)
-      return NULL;
+      return retval;
+      
+   if(flags & DW_CR_RETDATA)
+      type = _DW_DATA_TYPE_POINTER;
 
    memset(&lvi, 0, sizeof(LV_ITEM));
 
@@ -9721,9 +10053,18 @@
    lvi.mask = LVIF_PARAM;
 
    ListView_GetItem(handle, &lvi);
-
-   dw_window_set_data(handle, "_dw_index", (void *)_index);
-   return (char *)lvi.lParam;
+   params = (void **)lvi.lParam;
+   
+   if(params)
+   {
+      if(type == _DW_DATA_TYPE_STRING && params[type])
+         retval = _strdup((char *)params[type]);
+      else
+         retval = (char *)params[type];
+   }
+
+   dw_window_set_data(handle, "_dw_index", DW_INT_TO_POINTER(_index));
+   return retval;
 }
 
 /*
@@ -9737,22 +10078,37 @@
 char * API dw_container_query_next(HWND handle, unsigned long flags)
 {
    LV_ITEM lvi;
-   int _index = (int)dw_window_get_data(handle, "_dw_index");
+   int _index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_index"));
+   void **params;
+   int type = _DW_DATA_TYPE_STRING;
+   char *retval = NULL;
 
    _index = ListView_GetNextItem(handle, _index, flags);
 
    if(_index == -1)
-      return NULL;
-
+      return retval;
+
+   if(flags & DW_CR_RETDATA)
+      type = _DW_DATA_TYPE_POINTER;
+      
    memset(&lvi, 0, sizeof(LV_ITEM));
 
    lvi.iItem = _index;
    lvi.mask = LVIF_PARAM;
 
    ListView_GetItem(handle, &lvi);
-
-   dw_window_set_data(handle, "_dw_index", (void *)_index);
-   return (char *)lvi.lParam;
+   params = (void **)lvi.lParam;
+
+   if(params)
+   {
+      if(type == _DW_DATA_TYPE_STRING && params[type])
+         retval = _strdup((char *)params[type]);
+      else
+         retval = (char *)params[type];
+   }
+
+   dw_window_set_data(handle, "_dw_index", DW_INT_TO_POINTER(_index));
+   return retval;
 }
 
 /*
@@ -9764,11 +10120,11 @@
 void API dw_container_cursor(HWND handle, char *text)
 {
    int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
-   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
 
    while ( index != -1 )
    {
       LV_ITEM lvi;
+      void **params;
 
       memset(&lvi, 0, sizeof(LV_ITEM));
 
@@ -9776,8 +10132,48 @@
       lvi.mask = LVIF_PARAM;
 
       ListView_GetItem( handle, &lvi );
-
-      if ( (textcomp && lvi.lParam && strcmp( (char *)lvi.lParam, text ) == 0) || (!textcomp && (char *)lvi.lParam == text) )
+      params = (void **)lvi.lParam;
+
+      if ( params && params[_DW_DATA_TYPE_STRING] && strcmp( (char *)params[_DW_DATA_TYPE_STRING], text ) == 0 )
+      {
+         unsigned long width, height;
+         
+         ListView_SetItemState( handle, index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED );
+         dw_window_get_pos_size( handle, NULL, NULL, &width, &height);
+         if(width < 10 || height < 10)
+            dw_window_set_data( handle, "_dw_cursor", DW_INT_TO_POINTER(index) );
+         ListView_EnsureVisible( handle, index, TRUE );
+         return;
+      }
+
+      index = ListView_GetNextItem( handle, index, LVNI_ALL );
+   }
+}
+
+/*
+ * Cursors the item with the text speficied, and scrolls to that item.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       text:  Text usually returned by dw_container_query().
+ */
+void API dw_container_cursor_by_data(HWND handle, void *data)
+{
+   int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
+
+   while ( index != -1 )
+   {
+      LV_ITEM lvi;
+      void **params;
+
+      memset(&lvi, 0, sizeof(LV_ITEM));
+
+      lvi.iItem = index;
+      lvi.mask = LVIF_PARAM;
+
+      ListView_GetItem( handle, &lvi );
+      params = (void **)lvi.lParam;
+
+      if ( params && params[_DW_DATA_TYPE_POINTER] == data )
       {
          unsigned long width, height;
          
@@ -9802,11 +10198,11 @@
 void API dw_container_delete_row(HWND handle, char *text)
 {
    int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
-   int textcomp = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_textcomp"));
 
    while(index != -1)
    {
       LV_ITEM lvi;
+      void **params;
 
       memset(&lvi, 0, sizeof(LV_ITEM));
 
@@ -9814,19 +10210,58 @@
       lvi.mask = LVIF_PARAM;
 
       ListView_GetItem(handle, &lvi);
-
-      if ( (textcomp && lvi.lParam && strcmp( (char *)lvi.lParam, text ) == 0) || (!textcomp && (char *)lvi.lParam == text) )
-      {
-         int _index = (int)dw_window_get_data(handle, "_dw_index");
+      params = (void **)lvi.lParam;
+
+      if ( params && params[_DW_DATA_TYPE_STRING] && strcmp( (char *)params[_DW_DATA_TYPE_STRING], text ) == 0 )
+      {
+         int _index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_index"));
 
          if(index < _index)
-            dw_window_set_data(handle, "_dw_index", (void *)(_index - 1));
+            dw_window_set_data(handle, "_dw_index", DW_INT_TO_POINTER((_index - 1)));
 
          ListView_DeleteItem(handle, index);
          return;
       }
 
-        index = ListView_GetNextItem(handle, index, LVNI_ALL);
+      index = ListView_GetNextItem(handle, index, LVNI_ALL);
+   }
+}
+
+/*
+ * Deletes the item with the text speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       text:  Text usually returned by dw_container_query().
+ */
+void API dw_container_delete_row_by_data(HWND handle, void *data)
+{
+   int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
+
+   while(index != -1)
+   {
+      LV_ITEM lvi;
+      void **params;
+
+      memset(&lvi, 0, sizeof(LV_ITEM));
+
+      lvi.iItem = index;
+      lvi.mask = LVIF_PARAM;
+
+      ListView_GetItem(handle, &lvi);
+      params = (void **)lvi.lParam;
+
+      if ( params && params[_DW_DATA_TYPE_POINTER] == data )
+      {
+         int _index = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_index"));
+
+         if(index < _index)
+            dw_window_set_data(handle, "_dw_index", DW_INT_TO_POINTER((_index - 1)));
+
+         ListView_DeleteItem(handle, index);
+         return;
+      }
+
+      index = ListView_GetNextItem(handle, index, LVNI_ALL);
    }
 }
 
@@ -9918,7 +10353,7 @@
 
    tnid.cbSize = sizeof(NOTIFYICONDATA);
    tnid.hWnd = handle;
-   tnid.uID = (UINT)icon;
+   tnid.uID = (UINT)(uintptr_t)icon;
    tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    tnid.uCallbackMessage = WM_USER+2;
    tnid.hIcon = (HICON)icon;
@@ -9942,7 +10377,7 @@
 
    tnid.cbSize = sizeof(NOTIFYICONDATA);
    tnid.hWnd = handle;
-   tnid.uID = (UINT)icon;
+   tnid.uID = (UINT)(uintptr_t)icon;
 
    Shell_NotifyIcon(NIM_DELETE, &tnid);
 }
@@ -9962,7 +10397,7 @@
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
    newbox->pad = 0;
@@ -10005,7 +10440,7 @@
 
    DeleteObject(hPen);
    DeleteObject(hBrush);
-   TlsSetValue(_foreground, (LPVOID)foreground);
+   TlsSetValue(_foreground, (LPVOID)(uintptr_t)foreground);
    TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
    TlsSetValue(_hBrush, CreateSolidBrush(foreground));
 }
@@ -10026,7 +10461,7 @@
    if(value == DW_RGB_TRANSPARENT)
       TlsSetValue(_background, (LPVOID)DW_RGB_TRANSPARENT);
    else
-      TlsSetValue(_background, (LPVOID)background);
+      TlsSetValue(_background, (LPVOID)(uintptr_t)background);
 }
 
 /* Allows the user to choose a color using the system's color chooser dialog.
@@ -10468,10 +10903,10 @@
       mustdelete = 1;
    }
 
-   background = (COLORREF)TlsGetValue(_background);
+   background = (COLORREF)(uintptr_t)TlsGetValue(_background);
    if(hFont)
       oldFont = SelectObject(hdc, hFont);
-   SetTextColor(hdc, (COLORREF)TlsGetValue(_foreground));
+   SetTextColor(hdc, (COLORREF)(uintptr_t)TlsGetValue(_foreground));
    if(background == DW_RGB_TRANSPARENT)
       SetBkMode(hdc, TRANSPARENT);
    else
@@ -11288,7 +11723,7 @@
    sa.lpSecurityDescriptor = &_dwsd;
    sa.bInheritHandle = FALSE;
 
-   handle = CreateFileMapping((HANDLE)0xFFFFFFFF, &sa, PAGE_READWRITE, 0, size, UTF8toWide(name));
+   handle = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, size, UTF8toWide(name));
 
    if(!handle)
       return 0;
@@ -11342,13 +11777,40 @@
    return 0;
 }
 
-/*
- * Encapsulate thread creation on Win32.
- */
-void _dwthreadstart(void *data)
-{
-   void (* threadfunc)(void *) = NULL;
-   void **tmp = (void **)data;
+/* 
+ * Generally an internal function called from a newly created
+ * thread to setup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they create threads that require access to Dynamic Windows.
+ */
+void API _dw_init_thread(void)
+{
+    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, brush);
+#endif    
+    TlsSetValue(_foreground, DW_UINT_TO_POINTER(foreground));
+    TlsSetValue(_background, DW_UINT_TO_POINTER(background));
+    TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
+    TlsSetValue(_hBrush, CreateSolidBrush(foreground));
+}
+
+/* 
+ * Generally an internal function called from a terminating
+ * thread to cleanup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they exit threads that require access to Dynamic Windows.
+ */
+void API _dw_deinit_thread(void)
+{
    HPEN hPen;
    HBRUSH hBrush;
 #ifdef GDIPLUS
@@ -11356,12 +11818,6 @@
    GpPen *pen;
 #endif       
 
-   _init_thread();
-
-   threadfunc = (void (*)(void *))tmp[0];
-   threadfunc(tmp[1]);
-
-   free(tmp);
    if((hPen = TlsGetValue(_hPen)))
        DeleteObject(hPen);
    if((hBrush = TlsGetValue(_hBrush)))
@@ -11375,6 +11831,23 @@
 }
 
 /*
+ * Encapsulate thread creation on Win32.
+ */
+void _dwthreadstart(void *data)
+{
+   void (* threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+
+   _dw_init_thread();
+
+   threadfunc = (void (*)(void *))tmp[0];
+   threadfunc(tmp[1]);
+
+   free(tmp);
+   _dw_deinit_thread();
+}
+
+/*
  * Creates a new thread with a starting point of func.
  * Parameters:
  *       func: Function which will be run in the new thread.
@@ -11401,6 +11874,7 @@
 void API dw_thread_end(void)
 {
 #if !defined(__CYGWIN__)
+   _dw_deinit_thread();
    _endthread();
 #endif
 }
@@ -11419,10 +11893,8 @@
 
 /*
  * Cleanly terminates a DW session, should be signal handler safe.
- * Parameters:
- *       exitcode: Exit code reported to the operating system.
- */
-void API dw_exit(int exitcode)
+ */
+void API dw_shutdown(void)
 {
    OleUninitialize();
 #ifdef AEROGLASS
@@ -11431,6 +11903,16 @@
 #endif   
    FreeLibrary(huxtheme);
    DestroyWindow(hwndTooltip);
+}
+
+/*
+ * Cleanly terminates a DW session, should be signal handler safe.
+ * Parameters:
+ *       exitcode: Exit code reported to the operating system.
+ */
+void API dw_exit(int exitcode)
+{
+   dw_shutdown();
    exit(exitcode);
 }
 
@@ -11450,26 +11932,26 @@
                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
                      0,0,0,0,
                      DW_HWND_OBJECT,
-                     (HMENU)id,
+                     (HMENU)(uintptr_t)id,
                      DWInstance,
                      NULL);
 
    if(tmp)
    {
       HWND tmpbox = dw_box_new(DW_VERT, 0);
-        float *percent = (float *)malloc(sizeof(float));
+      float *percent = (float *)malloc(sizeof(float));
 
       dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0);
       SetParent(tmpbox, tmp);
-      dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox);
+      dw_window_set_data(tmp, "_dw_topleft", DW_POINTER(tmpbox));
 
       tmpbox = dw_box_new(DW_VERT, 0);
       dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0);
       SetParent(tmpbox, tmp);
-      dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox);
+      dw_window_set_data(tmp, "_dw_bottomright", DW_POINTER(tmpbox));
       *percent = 50.0;
-      dw_window_set_data(tmp, "_dw_percent", (void *)percent);
-      dw_window_set_data(tmp, "_dw_type", (void *)type);
+      dw_window_set_data(tmp, "_dw_percent", DW_POINTER(percent));
+      dw_window_set_data(tmp, "_dw_type", DW_INT_TO_POINTER(type));
    }
    return tmp;
 }
@@ -11482,8 +11964,8 @@
 void API dw_splitbar_set(HWND handle, float percent)
 {
    float *mypercent = (float *)dw_window_get_data(handle, "_dw_percent");
-   int type = (int)dw_window_get_data(handle, "_dw_type");
-    unsigned long width, height;
+   int type = DW_POINTER_TO_INT(dw_window_get_data(handle, "_dw_type"));
+   unsigned long width, height;
 
    if(mypercent)
       *mypercent = percent;
@@ -11528,7 +12010,7 @@
                            WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | MCS_DAYSTATE,
                            0,0,0,0,
                            DW_HWND_OBJECT,
-                           (HMENU)id,
+                           (HMENU)(uintptr_t)id,
                            DWInstance,
                            NULL);
    if ( tmp )
@@ -11760,6 +12242,8 @@
          strcpy(env->osName, "Windows 7");
       else if(env->MajorVersion == 6 && env->MinorVersion > 1)
          strcpy(env->osName, "Windows 8");
+      else if(env->MajorVersion == 10)
+         strcpy(env->osName, "Windows 10");
       else
          strcpy(env->osName, "Windows NT");
 
@@ -11947,10 +12431,15 @@
 
    for(z=0;z<count;z++)
    {
-      newparams[z] = malloc(strlen(params[z])+3);
-      strcpy(newparams[z], "\"");
-      strcat(newparams[z], params[z]);
-      strcat(newparams[z], "\"");
+      if(strchr(params[z], ' '))
+      {		  
+         newparams[z] = malloc(strlen(params[z])+3);
+         strcpy(newparams[z], "\"");
+         strcat(newparams[z], params[z]);
+         strcat(newparams[z], "\"");
+      }
+      else 
+         newparams[z] = strdup(params[z]);
    }
    newparams[count] = NULL;
 
@@ -11992,7 +12481,7 @@
       }
    }
 
-   retcode = (int)ShellExecute(NULL, TEXT("open"), UTF8toWide(browseurl), NULL, NULL, SW_SHOWNORMAL);
+   retcode = DW_POINTER_TO_INT(ShellExecute(NULL, TEXT("open"), UTF8toWide(browseurl), NULL, NULL, SW_SHOWNORMAL));
    if(retcode<33 && retcode != 2)
       return DW_ERROR_UNKNOWN;
    return DW_ERROR_NONE;
@@ -12002,7 +12491,7 @@
 {
     PRINTDLG pd;
     DOCINFO di;
-    int (*drawfunc)(HPRINT, HPIXMAP, int, void *);
+    int (DWSIGNAL *drawfunc)(HPRINT, HPIXMAP, int, void *);
     void *drawdata;
     unsigned long flags;
 } DWPrint;
@@ -12340,7 +12829,7 @@
 
       if(timerid)
       {
-         _new_signal(WM_TIMER, NULL, timerid, sigfunc, data);
+         _new_signal(WM_TIMER, NULL, timerid, sigfunc, NULL, data);
          return timerid;
       }
    }
@@ -12397,6 +12886,20 @@
  */
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
 {
+    dw_signal_connect_data(window, signame, sigfunc, NULL, data);
+}
+
+/*
+ * Add a callback to a window event with a closure callback.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       signame: A string pointer identifying which signal to be hooked.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       discfunc: The pointer to the function called when this handler is removed.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data)
+{
    ULONG message = 0, id = 0;
 
    if (window && signame && sigfunc)
@@ -12412,7 +12915,7 @@
             char buffer[16];
             HWND owner;
 
-            _snprintf(buffer, 15, "_dw_id%d", (int)window);
+            _snprintf(buffer, 15, "_dw_id%d", (int)(intptr_t)window);
             owner = (HWND)dw_window_get_data(DW_HWND_OBJECT, buffer);
 
             /* Make sure there are no dupes from popups */
@@ -12420,11 +12923,11 @@
 
             if (owner)
             {
-               id = (ULONG)window;
+               id = (ULONG)(uintptr_t)window;
                window = owner;
             }
          }
-         _new_signal(message, window, id, sigfunc, data);
+         _new_signal(message, window, id, sigfunc, discfunc, data);
       }
    }
 }
@@ -12444,9 +12947,16 @@
 
    while(tmp)
    {
-      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->message == message)
-      {
-        if(prev)
+      if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->message == message)
+      {
+         void (DWSIGNAL *discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
+         if(prev)
          {
             prev->next = tmp->next;
             free(tmp);
@@ -12478,8 +12988,15 @@
 
    while(tmp)
    {
-      if((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window)
-      {
+      if((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window)
+      {
+         void (DWSIGNAL *discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
          if(prev)
          {
             prev->next = tmp->next;
@@ -12513,8 +13030,15 @@
 
    while(tmp)
    {
-      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->data == data)
-      {
+      if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->data == data)
+      {
+         void (DWSIGNAL *discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
         if(prev)
          {
             prev->next = tmp->next;
@@ -12569,4 +13093,3 @@
     return NULL;
 #endif
 }
-