changeset 2:f3314e97472f

First step in modernizing the installer/2 codebase. Sync up with Dynamic Windows 2.2... only worrying about OS/2 for now.
author Brian Smith <brian@dbsoft.org>
date Sun, 13 Nov 2011 07:22:43 -0600
parents 821abb186ec1
children 445f5fc8d53d
files configure dw.h install.c instsup.c os2/dw.c packinst/packinst.c rexx.c scripts/finished.cmd scripts/page1.cmd scripts/page2.cmd scripts/page3.cmd scripts/page4.cmd win/dw.c
diffstat 7 files changed, 23948 insertions(+), 18472 deletions(-) [+]
line wrap: on
line diff
--- a/dw.h	Fri Feb 18 09:04:25 2011 -0600
+++ b/dw.h	Sun Nov 13 07:22:43 2011 -0600
@@ -1,1085 +1,1719 @@
-/* $Id: dw.h,v 1.33 2003/12/02 18:40:52 bsmith Exp $ */
-
-#ifndef _H_DW
-#define _H_DW
-
-/* Dynamic Windows version numbers */
-#define DW_MAJOR_VERSION 1
-#define DW_MINOR_VERSION 0
-#define DW_SUB_VERSION 0
-
-/* These corespond to the entries in the color
- * arrays in the Win32 dw.c, they are also the
- * same as DOS ANSI colors.
- */
-#define DW_CLR_BLACK             0
-#define DW_CLR_DARKRED           1
-#define DW_CLR_DARKGREEN         2
-#define DW_CLR_BROWN             3
-#define DW_CLR_DARKBLUE          4
-#define DW_CLR_DARKPINK          5
-#define DW_CLR_DARKCYAN          6
-#define DW_CLR_PALEGRAY          7
-#define DW_CLR_DARKGRAY          8
-#define DW_CLR_RED               9
-#define DW_CLR_GREEN             10
-#define DW_CLR_YELLOW            11
-#define DW_CLR_BLUE              12
-#define DW_CLR_PINK              13
-#define DW_CLR_CYAN              14
-#define DW_CLR_WHITE             15
-#define DW_CLR_DEFAULT           16
-
-/* Signal handler defines */
-#define DW_SIGNAL_CONFIGURE      "configure_event"
-#define DW_SIGNAL_KEY_PRESS      "key_press_event"
-#define DW_SIGNAL_BUTTON_PRESS   "button_press_event"
-#define DW_SIGNAL_BUTTON_RELEASE "button_release_event"
-#define DW_SIGNAL_MOTION_NOTIFY  "motion_notify_event"
-#define DW_SIGNAL_DELETE         "delete_event"
-#define DW_SIGNAL_EXPOSE         "expose_event"
-#define DW_SIGNAL_CLICKED        "clicked"
-#define DW_SIGNAL_ITEM_ENTER     "container-select"
-#define DW_SIGNAL_ITEM_CONTEXT   "container-context"
-#define DW_SIGNAL_ITEM_SELECT    "tree-select"
-#define DW_SIGNAL_LIST_SELECT    "item-select"
-#define DW_SIGNAL_SET_FOCUS      "set-focus"
-#define DW_SIGNAL_VALUE_CHANGED  "value_changed"
-#define DW_SIGNAL_SWITCH_PAGE    "switch-page"
-#define DW_SIGNAL_COLUMN_CLICK   "click-column"
-#define DW_SIGNAL_TREE_EXPAND    "tree-expand"
-
-#if defined(__OS2__) || defined(__WIN32__) || defined(__MAC__) || defined(WINNT) || defined(__EMX__)
-/* OS/2, Windows or MacOS */
-
-#if defined(__IBMC__) && !defined(API)
-#define API _System
-#endif
-
-/* Used internally */
-#define TYPEBOX  0
-#define TYPEITEM 1
-
-#define SIZESTATIC 0
-#define SIZEEXPAND 1
-
-#define SPLITBAR_WIDTH 4
-#define BUBBLE_HELP_MAX 256
-
-typedef struct _user_data
-{
-	struct _user_data *next;
-	void              *data;
-	char              *varname;
-} UserData;
-
-/* OS/2 Specific section */
-#if defined(__OS2__) || defined(__EMX__)
-#define INCL_DOS
-#define INCL_WIN
-#define INCL_GPI
-
-#include <os2.h>
-
-#define DW_DT_LEFT               DT_LEFT
-#define DW_DT_QUERYEXTENT        DT_QUERYEXTENT
-#define DW_DT_UNDERSCORE         DT_UNDERSCORE
-#define DW_DT_STRIKEOUT          DT_STRIKEOUT
-#define DW_DT_TEXTATTRS          DT_TEXTATTRS
-#define DW_DT_EXTERNALLEADING    DT_EXTERNALLEADING
-#define DW_DT_CENTER             DT_CENTER
-#define DW_DT_RIGHT              DT_RIGHT
-#define DW_DT_TOP                DT_TOP
-#define DW_DT_VCENTER            DT_VCENTER
-#define DW_DT_BOTTOM             DT_BOTTOM
-#define DW_DT_HALFTONE           DT_HALFTONE
-#define DW_DT_MNEMONIC           DT_MNEMONIC
-#define DW_DT_WORDBREAK          DT_WORDBREAK
-#define DW_DT_ERASERECT          DT_ERASERECT
-
-#ifndef FCF_CLOSEBUTTON
-#define FCF_CLOSEBUTTON            0x04000000L
-#endif
-
-#define DW_FCF_TITLEBAR          FCF_TITLEBAR
-#define DW_FCF_SYSMENU           (FCF_SYSMENU | FCF_CLOSEBUTTON)
-#define DW_FCF_MENU              FCF_MENU
-#define DW_FCF_SIZEBORDER        FCF_SIZEBORDER
-#define DW_FCF_MINBUTTON         FCF_MINBUTTON
-#define DW_FCF_MAXBUTTON         FCF_MAXBUTTON
-#define DW_FCF_MINMAX            FCF_MINMAX
-#define DW_FCF_VERTSCROLL        FCF_VERTSCROLL
-#define DW_FCF_HORZSCROLL        FCF_HORZSCROLL
-#define DW_FCF_DLGBORDER         FCF_DLGBORDER
-#define DW_FCF_BORDER            FCF_BORDER
-#define DW_FCF_SHELLPOSITION     FCF_SHELLPOSITION
-#define DW_FCF_TASKLIST          FCF_TASKLIST
-#define DW_FCF_NOBYTEALIGN       FCF_NOBYTEALIGN
-#define DW_FCF_NOMOVEWITHOWNER   FCF_NOMOVEWITHOWNER
-#define DW_FCF_SYSMODAL          FCF_SYSMODAL
-#define DW_FCF_HIDEBUTTON        FCF_HIDEBUTTON
-#define DW_FCF_HIDEMAX           FCF_HIDEMAX
-#define DW_FCF_AUTOICON          FCF_AUTOICON
-#define DW_FCF_MAXIMIZE          WS_MAXIMIZED
-#define DW_FCF_MINIMIZE          WS_MINIMIZED
-
-#define DW_CFA_BITMAPORICON      CFA_BITMAPORICON
-#define DW_CFA_STRING            CFA_STRING
-#define DW_CFA_ULONG             CFA_ULONG
-#define DW_CFA_TIME              CFA_TIME
-#define DW_CFA_DATE              CFA_DATE
-#define DW_CFA_CENTER            CFA_CENTER
-#define DW_CFA_LEFT              CFA_LEFT
-#define DW_CFA_RIGHT             CFA_RIGHT
-#define DW_CFA_HORZSEPARATOR     CFA_HORZSEPARATOR
-#define DW_CFA_SEPARATOR         CFA_SEPARATOR
-#define DW_CFA_STRINGANDICON     0
-
-#define DW_CRA_SELECTED          CRA_SELECTED
-#define DW_CRA_CURSORED          CRA_CURSORED
-
-#define DW_LS_MULTIPLESEL        LS_MULTIPLESEL
-
-#define DW_LIT_NONE              -1
-
-#define DW_MLE_CASESENSITIVE     MLFSEARCH_CASESENSITIVE
-
-#define DW_POINTER_ARROW         SPTR_ARROW
-#define DW_POINTER_CLOCK         SPTR_WAIT
-
-#define DW_OS2_NEW_WINDOW        1
-
-/* flag values for dw_messagebox() */
-#define DW_MB_OK                 MB_OK
-#define DW_MB_OKCANCEL           MB_OKCANCEL
-#define DW_MB_YESNO              MB_YESNO
-#define DW_MB_YESNOCANCEL        MB_YESNOCANCEL
-
-#define DW_MB_WARNING            MB_WARNING
-#define DW_MB_ERROR              MB_ERROR
-#define DW_MB_INFORMATION        MB_INFORMATION
-#define DW_MB_QUESTION           MB_QUERY
-
-/* Virtual Key Codes */
-#define VK_LBUTTON           VK_BUTTON1
-#define VK_RBUTTON           VK_BUTTON2
-#define VK_MBUTTON           VK_BUTTON3
-#define VK_RETURN            VK_NEWLINE
-#define VK_SNAPSHOT          VK_PRINTSCRN
-#define VK_CANCEL            VK_BREAK
-#define VK_CAPITAL           VK_CAPSLOCK
-#define VK_ESCAPE            VK_ESC
-#define VK_PRIOR             VK_PAGEUP
-#define VK_NEXT              VK_PAGEDOWN
-#define VK_SELECT            133
-#define VK_EXECUTE           134
-#define VK_PRINT             135
-#define VK_HELP              136
-#define VK_LWIN              137
-#define VK_RWIN              138
-#define VK_MULTIPLY          ('*' + 128)
-#define VK_ADD               ('+' + 128)
-#define VK_SEPARATOR         141
-#define VK_SUBTRACT          ('-' + 128)
-#define VK_DECIMAL           ('.' + 128)
-#define VK_DIVIDE            ('/' + 128)
-#define VK_SCROLL            VK_SCRLLOCK
-#define VK_LSHIFT            VK_SHIFT
-#define VK_RSHIFT            147
-#define VK_LCONTROL          VK_CTRL
-#define VK_RCONTROL          149
-#define VK_NUMPAD0           ('0' + 128)
-#define VK_NUMPAD1           ('1' + 128)
-#define VK_NUMPAD2           ('2' + 128)
-#define VK_NUMPAD3           ('3' + 128)
-#define VK_NUMPAD4           ('4' + 128)
-#define VK_NUMPAD5           ('5' + 128)
-#define VK_NUMPAD6           ('6' + 128)
-#define VK_NUMPAD7           ('7' + 128)
-#define VK_NUMPAD8           ('8' + 128)
-#define VK_NUMPAD9           ('9' + 128)
-#define VK_BACK              VK_BACKSPACE
-#define VK_LMENU             VK_MENU
-#define VK_RMENU             VK_MENU
-
-typedef struct _window_data {
-	PFNWP oldproc;
-	UserData *root;
-	HWND clickdefault;
-	ULONG flags;
-	void *data;
-} WindowData;
-
-typedef struct _hpixmap {
-	unsigned long width, height;
-	HDC hdc;
-	HPS hps;
-	HBITMAP hbm;
-	HWND handle;
-} *HPIXMAP;
-
-typedef void *HTREEITEM;
-typedef HWND HMENUI;
-typedef HMODULE HMOD;
-typedef unsigned short UWORD;
-
-extern HAB dwhab;
-extern HMQ dwhmq;
-#endif
-
-#if defined(__MAC__)
-/* MacOS specific section */
-#include <Carbon/Carbon.h>
-
-typedef ControlRef HWND;
-typedef ThreadID DWTID;
-typedef unsigned long ULONG;
-typedef long LONG;
-typedef unsigned short USHORT;
-typedef short SHORT;
-typedef unsigned short UWORD;
-typedef short WORD ;
-typedef unsigned char UCHAR;
-typedef char CHAR;
-typedef unsigned UINT;
-typedef int INT;
-typedef void *HMTX;
-typedef void *HEV;
-typedef void *HMOD;
-typedef void *HPIXMAP;
-typedef void *HTREEITEM;
-typedef void *HMENUI;
-
-typedef struct _window_data {
-	UserData *root;
-	HWND clickdefault;
-	ULONG flags;
-	void *data;
-} WindowData;
-
-#define DW_DT_LEFT               0
-#define DW_DT_QUERYEXTENT        0
-#define DW_DT_UNDERSCORE         0
-#define DW_DT_STRIKEOUT          0
-#define DW_DT_TEXTATTRS          0
-#define DW_DT_EXTERNALLEADING    0
-#define DW_DT_CENTER             0
-#define DW_DT_RIGHT              0
-#define DW_DT_TOP                0
-#define DW_DT_VCENTER            0
-#define DW_DT_BOTTOM             0
-#define DW_DT_HALFTONE           0
-#define DW_DT_MNEMONIC           0
-#define DW_DT_WORDBREAK          0
-#define DW_DT_ERASERECT          0
-
-#define DW_FCF_TITLEBAR          0
-#define DW_FCF_SYSMENU           0
-#define DW_FCF_MENU              0
-#define DW_FCF_SIZEBORDER        0
-#define DW_FCF_MINBUTTON         0
-#define DW_FCF_MAXBUTTON         0
-#define DW_FCF_MINMAX            0
-#define DW_FCF_VERTSCROLL        0
-#define DW_FCF_HORZSCROLL        0
-#define DW_FCF_DLGBORDER         0
-#define DW_FCF_BORDER            0
-#define DW_FCF_SHELLPOSITION     0
-#define DW_FCF_TASKLIST          0
-#define DW_FCF_NOBYTEALIGN       0
-#define DW_FCF_NOMOVEWITHOWNER   0
-#define DW_FCF_SYSMODAL          0
-#define DW_FCF_HIDEBUTTON        0
-#define DW_FCF_HIDEMAX           0
-#define DW_FCF_AUTOICON          0
-#define DW_FCF_MAXIMIZE          0
-#define DW_FCF_MINIMIZE          0
-
-#define DW_CFA_BITMAPORICON      1
-#define DW_CFA_STRING            (1 << 1)
-#define DW_CFA_ULONG             (1 << 2)
-#define DW_CFA_TIME              (1 << 3)
-#define DW_CFA_DATE              (1 << 4)
-#define DW_CFA_CENTER            (1 << 5)
-#define DW_CFA_LEFT              (1 << 6)
-#define DW_CFA_RIGHT             (1 << 7)
-#define DW_CFA_STRINGANDICON     (1 << 8)
-#define DW_CFA_HORZSEPARATOR     0
-#define DW_CFA_SEPARATOR         0
-
-#define DW_CRA_SELECTED          1
-#define DW_CRA_CURSORED          (1 << 1)
-
-#define DW_LS_MULTIPLESEL        1
-
-#define DW_LIT_NONE              -1
-
-#define DW_MLE_CASESENSITIVE     MLFSEARCH_CASESENSITIVE
-
-#define DW_POINTER_ARROW         0
-#define DW_POINTER_CLOCK         watchCursor
-
-#define HWND_DESKTOP		 ((HWND)0)
-
-/* flag values for dw_messagebox() */
-#define DW_MB_OK                 (1 << 1)
-#define DW_MB_OKCANCEL           (1 << 2)
-#define DW_MB_YESNO              (1 << 3)
-#define DW_MB_YESNOCANCEL        (1 << 4)
-
-#define DW_MB_WARNING            (1 << 10)
-#define DW_MB_ERROR              (1 << 11)
-#define DW_MB_INFORMATION        (1 << 12)
-#define DW_MB_QUESTION           (1 << 13)
-
-
-#endif
-
-/* Windows specific section */
-#if defined(__WIN32__) || defined(WINNT)
-#include <windows.h>
-#include <commctrl.h>
-
-#if defined(MSVC) && !defined(API)
-#define API _cdecl
-#endif
-
-#define DW_DT_LEFT               SS_LEFT
-#define DW_DT_QUERYEXTENT        0
-#define DW_DT_UNDERSCORE         0
-#define DW_DT_STRIKEOUT          0
-#define DW_DT_TEXTATTRS          0
-#define DW_DT_EXTERNALLEADING    0
-#define DW_DT_CENTER             SS_CENTER
-#define DW_DT_RIGHT              SS_RIGHT
-#define DW_DT_TOP                0
-#define DW_DT_VCENTER            SS_NOPREFIX
-#define DW_DT_BOTTOM             0
-#define DW_DT_HALFTONE           0
-#define DW_DT_MNEMONIC           0
-#define DW_DT_WORDBREAK          0
-#define DW_DT_ERASERECT          0
-
-#define DW_FCF_TITLEBAR          WS_CAPTION
-#define DW_FCF_SYSMENU           WS_SYSMENU
-#define DW_FCF_MENU              0
-#define DW_FCF_SIZEBORDER        WS_THICKFRAME
-#define DW_FCF_MINBUTTON         WS_MINIMIZEBOX
-#define DW_FCF_MAXBUTTON         WS_MAXIMIZEBOX
-#define DW_FCF_MINMAX            (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
-#define DW_FCF_VERTSCROLL        WS_VSCROLL
-#define DW_FCF_HORZSCROLL        WS_HSCROLL
-#define DW_FCF_DLGBORDER         WS_DLGFRAME
-#define DW_FCF_BORDER            WS_BORDER
-#define DW_FCF_SHELLPOSITION     0
-#define DW_FCF_TASKLIST          WS_VSCROLL
-#define DW_FCF_NOBYTEALIGN       0
-#define DW_FCF_NOMOVEWITHOWNER   0
-#define DW_FCF_SYSMODAL          0
-#define DW_FCF_HIDEBUTTON        WS_MINIMIZEBOX
-#define DW_FCF_HIDEMAX           0
-#define DW_FCF_AUTOICON          0
-#define DW_FCF_MAXIMIZE          WS_MAXIMIZE
-#define DW_FCF_MINIMIZE          WS_MINIMIZE
-
-#define DW_CFA_BITMAPORICON      1
-#define DW_CFA_STRING            (1 << 1)
-#define DW_CFA_ULONG             (1 << 2)
-#define DW_CFA_TIME              (1 << 3)
-#define DW_CFA_DATE              (1 << 4)
-#define DW_CFA_CENTER            (1 << 5)
-#define DW_CFA_LEFT              (1 << 6)
-#define DW_CFA_RIGHT             (1 << 7)
-#define DW_CFA_STRINGANDICON     (1 << 8)
-#define DW_CFA_HORZSEPARATOR     0
-#define DW_CFA_SEPARATOR         0
-
-#define DW_CRA_SELECTED          LVNI_SELECTED
-#define DW_CRA_CURSORED          LVNI_FOCUSED
-
-#define DW_LS_MULTIPLESEL        LBS_MULTIPLESEL
-
-#define DW_LIT_NONE              -1
-
-#define DW_MLE_CASESENSITIVE     1
-
-#define DW_POINTER_ARROW         32512
-#define DW_POINTER_CLOCK         32514
-
-/* flag values for dw_messagebox() */
-#define DW_MB_OK                 MB_OK
-#define DW_MB_OKCANCEL           MB_OKCANCEL
-#define DW_MB_YESNO              MB_YESNO
-#define DW_MB_YESNOCANCEL        MB_YESNOCANCEL
-
-#define DW_MB_WARNING            MB_ICONWARNING
-#define DW_MB_ERROR              MB_ICONERROR
-#define DW_MB_INFORMATION        MB_ICONINFORMATION
-#define DW_MB_QUESTION           MB_ICONQUESTION
-
-/* Key Modifiers */
-#define KC_CTRL                  (1)
-#define KC_SHIFT                 (1 << 1)
-#define KC_ALT                   (1 << 2)
-
-#define STATICCLASSNAME "STATIC"
-#define COMBOBOXCLASSNAME "COMBOBOX"
-#define LISTBOXCLASSNAME "LISTBOX"
-#define BUTTONCLASSNAME "BUTTON"
-#define POPUPMENUCLASSNAME "POPUPMENU"
-#define EDITCLASSNAME "EDIT"
-#define FRAMECLASSNAME "FRAME"
-#define SCROLLBARCLASSNAME "SCROLLBAR"
-
-#define ClassName "dynamicwindows"
-#define SplitbarClassName "dwsplitbar"
-#define ObjectClassName "dwobjectclass"
-#define DefaultFont NULL
-
-typedef struct _color {
-	int fore;
-	int back;
-	HWND combo, buddy;
-	int user;
-	int vcenter;
-	HWND clickdefault;
-	HBRUSH hbrush;
-	HFONT hfont;
-	char fontname[128];
-	WNDPROC pOldProc;
-	UserData *root;
-} ColorInfo;
-
-typedef struct _notebookpage {
-	ColorInfo cinfo;
-	TC_ITEM item;
-	HWND hwnd;
-	int realid;
-} NotebookPage;
-
-typedef HANDLE HMTX;
-typedef HANDLE HEV;
-typedef HANDLE HMOD;
-
-typedef struct _container {
-	ColorInfo cinfo;
-	ULONG *flags;
-	WNDPROC pOldProc;
-	ULONG columns;
-} ContainerInfo;
-
-typedef struct _hpixmap {
-	unsigned long width, height;
-	HBITMAP hbm;
-	HDC hdc;
-	HWND handle;
-	void *bits;
-} *HPIXMAP;
-
-typedef HWND HMENUI;
-#endif
-
-typedef struct _item {
-	/* Item type - Box or Item */
-	int type;
-	/* Handle to Frame or Window */
-	HWND hwnd;
-	/* Width and Height of static size */
-	int width, height, origwidth, origheight;
-	/* Size Type - Static or Expand */
-	int hsize, vsize;
-	/* Padding */
-	int pad;
-	/* Ratio of current item */
-	float xratio, yratio;
-} Item;
-
-typedef struct _box {
-#if defined(__WIN32__) || defined(WINNT)
-	ColorInfo cinfo;
-#elif defined(__OS2__) || defined(__EMX__)
-	PFNWP oldproc;
-	UserData *root;
-	HWND hwndtitle;
-	int titlebar;
-#endif
-	/* Number of items in the box */
-	int count;
-	/* Box type - horizontal or vertical */
-	int type;
-	/* Padding */
-	int pad, parentpad, grouppadx, grouppady;
-	/* Groupbox */
-	HWND grouphwnd;
-	/* Default item */
-	HWND defaultitem;
-	/* Used as temporary storage in the calculation stage */
-	int upx, upy, minheight, minwidth;
-	/* Ratio in this box */
-	float xratio, yratio, parentxratio, parentyratio;
-	/* Used for calculating individual item ratios */
-	int width, height;
-	/* Any combinations of flags describing the box */
-	unsigned long flags;
-	/* Array of item structures */
-	struct _item *items;
-} Box;
-
-typedef struct _bubblebutton {
-#if defined(__WIN32__) || defined(WINNT)
-	ColorInfo cinfo;
-	int checkbox;
-	WNDPROC pOldProc;
-#endif
-#if defined(__OS2__) || defined(__EMX__)
-	PFNWP pOldProc;
-	UserData *root;
-#endif
-	unsigned long id;
-	char bubbletext[BUBBLE_HELP_MAX];
-} BubbleButton;
-
-#else
-/* GTK Specific section */
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkkeysyms.h>
-#include <pthread.h>
-#include <dlfcn.h>
-
-#define DW_DT_LEFT               1
-#define DW_DT_UNDERSCORE         (1 << 1)
-#define DW_DT_STRIKEOUT          (1 << 2)
-#define DW_DT_CENTER             (1 << 3)
-#define DW_DT_RIGHT              (1 << 4)
-#define DW_DT_TOP                (1 << 5)
-#define DW_DT_VCENTER            (1 << 6)
-#define DW_DT_BOTTOM             (1 << 7)
-#define DW_DT_HALFTONE           (1 << 8)
-#define DW_DT_MNEMONIC           (1 << 9)
-#define DW_DT_WORDBREAK          (1 << 10)
-#define DW_DT_ERASERECT          (1 << 11)
-
-/* these don't exist under gtk, so make them dummy entries */
-#define DW_DT_QUERYEXTENT        0
-#define DW_DT_TEXTATTRS          0
-#define DW_DT_EXTERNALLEADING    0
-
-#define DW_FCF_TITLEBAR          1
-#define DW_FCF_SYSMENU           (1 << 1)
-#define DW_FCF_MENU              (1 << 2)
-#define DW_FCF_SIZEBORDER        (1 << 3)
-#define DW_FCF_MINBUTTON         (1 << 4)
-#define DW_FCF_MAXBUTTON         (1 << 5)
-#define DW_FCF_MINMAX            (1 << 6)
-#define DW_FCF_VERTSCROLL        (1 << 7)
-#define DW_FCF_HORZSCROLL        (1 << 8)
-#define DW_FCF_DLGBORDER         (1 << 9)
-#define DW_FCF_BORDER            (1 << 10)
-#define DW_FCF_SHELLPOSITION     (1 << 11)
-#define DW_FCF_TASKLIST          (1 << 12)
-#define DW_FCF_NOBYTEALIGN       (1 << 13)
-#define DW_FCF_NOMOVEWITHOWNER   (1 << 14)
-#define DW_FCF_SYSMODAL          (1 << 15)
-#define DW_FCF_HIDEBUTTON        (1 << 16)
-#define DW_FCF_HIDEMAX           (1 << 17)
-#define DW_FCF_AUTOICON          (1 << 18)
-#define DW_FCF_MAXIMIZE          (1 << 19)
-#define DW_FCF_MINIMIZE          (1 << 20)
-
-#define DW_CFA_BITMAPORICON      1
-#define DW_CFA_STRING            (1 << 1)
-#define DW_CFA_ULONG             (1 << 2)
-#define DW_CFA_TIME              (1 << 3)
-#define DW_CFA_DATE              (1 << 4)
-#define DW_CFA_CENTER            (1 << 5)
-#define DW_CFA_LEFT              (1 << 6)
-#define DW_CFA_RIGHT             (1 << 7)
-#define DW_CFA_HORZSEPARATOR     (1 << 8)
-#define DW_CFA_SEPARATOR         (1 << 9)
-#define DW_CFA_STRINGANDICON     (1 << 10)
-
-#define DW_CRA_SELECTED          1
-#define DW_CRA_CURSORED          (1 << 1)
-
-#define DW_LS_MULTIPLESEL        1
-
-#define DW_LIT_NONE              -1
-
-#define DW_MLE_CASESENSITIVE     1
-
-#define DW_POINTER_ARROW         GDK_TOP_LEFT_ARROW
-#define DW_POINTER_CLOCK         GDK_WATCH
-
-#define HWND_DESKTOP             ((HWND)0)
-
-/* flag values for dw_messagebox() */
-#define DW_MB_OK                 (1 << 1)
-#define DW_MB_OKCANCEL           (1 << 2)
-#define DW_MB_YESNO              (1 << 3)
-#define DW_MB_YESNOCANCEL        (1 << 4)
-
-#define DW_MB_WARNING            (1 << 10)
-#define DW_MB_ERROR              (1 << 11)
-#define DW_MB_INFORMATION        (1 << 12)
-#define DW_MB_QUESTION           (1 << 13)
-
-/* Virtual Key Codes */
-#define VK_LBUTTON           GDK_Pointer_Button1
-#define VK_RBUTTON           GDK_Pointer_Button3
-#define VK_CANCEL            GDK_Cancel
-#define VK_MBUTTON           GDK_Pointer_Button2
-#define VK_BACK              GDK_BackSpace
-#define VK_TAB               GDK_Tab
-#define VK_CLEAR             GDK_Clear
-#define VK_RETURN            GDK_Return
-#define VK_MENU              GDK_Menu
-#define VK_PAUSE             GDK_Pause
-#define VK_CAPITAL           GDK_Caps_Lock
-#define VK_ESCAPE            GDK_Escape
-#define VK_SPACE             GDK_space
-#define VK_PRIOR             GDK_Page_Up
-#define VK_NEXT              GDK_Page_Down
-#define VK_END               GDK_End
-#define VK_HOME              GDK_Home
-#define VK_LEFT              GDK_Left
-#define VK_UP                GDK_Up
-#define VK_RIGHT             GDK_Right
-#define VK_DOWN              GDK_Down
-#define VK_SELECT            GDK_Select
-#define VK_PRINT             GDK_Sys_Req
-#define VK_EXECUTE           GDK_Execute
-#define VK_SNAPSHOT          GDK_Print
-#define VK_INSERT            GDK_Insert
-#define VK_DELETE            GDK_Delete
-#define VK_HELP              GDK_Help
-#define VK_LWIN              GDK_Super_L
-#define VK_RWIN              GDK_Super_R
-#define VK_NUMPAD0           GDK_KP_0
-#define VK_NUMPAD1           GDK_KP_1
-#define VK_NUMPAD2           GDK_KP_2
-#define VK_NUMPAD3           GDK_KP_3
-#define VK_NUMPAD4           GDK_KP_4
-#define VK_NUMPAD5           GDK_KP_5
-#define VK_NUMPAD6           GDK_KP_6
-#define VK_NUMPAD7           GDK_KP_7
-#define VK_NUMPAD8           GDK_KP_8
-#define VK_NUMPAD9           GDK_KP_9
-#define VK_MULTIPLY          GDK_KP_Multiply
-#define VK_ADD               GDK_KP_Add
-#define VK_SEPARATOR         GDK_KP_Separator
-#define VK_SUBTRACT          GDK_KP_Subtract
-#define VK_DECIMAL           GDK_KP_Decimal
-#define VK_DIVIDE            GDK_KP_Divide
-#define VK_F1                GDK_F1
-#define VK_F2                GDK_F2
-#define VK_F3                GDK_F3
-#define VK_F4                GDK_F4
-#define VK_F5                GDK_F5
-#define VK_F6                GDK_F6
-#define VK_F7                GDK_F7
-#define VK_F8                GDK_F8
-#define VK_F9                GDK_F9
-#define VK_F10               GDK_F10
-#define VK_F11               GDK_F11
-#define VK_F12               GDK_F12
-#define VK_F13               GDK_F13
-#define VK_F14               GDK_F14
-#define VK_F15               GDK_F15
-#define VK_F16               GDK_F16
-#define VK_F17               GDK_F17
-#define VK_F18               GDK_F18
-#define VK_F19               GDK_F19
-#define VK_F20               GDK_F20
-#define VK_F21               GDK_F21
-#define VK_F22               GDK_F22
-#define VK_F23               GDK_F23
-#define VK_F24               GDK_F24
-#define VK_NUMLOCK           GDK_Num_Lock
-#define VK_SCROLL            GDK_Scroll_Lock
-#define VK_LSHIFT            GDK_Shift_L
-#define VK_RSHIFT            GDK_Shift_R
-#define VK_LCONTROL          GDK_Control_L
-#define VK_RCONTROL          GDK_Control_R
-#define VK_LMENU             GDK_Menu
-#define VK_RMENU             GDK_Menu
-
-/* Key Modifiers */
-#define KC_CTRL              GDK_CONTROL_MASK
-#define KC_SHIFT             GDK_SHIFT_MASK
-#define KC_ALT               GDK_MOD1_MASK
-
-typedef GtkWidget *HWND;
-#ifndef _ENVRNMNT_H
-typedef unsigned long ULONG;
-#endif
-typedef long LONG;
-typedef unsigned short USHORT;
-typedef short SHORT;
-typedef unsigned short UWORD;
-typedef short WORD ;
-typedef unsigned char UCHAR;
-typedef char CHAR;
-typedef unsigned UINT;
-typedef int INT;
-typedef pthread_mutex_t *HMTX;
-typedef struct _dw_unix_event {
-	pthread_mutex_t mutex;
-	pthread_cond_t event;
-	pthread_t thread;
-	int alive;
-	int posted;
-} *HEV;
-typedef pthread_t DWTID;
-typedef void * HMOD;
-
-typedef struct _hpixmap {
-	unsigned long width, height;
-	GdkPixmap *pixmap;
-	HWND handle;
-} *HPIXMAP;
-
-typedef GtkWidget *HMENUI;
-typedef void *HTREEITEM;
-
-typedef struct _resource_struct {
-	long resource_max, *resource_id;
-	char **resource_data;
-} DWResources;
-
-#if !defined(DW_RESOURCES) || defined(BUILD_DLL)
-static DWResources _resources = { 0, 0, 0 };
-#else
-extern DWResources _resources;
-#endif
-
-#endif
-
-#if !defined(__OS2__) && !defined(__EMX__)
-typedef struct _CDATE
-{
-	UCHAR  day;
-	UCHAR  month;
-	USHORT year;
-} CDATE;
-typedef CDATE *PCDATE;
-
-typedef struct _CTIME
-{
-	UCHAR hours;
-	UCHAR minutes;
-	UCHAR seconds;
-	UCHAR ucReserved;
-} CTIME;
-typedef CTIME *PCTIME;
-#endif
-
-#if defined(__OS2__) || defined(__WIN32__) || defined(WINNT) || defined(__EMX__)
-typedef unsigned long DWTID;
-#endif
-
-typedef struct _dwenv {
-	/* Operating System Name and DW Build Date/Time */
-	char osName[30], buildDate[30], buildTime[30];
-	/* Versions and builds */
-	short MajorVersion, MinorVersion, MajorBuild, MinorBuild;
-	/* Dynamic Window version */
-	short DWMajorVersion, DWMinorVersion, DWSubVersion;
-} DWEnv;
-
-
-typedef struct _dwexpose {
-	int x, y;
-	int width, height;
-} DWExpose;
-
-typedef struct _dwdialog {
-	HEV eve;
-	int done;
-	int method;
-	void *data, *result;
-} DWDialog;
-
-#define DW_SIGNAL_FUNC(a) ((void *)a)
-
-#define DW_DESKTOP               HWND_DESKTOP
-#define DW_MINIMIZED 1
-
-#define DW_BUTTON1_MASK 1
-#define DW_BUTTON2_MASK (1 << 1)
-#define DW_BUTTON3_MASK (1 << 2)
-
-#define DW_EXEC_CON 0
-#define DW_EXEC_GUI 1
-
-#define DW_FILE_OPEN      0
-#define DW_FILE_SAVE      1
-#define DW_DIRECTORY_OPEN 2
-
-#define DW_HORZ 0
-#define DW_VERT 1
-
-/* Obsolete, should disappear sometime */
-#define BOXHORZ DW_HORZ
-#define BOXVERT DW_VERT
-
-#define DW_SCROLL_UP 0
-#define DW_SCROLL_DOWN 1
-#define DW_SCROLL_TOP 2
-#define DW_SCROLL_BOTTOM 3
-
-/* return values for dw_messagebox() */
-#define DW_MB_RETURN_OK           0
-#define DW_MB_RETURN_YES          1
-#define DW_MB_RETURN_NO           0
-#define DW_MB_RETURN_CANCEL       2
-
-#define DW_PIXMAP_WIDTH(x) (x ? x->width : 0)
-#define DW_PIXMAP_HEIGHT(x) (x ? x->height : 0)
-
-#define DW_RGB_COLOR (0xF0000000)
-#define DW_RGB_TRANSPARENT (0x0F000000)
-#define DW_RGB_MASK (0x00FFFFFF)
-#define DW_RED_MASK (0x000000FF)
-#define DW_GREEN_MASK (0x0000FF00)
-#define DW_BLUE_MASK (0x00FF0000)
-#define DW_RED_VALUE(a) (a & DW_RED_MASK)
-#define DW_GREEN_VALUE(a) ((a & DW_GREEN_MASK) >> 8)
-#define DW_BLUE_VALUE(a) ((a & DW_BLUE_MASK) >> 16)
-#define DW_RGB(a, b, c) (0xF0000000 | a | b << 8 | c << 16)
-
-#define DW_MENU_SEPARATOR ""
-#define DW_NOMENU 0
-
-#if defined(__OS2__) || defined(__EMX__)
-#define DW_OS2_RGB(a) ((DW_RED_VALUE(a) << 16) | (DW_GREEN_VALUE(a) << 8) | DW_BLUE_VALUE(a))
-#endif
-
-#ifndef API
-#define API
-#endif
-
-#define DWSIGNAL API
-
-/* Let other APIs know what types we've defined,
- * Regina REXX in particular, on Unix.
- */
-#define ULONG_TYPEDEFED 1
-#define LONG_TYPEDEFED 1
-#define USHORT_TYPEDEFED 1
-#define SHORT_TYPEDEFED 1
-#define UWORD_TYPEDEFED 1
-#define WORD_TYPEDEFED 1
-#define UCHAR_TYPEDEFED 1
-#define CHAR_TYPEDEFED 1
-#define UINT_TYPEDEFED 1
-#define INT_TYPEDEFED 1
-
-/* Public function prototypes */
-void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
-void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
-#if !defined(__OS2__) && !defined(__WIN32__) && !defined(__EMX__) && !defined(__MAC__)
-int API dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]);
-#define dw_init(a, b, c) dw_int_init(&_resources, a, &b, &c)
-#else
-int API dw_init(int newthread, int argc, char *argv[]);
-#endif
-void API dw_main(void);
-void API dw_main_sleep(int seconds);
-void API dw_main_iteration(void);
-void API dw_free(void *ptr);
-int API dw_window_show(HWND handle);
-int API dw_window_hide(HWND handle);
-int API dw_window_minimize(HWND handle);
-int API dw_window_raise(HWND handle);
-int API dw_window_lower(HWND handle);
-int API dw_window_destroy(HWND handle);
-void API dw_window_redraw(HWND handle);
-int API dw_window_set_font(HWND handle, char *fontname);
-int API dw_window_set_color(HWND handle, unsigned long fore, unsigned long back);
-HWND API dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle);
-HWND API dw_box_new(int type, int pad);
-HWND API dw_groupbox_new(int type, int pad, char *title);
-HWND API dw_mdi_new(unsigned long id);
-HWND API dw_bitmap_new(unsigned long id);
-HWND API dw_bitmapbutton_new(char *text, unsigned long id);
-HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename);
-HWND API dw_container_new(unsigned long id, int multi);
-HWND API dw_tree_new(unsigned long id);
-HWND API dw_text_new(char *text, unsigned long id);
-HWND API dw_status_text_new(char *text, unsigned long id);
-HWND API dw_mle_new(unsigned long id);
-HWND API dw_entryfield_new(char *text, unsigned long id);
-HWND API dw_entryfield_password_new(char *text, ULONG id);
-HWND API dw_combobox_new(char *text, unsigned long id);
-HWND API dw_button_new(char *text, unsigned long id);
-HWND API dw_spinbutton_new(char *text, unsigned long id);
-HWND API dw_radiobutton_new(char *text, ULONG id);
-HWND API dw_percent_new(unsigned long id);
-HWND API dw_slider_new(int vertical, int increments, ULONG id);
-HWND API dw_scrollbar_new(int vertical, int increments, ULONG id);
-HWND API dw_checkbox_new(char *text, unsigned long id);
-HWND API dw_listbox_new(unsigned long id, int multi);
-void API dw_listbox_append(HWND handle, char *text);
-void API dw_listbox_clear(HWND handle);
-int API dw_listbox_count(HWND handle);
-void API dw_listbox_set_top(HWND handle, int top);
-void API dw_listbox_select(HWND handle, int index, int state);
-void API dw_listbox_delete(HWND handle, int index);
-void API dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length);
-void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer);
-unsigned int API dw_listbox_selected(HWND handle);
-int API dw_listbox_selected_multi(HWND handle, int where);
-unsigned int API dw_percent_query_range(HWND handle);
-void API dw_percent_set_pos(HWND handle, unsigned int position);
-unsigned int API dw_slider_query_pos(HWND handle);
-void API dw_slider_set_pos(HWND handle, unsigned int position);
-unsigned int API dw_scrollbar_query_pos(HWND handle);
-void API dw_scrollbar_set_pos(HWND handle, unsigned int position);
-void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible);
-void API dw_window_set_pos(HWND handle, unsigned long x, unsigned long y);
-void API dw_window_set_usize(HWND handle, unsigned long width, unsigned long height);
-void API dw_window_set_pos_size(HWND handle, unsigned long x, unsigned long y, unsigned long width, unsigned long height);
-void API dw_window_get_pos_size(HWND handle, unsigned long *x, unsigned long *y, unsigned long *width, unsigned long *height);
-void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask);
-void API dw_window_set_icon(HWND handle, unsigned long id);
-void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
-char * API dw_window_get_text(HWND handle);
-void API dw_window_set_text(HWND handle, char *text);
-int API dw_window_set_border(HWND handle, int border);
-void API dw_window_disable(HWND handle);
-void API dw_window_enable(HWND handle);
-void API dw_window_capture(HWND handle);
-void API dw_window_release(void);
-void API dw_window_reparent(HWND handle, HWND newparent);
-void API dw_window_pointer(HWND handle, int pointertype);
-void API dw_window_default(HWND window, HWND defaultitem);
-void API dw_window_click_default(HWND window, HWND next);
-unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint);
-void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length);
-void API dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines);
-void API dw_mle_delete(HWND handle, int startpoint, int length);
-void API dw_mle_clear(HWND handle);
-void API dw_mle_freeze(HWND handle);
-void API dw_mle_thaw(HWND handle);
-void API dw_mle_set(HWND handle, int point);
-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);
-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);
-void API dw_entryfield_set_limit(HWND handle, ULONG limit);
-long API dw_spinbutton_query(HWND handle);
-int API dw_checkbox_query(HWND handle);
-void API dw_checkbox_set(HWND handle, int value);
-HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata);
-HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata);
-void API dw_tree_clear(HWND handle);
-void API dw_tree_delete(HWND handle, HTREEITEM item);
-void API dw_tree_set(HWND handle, HTREEITEM item, char *title, unsigned long icon);
-void API dw_tree_expand(HWND handle, HTREEITEM item);
-void API dw_tree_collapse(HWND handle, HTREEITEM item);
-void API dw_tree_item_select(HWND handle, HTREEITEM item);
-void API dw_tree_set_data(HWND handle, HTREEITEM item, void *itemdata);
-void * API dw_tree_get_data(HWND handle, HTREEITEM item);
-char * API dw_tree_get_title(HWND handle, HTREEITEM item);
-HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item);
-int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator);
-unsigned long API dw_icon_load(unsigned long module, unsigned long id);
-unsigned long API dw_icon_load_from_file(char *filename);
-void API dw_icon_free(unsigned long handle);
-void * API dw_container_alloc(HWND handle, int rowcount);
-void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data);
-void API dw_container_change_item(HWND handle, int column, int row, void *data);
-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_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);
-char * API dw_container_query_start(HWND handle, unsigned long flags);
-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_delete_row(HWND handle, char *text);
-void API dw_container_optimize(HWND handle);
-int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count);
-void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data);
-void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon);
-void dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext);
-void dw_taskbar_delete(HWND handle, unsigned long icon);
-int API dw_screen_width(void);
-int API dw_screen_height(void);
-unsigned long API dw_color_depth(void);
-HWND API dw_notebook_new(unsigned long id, int top);
-unsigned long API dw_notebook_page_new(HWND handle, unsigned long flags, int front);
-void API dw_notebook_page_destroy(HWND handle, unsigned int pageid);
-void API dw_notebook_page_set_text(HWND handle, unsigned long pageid, char *text);
-void API dw_notebook_page_set_status_text(HWND handle, unsigned long pageid, char *text);
-void API dw_notebook_page_set(HWND handle, unsigned int pageid);
-unsigned long API dw_notebook_page_query(HWND handle);
-void API dw_notebook_pack(HWND handle, unsigned long pageid, HWND page);
-HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id);
-void API dw_splitbar_set(HWND handle, float percent);
-float API dw_splitbar_get(HWND handle);
-HMENUI API dw_menu_new(unsigned long id);
-HMENUI API dw_menubar_new(HWND location);
-HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu);
-void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check);
-void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y);
-void API dw_menu_destroy(HMENUI *menu);
-void API dw_pointer_query_pos(long *x, long *y);
-void API dw_pointer_set_pos(long x, long y);
-void API dw_window_function(HWND handle, void *function, void *data);
-HWND API dw_window_from_id(HWND handle, int id);
-HMTX API dw_mutex_new(void);
-void API dw_mutex_close(HMTX mutex);
-void API dw_mutex_lock(HMTX mutex);
-void API dw_mutex_unlock(HMTX mutex);
-HEV API dw_event_new(void);
-int API dw_event_reset(HEV eve);
-int API dw_event_post(HEV eve);
-int API dw_event_wait(HEV eve, unsigned long timeout);
-int API dw_event_close (HEV *eve);
-DWTID API dw_thread_new(void *func, void *data, int stack);
-void API dw_thread_end(void);
-DWTID API dw_thread_id(void);
-void API dw_exit(int exitcode);
-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);
-void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y);
-void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2);
-void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height);
-void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text);
-void API dw_font_text_extents(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height);
-void API dw_flush(void);
-void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc);
-HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth);
-HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename);
-HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id);
-void API dw_pixmap_destroy(HPIXMAP pixmap);
-void API dw_beep(int freq, int dur);
-int API dw_messagebox(char *title, int flags, char *format, ...);
-void API dw_environment_query(DWEnv *env);
-int API dw_exec(char *program, int type, char **params);
-int API dw_browse(char *url);
-char * API dw_file_browse(char *title, char *defpath, char *ext, int flags);
-char * API dw_user_dir(void);
-DWDialog * API dw_dialog_new(void *data);
-int API dw_dialog_dismiss(DWDialog *dialog, void *result);
-void * API dw_dialog_wait(DWDialog *dialog);
-void API dw_window_set_data(HWND window, char *dataname, void *data);
-void * API dw_window_get_data(HWND window, char *dataname);
-int API dw_module_load(char *name, HMOD *handle);
-int API dw_module_symbol(HMOD handle, char *name, void**func);
-int API dw_module_close(HMOD handle);
-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_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);
-
-#endif
+/* $Id: dw.h 1311 2011-11-03 23:34:10Z bsmith $ */
+
+#ifndef _H_DW
+#define _H_DW
+
+/* Dynamic Windows version numbers */
+#define DW_MAJOR_VERSION 2
+#define DW_MINOR_VERSION 1
+#define DW_SUB_VERSION 0
+
+#if !defined(__PHOTON__)
+/* These corespond to the entries in the color
+ * arrays in the Win32 dw.c, they are also the
+ * same as DOS ANSI colors.
+ */
+#define DW_CLR_BLACK             0
+#define DW_CLR_DARKRED           1
+#define DW_CLR_DARKGREEN         2
+#define DW_CLR_BROWN             3
+#define DW_CLR_DARKBLUE          4
+#define DW_CLR_DARKPINK          5
+#define DW_CLR_DARKCYAN          6
+#define DW_CLR_PALEGRAY          7
+#define DW_CLR_DARKGRAY          8
+#define DW_CLR_RED               9
+#define DW_CLR_GREEN             10
+#define DW_CLR_YELLOW            11
+#define DW_CLR_BLUE              12
+#define DW_CLR_PINK              13
+#define DW_CLR_CYAN              14
+#define DW_CLR_WHITE             15
+#define DW_CLR_DEFAULT           16
+#endif
+
+/* Signal handler defines */
+#define DW_SIGNAL_CONFIGURE      "configure_event"
+#define DW_SIGNAL_KEY_PRESS      "key_press_event"
+#define DW_SIGNAL_BUTTON_PRESS   "button_press_event"
+#define DW_SIGNAL_BUTTON_RELEASE "button_release_event"
+#define DW_SIGNAL_MOTION_NOTIFY  "motion_notify_event"
+#define DW_SIGNAL_DELETE         "delete_event"
+#define DW_SIGNAL_EXPOSE         "expose_event"
+#define DW_SIGNAL_CLICKED        "clicked"
+#define DW_SIGNAL_ITEM_ENTER     "container-select"
+#define DW_SIGNAL_ITEM_CONTEXT   "container-context"
+#define DW_SIGNAL_ITEM_SELECT    "tree-select"
+#define DW_SIGNAL_LIST_SELECT    "item-select"
+#define DW_SIGNAL_SET_FOCUS      "set-focus"
+#define DW_SIGNAL_VALUE_CHANGED  "value_changed"
+#define DW_SIGNAL_SWITCH_PAGE    "switch-page"
+#define DW_SIGNAL_COLUMN_CLICK   "click-column"
+#define DW_SIGNAL_TREE_EXPAND    "tree-expand"
+
+/* status of menu items */
+#define DW_MIS_ENABLED           1
+#define DW_MIS_DISABLED          (1 << 1)
+#define DW_MIS_CHECKED           (1 << 2)
+#define DW_MIS_UNCHECKED         (1 << 3)
+
+/* ensure we can build the Gtk port with MingW on Windows */
+#if defined(DW_USE_GTK) && defined(__MINGW32__)
+# ifndef GDK_WINDOWING_WIN32
+#   define GDK_WINDOWING_WIN32
+# endif
+#endif
+
+#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || defined(__MAC__) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__)
+/* OS/2, Windows or MacOS */
+
+#if (defined(__IBMC__) || defined(_System)) && !defined(API)
+#define API _System
+#endif
+
+/* Used internally */
+#define TYPEBOX  0
+#define TYPEITEM 1
+
+#define SIZESTATIC 0
+#define SIZEEXPAND 1
+
+#define SPLITBAR_WIDTH 4
+#define BUBBLE_HELP_MAX 256
+
+typedef struct _user_data
+{
+   struct _user_data *next;
+   void              *data;
+   char              *varname;
+} UserData;
+
+/* OS/2 Specific section */
+#if defined(__OS2__) || defined(__EMX__)
+#define INCL_DOS
+#define INCL_WIN
+#define INCL_GPI
+
+#include <os2.h>
+
+#define DW_DT_LEFT               DT_LEFT
+#define DW_DT_QUERYEXTENT        DT_QUERYEXTENT
+#define DW_DT_UNDERSCORE         DT_UNDERSCORE
+#define DW_DT_STRIKEOUT          DT_STRIKEOUT
+#define DW_DT_TEXTATTRS          DT_TEXTATTRS
+#define DW_DT_EXTERNALLEADING    DT_EXTERNALLEADING
+#define DW_DT_CENTER             DT_CENTER
+#define DW_DT_RIGHT              DT_RIGHT
+#define DW_DT_TOP                DT_TOP
+#define DW_DT_VCENTER            DT_VCENTER
+#define DW_DT_BOTTOM             DT_BOTTOM
+#define DW_DT_HALFTONE           DT_HALFTONE
+#define DW_DT_MNEMONIC           DT_MNEMONIC
+#define DW_DT_WORDBREAK          DT_WORDBREAK
+#define DW_DT_ERASERECT          DT_ERASERECT
+
+#ifndef FCF_CLOSEBUTTON
+#define FCF_CLOSEBUTTON            0x04000000L
+#endif
+
+#define DW_FCF_CLOSEBUTTON       0
+#define DW_FCF_TITLEBAR          FCF_TITLEBAR
+#define DW_FCF_SYSMENU           (FCF_SYSMENU | FCF_CLOSEBUTTON)
+#define DW_FCF_MENU              FCF_MENU
+#define DW_FCF_SIZEBORDER        FCF_SIZEBORDER
+#define DW_FCF_MINBUTTON         FCF_MINBUTTON
+#define DW_FCF_MAXBUTTON         FCF_MAXBUTTON
+#define DW_FCF_MINMAX            FCF_MINMAX
+#define DW_FCF_VERTSCROLL        FCF_VERTSCROLL
+#define DW_FCF_HORZSCROLL        FCF_HORZSCROLL
+#define DW_FCF_DLGBORDER         FCF_DLGBORDER
+#define DW_FCF_BORDER            FCF_BORDER
+#define DW_FCF_SHELLPOSITION     FCF_SHELLPOSITION
+#define DW_FCF_TASKLIST          FCF_TASKLIST
+#define DW_FCF_NOBYTEALIGN       FCF_NOBYTEALIGN
+#define DW_FCF_NOMOVEWITHOWNER   FCF_NOMOVEWITHOWNER
+#define DW_FCF_SYSMODAL          FCF_SYSMODAL
+#define DW_FCF_HIDEBUTTON        FCF_HIDEBUTTON
+#define DW_FCF_HIDEMAX           FCF_HIDEMAX
+#define DW_FCF_AUTOICON          FCF_AUTOICON
+#define DW_FCF_MAXIMIZE          WS_MAXIMIZED
+#define DW_FCF_MINIMIZE          WS_MINIMIZED
+
+#define DW_CFA_BITMAPORICON      CFA_BITMAPORICON
+#define DW_CFA_STRING            CFA_STRING
+#define DW_CFA_ULONG             CFA_ULONG
+#define DW_CFA_TIME              CFA_TIME
+#define DW_CFA_DATE              CFA_DATE
+#define DW_CFA_CENTER            CFA_CENTER
+#define DW_CFA_LEFT              CFA_LEFT
+#define DW_CFA_RIGHT             CFA_RIGHT
+#define DW_CFA_HORZSEPARATOR     CFA_HORZSEPARATOR
+#define DW_CFA_SEPARATOR         CFA_SEPARATOR
+#define DW_CFA_STRINGANDICON     0
+
+#define DW_CRA_SELECTED          CRA_SELECTED
+#define DW_CRA_CURSORED          CRA_CURSORED
+
+#define DW_LS_MULTIPLESEL        LS_MULTIPLESEL
+
+#define DW_LIT_NONE              -1
+
+#define DW_MLE_CASESENSITIVE     MLFSEARCH_CASESENSITIVE
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         SPTR_ARROW
+#define DW_POINTER_CLOCK         SPTR_WAIT
+#define DW_POINTER_QUESTION      SPTR_ICONQUESTION
+
+#define DW_BS_NOBORDER           BS_NOBORDER
+
+#define DW_OS2_NEW_WINDOW        1
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 MB_OK
+#define DW_MB_OKCANCEL           MB_OKCANCEL
+#define DW_MB_YESNO              MB_YESNO
+#define DW_MB_YESNOCANCEL        MB_YESNOCANCEL
+
+#define DW_MB_WARNING            MB_WARNING
+#define DW_MB_ERROR              MB_ERROR
+#define DW_MB_INFORMATION        MB_INFORMATION
+#define DW_MB_QUESTION           MB_QUERY
+
+/* Virtual Key Codes */
+#define VK_LBUTTON           VK_BUTTON1
+#define VK_RBUTTON           VK_BUTTON2
+#define VK_MBUTTON           VK_BUTTON3
+#define VK_RETURN            VK_NEWLINE
+#define VK_SNAPSHOT          VK_PRINTSCRN
+#define VK_CANCEL            VK_BREAK
+#define VK_CAPITAL           VK_CAPSLOCK
+#define VK_ESCAPE            VK_ESC
+#define VK_PRIOR             VK_PAGEUP
+#define VK_NEXT              VK_PAGEDOWN
+#define VK_SELECT            133
+#define VK_EXECUTE           134
+#define VK_PRINT             135
+#define VK_HELP              136
+#define VK_LWIN              137
+#define VK_RWIN              138
+#define VK_MULTIPLY          ('*' + 128)
+#define VK_ADD               ('+' + 128)
+#define VK_SEPARATOR         141
+#define VK_SUBTRACT          ('-' + 128)
+#define VK_DECIMAL           ('.' + 128)
+#define VK_DIVIDE            ('/' + 128)
+#define VK_SCROLL            VK_SCRLLOCK
+#define VK_LSHIFT            VK_SHIFT
+#define VK_RSHIFT            147
+#define VK_LCONTROL          VK_CTRL
+#define VK_RCONTROL          149
+#define VK_NUMPAD0           ('0' + 128)
+#define VK_NUMPAD1           ('1' + 128)
+#define VK_NUMPAD2           ('2' + 128)
+#define VK_NUMPAD3           ('3' + 128)
+#define VK_NUMPAD4           ('4' + 128)
+#define VK_NUMPAD5           ('5' + 128)
+#define VK_NUMPAD6           ('6' + 128)
+#define VK_NUMPAD7           ('7' + 128)
+#define VK_NUMPAD8           ('8' + 128)
+#define VK_NUMPAD9           ('9' + 128)
+#define VK_BACK              VK_BACKSPACE
+#define VK_LMENU             VK_MENU
+#define VK_RMENU             VK_MENU
+
+typedef struct _window_data {
+   PFNWP oldproc;
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
+} WindowData;
+
+typedef struct _hpixmap {
+   unsigned long width, height;
+   HDC hdc;
+   HPS hps;
+   HBITMAP hbm;
+   HWND handle, font;
+   unsigned long transcolor;
+} *HPIXMAP;
+
+typedef void *HTREEITEM;
+typedef HWND HMENUI;
+typedef HMODULE HMOD;
+typedef unsigned short UWORD;
+typedef unsigned long HSHM;
+typedef unsigned long HICN;
+
+extern HAB dwhab;
+extern HMQ dwhmq;
+#endif
+
+#if defined(__MAC__)
+/* MacOS specific section */
+#include <pthread.h>
+#include <dlfcn.h>
+
+/* Unfortunately using Cocoa we can't include
+ * Cocoa.h from C code, so we have to instead
+ * use opaque types and use the values from
+ * Cocoa.h in the header here directly without
+ * using the symbolic names.
+ */
+
+#define TRUE 1
+#define FALSE 0
+
+typedef void *HWND;
+typedef void *HSHM;
+typedef unsigned long ULONG;
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef short SHORT;
+typedef unsigned short UWORD;
+typedef short WORD ;
+typedef unsigned char UCHAR;
+typedef char CHAR;
+typedef unsigned UINT;
+typedef int INT;
+typedef pthread_mutex_t *HMTX;
+typedef struct _dw_unix_event {
+   pthread_mutex_t mutex;
+   pthread_cond_t event;
+   pthread_t thread;
+   int alive;
+   int posted;
+} *HEV;
+typedef pthread_t DWTID;
+typedef void * HMOD;
+struct _dw_unix_shm {
+   int fd;
+   char *path;
+   int sid;
+   int size;
+};
+typedef void *HTREEITEM;
+typedef void *HMENUI;
+typedef void *HICN;
+
+typedef struct _window_data {
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
+} WindowData;
+
+typedef struct _hpixmap {
+    unsigned long width, height;
+    void *image, *font;
+    HWND handle;
+} *HPIXMAP;
+
+void _dw_pool_drain(void);
+
+#define DW_DT_LEFT               0 /* NSLeftTextAlignment */
+#define DW_DT_QUERYEXTENT        0
+#define DW_DT_UNDERSCORE         0
+#define DW_DT_STRIKEOUT          0
+#define DW_DT_TEXTATTRS          0
+#define DW_DT_EXTERNALLEADING    0
+#define DW_DT_CENTER             2 /* NSCenterTextAlignment */
+#define DW_DT_RIGHT              1 /* NSRightTextAlignment */
+#define DW_DT_TOP                0
+#define DW_DT_VCENTER            (1 << 10)
+#define DW_DT_BOTTOM             0
+#define DW_DT_HALFTONE           0
+#define DW_DT_MNEMONIC           0
+#define DW_DT_WORDBREAK          0
+#define DW_DT_ERASERECT          0
+
+#define DW_FCF_CLOSEBUTTON       (1 << 1) /* NSClosableWindowMask */
+#define DW_FCF_TITLEBAR          (1 << 0) /* NSTitledWindowMask */
+#define DW_FCF_SYSMENU           (1 << 1) /* NSClosableWindowMask */
+#define DW_FCF_MENU              0
+#define DW_FCF_SIZEBORDER        (1 << 3) /* NSResizableWindowMask */
+#define DW_FCF_MINBUTTON         (1 << 2) /* NSMiniaturizableWindowMask */
+#define DW_FCF_MAXBUTTON         0
+#define DW_FCF_MINMAX            (1 << 2) /* NSMiniaturizableWindowMask */
+#define DW_FCF_VERTSCROLL        0
+#define DW_FCF_HORZSCROLL        0
+#define DW_FCF_DLGBORDER         0
+#define DW_FCF_BORDER            0
+#define DW_FCF_SHELLPOSITION     0
+#define DW_FCF_TASKLIST          0
+#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_NOMOVEWITHOWNER   0
+#define DW_FCF_SYSMODAL          0
+#define DW_FCF_HIDEBUTTON        0
+#define DW_FCF_HIDEMAX           0
+#define DW_FCF_AUTOICON          0
+#define DW_FCF_MAXIMIZE          0
+#define DW_FCF_MINIMIZE          0
+
+#define DW_CFA_BITMAPORICON      1
+#define DW_CFA_STRING            (1 << 1)
+#define DW_CFA_ULONG             (1 << 2)
+#define DW_CFA_TIME              (1 << 3)
+#define DW_CFA_DATE              (1 << 4)
+#define DW_CFA_CENTER            (1 << 5)
+#define DW_CFA_LEFT              (1 << 6)
+#define DW_CFA_RIGHT             (1 << 7)
+#define DW_CFA_STRINGANDICON     (1 << 8)
+#define DW_CFA_HORZSEPARATOR     0
+#define DW_CFA_SEPARATOR         0
+
+#define DW_CRA_SELECTED          1
+#define DW_CRA_CURSORED          (1 << 1)
+
+#define DW_LS_MULTIPLESEL        1
+
+#define DW_LIT_NONE              -1
+
+#define DW_MLE_CASESENSITIVE     2 /* NSLiteralSearch */
+
+#define DW_BS_NOBORDER           1
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         1
+#define DW_POINTER_CLOCK         2
+#define DW_POINTER_QUESTION      3
+
+#define HWND_DESKTOP     ((HWND)0)
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 (1 << 1)
+#define DW_MB_OKCANCEL           (1 << 2)
+#define DW_MB_YESNO              (1 << 3)
+#define DW_MB_YESNOCANCEL        (1 << 4)
+
+#define DW_MB_WARNING            (1 << 10)
+#define DW_MB_ERROR              (1 << 11)
+#define DW_MB_INFORMATION        (1 << 12)
+#define DW_MB_QUESTION           (1 << 13)
+
+/* Virtual Key Codes */
+#define VK_LBUTTON               0xFF10 /* TODO */
+#define VK_RBUTTON               0xFF11 /* TODO */
+#define VK_CANCEL                0xFF12 /* TODO */
+#define VK_MBUTTON               0xFF13 /* TODO */
+#define VK_BACK                  0x7F
+#define VK_TAB                   0x09
+#define VK_CLEAR                 71
+#define VK_RETURN                13
+#define VK_MENU                  0xF735 /* NSMenuFunctionKey */
+#define VK_PAUSE                 0xF730 /* NSPauseFunctionKey */
+#define VK_CAPITAL               57
+#define VK_ESCAPE                0x1B
+#define VK_SPACE                 ' '
+#define VK_PRIOR                 0xF72C /* NSPageUpFunctionKey */
+#define VK_NEXT                  0xF72D /* NSPageDownFunctionKey */
+#define VK_END                   0xF72B /* NSEndFunctionKey */
+#define VK_HOME                  0xF729 /* NSHomeFunctionKey */
+#define VK_LEFT                  0xF702 /* NSLeftArrowFunctionKey */
+#define VK_UP                    0xF700 /* NSUpArrowFunctionKey */
+#define VK_RIGHT                 0xF703 /* NSRightArrowFunctionKey */
+#define VK_DOWN                  0xF701 /* NSDownArrowFunctionKey */
+#define VK_SELECT                0xF741 /* NSSelectFunctionKey */
+#define VK_PRINT                 0xF738 /* NSPrintFunctionKey */
+#define VK_EXECUTE               0xF742 /* NSExecuteFunctionKey */
+#define VK_SNAPSHOT              0xF72E /* NSPrintScreenFunctionKey */
+#define VK_INSERT                0xF727 /* NSInsertFunctionKey */
+#define VK_DELETE                0xF728 /* NSDeleteFunctionKey */
+#define VK_HELP                  0xF746 /* NSHelpFunctionKey */
+#define VK_LWIN                  55
+#define VK_RWIN                  0xFF14 /* TODO */
+#define VK_NUMPAD0               82
+#define VK_NUMPAD1               83
+#define VK_NUMPAD2               84
+#define VK_NUMPAD3               85
+#define VK_NUMPAD4               86
+#define VK_NUMPAD5               87
+#define VK_NUMPAD6               88
+#define VK_NUMPAD7               89
+#define VK_NUMPAD8               91
+#define VK_NUMPAD9               92
+#define VK_MULTIPLY              67
+#define VK_ADD                   69
+#define VK_SEPARATOR             0xFF15 /* TODO */
+#define VK_SUBTRACT              78
+#define VK_DECIMAL               65
+#define VK_DIVIDE                75
+#define VK_F1                    0xF704 /* NSF1FunctionKey */
+#define VK_F2                    0xF705 /* NSF2FunctionKey */
+#define VK_F3                    0xF706 /* NSF3FunctionKey */
+#define VK_F4                    0xF707 /* NSF4FunctionKey */
+#define VK_F5                    0xF708 /* NSF5FunctionKey */
+#define VK_F6                    0xF709 /* NSF6FunctionKey */
+#define VK_F7                    0xF70A /* NSF7FunctionKey */
+#define VK_F8                    0xF70B /* NSF8FunctionKey */
+#define VK_F9                    0xF70C /* NSF9FunctionKey */
+#define VK_F10                   0xF70D /* NSF10FunctionKey */
+#define VK_F11                   0xF70E /* NSF11FunctionKey */
+#define VK_F12                   0xF70F /* NSF12FunctionKey */
+#define VK_F13                   0xF710 /* NSF13FunctionKey */
+#define VK_F14                   0xF711 /* NSF14FunctionKey */
+#define VK_F15                   0xF712 /* NSF15FunctionKey */
+#define VK_F16                   0xF713 /* NSF16FunctionKey */
+#define VK_F17                   0xF714 /* NSF17FunctionKey */
+#define VK_F18                   0xF715 /* NSF18FunctionKey */
+#define VK_F19                   0xF716 /* NSF19FunctionKey */
+#define VK_F20                   0xF717 /* NSF20FunctionKey */
+#define VK_F21                   0xF718 /* NSF21FunctionKey */
+#define VK_F22                   0xF719 /* NSF22FunctionKey */
+#define VK_F23                   0xF71A /* NSF23FunctionKey */
+#define VK_F24                   0xF71B /* NSF24FunctionKey */
+#define VK_NUMLOCK               0xFF16 /* TODO */
+#define VK_SCROLL                0xF72F /* NSScrollLockFunctionKey */
+#define VK_LSHIFT                56
+#define VK_RSHIFT                60
+#define VK_LCONTROL              59
+#define VK_RCONTROL              62
+#define VK_LMENU                 0xF735 /* NSMenuFunctionKey */
+#define VK_RMENU                 0xF735 /* NSMenuFunctionKey */
+
+/* Key Modifiers */
+#define KC_CTRL                  (1 << 18) /* NSControlKeyMask */
+#define KC_SHIFT                 (1 << 17) /* NSShiftKeyMask */
+#define KC_ALT                   (1 << 19) /* NSAlternateKeyMask */
+#endif
+
+/* Windows specific section */
+#if defined(__WIN32__) || defined(WINNT)
+#include <windows.h>
+#include <commctrl.h>
+
+#if defined(MSVC) && !defined(API)
+# ifdef __MINGW32__
+#  ifdef BUILD_DLL
+#   define API APIENTRY __declspec(dllexport)
+#  else
+#   define API APIENTRY __declspec(dllimport)
+#  endif
+# else
+#  define API _cdecl
+#endif
+#endif
+
+#define DW_DT_LEFT               SS_LEFT
+#define DW_DT_QUERYEXTENT        0
+#define DW_DT_UNDERSCORE         0
+#define DW_DT_STRIKEOUT          0
+#define DW_DT_TEXTATTRS          0
+#define DW_DT_EXTERNALLEADING    0
+#define DW_DT_CENTER             SS_CENTER
+#define DW_DT_RIGHT              SS_RIGHT
+#define DW_DT_TOP                0
+#define DW_DT_VCENTER            SS_NOPREFIX
+#define DW_DT_BOTTOM             0
+#define DW_DT_HALFTONE           0
+#define DW_DT_MNEMONIC           0
+#define DW_DT_WORDBREAK          0
+#define DW_DT_ERASERECT          0
+
+#define DW_FCF_CLOSEBUTTON       0
+#define DW_FCF_TITLEBAR          WS_CAPTION
+#define DW_FCF_SYSMENU           WS_SYSMENU
+#define DW_FCF_MENU              0
+#define DW_FCF_SIZEBORDER        WS_THICKFRAME
+#define DW_FCF_MINBUTTON         WS_MINIMIZEBOX
+#define DW_FCF_MAXBUTTON         WS_MAXIMIZEBOX
+#define DW_FCF_MINMAX            (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
+#define DW_FCF_VERTSCROLL        WS_VSCROLL
+#define DW_FCF_HORZSCROLL        WS_HSCROLL
+#define DW_FCF_DLGBORDER         WS_DLGFRAME
+#define DW_FCF_BORDER            WS_BORDER
+#define DW_FCF_SHELLPOSITION     0
+#define DW_FCF_TASKLIST          WS_VSCROLL
+#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_NOMOVEWITHOWNER   0
+#define DW_FCF_SYSMODAL          0
+#define DW_FCF_HIDEBUTTON        WS_MINIMIZEBOX
+#define DW_FCF_HIDEMAX           (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)
+#define DW_FCF_AUTOICON          0
+#define DW_FCF_MAXIMIZE          WS_MAXIMIZE
+#define DW_FCF_MINIMIZE          WS_MINIMIZE
+
+#define DW_CFA_BITMAPORICON      1
+#define DW_CFA_STRING            (1 << 1)
+#define DW_CFA_ULONG             (1 << 2)
+#define DW_CFA_TIME              (1 << 3)
+#define DW_CFA_DATE              (1 << 4)
+#define DW_CFA_CENTER            (1 << 5)
+#define DW_CFA_LEFT              (1 << 6)
+#define DW_CFA_RIGHT             (1 << 7)
+#define DW_CFA_STRINGANDICON     (1 << 8)
+#define DW_CFA_HORZSEPARATOR     0
+#define DW_CFA_SEPARATOR         0
+
+#define DW_CRA_SELECTED          LVNI_SELECTED
+#define DW_CRA_CURSORED          LVNI_FOCUSED
+
+#define DW_LS_MULTIPLESEL        LBS_MULTIPLESEL
+
+#define DW_LIT_NONE              -1
+
+#define DW_MLE_CASESENSITIVE     1
+
+#define DW_BS_NOBORDER           BS_FLAT
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         32512
+#define DW_POINTER_CLOCK         32514
+#define DW_POINTER_QUESTION      32651
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 MB_OK
+#define DW_MB_OKCANCEL           MB_OKCANCEL
+#define DW_MB_YESNO              MB_YESNO
+#define DW_MB_YESNOCANCEL        MB_YESNOCANCEL
+
+#define DW_MB_WARNING            MB_ICONWARNING
+#define DW_MB_ERROR              MB_ICONERROR
+#define DW_MB_INFORMATION        MB_ICONINFORMATION
+#define DW_MB_QUESTION           MB_ICONQUESTION
+
+/* Key Modifiers */
+#define KC_CTRL                  (1)
+#define KC_SHIFT                 (1 << 1)
+#define KC_ALT                   (1 << 2)
+
+#define STATICCLASSNAME "STATIC"
+#define COMBOBOXCLASSNAME "COMBOBOX"
+#define LISTBOXCLASSNAME "LISTBOX"
+#define BUTTONCLASSNAME "BUTTON"
+#define POPUPMENUCLASSNAME "POPUPMENU"
+#define EDITCLASSNAME "EDIT"
+#define FRAMECLASSNAME "FRAME"
+#define SCROLLBARCLASSNAME "SCROLLBAR"
+
+#define ClassName "dynamicwindows"
+#define SplitbarClassName "dwsplitbar"
+#define ObjectClassName "dwobjectclass"
+#define BrowserClassName "dwbrowserclass"
+#define ScrollClassName "dwscrollclass"
+#define DefaultFont NULL
+
+typedef struct _color {
+   int fore;
+   int back;
+   HWND combo, buddy;
+   int user;
+   int vcenter;
+   HWND clickdefault;
+   HBRUSH hbrush;
+   HFONT hfont;
+   char fontname[128];
+   WNDPROC pOldProc;
+   UserData *root;
+} ColorInfo;
+
+typedef struct _notebookpage {
+   ColorInfo cinfo;
+   TC_ITEM item;
+   HWND hwnd;
+   int realid;
+} NotebookPage;
+
+typedef HANDLE HMTX;
+typedef HANDLE HEV;
+typedef HANDLE HMOD;
+typedef HANDLE HSHM;
+typedef HANDLE HICN;
+
+typedef struct _container {
+   ColorInfo cinfo;
+   ULONG *flags;
+   ULONG columns;
+   COLORREF odd, even;
+} ContainerInfo;
+
+typedef struct _hpixmap {
+   unsigned long width, height;
+   HBITMAP hbm;
+   HDC hdc;
+   unsigned long transcolor;
+   HWND handle;
+   void *bits;
+   unsigned long depth;
+   HFONT font;
+} *HPIXMAP;
+
+typedef HWND HMENUI;
+#endif
+
+typedef struct _item {
+   /* Item type - Box or Item */
+   int type;
+   /* Handle to Frame or Window */
+   HWND hwnd;
+   /* Width and Height of static size */
+   int width, height, origwidth, origheight;
+   /* Size Type - Static or Expand */
+   int hsize, vsize;
+   /* Padding */
+   int pad;
+   /* Ratio of current item */
+   float xratio, yratio;
+} Item;
+
+typedef struct _box {
+#if defined(__WIN32__) || defined(WINNT)
+   ColorInfo cinfo;
+#elif defined(__OS2__) || defined(__EMX__)
+   PFNWP oldproc;
+   UserData *root;
+   HWND hwndtitle, hwnd;
+   int titlebar;
+#endif
+   /* Number of items in the box */
+   int count;
+   /* Box type - horizontal or vertical */
+   int type;
+   /* Padding */
+   int pad, parentpad, grouppadx, grouppady;
+   /* Groupbox */
+   HWND grouphwnd;
+   /* Default item */
+   HWND defaultitem;
+   /* Used as temporary storage in the calculation stage */
+   int upx, upy, minheight, minwidth;
+   /* Ratio in this box */
+   float xratio, yratio, parentxratio, parentyratio;
+   /* Used for calculating individual item ratios */
+   int width, height;
+   /* Any combinations of flags describing the box */
+   unsigned long flags;
+   /* Array of item structures */
+   struct _item *items;
+} Box;
+
+typedef struct _bubblebutton {
+#if defined(__WIN32__) || defined(WINNT)
+   ColorInfo cinfo;
+   int checkbox;
+   WNDPROC pOldProc;
+#endif
+#if defined(__OS2__) || defined(__EMX__)
+   PFNWP pOldProc;
+   UserData *root;
+   unsigned long id;
+   char bubbletext[BUBBLE_HELP_MAX];
+#endif
+} BubbleButton;
+
+#elif defined(__PHOTON__)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+/* Photon specific section */
+#include <Pt.h>
+#include <Ph.h>
+/* which image formats supported */
+#define PX_IMAGE_MODULES
+#define PX_GIF_SUPPORT
+#define PX_JPG_SUPPORT
+#define PX_BMP_SUPPORT
+#define PX_PND_SUPPORT
+#include <photon/PxImage.h>
+
+#define TRUE  1
+#define FALSE 0
+
+typedef PtWidget_t *pPtWidget_t;
+typedef pPtWidget_t HWND;
+
+typedef unsigned long ULONG;
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef short SHORT;
+typedef unsigned short UWORD;
+typedef short WORD ;
+typedef unsigned char UCHAR;
+typedef char CHAR;
+typedef unsigned UINT;
+typedef int INT;
+typedef void *HMTX;
+typedef void *HEV;
+typedef void *HSHM;
+typedef void *HMOD;
+typedef PtTreeItem_t *HTREEITEM;
+typedef HWND HMENUI;
+typedef int DWTID;
+typedef unsigned long HICN;
+
+typedef struct _user_data
+{
+   struct _user_data *next;
+   void              *data;
+   char              *varname;
+} UserData;
+
+typedef struct _window_data {
+   UserData *root;
+   HWND clickdefault;
+   ULONG flags;
+   void *data;
+} WindowData;
+
+typedef struct _hpixmap {
+   unsigned long width, height;
+   /* ?? *pixmap; */
+   HWND handle;
+} *HPIXMAP;
+
+/* colors matching Photon Graphics colors */
+#define DW_CLR_BLACK             Pg_BLACK
+#define DW_CLR_DARKRED           Pg_DRED
+#define DW_CLR_DARKGREEN         Pg_DGREEN
+#define DW_CLR_BROWN             Pg_BROWN
+#define DW_CLR_DARKBLUE          Pg_DBLUE
+#define DW_CLR_DARKPINK          Pg_PURPLE
+#define DW_CLR_DARKCYAN          Pg_DCYAN
+#define DW_CLR_PALEGRAY          Pg_GRAY
+#define DW_CLR_DARKGRAY          Pg_MGRAY
+#define DW_CLR_RED               Pg_RED
+#define DW_CLR_GREEN             Pg_GREEN
+#define DW_CLR_YELLOW            Pg_YELLOW
+#define DW_CLR_BLUE              Pg_BLUE
+#define DW_CLR_PINK              Pg_MAGENTA
+#define DW_CLR_CYAN              Pg_CYAN
+#define DW_CLR_WHITE             Pg_WHITE
+#define DW_CLR_DEFAULT           Pg_GRAY
+/* color manipulation macros */
+#define DW_RGB_COLOR (0xF0000000)
+#define DW_RGB_TRANSPARENT (0x0F000000)
+#define DW_RGB_MASK (0x00FFFFFF)
+#define DW_RED_MASK (0x00FF0000)
+#define DW_GREEN_MASK (0x0000FF00)
+#define DW_BLUE_MASK (0x000000FF)
+#define DW_RED_VALUE(a) PgRedValue(a)
+#define DW_GREEN_VALUE(a) PgGreenValue(a)
+#define DW_BLUE_VALUE(a) PgBluValue(a)
+#define DW_RGB(a, b, c) PgRGB( a, b, c )
+
+#define DW_DT_LEFT               0
+#define DW_DT_QUERYEXTENT        0
+#define DW_DT_UNDERSCORE         0
+#define DW_DT_STRIKEOUT          0
+#define DW_DT_TEXTATTRS          0
+#define DW_DT_EXTERNALLEADING    0
+#define DW_DT_CENTER             0
+#define DW_DT_RIGHT              0
+#define DW_DT_TOP                0
+#define DW_DT_VCENTER            0
+#define DW_DT_BOTTOM             0
+#define DW_DT_HALFTONE           0
+#define DW_DT_MNEMONIC           0
+#define DW_DT_WORDBREAK          0
+#define DW_DT_ERASERECT          0
+
+#define DW_FCF_CLOSEBUTTON       Ph_WM_RENDER_CLOSE
+#define DW_FCF_TITLEBAR          Ph_WM_RENDER_TITLE
+#define DW_FCF_SYSMENU           0
+#define DW_FCF_MENU              Ph_WM_RENDER_MENU
+#define DW_FCF_SIZEBORDER        Ph_WM_RENDER_RESIZE
+#define DW_FCF_MINBUTTON         Ph_WM_RENDER_MIN
+#define DW_FCF_MAXBUTTON         Ph_WM_RENDER_MAX
+#define DW_FCF_MINMAX            (Ph_WM_RENDER_MIN|Ph_WM_RENDER_MAX)
+#define DW_FCF_VERTSCROLL        0
+#define DW_FCF_HORZSCROLL        0
+#define DW_FCF_DLGBORDER         0
+#define DW_FCF_BORDER            Ph_WM_RENDER_BORDER
+#define DW_FCF_SHELLPOSITION     0
+#define DW_FCF_TASKLIST          0
+#define DW_FCF_NOBYTEALIGN       0
+#define DW_FCF_NOMOVEWITHOWNER   0
+#define DW_FCF_SYSMODAL          0
+#define DW_FCF_HIDEBUTTON        0
+#define DW_FCF_HIDEMAX           0
+#define DW_FCF_AUTOICON          (Ph_WM_RENDER_ASICON | ~Ph_WM_RENDER_ASAPP)
+#define DW_FCF_MAXIMIZE          0
+#define DW_FCF_MINIMIZE          0
+
+#define DW_CFA_BITMAPORICON      1
+#define DW_CFA_STRING            (1 << 1)
+#define DW_CFA_ULONG             (1 << 2)
+#define DW_CFA_TIME              (1 << 3)
+#define DW_CFA_DATE              (1 << 4)
+#define DW_CFA_CENTER            (1 << 5)
+#define DW_CFA_LEFT              (1 << 6)
+#define DW_CFA_RIGHT             (1 << 7)
+#define DW_CFA_STRINGANDICON     (1 << 8)
+#define DW_CFA_HORZSEPARATOR     0
+#define DW_CFA_SEPARATOR         0
+
+#define DW_CRA_SELECTED          1
+#define DW_CRA_CURSORED          (1 << 1)
+
+#define DW_LS_MULTIPLESEL        1
+
+#define DW_LIT_NONE              -1
+
+#ifdef MLFSEARCH_CASESENSITIVE
+# define DW_MLE_CASESENSITIVE    MLFSEARCH_CASESENSITIVE
+#else
+# define DW_MLE_CASESENSITIVE    0
+#endif
+
+#define DW_BS_NOBORDER           1
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         0
+#define DW_POINTER_CLOCK         0
+#define DW_POINTER_QUESTION      0
+
+#define HWND_DESKTOP     ((HWND)0)
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 (1 << 1)
+#define DW_MB_OKCANCEL           (1 << 2)
+#define DW_MB_YESNO              (1 << 3)
+#define DW_MB_YESNOCANCEL        (1 << 4)
+
+#define DW_MB_WARNING            (1 << 10)
+#define DW_MB_ERROR              (1 << 11)
+#define DW_MB_INFORMATION        (1 << 12)
+#define DW_MB_QUESTION           (1 << 13)
+
+/* Virtual Key Codes */
+#define VK_LBUTTON               0
+#define VK_RBUTTON               0
+#define VK_CANCEL                0
+#define VK_MBUTTON               0
+#define VK_BACK                  0
+#define VK_TAB                   0
+#define VK_CLEAR                 0
+#define VK_RETURN                0
+#define VK_MENU                  0
+#define VK_PAUSE                 0
+#define VK_CAPITAL               0
+#define VK_ESCAPE                0
+#define VK_SPACE                 0
+#define VK_PRIOR                 0
+#define VK_NEXT                  0
+#define VK_END                   0
+#define VK_HOME                  0
+#define VK_LEFT                  0
+#define VK_UP                    0
+#define VK_RIGHT                 0
+#define VK_DOWN                  0
+#define VK_SELECT                0
+#define VK_PRINT                 0
+#define VK_EXECUTE               0
+#define VK_SNAPSHOT              0
+#define VK_INSERT                0
+#define VK_DELETE                0
+#define VK_HELP                  0
+#define VK_LWIN                  0
+#define VK_RWIN                  0
+#define VK_NUMPAD0               0
+#define VK_NUMPAD1               0
+#define VK_NUMPAD2               0
+#define VK_NUMPAD3               0
+#define VK_NUMPAD4               0
+#define VK_NUMPAD5               0
+#define VK_NUMPAD6               0
+#define VK_NUMPAD7               0
+#define VK_NUMPAD8               0
+#define VK_NUMPAD9               0
+#define VK_MULTIPLY              0
+#define VK_ADD                   0
+#define VK_SEPARATOR             0
+#define VK_SUBTRACT              0
+#define VK_DECIMAL               0
+#define VK_DIVIDE                0
+#define VK_F1                    0
+#define VK_F2                    0
+#define VK_F3                    0
+#define VK_F4                    0
+#define VK_F5                    0
+#define VK_F6                    0
+#define VK_F7                    0
+#define VK_F8                    0
+#define VK_F9                    0
+#define VK_F10                   0
+#define VK_F11                   0
+#define VK_F12                   0
+#define VK_F13                   0
+#define VK_F14                   0
+#define VK_F15                   0
+#define VK_F16                   0
+#define VK_F17                   0
+#define VK_F18                   0
+#define VK_F19                   0
+#define VK_F20                   0
+#define VK_F21                   0
+#define VK_F22                   0
+#define VK_F23                   0
+#define VK_F24                   0
+#define VK_NUMLOCK               0
+#define VK_SCROLL                0
+#define VK_LSHIFT                0
+#define VK_RSHIFT                0
+#define VK_LCONTROL              0
+#define VK_RCONTROL              0
+#define VK_LMENU                 0
+#define VK_RMENU                 0
+
+/* Key Modifiers */
+#define KC_CTRL                  (1)
+#define KC_SHIFT                 (1 << 1)
+#define KC_ALT                   (1 << 2)
+
+#else
+/* GTK Specific section */
+#include <gtk/gtk.h>
+#ifdef GDK_WINDOWING_X11
+# include <gdk/gdkx.h>
+#else
+# include <gdk/gdk.h>
+#endif
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkkeysyms.h>
+#include <pthread.h>
+#if !defined(GDK_WINDOWING_WIN32)
+# include <dlfcn.h>
+#endif
+
+#define DW_DT_LEFT               1
+#define DW_DT_UNDERSCORE         (1 << 1)
+#define DW_DT_STRIKEOUT          (1 << 2)
+#define DW_DT_CENTER             (1 << 3)
+#define DW_DT_RIGHT              (1 << 4)
+#define DW_DT_TOP                (1 << 5)
+#define DW_DT_VCENTER            (1 << 6)
+#define DW_DT_BOTTOM             (1 << 7)
+#define DW_DT_HALFTONE           (1 << 8)
+#define DW_DT_MNEMONIC           (1 << 9)
+#define DW_DT_WORDBREAK          (1 << 10)
+#define DW_DT_ERASERECT          (1 << 11)
+
+/* these don't exist under gtk, so make them dummy entries */
+#define DW_DT_QUERYEXTENT        0
+#define DW_DT_TEXTATTRS          0
+#define DW_DT_EXTERNALLEADING    0
+
+#define DW_FCF_TITLEBAR          1
+#define DW_FCF_SYSMENU           (1 << 1)
+#define DW_FCF_MENU              (1 << 2)
+#define DW_FCF_SIZEBORDER        (1 << 3)
+#define DW_FCF_MINBUTTON         (1 << 4)
+#define DW_FCF_MAXBUTTON         (1 << 5)
+#define DW_FCF_MINMAX            (1 << 6)
+#define DW_FCF_VERTSCROLL        (1 << 7)
+#define DW_FCF_HORZSCROLL        (1 << 8)
+#define DW_FCF_DLGBORDER         (1 << 9)
+#define DW_FCF_BORDER            (1 << 10)
+#define DW_FCF_SHELLPOSITION     (1 << 11)
+#define DW_FCF_TASKLIST          (1 << 12)
+#define DW_FCF_NOBYTEALIGN       (1 << 13)
+#define DW_FCF_NOMOVEWITHOWNER   (1 << 14)
+#define DW_FCF_SYSMODAL          (1 << 15)
+#define DW_FCF_HIDEBUTTON        (1 << 16)
+#define DW_FCF_HIDEMAX           (1 << 17)
+#define DW_FCF_AUTOICON          (1 << 18)
+#define DW_FCF_MAXIMIZE          (1 << 19)
+#define DW_FCF_MINIMIZE          (1 << 20)
+#define DW_FCF_CLOSEBUTTON       (1 << 21)
+
+#define DW_CFA_BITMAPORICON      1
+#define DW_CFA_STRING            (1 << 1)
+#define DW_CFA_ULONG             (1 << 2)
+#define DW_CFA_TIME              (1 << 3)
+#define DW_CFA_DATE              (1 << 4)
+#define DW_CFA_CENTER            (1 << 5)
+#define DW_CFA_LEFT              (1 << 6)
+#define DW_CFA_RIGHT             (1 << 7)
+#define DW_CFA_HORZSEPARATOR     (1 << 8)
+#define DW_CFA_SEPARATOR         (1 << 9)
+#define DW_CFA_STRINGANDICON     (1 << 10)
+
+#define DW_CRA_SELECTED          1
+#define DW_CRA_CURSORED          (1 << 1)
+
+#define DW_LS_MULTIPLESEL        1
+
+#define DW_LIT_NONE              -1
+
+#define DW_MLE_CASESENSITIVE     1
+
+#define DW_BS_NOBORDER           1
+
+#define DW_POINTER_DEFAULT       0
+#define DW_POINTER_ARROW         GDK_TOP_LEFT_ARROW
+#define DW_POINTER_CLOCK         GDK_WATCH
+#define DW_POINTER_QUESTION      GDK_QUESTION_ARROW
+
+#define HWND_DESKTOP             ((HWND)0)
+
+/* flag values for dw_messagebox() */
+#define DW_MB_OK                 (1 << 1)
+#define DW_MB_OKCANCEL           (1 << 2)
+#define DW_MB_YESNO              (1 << 3)
+#define DW_MB_YESNOCANCEL        (1 << 4)
+
+#define DW_MB_WARNING            (1 << 10)
+#define DW_MB_ERROR              (1 << 11)
+#define DW_MB_INFORMATION        (1 << 12)
+#define DW_MB_QUESTION           (1 << 13)
+
+/* Virtual Key Codes */
+#if GTK_MAJOR_VERSION > 2
+#define VK_LBUTTON           GDK_KEY_Pointer_Button1
+#define VK_RBUTTON           GDK_KEY_Pointer_Button3
+#define VK_CANCEL            GDK_KEY_Cancel
+#define VK_MBUTTON           GDK_KEY_Pointer_Button2
+#define VK_BACK              GDK_KEY_BackSpace
+#define VK_TAB               GDK_KEY_Tab
+#define VK_CLEAR             GDK_KEY_Clear
+#define VK_RETURN            GDK_KEY_Return
+#define VK_MENU              GDK_KEY_Menu
+#define VK_PAUSE             GDK_KEY_Pause
+#define VK_CAPITAL           GDK_KEY_Caps_Lock
+#define VK_ESCAPE            GDK_KEY_Escape
+#define VK_SPACE             GDK_KEY_space
+#define VK_PRIOR             GDK_KEY_Page_Up
+#define VK_NEXT              GDK_KEY_Page_Down
+#define VK_END               GDK_KEY_End
+#define VK_HOME              GDK_KEY_Home
+#define VK_LEFT              GDK_KEY_Left
+#define VK_UP                GDK_KEY_Up
+#define VK_RIGHT             GDK_KEY_Right
+#define VK_DOWN              GDK_KEY_Down
+#define VK_SELECT            GDK_KEY_Select
+#define VK_PRINT             GDK_KEY_Sys_Req
+#define VK_EXECUTE           GDK_KEY_Execute
+#define VK_SNAPSHOT          GDK_KEY_Print
+#define VK_INSERT            GDK_KEY_Insert
+#define VK_DELETE            GDK_KEY_Delete
+#define VK_HELP              GDK_KEY_Help
+#define VK_LWIN              GDK_KEY_Super_L
+#define VK_RWIN              GDK_KEY_Super_R
+#define VK_NUMPAD0           GDK_KEY_KP_0
+#define VK_NUMPAD1           GDK_KEY_KP_1
+#define VK_NUMPAD2           GDK_KEY_KP_2
+#define VK_NUMPAD3           GDK_KEY_KP_3
+#define VK_NUMPAD4           GDK_KEY_KP_4
+#define VK_NUMPAD5           GDK_KEY_KP_5
+#define VK_NUMPAD6           GDK_KEY_KP_6
+#define VK_NUMPAD7           GDK_KEY_KP_7
+#define VK_NUMPAD8           GDK_KEY_KP_8
+#define VK_NUMPAD9           GDK_KEY_KP_9
+#define VK_MULTIPLY          GDK_KEY_KP_Multiply
+#define VK_ADD               GDK_KEY_KP_Add
+#define VK_SEPARATOR         GDK_KEY_KP_Separator
+#define VK_SUBTRACT          GDK_KEY_KP_Subtract
+#define VK_DECIMAL           GDK_KEY_KP_Decimal
+#define VK_DIVIDE            GDK_KEY_KP_Divide
+#define VK_F1                GDK_KEY_F1
+#define VK_F2                GDK_KEY_F2
+#define VK_F3                GDK_KEY_F3
+#define VK_F4                GDK_KEY_F4
+#define VK_F5                GDK_KEY_F5
+#define VK_F6                GDK_KEY_F6
+#define VK_F7                GDK_KEY_F7
+#define VK_F8                GDK_KEY_F8
+#define VK_F9                GDK_KEY_F9
+#define VK_F10               GDK_KEY_F10
+#define VK_F11               GDK_KEY_F11
+#define VK_F12               GDK_KEY_F12
+#define VK_F13               GDK_KEY_F13
+#define VK_F14               GDK_KEY_F14
+#define VK_F15               GDK_KEY_F15
+#define VK_F16               GDK_KEY_F16
+#define VK_F17               GDK_KEY_F17
+#define VK_F18               GDK_KEY_F18
+#define VK_F19               GDK_KEY_F19
+#define VK_F20               GDK_KEY_F20
+#define VK_F21               GDK_KEY_F21
+#define VK_F22               GDK_KEY_F22
+#define VK_F23               GDK_KEY_F23
+#define VK_F24               GDK_KEY_F24
+#define VK_NUMLOCK           GDK_KEY_Num_Lock
+#define VK_SCROLL            GDK_KEY_Scroll_Lock
+#define VK_LSHIFT            GDK_KEY_Shift_L
+#define VK_RSHIFT            GDK_KEY_Shift_R
+#define VK_LCONTROL          GDK_KEY_Control_L
+#define VK_RCONTROL          GDK_KEY_Control_R
+#define VK_LMENU             GDK_KEY_Menu
+#define VK_RMENU             GDK_KEY_Menu
+
+#else
+#define VK_LBUTTON           GDK_Pointer_Button1
+#define VK_RBUTTON           GDK_Pointer_Button3
+#define VK_CANCEL            GDK_Cancel
+#define VK_MBUTTON           GDK_Pointer_Button2
+#define VK_BACK              GDK_BackSpace
+#define VK_TAB               GDK_Tab
+#define VK_CLEAR             GDK_Clear
+#define VK_RETURN            GDK_Return
+#define VK_MENU              GDK_Menu
+#define VK_PAUSE             GDK_Pause
+#define VK_CAPITAL           GDK_Caps_Lock
+#define VK_ESCAPE            GDK_Escape
+#define VK_SPACE             GDK_space
+#define VK_PRIOR             GDK_Page_Up
+#define VK_NEXT              GDK_Page_Down
+#define VK_END               GDK_End
+#define VK_HOME              GDK_Home
+#define VK_LEFT              GDK_Left
+#define VK_UP                GDK_Up
+#define VK_RIGHT             GDK_Right
+#define VK_DOWN              GDK_Down
+#define VK_SELECT            GDK_Select
+#define VK_PRINT             GDK_Sys_Req
+#define VK_EXECUTE           GDK_Execute
+#define VK_SNAPSHOT          GDK_Print
+#define VK_INSERT            GDK_Insert
+#define VK_DELETE            GDK_Delete
+#define VK_HELP              GDK_Help
+#define VK_LWIN              GDK_Super_L
+#define VK_RWIN              GDK_Super_R
+#define VK_NUMPAD0           GDK_KP_0
+#define VK_NUMPAD1           GDK_KP_1
+#define VK_NUMPAD2           GDK_KP_2
+#define VK_NUMPAD3           GDK_KP_3
+#define VK_NUMPAD4           GDK_KP_4
+#define VK_NUMPAD5           GDK_KP_5
+#define VK_NUMPAD6           GDK_KP_6
+#define VK_NUMPAD7           GDK_KP_7
+#define VK_NUMPAD8           GDK_KP_8
+#define VK_NUMPAD9           GDK_KP_9
+#define VK_MULTIPLY          GDK_KP_Multiply
+#define VK_ADD               GDK_KP_Add
+#define VK_SEPARATOR         GDK_KP_Separator
+#define VK_SUBTRACT          GDK_KP_Subtract
+#define VK_DECIMAL           GDK_KP_Decimal
+#define VK_DIVIDE            GDK_KP_Divide
+#define VK_F1                GDK_F1
+#define VK_F2                GDK_F2
+#define VK_F3                GDK_F3
+#define VK_F4                GDK_F4
+#define VK_F5                GDK_F5
+#define VK_F6                GDK_F6
+#define VK_F7                GDK_F7
+#define VK_F8                GDK_F8
+#define VK_F9                GDK_F9
+#define VK_F10               GDK_F10
+#define VK_F11               GDK_F11
+#define VK_F12               GDK_F12
+#define VK_F13               GDK_F13
+#define VK_F14               GDK_F14
+#define VK_F15               GDK_F15
+#define VK_F16               GDK_F16
+#define VK_F17               GDK_F17
+#define VK_F18               GDK_F18
+#define VK_F19               GDK_F19
+#define VK_F20               GDK_F20
+#define VK_F21               GDK_F21
+#define VK_F22               GDK_F22
+#define VK_F23               GDK_F23
+#define VK_F24               GDK_F24
+#define VK_NUMLOCK           GDK_Num_Lock
+#define VK_SCROLL            GDK_Scroll_Lock
+#define VK_LSHIFT            GDK_Shift_L
+#define VK_RSHIFT            GDK_Shift_R
+#define VK_LCONTROL          GDK_Control_L
+#define VK_RCONTROL          GDK_Control_R
+#define VK_LMENU             GDK_Menu
+#define VK_RMENU             GDK_Menu
+#endif
+
+/* Key Modifiers */
+#define KC_CTRL              GDK_CONTROL_MASK
+#define KC_SHIFT             GDK_SHIFT_MASK
+#define KC_ALT               GDK_MOD1_MASK
+
+typedef GtkWidget *HWND;
+#ifndef _ENVRNMNT_H
+typedef unsigned long ULONG;
+#endif
+typedef long LONG;
+typedef unsigned short USHORT;
+typedef short SHORT;
+typedef unsigned short UWORD;
+typedef short WORD ;
+typedef unsigned char UCHAR;
+typedef char CHAR;
+typedef unsigned UINT;
+typedef int INT;
+typedef pthread_mutex_t *HMTX;
+typedef struct _dw_unix_event {
+   pthread_mutex_t mutex;
+   pthread_cond_t event;
+   pthread_t thread;
+   int alive;
+   int posted;
+} *HEV;
+typedef pthread_t DWTID;
+typedef void * HMOD;
+struct _dw_unix_shm {
+   int fd;
+   char *path;
+   int sid;
+   int size;
+};
+
+typedef struct _hpixmap {
+   unsigned long width, height;
+   HWND handle;
+   char *font;
+#if GTK_MAJOR_VERSION > 1
+   GdkPixbuf *pixbuf;  /* the actual image */
+#endif
+#if GTK_MAJOR_VERSION > 2
+   cairo_surface_t *image; /* Going to have dual storage for now */
+#else
+   GdkPixmap *pixmap;  /* the actual image */
+   GdkBitmap *bitmap;  /* if not null, the image mask representing the transparency mask */
+   void *image;        /* Opaque handle to a cairo_surface_t for printing */
+#endif
+} *HPIXMAP;
+
+typedef GtkWidget *HMENUI;
+typedef void *HTREEITEM;
+typedef void *HSHM;
+typedef void *HICN;
+
+typedef struct _resource_struct {
+   long resource_max, *resource_id;
+   char **resource_data;
+} DWResources;
+
+#if !defined(DW_RESOURCES) || defined(BUILD_DLL)
+static DWResources _resources = { 0, 0, 0 };
+#else
+extern DWResources _resources;
+#endif
+
+#endif
+
+#if !defined(__OS2__) && !defined(__EMX__)
+typedef struct _CDATE
+{
+   UCHAR  day;
+   UCHAR  month;
+   USHORT year;
+} CDATE;
+typedef CDATE *PCDATE;
+
+typedef struct _CTIME
+{
+   UCHAR hours;
+   UCHAR minutes;
+   UCHAR seconds;
+   UCHAR ucReserved;
+} CTIME;
+typedef CTIME *PCTIME;
+#endif
+
+#if defined(__OS2__) || (defined(__WIN32__) && !defined(GDK_WINDOWING_WIN32)) || (defined(WINNT) && !defined(GDK_WINDOWING_WIN32)) || defined(__EMX__)
+typedef unsigned long DWTID;
+#endif
+
+typedef struct _dwenv {
+   /* Operating System Name and DW Build Date/Time */
+   char osName[30], buildDate[30], buildTime[30];
+   /* Versions and builds */
+   short MajorVersion, MinorVersion, MajorBuild, MinorBuild;
+   /* Dynamic Window version */
+   short DWMajorVersion, DWMinorVersion, DWSubVersion;
+} DWEnv;
+
+
+typedef struct _dwexpose {
+   int x, y;
+   int width, height;
+} DWExpose;
+
+typedef struct _dwdialog {
+   HEV eve;
+   int done;
+   int method;
+   void *data, *result;
+} DWDialog;
+
+typedef void *HPRINT;
+
+#define DW_SIGNAL_FUNC(a) ((void *)a)
+
+#define DW_DESKTOP               HWND_DESKTOP
+#define DW_MINIMIZED 1
+
+#define DW_BUTTON1_MASK 1
+#define DW_BUTTON2_MASK (1 << 1)
+#define DW_BUTTON3_MASK (1 << 2)
+
+#define DW_EXEC_CON 0
+#define DW_EXEC_GUI 1
+
+#define DW_FILE_OPEN      0
+#define DW_FILE_SAVE      1
+#define DW_DIRECTORY_OPEN 2
+
+#define DW_HORZ 0
+#define DW_VERT 1
+
+#define DW_TIMEOUT_INFINITE ((unsigned long)-1)
+
+/* Obsolete, should disappear sometime */
+#define BOXHORZ DW_HORZ
+#define BOXVERT DW_VERT
+
+#define DW_SCROLL_UP 0
+#define DW_SCROLL_DOWN 1
+#define DW_SCROLL_TOP 2
+#define DW_SCROLL_BOTTOM 3
+
+/* return values for dw_messagebox() */
+#define DW_MB_RETURN_OK           0
+#define DW_MB_RETURN_YES          1
+#define DW_MB_RETURN_NO           0
+#define DW_MB_RETURN_CANCEL       2
+
+#define DW_PIXMAP_WIDTH(x) (x ? x->width : 0)
+#define DW_PIXMAP_HEIGHT(x) (x ? x->height : 0)
+
+#if !defined(__PHOTON__)
+#define DW_RGB_COLOR (0xF0000000)
+#define DW_RGB_TRANSPARENT (0x0F000000)
+#define DW_RGB_MASK (0x00FFFFFF)
+#define DW_RED_MASK (0x000000FF)
+#define DW_GREEN_MASK (0x0000FF00)
+#define DW_BLUE_MASK (0x00FF0000)
+#define DW_RED_VALUE(a) (a & DW_RED_MASK)
+#define DW_GREEN_VALUE(a) ((a & DW_GREEN_MASK) >> 8)
+#define DW_BLUE_VALUE(a) ((a & DW_BLUE_MASK) >> 16)
+#define DW_RGB(a, b, c) (0xF0000000 | (a) | (b) << 8 | (c) << 16)
+#endif
+
+#define DW_MENU_SEPARATOR ""
+#define DW_NOMENU 0
+#define DW_MENU_AUTO 0
+#define DW_MENU_POPUP (unsigned long)-1
+
+#define DW_PERCENT_INDETERMINATE ((unsigned int)-1)
+
+/* Return value error codes */
+#define DW_ERROR_NONE      0
+#define DW_ERROR_GENERAL   1
+#define DW_ERROR_TIMEOUT   2
+#define DW_ERROR_NON_INIT  3
+#define DW_ERROR_NO_MEM    4
+#define DW_ERROR_INTERRUPT 5
+#define DW_ERROR_UNKNOWN   -1
+
+/* Embedded HTML actions */
+#define DW_HTML_GOBACK     0
+#define DW_HTML_GOFORWARD  1
+#define DW_HTML_GOHOME     2
+#define DW_HTML_SEARCH     3
+#define DW_HTML_RELOAD     4
+#define DW_HTML_STOP       5
+#define DW_HTML_PRINT      6
+
+/* Drawing flags... used for Arc currently */
+#define DW_DRAW_DEFAULT    0
+#define DW_DRAW_FILL       1
+#define DW_DRAW_FULL       (1 << 1)
+
+
+/* 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
+#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
+#define DW_INT_TO_POINTER(a) ((void *)a)
+#define DW_POINTER_TO_INT(a) ((int)a)
+#define DW_UINT_TO_POINTER(a) ((void *)a)
+#define DW_POINTER_TO_UINT(a) ((unsigned int)a)
+#endif
+
+#ifndef API
+#define API
+#endif
+
+#define DWSIGNAL API
+
+/* Let other APIs know what types we've defined,
+ * Regina REXX in particular, on Unix.
+ */
+#define ULONG_TYPEDEFED 1
+#define LONG_TYPEDEFED 1
+#define USHORT_TYPEDEFED 1
+#define SHORT_TYPEDEFED 1
+#define UWORD_TYPEDEFED 1
+#define WORD_TYPEDEFED 1
+#define UCHAR_TYPEDEFED 1
+#define CHAR_TYPEDEFED 1
+#define UINT_TYPEDEFED 1
+#define INT_TYPEDEFED 1
+
+/* Public function prototypes */
+void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
+void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad);
+void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad);
+#if !defined(__OS2__) && !defined(__WIN32__) && !defined(__EMX__) && !defined(__MAC__)
+int API dw_int_init(DWResources *res, int newthread, int *argc, char **argv[]);
+#define dw_init(a, b, c) dw_int_init(&_resources, a, &b, &c)
+#else
+int API dw_init(int newthread, int argc, char *argv[]);
+#endif
+void API dw_main(void);
+void API dw_main_sleep(int seconds);
+void API dw_main_iteration(void);
+void API dw_free(void *ptr);
+int API dw_window_show(HWND handle);
+int API dw_window_hide(HWND handle);
+int API dw_window_minimize(HWND handle);
+int API dw_window_raise(HWND handle);
+int API dw_window_lower(HWND handle);
+int API dw_window_destroy(HWND handle);
+void API dw_window_redraw(HWND handle);
+int API dw_window_set_font(HWND handle, char *fontname);
+char * API dw_window_get_font(HWND handle);
+int API dw_window_set_color(HWND handle, unsigned long fore, unsigned long back);
+HWND API dw_window_new(HWND hwndOwner, char *title, unsigned long flStyle);
+HWND API dw_box_new(int type, int pad);
+HWND API dw_scrollbox_new(int type, int pad);
+int API dw_scrollbox_get_pos( HWND handle, int orient );
+int API dw_scrollbox_get_range( HWND handle, int orient );
+HWND API dw_groupbox_new(int type, int pad, char *title);
+HWND API dw_mdi_new(unsigned long id);
+HWND API dw_bitmap_new(unsigned long id);
+HWND API dw_bitmapbutton_new(char *text, unsigned long id);
+HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename);
+HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *str, int len);
+HWND API dw_container_new(unsigned long id, int multi);
+HWND API dw_tree_new(unsigned long id);
+HWND API dw_text_new(char *text, unsigned long id);
+HWND API dw_status_text_new(char *text, unsigned long id);
+HWND API dw_mle_new(unsigned long id);
+HWND API dw_entryfield_new(char *text, unsigned long id);
+HWND API dw_entryfield_password_new(char *text, ULONG id);
+HWND API dw_combobox_new(char *text, unsigned long id);
+HWND API dw_button_new(char *text, unsigned long id);
+HWND API dw_spinbutton_new(char *text, unsigned long id);
+HWND API dw_radiobutton_new(char *text, ULONG id);
+HWND API dw_percent_new(unsigned long id);
+HWND API dw_slider_new(int vertical, int increments, ULONG id);
+HWND API dw_scrollbar_new(int vertical, ULONG id);
+HWND API dw_checkbox_new(char *text, unsigned long id);
+HWND API dw_listbox_new(unsigned long id, int multi);
+void API dw_listbox_append(HWND handle, char *text);
+void API dw_listbox_insert(HWND handle, char *text, int pos);
+void API dw_listbox_list_append(HWND handle, char **text, int count);
+void API dw_listbox_clear(HWND handle);
+int API dw_listbox_count(HWND handle);
+void API dw_listbox_set_top(HWND handle, int top);
+void API dw_listbox_select(HWND handle, int index, int state);
+void API dw_listbox_delete(HWND handle, int index);
+void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length);
+void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer);
+int API dw_listbox_selected(HWND handle);
+int API dw_listbox_selected_multi(HWND handle, int where);
+void API dw_percent_set_pos(HWND handle, unsigned int position);
+unsigned int API dw_slider_get_pos(HWND handle);
+void API dw_slider_set_pos(HWND handle, unsigned int position);
+unsigned int API dw_scrollbar_get_pos(HWND handle);
+void API dw_scrollbar_set_pos(HWND handle, unsigned int position);
+void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible);
+void API dw_window_set_pos(HWND handle, long x, long y);
+void API dw_window_set_size(HWND handle, unsigned long width, unsigned long height);
+void API dw_window_set_pos_size(HWND handle, long x, long y, unsigned long width, unsigned long height);
+void API dw_window_get_pos_size(HWND handle, long *x, long *y, unsigned long *width, unsigned long *height);
+void API dw_window_set_style(HWND handle, unsigned long style, unsigned long mask);
+void API dw_window_set_icon(HWND handle, HICN icon);
+void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename);
+void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len);
+char * API dw_window_get_text(HWND handle);
+void API dw_window_set_text(HWND handle, char *text);
+int API dw_window_set_border(HWND handle, int border);
+void API dw_window_disable(HWND handle);
+void API dw_window_enable(HWND handle);
+void API dw_window_capture(HWND handle);
+void API dw_window_release(void);
+void API dw_window_reparent(HWND handle, HWND newparent);
+void API dw_window_set_pointer(HWND handle, int pointertype);
+void API dw_window_default(HWND window, HWND defaultitem);
+void API dw_window_click_default(HWND window, HWND next);
+unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint);
+void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length);
+void API dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines);
+void API dw_mle_delete(HWND handle, int startpoint, int length);
+void API dw_mle_clear(HWND handle);
+void API dw_mle_freeze(HWND handle);
+void API dw_mle_thaw(HWND handle);
+void API dw_mle_set_cursor(HWND handle, int point);
+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);
+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);
+void API dw_entryfield_set_limit(HWND handle, ULONG limit);
+long API dw_spinbutton_get_pos(HWND handle);
+int API dw_checkbox_get(HWND handle);
+void API dw_checkbox_set(HWND handle, int value);
+HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata);
+HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata);
+void API dw_tree_clear(HWND handle);
+void API dw_tree_item_delete(HWND handle, HTREEITEM item);
+void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon);
+void API dw_tree_item_expand(HWND handle, HTREEITEM item);
+void API dw_tree_item_collapse(HWND handle, HTREEITEM item);
+void API dw_tree_item_select(HWND handle, HTREEITEM item);
+void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata);
+void * API dw_tree_item_get_data(HWND handle, HTREEITEM item);
+char * API dw_tree_get_title(HWND handle, HTREEITEM item);
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item);
+int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator);
+HICN API dw_icon_load(unsigned long module, unsigned long id);
+HICN API dw_icon_load_from_file(char *filename);
+HICN API dw_icon_load_from_data(char *data, int len);
+void API dw_icon_free(HICN handle);
+void * API dw_container_alloc(HWND handle, int rowcount);
+void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data);
+void API dw_container_change_item(HWND handle, int column, int row, void *data);
+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_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);
+char * API dw_container_query_start(HWND handle, unsigned long flags);
+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_delete_row(HWND handle, char *text);
+void API dw_container_optimize(HWND handle);
+void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor);
+int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count);
+void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data);
+void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon);
+void API dw_filesystem_change_item(HWND handle, int column, int row, void *data);
+void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon);
+int API dw_container_get_column_type(HWND handle, int column);
+int API dw_filesystem_get_column_type(HWND handle, int column);
+void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext);
+void API dw_taskbar_delete(HWND handle, HICN icon);
+int API dw_screen_width(void);
+int API dw_screen_height(void);
+unsigned long API dw_color_depth_get(void);
+HWND API dw_notebook_new(unsigned long id, int top);
+unsigned long API dw_notebook_page_new(HWND handle, unsigned long flags, int front);
+void API dw_notebook_page_destroy(HWND handle, unsigned int pageid);
+void API dw_notebook_page_set_text(HWND handle, unsigned long pageid, char *text);
+void API dw_notebook_page_set_status_text(HWND handle, unsigned long pageid, char *text);
+void API dw_notebook_page_set(HWND handle, unsigned int pageid);
+unsigned long API dw_notebook_page_get(HWND handle);
+void API dw_notebook_pack(HWND handle, unsigned long pageid, HWND page);
+HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id);
+void API dw_splitbar_set(HWND handle, float percent);
+float API dw_splitbar_get(HWND handle);
+HMENUI API dw_menu_new(unsigned long id);
+HMENUI API dw_menubar_new(HWND location);
+HWND API dw_menu_append_item(HMENUI menu, char *title, unsigned long id, unsigned long flags, int end, int check, HMENUI submenu);
+#ifdef INCOMPLETE
+void API dw_menu_delete_item(HMENUI menu, unsigned long id);
+#endif
+void API dw_menu_item_set_check(HMENUI menu, unsigned long id, int check);
+void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state);
+void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y);
+void API dw_menu_destroy(HMENUI *menu);
+void API dw_pointer_query_pos(long *x, long *y);
+void API dw_pointer_set_pos(long x, long y);
+void API dw_window_function(HWND handle, void *function, void *data);
+HWND API dw_window_from_id(HWND handle, int id);
+HMTX API dw_mutex_new(void);
+void API dw_mutex_close(HMTX mutex);
+void API dw_mutex_lock(HMTX mutex);
+int API dw_mutex_trylock(HMTX mutex);
+void API dw_mutex_unlock(HMTX mutex);
+HEV API dw_event_new(void);
+int API dw_event_reset(HEV eve);
+int API dw_event_post(HEV eve);
+int API dw_event_wait(HEV eve, unsigned long timeout);
+int API dw_event_close (HEV *eve);
+DWTID API dw_thread_new(void *func, void *data, int stack);
+void API dw_thread_end(void);
+DWTID API dw_thread_id(void);
+void API dw_exit(int exitcode);
+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);
+unsigned long API dw_color_choose(unsigned long value);
+char * API dw_font_choose(char *currfont);
+void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y);
+void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2);
+void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height);
+void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int fill, int npoints, int *x, int *y);
+void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2);
+void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text);
+void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height);
+void API dw_font_set_default(char *fontname);
+void API dw_flush(void);
+void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc);
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight);
+HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth);
+HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename);
+HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len);
+HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id);
+void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color );
+int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname);
+void API dw_pixmap_destroy(HPIXMAP pixmap);
+void API dw_beep(int freq, int dur);
+void API dw_debug(char *format, ...);
+int API dw_messagebox(char *title, int flags, char *format, ...);
+void API dw_environment_query(DWEnv *env);
+int API dw_exec(char *program, int type, char **params);
+int API dw_browse(char *url);
+char * API dw_file_browse(char *title, char *defpath, char *ext, int flags);
+char * API dw_user_dir(void);
+DWDialog * API dw_dialog_new(void *data);
+int API dw_dialog_dismiss(DWDialog *dialog, void *result);
+void * API dw_dialog_wait(DWDialog *dialog);
+void API dw_window_set_data(HWND window, char *dataname, void *data);
+void * API dw_window_get_data(HWND window, char *dataname);
+int API dw_module_load(char *name, HMOD *handle);
+int API dw_module_symbol(HMOD handle, char *name, void**func);
+int API dw_module_close(HMOD handle);
+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_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);
+HEV API dw_named_event_new(char *name);
+HEV API dw_named_event_get(char *name);
+int API dw_named_event_reset(HEV eve);
+int API dw_named_event_post(HEV eve);
+int API dw_named_event_wait(HEV eve, unsigned long timeout);
+int API dw_named_event_close(HEV eve);
+HSHM API dw_named_memory_new(void **dest, int size, char *name);
+HSHM API dw_named_memory_get(void **dest, int size, char *name);
+int API dw_named_memory_free(HSHM handle, void *ptr);
+void API dw_html_action(HWND hwnd, int action);
+int API dw_html_raw(HWND hwnd, char *string);
+int API dw_html_url(HWND hwnd, char *url);
+HWND API dw_html_new(unsigned long id);
+char * API dw_clipboard_get_text(void);
+void API dw_clipboard_set_text( char *str, int len );
+HWND API dw_calendar_new(unsigned long id);
+void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day );
+void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day );
+HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata);
+int API dw_print_run(HPRINT print, unsigned long flags);
+void API dw_print_cancel(HPRINT print);
+
+#endif
--- a/install.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/install.c	Sun Nov 13 07:22:43 2011 -0600
@@ -1864,7 +1864,7 @@
 	for(j=1;j<INSTALLER_PACKAGE_COUNT;j++)
 		dw_listbox_append(listbox, INSTALLER_PACKAGES[j]);
 
-	dw_window_set_usize(entrywindow, 450, 350);
+	dw_window_set_size(entrywindow, 450, 350);
 
 	dw_window_show(entrywindow);
 
@@ -1930,21 +1930,20 @@
 
 	dw_signal_connect(okbutton, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(generic_cancel), (void *)param);
 
-	dw_window_set_usize(infowindow, 600, 400);
+	dw_window_set_size(infowindow, 600, 400);
 
-	dw_mle_set(mle, 0);
+	dw_mle_set_cursor(mle, 0);
 
 	dw_window_show(infowindow);
 }
 
 void update_percent(void)
 {
-	static int pixels = 0;
 	ULONG sliderpos = 0;
 
-	if(!no_update && files && (pixels = dw_percent_query_range(hwndper)))
+	if(!no_update && files)
 	{
-		sliderpos = (int)(((float)current_file/(float)files)*pixels);
+		sliderpos = (int)(((float)current_file/(float)files)*100);
 		dw_percent_set_pos(hwndper, sliderpos);
 	}
 }
--- a/instsup.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/instsup.c	Sun Nov 13 07:22:43 2011 -0600
@@ -42,7 +42,7 @@
 /* This should return the current color depth */
 ULONG color_depth(void)
 {
-    return dw_color_depth();
+    return dw_color_depth_get();
 }
 
 /* This should return true for WinNT/2K/XP and false on Win9x */
--- a/os2/dw.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/os2/dw.c	Sun Nov 13 07:22:43 2011 -0600
@@ -1,8853 +1,11227 @@
-/*
- * Dynamic Windows:
- *          A GTK like implementation of the PM GUI
- *
- * (C) 2000-2003 Brian Smith <dbsoft@technologist.com>
- * (C) 2000 Achim Hasenmueller <achimha@innotek.de>
- * (C) 2000 Peter Nielsen <peter@pmview.com>
- * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit)
- *
- */
-#define INCL_DOS
-#define INCL_DOSERRORS
-#define INCL_WIN
-#define INCL_GPI
-
-#include <os2.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <process.h>
-#include <time.h>
-#include <io.h>
-#ifndef __EMX__
-#include <direct.h>
-#endif
-#include <sys/time.h>
-#include "dw.h"
-
-#define QWP_USER 0
-
-MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
-void _do_resize(Box *thisbox, int x, int y);
-void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
-int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height);
-void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
-void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
-void _free_menu_data(HWND menu);
-
-char ClassName[] = "dynamicwindows";
-char SplitbarClassName[] = "dwsplitbar";
-char *DefaultFont = "9.WarpSans";
-
-HAB dwhab = 0;
-HMQ dwhmq = 0;
-DWTID _dwtid = 0;
-LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT;
-
-HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
-PRECORDCORE pCore = NULL, pCoreEmph = NULL;
-ULONG aulBuffer[4];
-HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
-
-unsigned long _colors[] = {
-	CLR_BLACK,
-	CLR_DARKRED,
-	CLR_DARKGREEN,
-	CLR_BROWN,
-	CLR_DARKBLUE,
-	CLR_DARKPINK,
-	CLR_DARKCYAN,
-	CLR_PALEGRAY,
-	CLR_DARKGRAY,
-	CLR_RED,
-	CLR_GREEN,
-	CLR_YELLOW,
-	CLR_BLUE,
-	CLR_PINK,
-	CLR_CYAN,
-	CLR_WHITE
-};
-
-#define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40)
-
-#ifndef min
-#define min(a, b) (((a < b) ? a : b))
-#endif
-
-typedef struct _sighandler
-{
-	struct _sighandler	*next;
-	ULONG message;
-	HWND window;
-	int id;
-	void *signalfunction;
-	void *data;
-
-} SignalHandler;
-
-SignalHandler *Root = NULL;
-
-typedef struct
-{
-	ULONG message;
-	char name[30];
-
-} SignalList;
-
-/* List of signals and their equivilent OS/2 message */
-#define SIGNALMAX 16
-
-SignalList SignalTranslate[SIGNALMAX] = {
-	{ WM_SIZE,         DW_SIGNAL_CONFIGURE },
-	{ WM_CHAR,         DW_SIGNAL_KEY_PRESS },
-	{ WM_BUTTON1DOWN,  DW_SIGNAL_BUTTON_PRESS },
-	{ WM_BUTTON1UP,    DW_SIGNAL_BUTTON_RELEASE },
-	{ WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
-	{ WM_CLOSE,        DW_SIGNAL_DELETE },
-	{ WM_PAINT,        DW_SIGNAL_EXPOSE },
-	{ WM_COMMAND,      DW_SIGNAL_CLICKED },
-	{ CN_ENTER,        DW_SIGNAL_ITEM_ENTER },
-	{ CN_CONTEXTMENU,  DW_SIGNAL_ITEM_CONTEXT },
-	{ LN_SELECT,       DW_SIGNAL_LIST_SELECT },
-	{ CN_EMPHASIS,     DW_SIGNAL_ITEM_SELECT },
-	{ WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
-	{ SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED },
-	{ BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE },
-	{ CN_EXPANDTREE,   DW_SIGNAL_TREE_EXPAND }
-};
-
-/* This function adds a signal handler callback into the linked list.
- */
-void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
-{
-	SignalHandler *new = malloc(sizeof(SignalHandler));
-
-	new->message = message;
-	new->window = window;
-	new->id = id;
-	new->signalfunction = signalfunction;
-	new->data = data;
-	new->next = NULL;
-
-	if (!Root)
-		Root = new;
-	else
-	{
-		SignalHandler *prev = NULL, *tmp = Root;
-		while(tmp)
-		{
-			if(tmp->message == message &&
-			   tmp->window == window &&
-			   tmp->id == id &&
-			   tmp->signalfunction == signalfunction)
-			{
-				tmp->data = data;
-				free(new);
-				return;
-			}
-			prev = tmp;
-			tmp = tmp->next;
-		}
-		if(prev)
-			prev->next = new;
-		else
-			Root = new;
-	}
-}
-
-/* Finds the message number for a given signal name */
-ULONG _findsigmessage(char *signame)
-{
-	int z;
-
-	for(z=0;z<SIGNALMAX;z++)
-	{
-		if(stricmp(signame, SignalTranslate[z].name) == 0)
-			return SignalTranslate[z].message;
-	}
-	return 0L;
-}
-
-typedef struct _CNRITEM
-{
-	MINIRECORDCORE rc;
-	HPOINTER       hptrIcon;
-	PVOID          user;
-	HTREEITEM      parent;
-
-} CNRITEM, *PCNRITEM;
-
-
-int _null_key(HWND window, int key, void *data)
-{
-	window = window; /* keep compiler happy */
-	key = key; /* keep compiler happy */
-	data = data; /* keep compiler happy */
-	return TRUE;
-}
-
-/* Find the desktop window handle */
-HWND _toplevel_window(HWND handle)
-{
-	HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
-
-	/* Find the toplevel window */
-	while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0)
-	{
-		lastbox = box;
-	}
-	if(box > 0)
-		return lastbox;
-	return handle;
-}
-
-
-/* A "safe" WinSendMsg() that tries multiple times in case the
- * queue is blocked for one reason or another.
- */
-MRESULT _dw_send_msg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, int failure)
-{
-	MRESULT res;
-	int z = 0;
-
-	while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure)
-	{
-		z++;
-		if(z > 5000000)
-			return (MRESULT)failure;
-		dw_main_sleep(1);
-	}
-	return res;
-}
-
-/* Return the entryfield child of a window */
-HWND _find_entryfield(HWND handle)
-{
-	HENUM henum;
-	HWND child, entry = 0;
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		char tmpbuf[100];
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "#6", 3)==0)  /* Entryfield */
-		{
-			entry = child;
-			break;
-		}
-	}
-	WinEndEnumWindows(henum);
-	return entry;
-}
-
-/* This function changes the owner of buttons in to the
- * dynamicwindows handle to fix a problem in notebooks.
- */
-void _fix_button_owner(HWND handle, HWND dw)
-{
-	HENUM henum;
-	HWND child;
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		char tmpbuf[100];
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "#3", 3)==0 && dw)  /* Button */
-			WinSetOwner(child, dw);
-		else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0)
-			dw = child;
-
-		_fix_button_owner(child, dw);
-	}
-	WinEndEnumWindows(henum);
-	return;
-}
-
-/* Free bitmap data associated with a window */
-void _free_bitmap(HWND handle)
-{
-	HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
-	HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps");
-	HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc");
-	HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap");
-	HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled");
-
-	if(pixmap)
-		dw_pixmap_destroy(pixmap);
-
-	if(disable)
-		dw_pixmap_destroy(disable);
-
-	if(hps)
-	{
-		GpiSetBitmap(hps, NULLHANDLE);
-		GpiAssociate(hps, NULLHANDLE);
-		GpiDestroyPS(hps);
-	}
-
-	if(hdc)
-		DevCloseDC(hdc);
-
-	if(hbm)
-		GpiDeleteBitmap(hbm);
-}
-
-/* This function removes and handlers on windows and frees
- * the user memory allocated to it.
- */
-void _free_window_memory(HWND handle)
-{
-	HENUM henum;
-	HWND child;
-	void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
-
-	dw_signal_disconnect_by_window(handle);
-
-	if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
-		_free_menu_data(child);
-
-	if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
-	{
-		Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER);
-
-		if(box)
-		{
-			if(box->count && box->items)
-				free(box->items);
-
-			WinSetWindowPtr(child, QWP_USER, 0);
-			free(box);
-		}
-	}
-
-	if(ptr)
-	{
-		WindowData *wd = (WindowData *)ptr;
-		char tmpbuf[100];
-
-		/* If this window has an associate bitmap destroy it. */
-		_free_bitmap(handle);
-
-		WinQueryClassName(handle, 99, tmpbuf);
-
-		if(strncmp(tmpbuf, "#1", 3)==0)
-		{
-			Box *box = (Box *)ptr;
-
-			if(box->count && box->items)
-				free(box->items);
-		}
-		else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-		{
-			void *data = dw_window_get_data(handle, "_dw_percent");
-
-			if(data)
-				free(data);
-		}
-		else if(strncmp(tmpbuf, "#37", 4)==0)
-		{
-			dw_container_clear(handle, FALSE);
-			if(wd && dw_window_get_data(handle, "_dw_container"))
-			{
-				void *oldflags = wd->data;
-
-				wd->data = NULL;
-				free(oldflags);
-			}
-		}
-
-		if(wd->oldproc)
-			WinSubclassWindow(handle, wd->oldproc);
-
-		dw_window_set_data(handle, NULL, NULL);
-		WinSetWindowPtr(handle, QWP_USER, 0);
-		free(ptr);
-	}
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-		_free_window_memory(child);
-
-	WinEndEnumWindows(henum);
-	return;
-}
-
-void _free_menu_data(HWND menu)
-{
-	int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0);
-
-	dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED);
-	_free_window_memory(menu);
-
-	for(i=0;i<count;i++)
-	{
-		SHORT menuid = (SHORT)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0);
-		MENUITEM mi;
-
-		if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi))
-		   && mi.hwndSubMenu)
-			_free_menu_data(mi.hwndSubMenu);
-	}
-}
-
-/* This function returns 1 if the window (widget) handle
- * passed to it is a valid window that can gain input focus.
- */
-int _validate_focus(HWND handle)
-{
-	char tmpbuf[100];
-
-	if(!handle)
-		return 0;
-
-	if(!WinIsWindowEnabled(handle) || dw_window_get_data(handle, "_dw_disabled"))
-		return 0;
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
-	   strncmp(tmpbuf, "#3", 3)==0 ||  /* Button */
-	   strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
-	   strncmp(tmpbuf, "#7", 3)==0 ||  /* List box */
-	   strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
-	   strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */
-	   strncmp(tmpbuf, "#37", 4)==0 || /* Container */
-	   strncmp(tmpbuf, "#38", 4)== 0)  /* Slider */
-		return 1;
-	return 0;
-}
-
-int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem)
-{
-	int z, n;
-	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(n=0;n<box->count;n++)
-	{
-		/* Vertical boxes are inverted on OS/2 */
-		if(box->type == DW_VERT)
-			z = n;
-		else
-			z = box->count - n - 1;
-
-		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))
-				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] = "";
-
-				WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
-				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");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
-
-						if(splitbox && _focus_check_box(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_query(box->items[z].hwnd), 0);
-
-					if(page)
-					{
-						notebox = (Box *)WinQueryWindowPtr(page, QWP_USER);
-
-						if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-int _focus_check_box_back(Box *box, HWND handle, int start, HWND defaultitem)
-{
-	int z, n;
-	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(n=0;n<box->count;n++)
-	{
-		/* Vertical boxes are inverted on OS/2 */
-		if(box->type == DW_VERT)
-			z = box->count - n - 1;
-		else
-			z = n;
-
-		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))
-				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] = "";
-
-				WinQueryClassName(box->items[z].hwnd, 99, 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_query(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;
-					}
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-/* This function finds the first widget in the
- * layout and moves the current focus to it.
- */
-int _initial_focus(HWND handle)
-{
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(handle, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	else
-		return 1;
-
-	if(thisbox)
-		_focus_check_box(thisbox, handle, 3, 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)
-{
-	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(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);
-	}
-}
-
-/* This function will recursively search a box and add up the total height of it */
-void _count_size(HWND box, int type, int *xsize, int *xorigsize)
-{
-	int size = 0, origsize = 0, z;
-	Box *tmp = WinQueryWindowPtr(box, QWP_USER);
-
-	if(!tmp)
-	{
-		*xsize = *xorigsize = 0;
-		return;
-	}
-
-	if(type == tmp->type)
-	{
-		/* If the box is going in the direction we want, then we
-		 * return the entire sum of the items.
-		 */
-		for(z=0;z<tmp->count;z++)
-		{
-			if(tmp->items[z].type == TYPEBOX)
-			{
-				int s, os;
-
-				_count_size(tmp->items[z].hwnd, type, &s, &os);
-				size += s;
-				origsize += os;
-			}
-			else
-			{
-				size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
-				origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
-			}
-		}
-	}
-	else
-	{
-		/* If the box is not going in the direction we want, then we only
-		 * want to return the maximum value.
-		 */
-		int tmpsize = 0, tmporigsize = 0;
-
-		for(z=0;z<tmp->count;z++)
-		{
-			if(tmp->items[z].type == TYPEBOX)
-				_count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize);
-			else
-			{
-				tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
-				tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
-			}
-
-			if(tmpsize > size)
-				size = tmpsize;
-		}
-	}
-
-	*xsize = size;
-	*xorigsize = origsize;
-}
-
-
-/* Function: TrackRectangle
- * Abstract: Tracks given rectangle.
- *
- * If rclBounds is NULL, then track rectangle on entire desktop.
- * rclTrack is in window coorditates and will be mapped to
- * desktop.
- */
-
-BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds)
-{
-	TRACKINFO track;
-	APIRET rc;
-
-	track.cxBorder = 1;
-	track.cyBorder = 1;
-	track.cxGrid   = 1;
-	track.cyGrid   = 1;
-	track.cxKeyboard = 8;
-	track.cyKeyboard = 8;
-
-	if(!rclTrack)
-		return FALSE;
-
-	if(rclBounds)
-	{
-		track.rclBoundary = *rclBounds;
-	}
-	else
-	{
-		track.rclBoundary.yTop    =
-			track.rclBoundary.xRight  = 3000;
-		track.rclBoundary.yBottom =
-			track.rclBoundary.xLeft   = -3000;
-	}
-
-	track.rclTrack = *rclTrack;
-
-	WinMapWindowPoints(hwndBase,
-					   HWND_DESKTOP,
-					   (PPOINTL)&track.rclTrack,
-					   2);
-
-	track.ptlMinTrackSize.x = track.rclTrack.xRight
-		- track.rclTrack.xLeft;
-	track.ptlMinTrackSize.y = track.rclTrack.yTop
-		- track.rclTrack.yBottom;
-	track.ptlMaxTrackSize.x = track.rclTrack.xRight
-		- track.rclTrack.xLeft;
-	track.ptlMaxTrackSize.y = track.rclTrack.yTop
-		- track.rclTrack.yBottom;
-
-	track.fs = TF_MOVE | TF_ALLINBOUNDARY;
-
-	rc = WinTrackRect(HWND_DESKTOP, 0, &track);
-
-	if(rc)
-		*rclTrack = track.rclTrack;
-
-	return rc;
-}
-
-void _check_resize_notebook(HWND hwnd)
-{
-	char tmpbuf[100];
-
-	WinQueryClassName(hwnd, 99, tmpbuf);
-
-	/* If we have a notebook we resize the page again. */
-	if(strncmp(tmpbuf, "#40", 4)==0)
-	{
-		unsigned long x, y, width, height;
-		ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR));
-
-		while(page)
-		{
-			HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0);
-			RECTL rc;
-
-			Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
-			if(pagebox)
-			{
-				dw_window_get_pos_size(hwnd, &x, &y, &width, &height);
-
-				rc.xLeft = x;
-				rc.yBottom = y;
-				rc.xRight = x + width;
-				rc.yTop = y + height;
-
-				WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
-
-				_do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
-			}
-			page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR));
-		}
-
-	}
-}
-
-/* Return the OS/2 color from the DW color */
-unsigned long _internal_color(unsigned long color)
-{
-	if(color < 16)
-		return _colors[color];
-	return color;
-}
-
-/* This function calculates how much space the widgets and boxes require
- * and does expansion as necessary.
- */
-int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
-				int pass, int *usedpadx, int *usedpady)
-{
-	int z, currentx = 0, currenty = 0;
-	int uymax = 0, uxmax = 0;
-	int upymax = 0, upxmax = 0;
-	/* Used for the SIZEEXPAND */
-	int nux = *usedx, nuy = *usedy;
-	int nupx = *usedpadx, nupy = *usedpady;
-
-	(*usedx) += (thisbox->pad * 2);
-	(*usedy) += (thisbox->pad * 2);
-
-	if(thisbox->grouphwnd)
-	{
-		char *text = dw_window_get_text(thisbox->grouphwnd);
-
-		thisbox->grouppady = 0;
-
-		if(text)
-		{
-			dw_font_text_extents(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
-			dw_free(text);
-		}
-
-		if(thisbox->grouppady)
-			thisbox->grouppady += 3;
-		else
-			thisbox->grouppady = 6;
-
-		thisbox->grouppadx = 6;
-
-		(*usedx) += thisbox->grouppadx;
-		(*usedpadx) += thisbox->grouppadx;
-		(*usedy) += thisbox->grouppady;
-		(*usedpady) += thisbox->grouppady;
-	}
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			int initialx, initialy;
-			Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-			initialx = x - (*usedx);
-			initialy = y - (*usedy);
-
-			if(tmp)
-			{
-				int newx, newy;
-				int nux = *usedx, nuy = *usedy;
-				int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
-
-				/* On the second pass we know how big the box needs to be and how
-				 * much space we have, so we can calculate a ratio for the new box.
-				 */
-				if(pass == 2)
-				{
-					int deep = *depth + 1;
-
-					_resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
-
-					tmp->upx = upx - *usedpadx;
-					tmp->upy = upy - *usedpady;
-
-					newx = x - nux;
-					newy = y - nuy;
-
-					tmp->width = thisbox->items[z].width = initialx - newx;
-					tmp->height = thisbox->items[z].height = initialy - newy;
-
-					tmp->parentxratio = thisbox->xratio;
-					tmp->parentyratio = thisbox->yratio;
-
-					tmp->parentpad = tmp->pad;
-
-					/* Just in case */
-					tmp->xratio = thisbox->xratio;
-					tmp->yratio = thisbox->yratio;
-
-					if(thisbox->type == DW_VERT)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
-
-						if((thisbox->items[z].width - tmppad)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].width-tmp->upx)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
-					}
-					if(thisbox->type == DW_HORZ)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
-
-						if((thisbox->items[z].height-tmppad)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].height-tmp->upy)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
-					}
-
-					nux = *usedx; nuy = *usedy;
-					upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
-				}
-
-				(*depth)++;
-
-				_resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
-
-				(*depth)--;
-
-				newx = x - nux;
-				newy = y - nuy;
-
-				tmp->minwidth = thisbox->items[z].width = initialx - newx;
-				tmp->minheight = thisbox->items[z].height = initialy - newy;
-			}
-		}
-
-		if(pass > 1 && *depth > 0)
-		{
-			if(thisbox->type == DW_VERT)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
-
-				if((thisbox->minwidth-tmppad) == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
-			}
-			else
-			{
-				if(thisbox->minwidth-thisbox->upx == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
-			}
-
-			if(thisbox->type == DW_HORZ)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
-
-				if((thisbox->minheight-tmppad) == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
-			}
-			else
-			{
-				if(thisbox->minheight-thisbox->upy == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
-			}
-
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-				if(tmp)
-				{
-					tmp->parentxratio = thisbox->items[z].xratio;
-					tmp->parentyratio = thisbox->items[z].yratio;
-				}
-			}
-		}
-		else
-		{
-			thisbox->items[z].xratio = thisbox->xratio;
-			thisbox->items[z].yratio = thisbox->yratio;
-		}
-
-		if(thisbox->type == DW_VERT)
-		{
-			int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
-
-			if(itemwidth > uxmax)
-				uxmax = itemwidth;
-			if(thisbox->items[z].hsize != SIZEEXPAND)
-			{
-				if(itemwidth > upxmax)
-					upxmax = itemwidth;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upxmax)
-					upxmax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].width == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].width = */
-			}
-			else
-			{
-				(*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					(*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
-				else
-					(*usedpadx) += thisbox->items[z].pad*2;
-			}
-		}
-		if(thisbox->type == DW_HORZ)
-		{
-			int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
-
-			if(itemheight > uymax)
-				uymax = itemheight;
-			if(thisbox->items[z].vsize != SIZEEXPAND)
-			{
-				if(itemheight > upymax)
-					upymax = itemheight;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upymax)
-					upymax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].height == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].height = */
-			}
-			else
-			{
-				(*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					(*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
-				else
-					(*usedpady) += thisbox->items[z].pad*2;
-			}
-		}
-	}
-
-	(*usedx) += uxmax;
-	(*usedy) += uymax;
-	(*usedpadx) += upxmax;
-	(*usedpady) += upymax;
-
-	currentx += thisbox->pad;
-	currenty += thisbox->pad;
-
-	if(thisbox->grouphwnd)
-	{
-		currentx += 3;
-		currenty += 3;
-	}
-
-	/* The second pass is for expansion and actual placement. */
-	if(pass > 1)
-	{
-		/* Any SIZEEXPAND items should be set to uxmax/uymax */
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
-				thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
-			if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
-				thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
-			/* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-
-				if(tmp)
-				{
-					if(*depth > 0)
-					{
-						float calcval;
-
-						if(thisbox->type == DW_VERT)
-						{
-							calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->xratio = thisbox->xratio;
-							else
-								tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->width = thisbox->items[z].width;
-						}
-						if(thisbox->type == DW_HORZ)
-						{
-							calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->yratio = thisbox->yratio;
-							else
-								tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->height = thisbox->items[z].height;
-						}
-					}
-
-					(*depth)++;
-
-					_resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
-
-					(*depth)--;
-
-				}
-			}
-		}
-
-		for(z=0;z<(thisbox->count);z++)
-		{
-			int height = thisbox->items[z].height;
-			int width = thisbox->items[z].width;
-			int pad = thisbox->items[z].pad;
-			HWND handle = thisbox->items[z].hwnd;
-			int vectorx, vectory;
-
-			/* When upxmax != pad*2 then ratios are incorrect. */
-			vectorx = (int)((width*thisbox->items[z].xratio)-width);
-			vectory = (int)((height*thisbox->items[z].yratio)-height);
-
-			if(width > 0 && height > 0)
-			{
-				char tmpbuf[100];
-				/* This is a hack to fix rounding of the sizing */
-				if(*depth == 0)
-				{
-					vectorx++;
-					vectory++;
-				}
-
-				/* If this item isn't going to expand... reset the vectors to 0 */
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					vectory = 0;
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					vectorx = 0;
-
-				WinQueryClassName(handle, 99, tmpbuf);
-
-				if(strncmp(tmpbuf, "#2", 3)==0)
-				{
-					HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
-					/* Make the combobox big enough to drop down. :) */
-					WinSetWindowPos(handle, HWND_TOP, 0, -100,
-									width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					WinSetWindowPos(frame, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-				}
-				else if(strncmp(tmpbuf, "#6", 3)==0)
-				{
-					/* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
-					WinSetWindowPos(handle, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
-									(width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-				}
-				else if(strncmp(tmpbuf, "#40", 5)==0)
-				{
-					WinSetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					_check_resize_notebook(handle);
-				}
-				else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-				{
-					/* Then try the bottom or right box */
-					float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-					int type = (int)dw_window_get_data(handle, "_dw_type");
-					int cx = width + vectorx;
-					int cy = height + vectory;
-
-					WinSetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad,
-									cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-
-					if(cx > 0 && cy > 0 && percent)
-						_handle_splitbar_resize(handle, *percent, type, cx, cy);
-				}
-				else
-				{
-					WinSetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad,
-									width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
-					if(thisbox->items[z].type == TYPEBOX)
-					{
-						Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
-
-						if(boxinfo && boxinfo->grouphwnd)
-							WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
-											width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE);
-
-					}
-
-				}
-
-				if(thisbox->type == DW_HORZ)
-					currentx += width + vectorx + (pad * 2);
-				if(thisbox->type == DW_VERT)
-					currenty += height + vectory + (pad * 2);
-			}
-		}
-	}
-	return 0;
-}
-
-void _do_resize(Box *thisbox, int x, int y)
-{
-	if(x != 0 && y != 0)
-	{
-		if(thisbox)
-		{
-			int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-			if(usedx-usedpadx == 0 || usedy-usedpady == 0)
-				return;
-
-			thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
-			thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
-
-			usedx = usedy = usedpadx = usedpady = depth = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
-		}
-	}
-}
-
-/* This procedure handles WM_QUERYTRACKINFO requests from the frame */
-MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(hWnd, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox && !thisbox->titlebar)
-	{
-		switch(msg)
-		{
-		case WM_QUERYTRACKINFO:
-			{
-				if(blah && *blah)
-				{
-					PTRACKINFO ptInfo;
-					int res;
-					PFNWP myfunc = *blah;
-					res = (int)myfunc(hWnd, msg, mp1, mp2);
-
-					ptInfo = (PTRACKINFO)(mp2);
-
-					ptInfo->ptlMinTrackSize.y = 8;
-					ptInfo->ptlMinTrackSize.x = 8;
-
-					return (MRESULT)res;
-				}
-			}
-		}
-	}
-
-	if(blah && *blah)
-	{
-		PFNWP myfunc = *blah;
-		return myfunc(hWnd, msg, mp1, mp2);
-	}
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-void _Top(HPS hpsPaint, RECTL rclPaint)
-{
-	POINTL ptl1, ptl2;
-
-	ptl1.x = rclPaint.xLeft;
-	ptl2.y = ptl1.y = rclPaint.yTop - 1;
-	ptl2.x = rclPaint.xRight - 1;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
-}
-
-/* Left hits the bottom */
-void _Left(HPS hpsPaint, RECTL rclPaint)
-{
-	POINTL ptl1, ptl2;
-
-	ptl2.x = ptl1.x = rclPaint.xLeft;
-	ptl1.y = rclPaint.yTop - 1;
-	ptl2.y = rclPaint.yBottom;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
-}
-
-void _Bottom(HPS hpsPaint, RECTL rclPaint)
-{
-	POINTL ptl1, ptl2;
-
-	ptl1.x = rclPaint.xRight - 1;
-	ptl1.y = ptl2.y = rclPaint.yBottom;
-	ptl2.x = rclPaint.xLeft;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
-}
-
-/* Right hits the top */
-void _Right(HPS hpsPaint, RECTL rclPaint)
-{
-	POINTL ptl1, ptl2;
-
-	ptl2.x = ptl1.x = rclPaint.xRight - 1;
-	ptl1.y = rclPaint.yBottom + 1;
-	ptl2.y = rclPaint.yTop - 1;
-	GpiMove(hpsPaint, &ptl1);
-	GpiLine(hpsPaint, &ptl2);
-}
-
-/* This procedure handles drawing of a status border */
-MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-
-	if(blah && *blah)
-	{
-		PFNWP myfunc = *blah;
-
-		switch(msg)
-		{
-		case WM_PAINT:
-			{
-				HPS hpsPaint;
-				RECTL rclPaint;
-				char buf[1024];
-
-				hpsPaint = WinBeginPaint(hWnd, 0, 0);
-				WinQueryWindowRect(hWnd, &rclPaint);
-				WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
-
-				GpiSetColor(hpsPaint, CLR_DARKGRAY);
-				_Top(hpsPaint, rclPaint);
-				_Left(hpsPaint, rclPaint);
-
-				GpiSetColor(hpsPaint, CLR_WHITE);
-				_Right(hpsPaint, rclPaint);
-				_Bottom(hpsPaint, rclPaint);
-
-				WinQueryWindowText(hWnd, 1024, buf);
-				rclPaint.xLeft += 3;
-				rclPaint.xRight--;
-				rclPaint.yTop--;
-				rclPaint.yBottom++;
-
-				GpiSetColor(hpsPaint, CLR_BLACK);
-				WinDrawText(hpsPaint, -1, buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
-				WinEndPaint(hpsPaint);
-
-				return (MRESULT)TRUE;
-			}
-		}
-		return myfunc(hWnd, msg, mp1, mp2);
-	}
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-void _click_default(HWND handle)
-{
-	char tmpbuf[100];
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strncmp(tmpbuf, "#3", 3)==0)
-	{
-		/* Generate click on default item */
-		SignalHandler *tmp = Root;
-
-		/* Find any callbacks for this function */
-		while(tmp)
-		{
-			if(tmp->message == WM_COMMAND)
-			{
-				int (*clickfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
-
-				/* Make sure it's the right window, and the right ID */
-				if(tmp->window == handle)
-				{
-					clickfunc(tmp->window, tmp->data);
-					tmp = NULL;
-				}
-			}
-			if(tmp)
-				tmp= tmp->next;
-		}
-	}
-	else
-		WinSetFocus(HWND_DESKTOP, handle);
-}
-
-#define ENTRY_CUT   1001
-#define ENTRY_COPY  1002
-#define ENTRY_PASTE 1003
-#define ENTRY_UNDO  1004
-#define ENTRY_SALL  1005
-
-/* Originally just intended for entryfields, it now serves as a generic
- * procedure for handling TAB presses to change input focus on controls.
- */
-MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-	char tmpbuf[100];
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	WinQueryClassName(hWnd, 99, tmpbuf);
-
-	/* These are the window classes which should get a menu */
-	if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
-	   strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
-	   strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
-	   strncmp(tmpbuf, "#32", 4)==0)   /* Spinbutton */
-	{
-		switch(msg)
-		{
-		case WM_CONTEXTMENU:
-			{
-				HMENUI hwndMenu = dw_menu_new(0L);
-				long x, y;
-
-				if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))
-				{
-					dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, FALSE, 0L);
-					dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L);
-				}
-				dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, FALSE, 0L);
-				if((strncmp(tmpbuf, "#10", 4)!=0  && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)))
-				{
-					dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, FALSE, 0L);
-					dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, FALSE, 0L);
-				}
-				dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L);
-				dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, FALSE, 0L);
-
-				WinSetFocus(HWND_DESKTOP, hWnd);
-				dw_pointer_query_pos(&x, &y);
-				dw_menu_popup(&hwndMenu, hWnd, x, y);
-			}
-			break;
-		case WM_COMMAND:
-			{
-				ULONG command = COMMANDMSG(&msg)->cmd;
-
-				/* MLE */
-				if(strncmp(tmpbuf, "#10", 4)==0)
-				{
-					switch(command)
-					{
-					case ENTRY_CUT:
-						return WinSendMsg(hWnd, MLM_CUT, 0, 0);
-					case ENTRY_COPY:
-						return WinSendMsg(hWnd, MLM_COPY, 0, 0);
-					case ENTRY_PASTE:
-						return WinSendMsg(hWnd, MLM_PASTE, 0, 0);
-					case ENTRY_UNDO:
-						return WinSendMsg(hWnd, MLM_UNDO, 0, 0);
-					case ENTRY_SALL:
-						{
-							ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0);
-							return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len);
-						}
-					}
-				}
-				else /* Other */
-				{
-					HWND handle = hWnd;
-
-					/* Get the entryfield handle from multi window controls */
-					if(strncmp(tmpbuf, "#2", 3)==0)
-						handle = WinWindowFromID(hWnd, 667);
-
-					if(handle)
-					{
-						switch(command)
-						{
-						case ENTRY_CUT:
-							return WinSendMsg(handle, EM_CUT, 0, 0);
-						case ENTRY_COPY:
-							return WinSendMsg(handle, EM_COPY, 0, 0);
-						case ENTRY_PASTE:
-							return WinSendMsg(handle, EM_PASTE, 0, 0);
-						case ENTRY_SALL:
-							{
-								LONG len = WinQueryWindowTextLength(hWnd);
-								return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0);
-							}
-						}
-					}
-				}
-			}
-			break;
-		}
-	}
-
-	switch(msg)
-	{
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		{
-			if(strncmp(tmpbuf, "#32", 4)==0)
-				_run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
-		}
-		break;
-	case WM_CONTROL:
-		{
-			if(strncmp(tmpbuf, "#38", 4)==0)
-				_run_event(hWnd, msg, mp1, mp2);
-		}
-		break;
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
-			_click_default(blah->clickdefault);
-		/* When you hit escape we get this value and the
-		 * window hangs for reasons unknown. (in an MLE)
-		 */
-		else if(SHORT1FROMMP(mp2) == 283)
-			return (MRESULT)TRUE;
-
-		break;
-	case WM_SIZE:
-		{
-			/* If it's a slider... make sure it shows the correct value */
-			if(strncmp(tmpbuf, "#38", 4)==0)
-				WinPostMsg(hWnd, WM_USER+7, 0, 0);
-		}
-		break;
-	case WM_USER+7:
-		{
-			int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value");
-			WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos);
-		}
-		break;
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-/*  Deal with combobox specifics and enhancements */
-MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
-
-	switch(msg)
-	{
-	case WM_CONTEXTMENU:
-	case WM_COMMAND:
-		return _entryproc(hWnd, msg, mp1, mp2);
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		/* A Similar problem to the MLE, if ESC just return */
-		if(SHORT1FROMMP(mp2) == 283)
-			return (MRESULT)TRUE;
-		break;
-	}
-
-	if(blah && blah->oldproc)
-		return blah->oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-/* Enhance the standard OS/2 MLE control */
-MRESULT EXPENTRY _mleproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	switch(msg)
-	{
-	case WM_VSCROLL:
-		if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK)
-		{
-			USHORT pos = SHORT1FROMMP(mp2);
-
-			WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION));
-		}
-		break;
-	}
-	return _entryproc(hWnd, msg, mp1, mp2);
-}
-
-/* Handle special messages for the spinbutton's entryfield */
-MRESULT EXPENTRY _spinentryproc(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_CONTEXTMENU:
-	case WM_COMMAND:
-		return _entryproc(hWnd, msg, mp1, mp2);
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-int _dw_int_pos(HWND hwnd)
-{
-	int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value");
-	int range = dw_percent_query_range(hwnd);
-	float fpos = (float)pos;
-	float frange = (float)range;
-	float fnew = (fpos/1000.0)*frange;
-	return (int)fnew;
-}
-
-void _dw_int_set(HWND hwnd, int pos)
-{
-	int inew, range = dw_percent_query_range(hwnd);
-	if(range)
-	{
-		float fpos = (float)pos;
-		float frange = (float)range;
-		float fnew = (fpos/frange)*1000.0;
-		inew = (int)fnew;
-		dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew);
-	}
-}
-
-/* Handle size changes in the percent class */
-MRESULT EXPENTRY _percentproc(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_SIZE:
-		WinPostMsg(hWnd, WM_USER+7, 0, 0);
-		break;
-	case WM_USER+7:
-		WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd));
-		break;
-	}
-
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-/* Handle correct painting of a combobox with the WS_CLIPCHILDREN
- * flag enabled, and also handle TABs to switch input focus.
- */
-MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-	PFNWP oldproc = 0;
-
-	if(blah)
-		oldproc = blah->oldproc;
-
-	switch(msg)
-	{
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
-			_click_default(blah->clickdefault);
-		break;
-	case WM_BUTTON1DBLCLK:
-	case WM_BUTTON2DBLCLK:
-	case WM_BUTTON3DBLCLK:
-		if(dw_window_get_data(hWnd, "_dw_disabled"))
-			return (MRESULT)TRUE;
-		break;
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
-			return (MRESULT)TRUE;
-		_run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
-		break;
-	case WM_SETFOCUS:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	case WM_PAINT:
-		{
-			HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT);
-			HPS hpsPaint;
-			POINTL ptl;
-			unsigned long width, height, thumbheight = 0;
-			ULONG color;
-
-			if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE)
-				dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight);
-
-			if(!thumbheight)
-				thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW);
-
-			/* Add 6 because it has a thick border like the entryfield */
-			thumbheight += 6;
-
-			color = (ULONG)dw_window_get_data(parent, "_dw_fore");
-			dw_window_get_pos_size(hWnd, 0, 0, &width, &height);
-
-			if(height > thumbheight)
-			{
-				hpsPaint = WinGetPS(hWnd);
-				if(color)
-					GpiSetColor(hpsPaint, _internal_color(color-1));
-				else
-					GpiSetColor(hpsPaint, CLR_PALEGRAY);
-
-				ptl.x = ptl.y = 0;
-				GpiMove(hpsPaint, &ptl);
-
-				ptl.x = width;
-				ptl.y = height - thumbheight;
-				GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0);
-
-				WinReleasePS(hpsPaint);
-			}
-		}
-		break;
-	}
-	if(oldproc)
-		return oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-void _GetPPFont(HWND hwnd, char *buff)
-{
-    ULONG AttrFound;
-    BYTE  AttrValue[128];
-    ULONG cbRetLen;
-
-    cbRetLen = WinQueryPresParam(hwnd,
-                                 PP_FONTNAMESIZE,
-                                 0,
-                                 &AttrFound,
-                                 sizeof(AttrValue),
-                                 &AttrValue,
-                                 QPF_NOINHERIT);
-
-    if(PP_FONTNAMESIZE == AttrFound && cbRetLen)
-    {
-        memcpy(buff, AttrValue, cbRetLen);
-    }
-}
-
-/* Returns height of specified window. */
-int _get_height(HWND handle)
-{
-	unsigned long height;
-	dw_window_get_pos_size(handle, NULL, NULL, NULL, &height);
-	return (int)height;
-}
-
-/* Find the height of the frame a desktop style window is sitting on */
-int _get_frame_height(HWND handle)
-{
-	while(handle)
-	{
-		HWND client;
-		if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
-		{
-            return _get_height(WinQueryWindow(handle, QW_PARENT));
-		}
-        handle = WinQueryWindow(handle, QW_PARENT);
-	}
-	return dw_screen_height();
-}
-
-int _HandleScroller(HWND handle, int pos, int which)
-{
-	MPARAM res;
-	int min, max, page;
-
-	if(which == SB_SLIDERTRACK)
-		return pos;
-
-	pos = dw_scrollbar_query_pos(handle);
-	res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
-
-	min = SHORT1FROMMP(res);
-	max = SHORT2FROMMP(res);
-	page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible");
-
-	switch(which)
-	{
-	case SB_LINEUP:
-		pos = pos - 1;
-		if(pos < min)
-			pos = min;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_LINEDOWN:
-		pos = pos + 1;
-		if(pos > max)
-			pos = max;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_PAGEUP:
-		pos = pos - page;
-		if(pos < min)
-			pos = min;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	case SB_PAGEDOWN:
-		pos = pos + page;
-		if(pos > max)
-			pos = max;
-		dw_scrollbar_set_pos(handle, pos);
-		return pos;
-	}
-	return -1;
-}
-
-void _clear_emphasis(void)
-{
-	if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph)
-		WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE));
-	hwndEmph = NULLHANDLE;
-	pCoreEmph = NULL;
-}
-
-/* Find the desktop window handle */
-HWND _menu_owner(HWND handle)
-{
-	HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner");
-	int menubar = (int)dw_window_get_data(handle, "_dw_menubar");
-
-	/* Find the toplevel window */
-	while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE)
-	{
-		menubar = (int)dw_window_get_data(lastowner, "_dw_menubar");
-		lastowner = menuowner;
-	}
-	if(menuowner && menubar)
-	{
-		HWND client = WinWindowFromID(menuowner, FID_CLIENT);
-
-		return client ? client : menuowner;
-	}
-	return NULLHANDLE;
-}
-
-MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	int result = -1;
-	SignalHandler *tmp = Root;
-	ULONG origmsg = msg;
-
-	if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN)
-		msg = WM_BUTTON1DOWN;
-	if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP)
-		msg = WM_BUTTON1UP;
-	if(msg == WM_VSCROLL || msg == WM_HSCROLL)
-		msg = WM_CONTROL;
-
-	/* Find any callbacks for this function */
-	while(tmp)
-	{
-		if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1)
-		{
-			switch(msg)
-			{
-			case WM_SETFOCUS:
-				{
-					if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
-					{
-						int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
-						{
-							result = setfocusfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-				}
-				break;
-			case WM_TIMER:
-				{
-					int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
-					if(tmp->id == (int)mp1)
-					{
-						if(!timerfunc(tmp->data))
-							dw_timer_disconnect(tmp->id);
-						tmp = NULL;
-					}
-					result = 0;
-				}
-				break;
-			case WM_SIZE:
-				{
-					int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
-
-					if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2))
-					{
-						result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_BUTTON1DOWN:
-				{
-					POINTS pts = (*((POINTS*)&mp1));
-					int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int button = 0;
-
-						switch(origmsg)
-						{
-						case WM_BUTTON1DOWN:
-							button = 1;
-							break;
-						case WM_BUTTON2DOWN:
-							button = 2;
-							break;
-						case WM_BUTTON3DOWN:
-							button = 3;
-							break;
-						}
-
-						result = buttonfunc(tmp->window, pts.x, _get_frame_height(tmp->window) - pts.y, button, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_BUTTON1UP:
-				{
-					POINTS pts = (*((POINTS*)&mp1));
-					int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int button = 0;
-
-						switch(origmsg)
-						{
-						case WM_BUTTON1UP:
-							button = 1;
-							break;
-						case WM_BUTTON2UP:
-							button = 2;
-							break;
-						case WM_BUTTON3UP:
-							button = 3;
-							break;
-						}
-
-						result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_MOUSEMOVE:
-				{
-					int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
-					{
-						int keys = 0;
-						SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1);
-
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
-							keys = DW_BUTTON1_MASK;
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
-							keys |= DW_BUTTON2_MASK;
-						if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
-							keys |= DW_BUTTON3_MASK;
-
-						result = motionfunc(tmp->window, x, _get_frame_height(tmp->window) - y, keys, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CHAR:
-				{
-					int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction;
-
-					if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
-					{
-						int vk;
-						char ch = 0;
-
-						if(SHORT1FROMMP(mp1) & KC_CHAR)
-							ch = (char)SHORT1FROMMP(mp2);
-						if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
-							vk = SHORT2FROMMP(mp2);
-						else
-							vk = SHORT1FROMMP(mp2) + 128;
-
-						/* This is a hack to fix shift presses showing
-						 * up as tabs!
-						 */
-						if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
-						{
-							ch = 0;
-							vk = VK_SHIFT;
-						}
-
-						result = keypressfunc(tmp->window, ch, vk,
-											  SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CLOSE:
-				{
-					int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-
-					if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
-					{
-						result = closefunc(tmp->window, tmp->data);
-						if(result)
-							result = FALSE;
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_PAINT:
-				{
-					HPS hps;
-					DWExpose exp;
-					int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction;
-					RECTL  rc;
-
-					if(hWnd == tmp->window)
-					{
-						int height = _get_height(hWnd);
-
-						hps = WinBeginPaint(hWnd, 0L, &rc);
-						exp.x = rc.xLeft;
-						exp.y = height - rc.yTop - 1;
-						exp.width = rc.xRight - rc. xLeft;
-						exp.height = rc.yTop - rc.yBottom;
-						result = exposefunc(hWnd, &exp, tmp->data);
-						WinEndPaint(hps);
-					}
-				}
-				break;
-			case WM_COMMAND:
-				{
-					int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
-					ULONG command = COMMANDMSG(&msg)->cmd;
-
-					if(tmp->id && command == tmp->id)
-					{
-						HWND menuowner = _menu_owner(tmp->window);
-
-						if(menuowner == hWnd || menuowner == NULLHANDLE)
-						{
-							result = clickfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					else if(tmp->window < 65536 && command == tmp->window)
-					{
-						result = clickfunc(popup ?  popup : tmp->window, tmp->data);
-						tmp = NULL;
-					}
-				}
-				break;
-			case WM_CONTROL:
-				if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
-				   (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
-				{
-					int svar = SLN_SLIDERTRACK;
-					if(origmsg == WM_CONTROL)
-						svar = SHORT2FROMMP(mp1);
-
-					switch(svar)
-					{
-					case CN_ENTER:
-						{
-							int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-							char *text = NULL;
-
-							if(mp2)
-							{
-								PRECORDCORE pre;
-
-								pre = ((PNOTIFYRECORDENTER)mp2)->pRecord;
-								if(pre)
-									text = pre->pszIcon;
-							}
-
-							if(tmp->window == conthwnd)
-							{
-								result = containerselectfunc(tmp->window, text, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_EXPANDTREE:
-						{
-							int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-
-							if(tmp->window == conthwnd)
-							{
-								result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_CONTEXTMENU:
-						{
-							int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
-							int id = SHORT1FROMMP(mp1);
-							HWND conthwnd = dw_window_from_id(hWnd, id);
-							char *text = NULL;
-							void *user = NULL;
-							LONG x,y;
-
-							if(mp2)
-							{
-								PCNRITEM pci;
-
-								pci = (PCNRITEM)mp2;
-
-								text = pci->rc.pszIcon;
-								user = pci->user;
-							}
-
-							dw_pointer_query_pos(&x, &y);
-
-							if(tmp->window == conthwnd)
-							{
-								int container = (int)dw_window_get_data(tmp->window, "_dw_container");
-
-								if(mp2)
-								{
-									if(!container)
-									{
-										NOTIFYRECORDEMPHASIS pre;
-
-										dw_tree_item_select(tmp->window, (HTREEITEM)mp2);
-										pre.pRecord = mp2;
-										pre.fEmphasisMask = CRA_CURSORED;
-										pre.hwndCnr = tmp->window;
-										_run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
-										pre.pRecord->flRecordAttr |= CRA_CURSORED;
-									}
-									else
-									{
-										if(pCoreEmph)
-											_clear_emphasis();
-										hwndEmph = tmp->window;
-										pCoreEmph = mp2;
-										WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE));
-									}
-								}
-								result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
-								tmp = NULL;
-							}
-						}
-						break;
-					case CN_EMPHASIS:
-						{
-							PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2;
-							static int emph_recurse = 0;
-
-							if(!emph_recurse)
-							{
-								emph_recurse = 1;
-
-								if(mp2)
-								{
-									if(tmp->window == pre->hwndCnr)
-									{
-										PCNRITEM pci = (PCNRITEM)pre->pRecord;
-
-										if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
-										{
-											int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
-
-											if(dw_window_get_data(tmp->window, "_dw_container"))
-												result = treeselectfunc(tmp->window, 0, pci->rc.pszIcon, tmp->data, 0);
-											else
-											{
-												if(lasthcnr == tmp->window && lastitem == (HWND)pci)
-												{
-													lasthcnr = 0;
-													lastitem = 0;
-												}
-												else
-												{
-													lasthcnr = tmp->window;
-													lastitem = (HWND)pci;
-													result = treeselectfunc(tmp->window, (HTREEITEM)pci, pci->rc.pszIcon, tmp->data, pci->user);
-												}
-											}
-											tmp = NULL;
-										}
-									}
-								}
-								emph_recurse = 0;
-							}
-						}
-						break;
-					case LN_SELECT:
-						{
-							char classbuf[100];
-
-							WinQueryClassName(tmp->window, 99, classbuf);
-
-							if(strncmp(classbuf, "#38", 4) == 0)
-							{
-								int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
-
-								if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
-								{
-									static int lastvalue = -1;
-									static HWND lasthwnd = NULLHANDLE;
-									int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
-									if(lastvalue != ulValue || lasthwnd != tmp->window)
-									{
-										result = valuechangedfunc(tmp->window, ulValue, tmp->data);
-										lastvalue = ulValue;
-										lasthwnd = tmp->window;
-									}
-									tmp = NULL;
-								}
-							}
-							else
-							{
-								int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction;
-								int id = SHORT1FROMMP(mp1);
-								HWND conthwnd = dw_window_from_id(hWnd, id);
-								static int _recursing = 0;
-
-								if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2)))
-								{
-									char buf1[500];
-									unsigned int index = dw_listbox_selected(tmp->window);
-
-									dw_listbox_query_text(tmp->window, index, buf1, 500);
-
-									_recursing = 1;
-
-									if(id && strncmp(classbuf, "#2", 3)==0)
-									{
-										char *buf2;
-
-										buf2 = dw_window_get_text(tmp->window);
-
-										/* This is to make sure the listboxselect function doesn't
-										 * get called if the user is modifying the entry text.
-										 */
-										if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0)
-											result = listboxselectfunc(tmp->window, index, tmp->data);
-
-										if(buf2)
-											free(buf2);
-									}
-									else
-										result = listboxselectfunc(tmp->window, index, tmp->data);
-
-									_recursing = 0;
-									tmp = NULL;
-								}
-							}
-						}
-						break;
-					case SLN_SLIDERTRACK:
-						{
-							int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
-
-							if(origmsg == WM_CONTROL)
-							{
-								/* Handle Slider control */
-								if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd)
-								{
-									static int lastvalue = -1;
-									static HWND lasthwnd = NULLHANDLE;
-									int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
-									if(lastvalue != ulValue || lasthwnd != tmp->window)
-									{
-										dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue);
-										result = valuechangedfunc(tmp->window, ulValue, tmp->data);
-										lastvalue = ulValue;
-										lasthwnd = tmp->window;
-									}
-									tmp = NULL;
-								}
-							}
-							else
-							{
-								/* Handle scrollbar control */
-								if(tmp->window > 65535 && tmp->window == WinWindowFromID(hWnd, (ULONG)mp1))
-								{
-									int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));;
-
-									if(pos > -1)
-									{
-										dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos);
-										result = valuechangedfunc(tmp->window, pos, tmp->data);
-									}
-									result = 0;
-									tmp = NULL;
-								}
-							}
-						}
-						break;
-					case BKN_PAGESELECTED:
-						{
-							PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
-
-							if(psn && tmp->window == psn->hwndBook)
-							{
-								int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction;
-
-								result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data);
-								tmp = NULL;
-							}
-						}
-						break;
-					}
-				}
-				break;
-			}
-		}
-
-		if(tmp)
-			tmp = tmp->next;
-
-	}
-	return (MRESULT)result;
-}
-
-/* Handles control messages sent to the box (owner). */
-MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	Box *blah = WinQueryWindowPtr(hWnd, QWP_USER);
-
-	switch(msg)
-	{
-	case WM_VSCROLL:
-	case WM_HSCROLL:
-		if(_run_event(hWnd, msg, mp1, mp2))
-		{
-			HWND window = WinWindowFromID(hWnd, (ULONG)mp1);
-			_HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));
-		}
-		break;
-	case WM_CONTROL:
-		_run_event(hWnd, msg, mp1, mp2);
-		break;
-	}
-
-	if(blah && blah->oldproc)
-		return blah->oldproc(hWnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-/* The main window procedure for Dynamic Windows, all the resizing code is done here. */
-MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	int result = -1;
-	static int command_active = 0;
-	void (* API windowfunc)(PVOID) = 0L;
-
-	if(!command_active)
-	{
-        /* Make sure we don't end up in infinite recursion */
-		command_active = 1;
-
-		result = (int)_run_event(hWnd, msg, mp1, mp2);
-
-		command_active = 0;
-	}
-
-	/* Now that any handlers are done... do normal processing */
-	switch( msg )
-	{
-   case WM_ERASEBACKGROUND:
-      return 0;
-
-	case WM_PAINT:
-		{
-		HPS    hps;
-		RECTL  rc;
-
-		hps = WinBeginPaint( hWnd, 0L, &rc );
-		WinEndPaint( hps );
-		break;
-		}
-
-	case WM_SIZE:
-		{
-			Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
-
-			if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2))
-				return (MPARAM)TRUE;
-
-			if(mybox && mybox->flags != DW_MINIMIZED)
-			{
-				/* Hide the window when recalculating to reduce
-				 * CPU load.
-				 */
-				WinShowWindow(hWnd, FALSE);
-
-				_do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
-
-				WinShowWindow(hWnd, TRUE);
-			}
-		}
-		break;
-	case WM_MINMAXFRAME:
-		{
-			Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
-			SWP *swp = (SWP *)mp1;
-
-			if(mybox && (swp->fl & SWP_MINIMIZE))
-				mybox->flags = DW_MINIMIZED;
-
-			if(mybox && (swp->fl & SWP_RESTORE))
-			{
-				if(!mybox->titlebar && mybox->hwndtitle)
-					WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE);
-				mybox->flags = 0;
-			}
-
-			if(mybox && (swp->fl & SWP_MAXIMIZE))
-			{
-				int z;
-				SWP swp2;
-
-				WinQueryWindowPos(swp->hwnd, &swp2);
-
-				if(swp2.cx == swp->cx && swp2.cy == swp->cy)
-					return FALSE;
-
-				mybox->flags = 0;
-
-				/* Hide the window when recalculating to reduce
-				 * CPU load.
-				 */
-				WinShowWindow(hWnd, FALSE);
-
-				_do_resize(mybox, swp->cx, swp->cy);
-
-				if(mybox->count == 1 && mybox->items[0].type == TYPEBOX)
-				{
-					mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER);
-
-					for(z=0;z<mybox->count;z++)
-						_check_resize_notebook(mybox->items[z].hwnd);
-
-				}
-
-				WinShowWindow(hWnd, TRUE);
-			}
-		}
-		break;
-	case WM_CONTROL:
-		switch(SHORT2FROMMP(mp1))
-		{
-		case BKN_PAGESELECTEDPENDING:
-			{
-				PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
-				HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0);
-				Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
-				unsigned long x, y, width, height;
-				RECTL rc;
-
-				if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur)
-				{
-					dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height);
-
-					rc.xLeft = x;
-					rc.yBottom = y;
-					rc.xRight = x + width;
-					rc.yTop = y + height;
-
-					WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
-
-					_do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
-				}
-			}
-			break;
-		}
-		break;
-	case WM_CLOSE:
-		if(result == -1)
-		{
-			dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
-			return (MRESULT)TRUE;
-		}
-		break;
-	case WM_MOUSEMOVE:
-		{
-			HPOINTER ptr = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer");
-
-			if(ptr)
-				WinSetPointer(HWND_DESKTOP, ptr);
-		}
-		break;
-	case WM_USER:
-		windowfunc = (void (* API)(void *))mp1;
-
-		if(windowfunc)
-			windowfunc((void *)mp2);
-		break;
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		break;
-	case WM_DESTROY:
-		{
-			HWND parent = WinQueryWindow(hWnd, QW_PARENT);
-
-			/* Free memory before destroying */
-			if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd)
-				_free_window_memory(parent);
-			else
-				_free_window_memory(hWnd);
-		}
-		break;
-	case WM_MENUEND:
-		_clear_emphasis();
-		if(dw_window_get_data((HWND)mp2, "_dw_popup"))
-			_free_menu_data((HWND)mp2);
-		break;
-	}
-
-	if(result != -1)
-		return (MRESULT)result;
-	else
-		return WinDefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-void _changebox(Box *thisbox, int percent, int type)
-{
-	int z;
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-			_changebox(tmp, percent, type);
-		}
-		else
-		{
-			if(type == DW_HORZ)
-			{
-				if(thisbox->items[z].hsize == SIZEEXPAND)
-					thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
-			}
-			else
-			{
-				if(thisbox->items[z].vsize == SIZEEXPAND)
-					thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
-			}
-		}
-	}
-}
-
-void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
-{
-	if(type == DW_HORZ)
-	{
-		int newx = x;
-		float ratio = (float)percent/(float)100.0;
-		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		Box *tmp = WinQueryWindowPtr(handle1, QWP_USER);
-
-		WinShowWindow(handle1, FALSE);
-		WinShowWindow(handle2, FALSE);
-
-		newx = (int)((float)newx * ratio) - (SPLITBAR_WIDTH/2);
-
-		WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, newx - 1, y - 1);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newx);
-
-		tmp = WinQueryWindowPtr(handle2, QWP_USER);
-
-		newx = x - newx - SPLITBAR_WIDTH;
-
-		WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, newx - 1, y - 1);
-
-		WinShowWindow(handle1, TRUE);
-		WinShowWindow(handle2, TRUE);
-	}
-	else
-	{
-		int newy = y;
-		float ratio = (float)percent/(float)100.0;
-		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		Box *tmp = WinQueryWindowPtr(handle1, QWP_USER);
-
-		WinShowWindow(handle1, FALSE);
-		WinShowWindow(handle2, FALSE);
-
-		newy = (int)((float)newy * ratio) - (SPLITBAR_WIDTH/2);
-
-		WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		tmp = WinQueryWindowPtr(handle2, QWP_USER);
-
-		newy = y - newy - SPLITBAR_WIDTH;
-
-		WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		WinShowWindow(handle1, TRUE);
-		WinShowWindow(handle2, TRUE);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newy);
-	}
-}
-
-
-/* This handles any activity on the splitbars (sizers) */
-MRESULT EXPENTRY _splitwndproc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
-	int type = (int)dw_window_get_data(hwnd, "_dw_type");
-	int start = (int)dw_window_get_data(hwnd, "_dw_start");
-
-	switch (msg)
-	{
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-		return (MRESULT)(FALSE);
-
-	case WM_PAINT:
-		{
-			HPS hps;
-			POINTL ptl[2];
-			RECTL rcl;
-
-			hps = WinBeginPaint(hwnd, 0, 0);
-
-			WinQueryWindowRect(hwnd, &rcl);
-
-			if(type == DW_HORZ)
-			{
-				ptl[0].x = rcl.xLeft + start;
-				ptl[0].y = rcl.yBottom;
-				ptl[1].x = rcl.xRight + start + 3;
-				ptl[1].y = rcl.yTop;
-			}
-			else
-			{
-				ptl[0].x = rcl.xLeft;
-				ptl[0].y = rcl.yBottom + start;
-				ptl[1].x = rcl.xRight;
-				ptl[1].y = rcl.yTop + start + 3;
-			}
-
-
-			GpiSetColor(hps, CLR_PALEGRAY);
-			GpiMove(hps, &ptl[0]);
-			GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0);
-			WinEndPaint(hps);
-		}
-		return MRFROMSHORT(FALSE);
-
-	case WM_MOUSEMOVE:
-		{
-			if(type == DW_HORZ)
-				WinSetPointer(HWND_DESKTOP,
-							  WinQuerySysPointer(HWND_DESKTOP,
-												 SPTR_SIZEWE,
-												 FALSE));
-			else
-				WinSetPointer(HWND_DESKTOP,
-							  WinQuerySysPointer(HWND_DESKTOP,
-												 SPTR_SIZENS,
-												 FALSE));
-		}
-		return MRFROMSHORT(FALSE);
-	case WM_BUTTON1DOWN:
-		{
-			APIRET rc;
-			RECTL  rclFrame;
-			RECTL  rclBounds;
-
-			WinQueryWindowRect(hwnd, &rclFrame);
-			WinQueryWindowRect(hwnd, &rclBounds);
-
-			WinMapWindowPoints(hwnd, HWND_DESKTOP,
-							   (PPOINTL)&rclBounds, 2);
-
-
-			if(type == DW_HORZ)
-			{
-				rclFrame.xLeft = start;
-				rclFrame.xRight = start + SPLITBAR_WIDTH;
-			}
-			else
-			{
-				rclFrame.yBottom = start;
-				rclFrame.yTop = start + SPLITBAR_WIDTH;
-			}
-
-			if(percent)
-			{
-				rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds);
-
-				if(rc == TRUE)
-				{
-					int width = (rclBounds.xRight - rclBounds.xLeft);
-					int height = (rclBounds.yTop - rclBounds.yBottom);
-
-					if(type == DW_HORZ)
-					{
-						start = rclFrame.xLeft - rclBounds.xLeft;
-						if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
-							*percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
-					}
-					else
-					{
-						start = rclFrame.yBottom - rclBounds.yBottom;
-						if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
-							*percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0);
-					}
-					_handle_splitbar_resize(hwnd, *percent, type, width, height);
-				}
-			}
-		}
-		return MRFROMSHORT(FALSE);
-	}
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
-}
-
-/* Function: BubbleProc
- * Abstract: Subclass procedure for bubble help
- */
-MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	MRESULT res;
-	PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
-
-	if(proc)
-		res = proc(hwnd, msg, mp1, mp2);
-	else
-		res = WinDefWindowProc(hwnd, msg, mp1, mp2);
-
-	if(msg == WM_PAINT)
-	{
-		POINTL ptl;
-		HPS hpsTemp;
-		RECTL rcl;
-		int height, width;
-
-		WinQueryWindowRect(hwnd, &rcl);
-		height = rcl.yTop - rcl.yBottom - 1;
-		width = rcl.xRight - rcl.xLeft - 1;
-
-		/* Draw a border around the bubble help */
-		hpsTemp = WinGetPS(hwnd);
-		GpiSetColor(hpsTemp, CLR_BLACK);
-		ptl.x = ptl.y = 0;
-		GpiMove(hpsTemp, &ptl);
-		ptl.x = 0;
-		ptl.y = height;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = ptl.y = 0;
-		GpiMove(hpsTemp, &ptl);
-		ptl.y = 0;
-		ptl.x = width;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = width;
-		ptl.y = height;
-		GpiMove(hpsTemp, &ptl);
-		ptl.x = 0;
-		ptl.y = height;
-		GpiLine(hpsTemp, &ptl);
-		ptl.x = width;
-		ptl.y = height;
-		GpiMove(hpsTemp, &ptl);
-		ptl.y = 0;
-		ptl.x = width;
-		GpiLine(hpsTemp, &ptl);
-		WinReleasePS(hpsTemp);
-	}
-	return res;
-}
-
-MRESULT EXPENTRY _button_draw(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, PFNWP oldproc, int indent)
-{
-	HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap");
-	HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled");
-	MRESULT res;
-
-	if(!oldproc)
-		res = WinDefWindowProc(hwnd, msg, mp1, mp2);
-	res = oldproc(hwnd, msg, mp1, mp2);
-
-	if(pixmap)
-	{
-		unsigned long width, height;
-		int x, y;
-
-		dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height);
-
-		x = (width - pixmap->width)/2;
-		y = (height - pixmap->height)/2;
-
-		if(disable && dw_window_get_data(hwnd, "_dw_disabled"))
-			dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0);
-		else
-			dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
-	}
-	return res;
-}
-
-/* Function: BtProc
- * Abstract: Subclass procedure for buttons
- */
-
-MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	BubbleButton *bubble;
-	PFNWP oldproc;
-
-	bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
-
-	if(!bubble)
-		return WinDefWindowProc(hwnd, msg, mp1, mp2);
-
-	oldproc = bubble->pOldProc;
-
-	switch(msg)
-	{
-	case WM_PAINT:
-		return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0);
-	case BM_SETHILITE:
-		return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1);
-	case WM_SETFOCUS:
-		if(mp2)
-			_run_event(hwnd, msg, mp1, mp2);
-		else
-			WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
-		break;
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-	case WM_BUTTON1DBLCLK:
-	case WM_BUTTON2DBLCLK:
-	case WM_BUTTON3DBLCLK:
-		if(dw_window_get_data(hwnd, "_dw_disabled"))
-			return (MRESULT)FALSE;
-		break;
-	case WM_BUTTON1UP:
-		{
-			SignalHandler *tmp = Root;
-
-			if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled"))
-			{
-				/* Find any callbacks for this function */
-				while(tmp)
-				{
-					if(tmp->message == WM_COMMAND)
-					{
-						/* Make sure it's the right window, and the right ID */
-						if(tmp->window == hwnd)
-						{
-							/* Due to the fact that if we run the function
-							 * here, finishing actions on the button will occur
-							 * after we run the signal handler.  So we post the
-							 * message so the button can finish what it needs to
-							 * do before we run our handler.
-							 */
-							WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
-							tmp = NULL;
-						}
-					}
-					if(tmp)
-						tmp= tmp->next;
-				}
-			}
-		}
-		break;
-	case WM_USER:
-		{
-            SignalHandler *tmp = (SignalHandler *)mp1;
-			int (* API clickfunc)(HWND, void *) = NULL;
-
-			if(tmp)
-			{
-				clickfunc = (int (* API)(HWND, void *))tmp->signalfunction;
-
-				clickfunc(tmp->window, tmp->data);
-			}
-		}
-        break;
-	case WM_CHAR:
-		{
-			/* A button press should also occur for an ENTER or SPACE press
-			 * while the button has the active input focus.
-			 */
-			if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ')
-			{
-				SignalHandler *tmp = Root;
-
-				/* Find any callbacks for this function */
-				while(tmp)
-				{
-					if(tmp->message == WM_COMMAND)
-					{
-						/* Make sure it's the right window, and the right ID */
-						if(tmp->window == hwnd)
-						{
-							WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
-							tmp = NULL;
-						}
-					}
-					if(tmp)
-						tmp= tmp->next;
-				}
-			}
-			if(SHORT1FROMMP(mp2) == '\t')
-			{
-				if(CHARMSG(&msg)->fs & KC_SHIFT)
-					_shift_focus_back(hwnd);
-				else
-					_shift_focus(hwnd);
-				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);
-				return FALSE;
-			}
-			else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN))
-			{
-				_shift_focus(hwnd);
-				return FALSE;
-			}
-		}
-		break;
-	case 0x041f:
-		if (hwndBubble)
-		{
-			WinDestroyWindow(hwndBubble);
-			hwndBubble = 0;
-		}
-		break;
-
-	case 0x041e:
-
-		if(!*bubble->bubbletext)
-			break;
-
-		if(hwndBubble)
-		{
-			WinDestroyWindow(hwndBubble);
-			hwndBubble = 0;
-		}
-
-		if(!hwndBubble)
-		{
-			HPS   hpsTemp = 0;
-			LONG  lHight;
-			LONG  lWidth;
-			POINTL txtPointl[TXTBOX_COUNT];
-			POINTL ptlWork = {0,0};
-			ULONG ulColor = CLR_YELLOW;
-			void *blah;
-
-			hwndBubbleLast   = hwnd;
-			hwndBubble = WinCreateWindow(HWND_DESKTOP,
-										 WC_STATIC,
-										 "",
-										 SS_TEXT |
-										 DT_CENTER |
-										 DT_VCENTER,
-                                         0,0,0,0,
-										 HWND_DESKTOP,
-										 HWND_TOP,
-										 0,
-										 NULL,
-										 NULL);
-
-			WinSetPresParam(hwndBubble,
-							PP_FONTNAMESIZE,
-							strlen(DefaultFont)+1,
-							DefaultFont);
-
-
-			WinSetPresParam(hwndBubble,
-							PP_BACKGROUNDCOLORINDEX,
-							sizeof(ulColor),
-							&ulColor);
-
-			WinSetWindowText(hwndBubble,
-							 bubble->bubbletext);
-
-			WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
-
-			hpsTemp = WinGetPS(hwndBubble);
-			GpiQueryTextBox(hpsTemp,
-							strlen(bubble->bubbletext),
-							bubble->bubbletext,
-							TXTBOX_COUNT,
-							txtPointl);
-			WinReleasePS(hpsTemp);
-
-			lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
-				txtPointl[TXTBOX_TOPLEFT ].x + 8;
-
-			lHight = txtPointl[TXTBOX_TOPLEFT].y -
-				txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
-
-			ptlWork.y -= lHight;
-
-			blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
-
-			if(blah)
-				WinSetWindowPtr(hwndBubble, QWP_USER, blah);
-
-			WinSetWindowPos(hwndBubble,
-							HWND_TOP,
-							ptlWork.x,
-							ptlWork.y,
-							lWidth,
-							lHight,
-							SWP_SIZE | SWP_MOVE | SWP_SHOW);
-		}
-		break;
-	}
-
-	if(!oldproc)
-		return WinDefWindowProc(hwnd, msg, mp1, mp2);
-	return oldproc(hwnd, msg, mp1, mp2);
-}
-
-MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
-{
-	int res = 0;
-	res = (int)_run_event(hwnd, msg, mp1, mp2);
-	switch(msg)
-	{
-	case WM_BUTTON1DOWN:
-	case WM_BUTTON2DOWN:
-	case WM_BUTTON3DOWN:
-		if(res == -1)
-			WinSetFocus(HWND_DESKTOP, hwnd);
-		else if(res)
-			return (MPARAM)TRUE;
-	}
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
-}
-
-MRESULT EXPENTRY _TreeProc(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:
-		{
-			HPS hps;
-			RECTL rcl;
-			POINTL ptl[2];
-
-			if(oldproc)
-				oldproc(hwnd, msg, mp1, mp2);
-
-			hps = WinBeginPaint(hwnd, 0, 0);
-			WinQueryWindowRect(hwnd, &rcl);
-			ptl[0].x = rcl.xLeft + 1;
-			ptl[0].y = rcl.yBottom + 1;
-			ptl[1].x = rcl.xRight - 1;
-			ptl[1].y = rcl.yTop - 1;
-
-			GpiSetColor(hps, CLR_BLACK);
-			GpiMove(hps, &ptl[0]);
-			GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0);
-			WinEndPaint(hps);
-		}
-		return MRFROMSHORT(FALSE);
-	case WM_SETFOCUS:
-		_run_event(hwnd, msg, mp1, mp2);
-		break;
-	case WM_CHAR:
-		if(SHORT1FROMMP(mp2) == '\t')
-		{
-			if(CHARMSG(&msg)->fs & KC_SHIFT)
-				_shift_focus_back(hwnd);
-			else
-				_shift_focus(hwnd);
-			return FALSE;
-		}
-		break;
-	}
-
-	_run_event(hwnd, msg, mp1, mp2);
-
-	if(oldproc)
-		return oldproc(hwnd, msg, mp1, mp2);
-
-	return WinDefWindowProc(hwnd, msg, mp1, mp2);
-}
-
-/*
- * Initializes the Dynamic Windows engine.
- * Parameters:
- *           newthread: True if this is the only thread.
- *                      False if there is already a message loop running.
- */
-int API dw_init(int newthread, int argc, char *argv[])
-{
-	APIRET rc;
-
-	argc = argc; /* keep compiler happy */
-	argv = argv; /* keep compiler happy */
-	if(newthread)
-	{
-		dwhab = WinInitialize(0);
-		dwhmq = WinCreateMsgQueue(dwhab, 0);
-	}
-
-	rc = WinRegisterClass(dwhab, ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32);
-	rc = WinRegisterClass(dwhab, SplitbarClassName, _splitwndproc, 0L, 32);
-
-	/* Get the OS/2 version. */
-	DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
-
-	desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE);
-
-	if(!IS_WARP4())
-		DefaultFont = "8.Helv";
-
-	/* This is a window that hangs around as long as the
-	 * application does and handles menu messages.
-	 */
-	hwndApp = dw_window_new(HWND_OBJECT, "", 0);
-
-	return rc;
-}
-
-/*
- * Runs a message loop for Dynamic Windows.
- */
-void API dw_main(void)
-{
-	QMSG qmsg;
-
-	_dwtid = dw_thread_id();
-
-	while(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-	}
-
-	WinDestroyMsgQueue(dwhmq);
-	WinTerminate(dwhab);
-}
-
-/*
- * Runs a message loop for Dynamic Windows, for a period of milliseconds.
- * Parameters:
- *           milliseconds: Number of milliseconds to run the loop for.
- */
-void API dw_main_sleep(int milliseconds)
-{
-	QMSG qmsg;
-#ifdef __EMX__
-	struct timeval tv, start;
-
-	gettimeofday(&start, NULL);
-	gettimeofday(&tv, NULL);
-
-	while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds)
-	{
-		if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
-		{
-			WinGetMsg(dwhab, &qmsg, 0, 0, 0);
-			if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-				_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-			WinDispatchMsg(dwhab, &qmsg);
-		}
-		else
-			DosSleep(1);
-		gettimeofday(&tv, NULL);
-	}
-#else
-	double start = (double)clock();
-
-	while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
-	{
-		if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
-		{
-			WinGetMsg(dwhab, &qmsg, 0, 0, 0);
-			if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-				_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-			WinDispatchMsg(dwhab, &qmsg);
-		}
-		else
-			DosSleep(1);
-	}
-#endif
-}
-
-/*
- * Processes a single message iteration and returns.
- */
-void API dw_main_iteration(void)
-{
-	QMSG qmsg;
-
-	_dwtid = dw_thread_id();
-
-	if(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-	}
-}
-
-/*
- * Free's memory allocated by dynamic windows.
- * Parameters:
- *           ptr: Pointer to dynamic windows allocated
- *                memory to be free()'d.
- */
-void API dw_free(void *ptr)
-{
-	free(ptr);
-}
-
-/*
- * Allocates and initializes a dialog struct.
- * Parameters:
- *           data: User defined data to be passed to functions.
- */
-DWDialog * API dw_dialog_new(void *data)
-{
-	DWDialog *tmp = malloc(sizeof(DWDialog));
-
-	tmp->eve = dw_event_new();
-	dw_event_reset(tmp->eve);
-	tmp->data = data;
-	tmp->done = FALSE;
-	tmp->result = NULL;
-
-    return tmp;
-}
-
-/*
- * Accepts a dialog struct and returns the given data to the
- * initial called of dw_dialog_wait().
- * Parameters:
- *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
- *           result: Data to be returned by dw_dialog_wait().
- */
-int API dw_dialog_dismiss(DWDialog *dialog, void *result)
-{
-	dialog->result = result;
-	dw_event_post(dialog->eve);
-	dialog->done = TRUE;
-	return 0;
-}
-
-/*
- * Accepts a dialog struct waits for dw_dialog_dismiss() to be
- * called by a signal handler with the given dialog struct.
- * Parameters:
- *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
- */
-void * API dw_dialog_wait(DWDialog *dialog)
-{
-	QMSG qmsg;
-	void *tmp;
-
-	while (WinGetMsg(dwhab, &qmsg, 0, 0, 0))
-	{
-		if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
-			_run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
-		WinDispatchMsg(dwhab, &qmsg);
-		if(dialog->done)
-			break;
-	}
-	dw_event_close(&dialog->eve);
-	tmp = dialog->result;
-	free(dialog);
-	return tmp;
-}
-
-
-/*
- * Displays a Message Box with given text and title..
- * Parameters:
- *           title: The title of the message box.
- *           flags: flags to indicate buttons and icon
- *           format: printf style format string.
- *           ...: Additional variables for use in the format.
- */
-int API dw_messagebox(char *title, int flags, char *format, ...)
-{
-	va_list args;
-	char outbuf[1024];
-	int rc;
-
-	va_start(args, format);
-	vsprintf(outbuf, format, args);
-	va_end(args);
-
-	rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, outbuf, title, 0, flags | MB_MOVEABLE);
-	if(rc == MBID_OK)
-		return DW_MB_RETURN_OK;
-	else if(rc == MBID_YES)
-		return DW_MB_RETURN_YES;
-	else if(rc == MBID_NO)
-		return DW_MB_RETURN_NO;
-	else if(rc == MBID_CANCEL)
-		return DW_MB_RETURN_CANCEL;
-	else return 0;
-}
-
-/*
- * Makes the window topmost.
- * Parameters:
- *           handle: The window handle to make topmost.
- */
-int API dw_window_raise(HWND handle)
-{
-	return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
-}
-
-/*
- * Makes the window bottommost.
- * Parameters:
- *           handle: The window handle to make bottommost.
- */
-int API dw_window_lower(HWND handle)
-{
-	return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
-}
-
-/*
- * Makes the window visible.
- * Parameters:
- *           handle: The window handle to make visible.
- */
-int API dw_window_show(HWND handle)
-{
-	int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
-	HSWITCH hswitch;
-	SWCNTRL swcntrl;
-
-	_fix_button_owner(_toplevel_window(handle), 0);
-	WinSetFocus(HWND_DESKTOP, handle);
-	_initial_focus(handle);
-
-	/* If this window has a  switch list entry make sure it is visible */
-	hswitch = WinQuerySwitchHandle(handle, 0);
-	if(hswitch)
-	{
-		WinQuerySwitchEntry(hswitch, &swcntrl);
-		swcntrl.uchVisibility = SWL_VISIBLE;
-		WinChangeSwitchEntry(hswitch, &swcntrl);
-	}
-	if(WinWindowFromID(handle, FID_CLIENT))
-	{
-		WindowData *blah = WinQueryWindowPtr(handle, QWP_USER);
-
-		if(blah && !(blah->flags & DW_OS2_NEW_WINDOW))
-		{
-			ULONG cx = dw_screen_width(), cy = dw_screen_height();
-			int newx, newy, changed = 0;
-			SWP swp;
-
-			blah->flags |= DW_OS2_NEW_WINDOW;
-
-			WinQueryWindowPos(handle, &swp);
-
-			newx = swp.x;
-			newy = swp.y;
-
-			if((swp.x+swp.cx) > cx)
-			{
-				newx = (cx - swp.cx)/2;
-				changed = 1;
-			}
-			if((swp.y+swp.cy) > cy)
-			{
-				newy = (cy - swp.cy)/2;
-				changed = 1;
-			}
-			if(changed)
-				WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE);
-		}
-	}
-	return rc;
-}
-
-/*
- * Minimizes or Iconifies a top-level window.
- * Parameters:
- *           handle: The window handle to minimize.
- */
-int API dw_window_minimize(HWND handle)
-{
-	HWND hwndclient = WinWindowFromID(handle, FID_CLIENT);
-
-	if(hwndclient)
-	{
-		Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER);
-
-		if(box)
-		{
-			if(!box->titlebar && box->hwndtitle)
-				WinSetParent(box->hwndtitle, handle, FALSE);
-		}
-	}
-
-	return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
-}
-
-/*
- * Makes the window invisible.
- * Parameters:
- *           handle: The window handle to make visible.
- */
-int API dw_window_hide(HWND handle)
-{
-	HSWITCH hswitch;
-	SWCNTRL swcntrl;
-
-	/* If this window has a  switch list entry make sure it is invisible */
-	hswitch = WinQuerySwitchHandle(handle, 0);
-	if(hswitch)
-	{
-		WinQuerySwitchEntry(hswitch, &swcntrl);
-		swcntrl.uchVisibility = SWL_INVISIBLE;
-		WinChangeSwitchEntry(hswitch, &swcntrl);
-	}
-	return WinShowWindow(handle, FALSE);
-}
-
-/*
- * Destroys a window and all of it's children.
- * Parameters:
- *           handle: The window handle to destroy.
- */
-int API dw_window_destroy(HWND handle)
-{
-	HWND frame, menu, parent = WinQueryWindow(handle, QW_PARENT);
-	Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
-
-	if(!handle)
-		return -1;
-
-	frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
-
-	if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
-		_free_menu_data(menu);
-
-	if(parent != desktop && thisbox && thisbox->count)
-	{
-		int z, index = -1;
-		Item *tmpitem, *thisitem = thisbox->items;
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisitem[z].hwnd == handle)
-				index = z;
-		}
-
-		if(index == -1)
-			return 0;
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-		/* Copy all but the current entry to the new list */
-		for(z=0;z<index;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-		for(z=index+1;z<thisbox->count;z++)
-		{
-			tmpitem[z-1] = thisitem[z];
-		}
-
-		thisbox->items = tmpitem;
-		free(thisitem);
-		thisbox->count--;
-		_free_window_memory(frame ? frame : handle);
-	}
-	return WinDestroyWindow(frame ? frame : handle);
-}
-
-/* Causes entire window to be invalidated and redrawn.
- * Parameters:
- *           handle: Toplevel window handle to be redrawn.
- */
-void API dw_window_redraw(HWND handle)
-{
-	HWND client = WinWindowFromID(handle, FID_CLIENT);
-	HWND window = client ? client : handle;
-	Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(window && mybox)
-	{
-		unsigned long width, height;
-
-		dw_window_get_pos_size(window, NULL, NULL, &width, &height);
-
-		WinShowWindow(client ? mybox->items[0].hwnd : handle, FALSE);
-		_do_resize(mybox, width, height);
-		WinShowWindow(client ? mybox->items[0].hwnd : handle, TRUE);
-	}
-}
-
-/*
- * Changes a window's parent to newparent.
- * Parameters:
- *           handle: The window handle to destroy.
- *           newparent: The window's new parent window.
- */
-void API dw_window_reparent(HWND handle, HWND newparent)
-{
-	HWND blah = WinWindowFromID(newparent, FID_CLIENT);
-	WinSetParent(handle, blah ? blah : newparent, TRUE);
-}
-
-/*
- * Sets the font used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          fontname: Name and size of the font in the form "size.fontname"
- */
-int API dw_window_set_font(HWND handle, char *fontname)
-{
-	return WinSetPresParam(handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
-}
-
-/* Internal version */
-int _dw_window_set_color(HWND handle, ULONG fore, ULONG back)
-{
-	if((fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-	{
-		RGB2 rgb2;
-
-		rgb2.bBlue = DW_BLUE_VALUE(fore);
-		rgb2.bGreen = DW_GREEN_VALUE(fore);
-		rgb2.bRed = DW_RED_VALUE(fore);
-		rgb2.fcOptions = 0;
-
-		WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2);
-
-	}
-	else if(fore != DW_CLR_DEFAULT)
-	{
-		fore = _internal_color(fore);
-
-		WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore);
-	}
-	if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
-	{
-		RGB2 rgb2;
-
-		rgb2.bBlue = DW_BLUE_VALUE(back);
-		rgb2.bGreen = DW_GREEN_VALUE(back);
-		rgb2.bRed = DW_RED_VALUE(back);
-		rgb2.fcOptions = 0;
-
-		WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2);
-		return 0;
-	}
-	else if(back != DW_CLR_DEFAULT)
-	{
-		back = _internal_color(back);
-
-		WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
-	}
-	return 0;
-}
-/*
- * Sets the colors used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          fore: Foreground color in DW_RGB format or a default color index.
- *          back: Background color in DW_RGB format or a default color index.
- */
-int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
-{
-	dw_window_set_data(handle, "_dw_fore", (void *)(fore+1));
-	dw_window_set_data(handle, "_dw_back", (void *)(back+1));
-
-	return _dw_window_set_color(handle, fore, back);
-}
-
-/*
- * Sets the font used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          border: Size of the window border in pixels.
- */
-int API dw_window_set_border(HWND handle, int border)
-{
-	WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border));
-	return 0;
-}
-
-/*
- * Captures the mouse input to this window.
- * Parameters:
- *       handle: Handle to receive mouse input.
- */
-void API dw_window_capture(HWND handle)
-{
-	WinSetCapture(HWND_DESKTOP, handle);
-}
-
-/*
- * Releases previous mouse capture.
- */
-void API dw_window_release(void)
-{
-	WinSetCapture(HWND_DESKTOP, NULLHANDLE);
-}
-
-/*
- * Tracks this window movement.
- * Parameters:
- *       handle: Handle to frame to be tracked.
- */
-void API dw_window_track(HWND handle)
-{
-	WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0);
-}
-
-/*
- * Changes the appearance of the mouse pointer.
- * Parameters:
- *       handle: Handle to widget for which to change.
- *       cursortype: ID of the pointer you want.
- */
-void API dw_window_pointer(HWND handle, int pointertype)
-{
-	if(handle == HWND_DESKTOP)
-		WinSetPointer(handle, WinQuerySysPointer(HWND_DESKTOP,pointertype, FALSE));
-	else
-		dw_window_set_data(handle, "_dw_pointer",
-						   pointertype < 65535 ?
-						   (void *)WinQuerySysPointer(HWND_DESKTOP,pointertype, FALSE)
-						   : (void *)pointertype);
-}
-
-/*
- * Create a new Window Frame.
- * Parameters:
- *       owner: The Owner's window handle or HWND_DESKTOP.
- *       title: The Window title.
- *       flStyle: Style flags, see the PM reference.
- */
-HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle)
-{
-	HWND hwndclient = 0, hwndframe;
-	Box *newbox = calloc(1, sizeof(Box));
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	ULONG winStyle = 0L;
-
-	newbox->pad = 0;
-	newbox->type = DW_VERT;
-	newbox->count = 0;
-
-	flStyle |= FCF_NOBYTEALIGN;
-
-	if(flStyle & DW_FCF_TITLEBAR)
-		newbox->titlebar = 1;
-	else
-		flStyle |= FCF_TITLEBAR;
-
-	if(!(flStyle & FCF_SHELLPOSITION))
-		blah->flags |= DW_OS2_NEW_WINDOW;
-
-	if(flStyle & WS_MAXIMIZED)
-	{
-		winStyle |= WS_MAXIMIZED;
-		flStyle &= ~WS_MAXIMIZED;
-	}
-	if(flStyle & WS_MINIMIZED)
-	{
-		winStyle |= WS_MINIMIZED;
-		flStyle &= ~WS_MINIMIZED;
-	}
-
-	hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &hwndclient);
-	newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR);
-	if(!newbox->titlebar && newbox->hwndtitle)
-		WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE);
-	blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc);
-	WinSetWindowPtr(hwndframe, QWP_USER, blah);
-	WinSetWindowPtr(hwndclient, QWP_USER, newbox);
-
-	return hwndframe;
-}
-
-/*
- * Create a new Box to be packed.
- * Parameters:
- *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
- *       pad: Number of pixels to pad around the box.
- */
-HWND API dw_box_new(int type, int pad)
-{
-	Box *newbox = calloc(1, sizeof(Box));
-	HWND hwndframe;
-
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-    newbox->grouphwnd = NULLHANDLE;
-
-	hwndframe = WinCreateWindow(HWND_OBJECT,
-								WC_FRAME,
-								NULL,
-								WS_VISIBLE | WS_CLIPCHILDREN |
-								FS_NOBYTEALIGN,
-								0,0,2000,1000,
-								NULLHANDLE,
-								HWND_TOP,
-								0L,
-								NULL,
-								NULL);
-
-	newbox->oldproc = WinSubclassWindow(hwndframe, _controlproc);
-	WinSetWindowPtr(hwndframe, QWP_USER, newbox);
-	dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
-	return hwndframe;
-}
-
-/*
- * Create a new Group Box to be packed.
- * Parameters:
- *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
- *       pad: Number of pixels to pad around the box.
- *       title: Text to be displayined in the group outline.
- */
-HWND API dw_groupbox_new(int type, int pad, char *title)
-{
-	Box *newbox = calloc(1, sizeof(Box));
-	HWND hwndframe;
-
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-
-	hwndframe = WinCreateWindow(HWND_OBJECT,
-								WC_FRAME,
-								NULL,
-								WS_VISIBLE |
-								FS_NOBYTEALIGN,
-								0,0,2000,1000,
-								NULLHANDLE,
-								HWND_TOP,
-								0L,
-								NULL,
-								NULL);
-
-	newbox->grouphwnd = WinCreateWindow(hwndframe,
-										WC_STATIC,
-										title,
-										WS_VISIBLE | SS_GROUPBOX |
-										WS_GROUP,
-										0,0,2000,1000,
-										NULLHANDLE,
-										HWND_TOP,
-										0L,
-										NULL,
-										NULL);
-
-	WinSetWindowPtr(hwndframe, QWP_USER, newbox);
-	dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
-	dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	dw_window_set_font(newbox->grouphwnd, DefaultFont);
-	return hwndframe;
-}
-
-/*
- * Create a new MDI Frame to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id or 0L.
- */
-HWND API dw_mdi_new(unsigned long id)
-{
-	HWND hwndframe;
-
-	id = id; /* keep compiler happy */
-	hwndframe = WinCreateWindow(HWND_OBJECT,
-								WC_FRAME,
-								NULL,
-								WS_VISIBLE | WS_CLIPCHILDREN |
-								FS_NOBYTEALIGN,
-								0,0,2000,1000,
-								NULLHANDLE,
-								HWND_TOP,
-								0L,
-								NULL,
-								NULL);
-	return hwndframe;
-}
-
-/*
- * Create a bitmap object to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_bitmap_new(ULONG id)
-{
-	return WinCreateWindow(HWND_OBJECT,
-						   WC_STATIC,
-						   NULL,
-						   WS_VISIBLE | SS_TEXT,
-						   0,0,2000,1000,
-						   NULLHANDLE,
-						   HWND_TOP,
-						   id,
-						   NULL,
-						   NULL);
-}
-
-/*
- * Create a notebook object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_notebook_new(ULONG id, int top)
-{
-	ULONG flags;
-	HWND tmp;
-
-	if(top)
-		flags = BKS_MAJORTABTOP;
-	else
-		flags = BKS_MAJORTABBOTTOM;
-
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_NOTEBOOK,
-						  NULL,
-						  WS_VISIBLE |
-#ifdef BKS_TABBEDDIALOG
-						  BKS_TABBEDDIALOG |
-#endif
-						  flags,
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  NULL,
-						  NULL);
-
-	/* Fix tab sizes on Warp 3 */
-	if(!IS_WARP4())
-	{
-		/* best sizes to be determined by trial and error */
-		WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB));
-	}
-
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a menu object to be popped up.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HMENUI API dw_menu_new(ULONG id)
-{
-	HMENUI tmp = WinCreateWindow(HWND_OBJECT,
-								 WC_MENU,
-								 NULL,
-								 WS_VISIBLE,
-								 0,0,2000,1000,
-								 NULLHANDLE,
-								 HWND_TOP,
-								 id,
-								 NULL,
-								 NULL);
-	return tmp;
-}
-
-/*
- * Create a menubar on a window.
- * Parameters:
- *       location: Handle of a window frame to be attached to.
- */
-HMENUI API dw_menubar_new(HWND location)
-{
-	HMENUI tmp = WinCreateWindow(location,
-								 WC_MENU,
-								 NULL,
-								 WS_VISIBLE | MS_ACTIONBAR,
-								 0,0,2000,1000,
-								 location,
-								 HWND_TOP,
-								 FID_MENU,
-								 NULL,
-								 NULL);
-	dw_window_set_data(tmp, "_dw_owner", (void *)location);
-	dw_window_set_data(tmp, "_dw_menubar", (void *)location);
-	return tmp;
-}
-
-/*
- * Destroys a menu created with dw_menubar_new or dw_menu_new.
- * Parameters:
- *       menu: Handle of a menu.
- */
-void API dw_menu_destroy(HMENUI *menu)
-{
-	if(menu)
-		WinDestroyWindow(*menu);
-}
-
-/*
- * Adds a menuitem or submenu to an existing menu.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       title: The title text on the menu item to be added.
- *       id: An ID to be used for message passing.
- *       flags: Extended attributes to set on the menu.
- *       end: If TRUE memu is positioned at the end of the menu.
- *       check: If TRUE menu is "check"able.
- *       submenu: Handle to an existing menu to be a submenu or NULL.
- */
-HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
-{
-	MENUITEM miSubMenu;
-	char buffer[15];
-
-	check = check; /* keep compiler happy */
-	if(!menux || id > 65536)
-		return NULLHANDLE;
-
-	if(end)
-		miSubMenu.iPosition=MIT_END;
-	else
-		miSubMenu.iPosition=0;
-
-	if(strlen(title) == 0)
-		miSubMenu.afStyle=MIS_SEPARATOR | flags;
-	else
-		miSubMenu.afStyle=MIS_TEXT | flags;
-	miSubMenu.afAttribute=0;
-	miSubMenu.id=id;
-	miSubMenu.hwndSubMenu = submenu;
-	miSubMenu.hItem=NULLHANDLE;
-
-	WinSendMsg(menux,
-			   MM_INSERTITEM,
-			   MPFROMP(&miSubMenu),
-			   MPFROMP(title));
-
-	sprintf(buffer, "_dw_id%d", id);
-	dw_window_set_data(hwndApp, buffer, (void *)menux);
-
-	if(submenu)
-		dw_window_set_data(submenu, "_dw_owner", (void *)menux);
-	return (HWND)id;
-}
-
-/*
- * Sets the state of a menu item check.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       id: Menuitem id.
- *       check: TRUE for checked FALSE for not checked.
- */
-void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check)
-{
-	if(check)
-		WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),
-				   MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
-	else
-		WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),
-				   MPFROM2SHORT(MIA_CHECKED, 0));
-}
-
-/*
- * Pops up a context menu at given x and y coordinates.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       parent: Handle to the window initiating the popup.
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
-{
-	if(menu)
-	{
-		popup = parent;
-		WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN);
-	}
-}
-
-/*
- * Returns the current X and Y coordinates of the mouse pointer.
- * Parameters:
- *       x: Pointer to variable to store X coordinate.
- *       y: Pointer to variable to store Y coordinate.
- */
-void API dw_pointer_query_pos(long *x, long *y)
-{
-	POINTL ptl;
-
-	WinQueryPointerPos(HWND_DESKTOP, &ptl);
-	if(x && y)
-	{
-		*x = ptl.x;
-		*y = dw_screen_height() - ptl.y;
-	}
-}
-
-/*
- * Sets the X and Y coordinates of the mouse pointer.
- * Parameters:
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_pointer_set_pos(long x, long y)
-{
-	WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y);
-}
-
-
-/*
- * Create a container object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_container_new(ULONG id, int multi)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_CONTAINER,
-							   NULL,
-							   WS_VISIBLE | CCS_READONLY |
-							   (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) |
-							   CCS_AUTOPOSITION,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_data(tmp, "_dw_container", (void *)1);
-	return tmp;
-}
-
-/*
- * Create a tree object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_tree_new(ULONG id)
-{
-	CNRINFO cnrinfo;
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_CONTAINER,
-							   NULL,
-							   WS_VISIBLE | CCS_READONLY |
-							   CCS_SINGLESEL | CCS_AUTOPOSITION,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-
-	cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE;
-	cnrinfo.slBitmapOrIcon.cx = 16;
-	cnrinfo.slBitmapOrIcon.cy = 16;
-	cnrinfo.cyLineSpacing = 0;
-	cnrinfo.cxTreeIndent = 16;
-	cnrinfo.cxTreeLine = 1;
-
-	WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON |
-														CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE));
-	blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new static text window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_text_new(char *text, ULONG id)
-{
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_STATIC,
-							   text,
-							   WS_VISIBLE | SS_TEXT,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
-}
-
-/*
- * Create a new status text window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_status_text_new(char *text, ULONG id)
-{
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_STATIC,
-							   text,
-							   WS_VISIBLE | SS_TEXT,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _statusproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
-}
-
-#ifndef MLS_LIMITVSCROLL
-#define MLS_LIMITVSCROLL           0x00000080L
-#endif
-
-/*
- * Create a new Multiline Editbox window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_mle_new(ULONG id)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_MLE,
-							   "",
-							   WS_VISIBLE |
-							   MLS_BORDER | MLS_IGNORETAB |
-							   MLS_READONLY | MLS_VSCROLL |
-							   MLS_LIMITVSCROLL,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _mleproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new Entryfield window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_entryfield_new(char *text, ULONG id)
-{
-
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_ENTRYFIELD,
-							   text,
-							   WS_VISIBLE | ES_MARGIN |
-							   ES_AUTOSCROLL | WS_TABSTOP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
-}
-
-/*
- * Create a new Entryfield (password) window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_entryfield_password_new(char *text, ULONG id)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_ENTRYFIELD,
-							   text,
-							   WS_VISIBLE | ES_MARGIN | ES_UNREADABLE |
-							   ES_AUTOSCROLL | WS_TABSTOP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
-}
-
-/*
- * Create a new Combobox window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the combpbox widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_combobox_new(char *text, ULONG id)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND frame = dw_box_new(DW_HORZ, 0);
-	HWND tmp = WinCreateWindow(frame,
-							   WC_COMBOBOX,
-							   text,
-							   WS_VISIBLE | CBS_DROPDOWN | WS_GROUP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	HENUM henum = WinBeginEnumWindows(tmp);
-	HWND child, last = NULLHANDLE;
-	
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		WindowData *moreblah = calloc(1, sizeof(WindowData));
-		moreblah->oldproc = WinSubclassWindow(child, _comboentryproc);
-		WinSetWindowPtr(child, QWP_USER, moreblah);
-		dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE);
-		last = child;
-	}
-	WinEndEnumWindows(henum);
-	blah->oldproc = WinSubclassWindow(tmp, _comboproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	dw_window_set_data(tmp, "_dw_comboentry", (void *)last);
-	dw_window_set_data(tmp, "_dw_combo_box", (void *)frame);
-	WinSetOwner(tmp, frame);
-	return tmp;
-}
-
-/*
- * Create a new button window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_button_new(char *text, ULONG id)
-{
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-
-	bubble->id = id;
-	bubble->bubbletext[0] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
-}
-
-/* Function: GenResIDStr
-** Abstract: Generate string '#nnnn' for a given ID for using with Button
-**           controls
-*/
-
-void _GenResIDStr(CHAR *buff, ULONG ulID)
-{
-	char *str;
-	int  slen = 0;
-
-	*buff++ = '#';
-
-	str = buff;
-
-	do
-	{
-		*str++ = (ulID % 10) + '0';
-		ulID /= 10;
-		slen++;
-	}
-	while(ulID);
-
-	*str-- = 0;
-
-	for(; str > buff; str--, buff++)
-	{
-		*buff ^= *str;
-		*str  ^= *buff;
-		*buff ^= *str;
-	}
-}
-
-
-/*
- * Create a new bitmap button window (widget) to be packed.
- * Parameters:
- *       text: Bubble help text to be displayed.
- *       id: An ID of a bitmap in the resource file.
- */
-HWND API dw_bitmapbutton_new(char *text, ULONG id)
-{
-	char idbuf[256];
-	HWND tmp;
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-
-	_GenResIDStr(idbuf, id);
-
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_BUTTON,
-						  idbuf,
-						  WS_VISIBLE | BS_PUSHBUTTON |
-						  BS_BITMAP | BS_AUTOSIZE |
-						  BS_NOPOINTERFOCUS,
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  NULL,
-						  NULL);
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-	dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
-	return tmp;
-}
-
-/*
- * Create a new bitmap button window (widget) to be packed from a file.
- * Parameters:
- *       text: Bubble help text to be displayed.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (BMP on OS/2 or Windows, XPM on Unix)
- */
-HWND dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
-{
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   "",
-							   WS_VISIBLE | BS_PUSHBUTTON |
-							   BS_AUTOSIZE | BS_NOPOINTERFOCUS,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	char *file = alloca(strlen(filename) + 5);
-	HPIXMAP pixmap = NULL, disabled = NULL;
-
-	if(file && (pixmap = calloc(1,sizeof(struct _hpixmap))))
-	{
-		int z, j, lim;
-		LONG fore;
-
-		strcpy(file, filename);
-
-		/* check if we can read from this file (it exists and read permission) */
-		if(access(file, 04) != 0)
-		{
-			/* Try with .bmp extention */
-			strcat(file, ".bmp");
-			if(access(file, 04) != 0)
-			{
-#if 0 /* don't free pixmap if bitmap doesn't exist; causes crash several lines below */
-				free(pixmap);
-				pixmap = NULL;
-#endif
-			}
-		}
-
-		/* Try to load the bitmap from file */
-		if(pixmap)
-			_load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
-
-		/* Create a disabled style pixmap */
-		disabled = dw_pixmap_new(tmp, pixmap->width, pixmap->height, dw_color_depth());
-		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;
-	}
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-
-	dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
-	dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
-	dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
-	return tmp;
-}
-
-/*
- * Create a new spinbutton window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_spinbutton_new(char *text, ULONG id)
-{
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_SPINBUTTON,
-							   text,
-							   WS_VISIBLE | SPBS_MASTER,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	HWND entry = _find_entryfield(tmp);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	blah = calloc(sizeof(WindowData), 1);
-	blah->oldproc = WinSubclassWindow(entry, _spinentryproc);
-	WinSetWindowPtr(entry, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
-}
-
-/*
- * Create a new radiobutton window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_radiobutton_new(char *text, ULONG id)
-{
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE |
-							   BS_AUTORADIOBUTTON,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
-}
-
-
-/*
- * Create a new slider window (widget) to be packed.
- * Parameters:
- *       vertical: TRUE or FALSE if slider is vertical.
- *       increments: Number of increments available.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_slider_new(int vertical, int increments, ULONG id)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	SLDCDATA sldcData = { 0, 0, 0, 0, 0 };
-	HWND tmp;
-
-	sldcData.cbSize = sizeof(SLDCDATA);
-    sldcData.usScale1Increments = increments;
-
-	tmp = WinCreateWindow(HWND_OBJECT,
-						  WC_SLIDER,
-						  "",
-						  WS_VISIBLE | SLS_SNAPTOINCREMENT |
-						  (vertical ? SLS_VERTICAL : SLS_HORIZONTAL),
-						  0,0,2000,1000,
-						  NULLHANDLE,
-						  HWND_TOP,
-						  id,
-						  &sldcData,
-						  NULL);
-
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	return tmp;
-}
-
-/*
- * Create a new scrollbar window (widget) to be packed.
- * Parameters:
- *       vertical: TRUE or FALSE if scrollbar is vertical.
- *       increments: Number of increments available.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_scrollbar_new(int vertical, int increments, ULONG id)
-{
-	increments = increments; /* keep compiler happy */
-	return WinCreateWindow(HWND_OBJECT,
-						   WC_SCROLLBAR,
-						   "",
-						   WS_VISIBLE | SBS_AUTOTRACK |
-						   (vertical ? SBS_VERT : SBS_HORZ),
-						   0,0,2000,1000,
-						   NULLHANDLE,
-						   HWND_TOP,
-						   id,
-						   NULL,
-						   NULL);
-}
-
-/*
- * Create a new percent bar window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_percent_new(ULONG id)
-{
-	WindowData *blah = calloc(1, sizeof(WindowData));
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_SLIDER,
-							   "",
-							   WS_VISIBLE | SLS_READONLY
-							   | SLS_RIBBONSTRIP,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _percentproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_disable(tmp);
-	return tmp;
-}
-
-/*
- * Create a new checkbox window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_checkbox_new(char *text, ULONG id)
-{
-	BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_BUTTON,
-							   text,
-							   WS_VISIBLE | BS_AUTOCHECKBOX,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	bubble->id = id;
-	bubble->bubbletext[0] = '\0';
-	bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
-	WinSetWindowPtr(tmp, QWP_USER, bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-	return tmp;
-}
-
-/*
- * Create a new listbox window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- *       multi: Multiple select TRUE or FALSE.
- */
-HWND API dw_listbox_new(ULONG id, int multi)
-{
-	WindowData *blah = calloc(sizeof(WindowData), 1);
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   WC_LISTBOX,
-							   NULL,
-							   WS_VISIBLE | LS_NOADJUSTPOS |
-							   (multi ? LS_MULTIPLESEL : 0),
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	blah->oldproc = WinSubclassWindow(tmp, _entryproc);
-	WinSetWindowPtr(tmp, QWP_USER, blah);
-	dw_window_set_font(tmp, DefaultFont);
-	dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
-	return tmp;
-}
-
-/*
- * Sets the icon used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- *       id: An ID to be used to specify the icon.
- */
-void API dw_window_set_icon(HWND handle, ULONG id)
-{
-	HPOINTER icon = id < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,id) : (HPOINTER)id;
-	WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0);
-}
-
-/* Internal function to load a bitmap from a file and return handles
- * to the bitmap, presentation space etc.
- */
-int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height)
-{
-	HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
-	ULONG OpenAction = 0;
-	PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data  */
-	FILESTATUS BitmapStatus;
-	ULONG cbRead;
-	PBITMAPFILEHEADER2 pBitmapFileHeader;
-	PBITMAPINFOHEADER2 pBitmapInfoHeader;
-	ULONG ScanLines, ulFlags;
-	HPS hps1;
-	HDC hdc1;
-	SIZEL sizl = { 0, 0 };
-
-	/* open bitmap file */
-	DosOpen(file, &BitmapFileHandle, &OpenAction, 0L,
-			FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
-			OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
-			OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
-			OPEN_FLAGS_NOINHERIT, 0L);
-
-	if(!BitmapFileHandle)
-		return 0;
-
-	/* find out how big the file is  */
-	DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
-					 sizeof(BitmapStatus));
-
-	/* allocate memory to load the bitmap */
-	DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
-				PAG_READ | PAG_WRITE | PAG_COMMIT);
-
-	/* read bitmap file into memory buffer */
-	DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
-			BitmapStatus.cbFile, &cbRead);
-
-	/* access first bytes as bitmap header */
-	pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
-
-	/* check if it's a valid bitmap data file */
-	if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
-	   (pBitmapFileHeader->usType != BFT_BMAP))
-	{
-		/* free memory of bitmap file buffer */
-		DosFreeMem(BitmapFileBegin);
-		/* close the bitmap file */
-		DosClose(BitmapFileHandle);
-		return 0;
-	}
-
-	/* check if it's a file with multiple bitmaps */
-	if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
-	{
-		/* we'll just use the first bitmap and ignore the others */
-		pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
-	}
-
-	/* set pointer to bitmap information block */
-	pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
-
-	/* find out if it's the new 2.0 format or the old format */
-	/* and query number of lines */
-	if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
-	{
-		*height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
-		*width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
-	}
-	else
-	{
-		*height = ScanLines = pBitmapInfoHeader->cy;
-		*width = pBitmapInfoHeader->cx;
-	}
-
-	/* now we need a presentation space, get it from static control */
-	hps1 = WinGetPS(handle);
-
-	hdc1    = GpiQueryDevice(hps1);
-	ulFlags = GpiQueryPS(hps1, &sizl);
-
-	*hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc1);
-	*hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	/* create bitmap now using the parameters from the info block */
-	*hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
-
-	/* select the new bitmap into presentation space */
-	GpiSetBitmap(*hps, *hbm);
-
-	/* now copy the bitmap data into the bitmap */
-	GpiSetBitmapBits(*hps, 0L, ScanLines,
-					 BitmapFileBegin + pBitmapFileHeader->offBits,
-					 (PBITMAPINFO2)pBitmapInfoHeader);
-
-	WinReleasePS(hps1);
-
-	/* free memory of bitmap file buffer */
-	DosFreeMem(BitmapFileBegin);
-	/* close the bitmap file */
-	DosClose(BitmapFileHandle);
-	return 1;
-}
-
-/*
- * Sets the bitmap used for a given static window.
- * Parameters:
- *       handle: Handle to the window.
- *       id: An ID to be used to specify the icon,
- *           (pass 0 if you use the filename param)
- *       filename: a path to a file (Bitmap on OS/2 or
- *                 Windows and a pixmap on Unix, pass
- *                 NULL if you use the id param)
- */
-void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
-{
-	HBITMAP hbm;
-	HPS     hps;
-
-	/* Destroy any old bitmap data */
-	_free_bitmap(handle);
-
-	/* If id is non-zero use the resource */
-	if(id)
-	{
-		hps = WinGetPS(handle);
-
-		hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0);
-	}
-	else if(filename)
-	{
-		HDC hdc;
-		unsigned long width, height;
-		char *file = alloca(strlen(filename) + 5);
-
-		if(!file)
-			return;
-
-		strcpy(file, filename);
-
-		/* check if we can read from this file (it exists and read permission) */
-		if(access(file, 04) != 0)
-		{
-			/* Try with .bmp extention */
-			strcat(file, ".bmp");
-			if(access(file, 04) != 0)
-				return;
-		}
-
-		if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height))
-			return;
-
-		dw_window_set_data(handle, "_dw_hps", (void *)hps);
-		dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
-		dw_window_set_data(handle, "_dw_width", (void *)width);
-		dw_window_set_data(handle, "_dw_height", (void *)height);
-	}
-	else
-		return;
-
-	WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
-	WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
-	if(id)
-		WinReleasePS(hps);
-	dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
-}
-
-/*
- * Sets the text used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- *       text: The text associsated with a given window.
- */
-void API dw_window_set_text(HWND handle, char *text)
-{
-	WinSetWindowText(handle, text);
-}
-
-/*
- * Gets the text used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- * Returns:
- *       text: The text associsated with a given window.
- */
-char * API dw_window_get_text(HWND handle)
-{
-	int len = WinQueryWindowTextLength(handle);
-	char *tempbuf = calloc(1, len + 2);
-
-	WinQueryWindowText(handle, len + 1, tempbuf);
-
-	return tempbuf;
-}
-
-/*
- * Disables given window (widget).
- * Parameters:
- *       handle: Handle to the window.
- */
-void API dw_window_disable(HWND handle)
-{
-	char tmpbuf[100];
-
-	if(dw_window_get_data(handle, "_dw_disabled"))
-		return;
-
-	WinQueryClassName(handle, 99, tmpbuf);
-	dw_window_set_data(handle, "_dw_disabled", (void *)1);
-
-	if(tmpbuf[0] == '#')
-	{
-		int val = atoi(&tmpbuf[1]);
-		HWND hwnd;
-
-		switch(val)
-		{
-		case 2:
-		case 6:
-		case 10:
-		case 32:
-		case 7:
-			hwnd = _find_entryfield(handle);
-			_dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY);
-			dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-            if(val == 2)
-				dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			if(hwnd)
-				dw_window_set_data(hwnd, "_dw_disabled", (void *)1);
-			return;
-		case 3:
-			if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap"))
-				WinEnableWindow(handle, FALSE);
-			else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
-				WinInvalidateRect(handle, NULL, FALSE);
-			else
-				_dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY);
-			dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
-			return;
-		}
-	}
-	WinEnableWindow(handle, FALSE);
-}
-
-/*
- * Enables given window (widget).
- * Parameters:
- *       handle: Handle to the window.
- */
-void API dw_window_enable(HWND handle)
-{
-	ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore");
-	ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back");
-	HWND hwnd = _find_entryfield(handle);
-
-	dw_window_set_data(handle, "_dw_disabled", 0);
-	if(hwnd)
-		dw_window_set_data(hwnd, "_dw_disabled", 0);
-	if(fore && back)
-		_dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1);
-	dw_signal_disconnect_by_data(handle, (void *)100);
-	WinEnableWindow(handle, TRUE);
-	if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
-		WinInvalidateRect(handle, NULL, FALSE);
-}
-
-/*
- * Gets the child window handle with specified ID.
- * Parameters:
- *       handle: Handle to the parent window.
- *       id: Integer ID of the child.
- */
-HWND API dw_window_from_id(HWND handle, int id)
-{
-	HENUM henum;
-	HWND child;
-	char tmpbuf[100];
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		int windowid = WinQueryWindowUShort(child, QWS_ID);
-		HWND found;
-
-		WinQueryClassName(child, 99, tmpbuf);
-
-		/* If the child is a box (frame) then recurse into it */
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			if((found = dw_window_from_id(child, id)) != NULLHANDLE)
-				return found;
-
-		if(windowid && windowid == id)
-		{
-			WinEndEnumWindows(henum);
-			return child;
-		}
-	}
-	WinEndEnumWindows(henum);
-	return NULLHANDLE;
-}
-
-/*
- * Pack windows (widgets) into a box from the end (or bottom).
- * Parameters:
- *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
- *       width: Width in pixels of the item or -1 to be self determined.
- *       height: Height in pixels of the item or -1 to be self determined.
- *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
- *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
- *       pad: Number of pixels of padding around the item.
- */
-void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
-{
-	Box *thisbox;
-	char *funcname = "dw_box_pack_end()";
-
-		/*
-		 * If you try and pack an item into itself VERY bad things can happen; like at least an
-		 * infinite loop on GTK! Lets be safe!
-		 */
-	if(box == item)
-	{
-		dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!",box,item);
-		return;
-	}
-
-	if(WinWindowFromID(box, FID_CLIENT))
-	{
-		box = WinWindowFromID(box, FID_CLIENT);
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-		hsize = TRUE;
-		vsize = TRUE;
-	}
-	else
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	if(thisbox)
-	{
-		if(thisbox->type == DW_HORZ)
-			_dw_box_pack_start(box, item, width, height, hsize, vsize, pad, funcname);
-		else
-			_dw_box_pack_end(box, item, width, height, hsize, vsize, pad, funcname);
-	}
-}
-
-void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname)
-{
-	Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-		HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-
-		WinQueryClassName(item, 99, tmpbuf);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			tmpitem[thisbox->count].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[thisbox->count].type = TYPEITEM;
-		}
-
-		tmpitem[thisbox->count].hwnd = item;
-		tmpitem[thisbox->count].origwidth = tmpitem[thisbox->count].width = width;
-		tmpitem[thisbox->count].origheight = tmpitem[thisbox->count].height = height;
-		tmpitem[thisbox->count].pad = pad;
-		if(hsize)
-			tmpitem[thisbox->count].hsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[thisbox->count].vsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-        /* Don't set the ownership if it's an entryfield  or spinbutton */
-		WinQueryClassName(item, 99, tmpbuf);
-		if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
-			WinSetOwner(item, box);
-		WinSetParent(frame ? frame : item, box, FALSE);
-	}
-}
-
-/*
- * Sets the size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          width: New width in pixels.
- *          height: New height in pixels.
- */
-void API dw_window_set_usize(HWND handle, ULONG width, ULONG height)
-{
-	WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
-}
-
-/*
- * Returns the width of the screen.
- */
-int API dw_screen_width(void)
-{
-	return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
-}
-
-/*
- * Returns the height of the screen.
- */
-int API dw_screen_height(void)
-{
-	return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
-}
-
-/* This should return the current color depth */
-unsigned long API dw_color_depth(void)
-{
-	HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
-	long colors;
-
-	DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors);
-	DevCloseDC(hdc);
-	return colors;
-}
-
-
-/*
- * Sets the position of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- */
-void API dw_window_set_pos(HWND handle, ULONG x, ULONG y)
-{
-	int myy = _get_frame_height(handle) - (y + _get_height(handle));
-
-	WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE);
-}
-
-/*
- * Sets the position and size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- *          width: Width of the widget.
- *          height: Height of the widget.
- */
-void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height)
-{
-	int myy = _get_frame_height(handle) - (y + height);
-
-	WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
-}
-
-/*
- * Gets the position and size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- *          width: Width of the widget.
- *          height: Height of the widget.
- */
-void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height)
-{
-	SWP swp;
-	WinQueryWindowPos(handle, &swp);
-	if(x)
-		*x = swp.x;
-	if(y)
-		*y = _get_frame_height(handle) - (swp.y + swp.cy);
-	if(width)
-		*width = swp.cx;
-	if(height)
-		*height = swp.cy;
-}
-
-/*
- * Sets the style of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          width: New width in pixels.
- *          height: New height in pixels.
- */
-void API dw_window_set_style(HWND handle, ULONG style, ULONG mask)
-{
-	WinSetWindowBits(handle, QWL_STYLE, style, mask);
-}
-
-/*
- * Adds a new page to specified notebook.
- * Parameters:
- *          handle: Window (widget) handle.
- *          flags: Any additional page creation flags.
- *          front: If TRUE page is added at the beginning.
- */
-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));
-}
-
-/*
- * Remove a page from a notebook.
- * Parameters:
- *          handle: Handle to the notebook widget.
- *          pageid: ID of the page to be destroyed.
- */
-void API dw_notebook_page_destroy(HWND handle, unsigned int pageid)
-{
-	WinSendMsg(handle, BKM_DELETEPAGE,
-			   MPFROMLONG(pageid),	(MPARAM)BKA_SINGLE);
-}
-
-/*
- * Queries the currently visible page ID.
- * Parameters:
- *          handle: Handle to the notebook widget.
- */
-unsigned long API dw_notebook_page_query(HWND handle)
-{
-	return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR));
-}
-
-/*
- * Sets the currently visibale page ID.
- * Parameters:
- *          handle: Handle to the notebook widget.
- *          pageid: ID of the page to be made visible.
- */
-void API dw_notebook_page_set(HWND handle, unsigned int pageid)
-{
-	WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L);
-}
-
-/*
- * Sets the text on the specified notebook tab.
- * Parameters:
- *          handle: Notebook handle.
- *          pageid: Page ID of the tab to set.
- *          text: Pointer to the text to set.
- */
-void API dw_notebook_page_set_text(HWND handle, ULONG pageid, char *text)
-{
-	WinSendMsg(handle, BKM_SETTABTEXT,
-			   MPFROMLONG(pageid),	MPFROMP(text));
-}
-
-/*
- * Sets the text on the specified notebook tab status area.
- * Parameters:
- *          handle: Notebook handle.
- *          pageid: Page ID of the tab to set.
- *          text: Pointer to the text to set.
- */
-void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text)
-{
-	WinSendMsg(handle, BKM_SETSTATUSLINETEXT,
-			   MPFROMLONG(pageid),	MPFROMP(text));
-}
-
-/*
- * Packs the specified box into the notebook page.
- * Parameters:
- *          handle: Handle to the notebook to be packed.
- *          pageid: Page ID in the notebook which is being packed.
- *          page: Box handle to be packed.
- */
-void API dw_notebook_pack(HWND handle, ULONG pageid, HWND page)
-{
-	HWND tmpbox = dw_box_new(DW_VERT, 0);
-
-	dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
-	WinSubclassWindow(tmpbox, _wndproc);
-	WinSendMsg(handle, BKM_SETPAGEWINDOWHWND,
-			   MPFROMLONG(pageid),	MPFROMHWND(tmpbox));
-}
-
-/*
- * Appends the specified text to the listbox's (or combobox) entry list.
- * Parameters:
- *          handle: Handle to the listbox to be appended to.
- *          text: Text to append into listbox.
- */
-void API dw_listbox_append(HWND handle, char *text)
-{
-	WinSendMsg(handle,
-			   LM_INSERTITEM,
-			   MPFROMSHORT(LIT_END),
-			   MPFROMP(text));
-}
-
-/*
- * Clears the listbox's (or combobox) list of all entries.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- */
-void API dw_listbox_clear(HWND handle)
-{
-	WinSendMsg(handle,
-			   LM_DELETEALL, 0L, 0L);
-}
-
-/*
- * Returns the listbox's item count.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- */
-int API dw_listbox_count(HWND handle)
-{
-	return (int)WinSendMsg(handle,
-						   LM_QUERYITEMCOUNT,0L, 0L);
-}
-
-/*
- * Sets the topmost item in the viewport.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- *          top: Index to the top item.
- */
-void API dw_listbox_set_top(HWND handle, int top)
-{
-	WinSendMsg(handle,
-			   LM_SETTOPINDEX,
-			   MPFROMSHORT(top),
-			   0L);
-}
-
-/*
- * Copies the given index item's text into buffer.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          index: Index into the list to be queried.
- *          buffer: Buffer where text will be copied.
- *          length: Length of the buffer (including NULL).
- */
-void API dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
-{
-	WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer);
-}
-
-/*
- * Sets the text of a given listbox entry.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          index: Index into the list to be queried.
- *          buffer: Buffer where text will be copied.
- */
-void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
-{
-	WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer);
-}
-
-/*
- * Returns the index to the item in the list currently selected.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- */
-unsigned int API dw_listbox_selected(HWND handle)
-{
-		return (unsigned int)WinSendMsg(handle,
-										LM_QUERYSELECTION,
-										MPFROMSHORT(LIT_CURSOR),
-										0);
-}
-
-/*
- * Returns the index to the current selected item or -1 when done.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          where: Either the previous return or -1 to restart.
- */
-int API dw_listbox_selected_multi(HWND handle, int where)
-{
-	int place = where;
-
-	if(where == -1)
-		place = LIT_FIRST;
-
-	place = (int)WinSendMsg(handle,
-							LM_QUERYSELECTION,
-							MPFROMSHORT(place),0L);
-	if(place == LIT_NONE)
-		return -1;
-	return place;
-}
-
-/*
- * Sets the selection state of a given index.
- * Parameters:
- *          handle: Handle to the listbox to be set.
- *          index: Item index.
- *          state: TRUE if selected FALSE if unselected.
- */
-void API dw_listbox_select(HWND handle, int index, int state)
-{
-	char tmpbuf[100];
-
-	WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state);
-
-	WinQueryClassName(handle, 99, tmpbuf);
-
-	/* If we are setting a combobox call the event handler manually */
-	if(strncmp(tmpbuf, "#6", 3)==0)
-		_run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle);
-}
-
-/*
- * Deletes the item with given index from the list.
- * Parameters:
- *          handle: Handle to the listbox to be set.
- *          index: Item index.
- */
-void API dw_listbox_delete(HWND handle, int index)
-{
-	WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0);
-}
-
-/*
- * Adds text to an MLE box and returns the current point.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          buffer: Text buffer to be imported.
- *          startpoint: Point to start entering text.
- */
-unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
-{
-	unsigned long point = startpoint;
-	PBYTE mlebuf;
-
-	/* Work around 64K limit */
-	if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
-	{
-		int amount, len = strlen(buffer), written = 0;
-
-		while(written < len)
-		{
-			if((len - written) > 65535)
-				amount = 65535;
-			else
-				amount = len - written;
-
-			memcpy(mlebuf, &buffer[written], amount);
-			mlebuf[amount] = '\0';
-
-			WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount+1));
-			WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(amount + 1));
-			dw_mle_delete(handle, point, 1);
-
-			written += amount;
-		}
-		DosFreeMem(mlebuf);
-	}
-	return point - 1;
-}
-
-/*
- * Grabs text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          buffer: Text buffer to be exported.
- *          startpoint: Point to start grabbing text.
- *          length: Amount of text to be grabbed.
- */
-void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
-{
-	PBYTE mlebuf;
-
-	/* Work around 64K limit */
-	if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
-	{
-		int amount, copied, written = 0;
-
-		while(written < length)
-		{
-			if((length - written) > 65535)
-				amount = 65535;
-			else
-				amount = length - written;
-
-			WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount));
-			copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount));
-
-			if(copied)
-			{
-				memcpy(&buffer[written], mlebuf, copied);
-
-				written += copied;
-			}
-			else
-				break;
-		}
-		DosFreeMem(mlebuf);
-	}
-}
-
-/*
- * Obtains information about an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          bytes: A pointer to a variable to return the total bytes.
- *          lines: A pointer to a variable to return the number of lines.
- */
-void API dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines)
-{
-	if(bytes)
-		*bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0);
-	if(lines)
-		*lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0);
-}
-
-/*
- * Deletes text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be deleted from.
- *          startpoint: Point to start deleting text.
- *          length: Amount of text to be deleted.
- */
-void API dw_mle_delete(HWND handle, int startpoint, int length)
-{
-	char *buf = malloc(length+1);
-	int z, dellen = length;
-
-	dw_mle_export(handle, buf, startpoint, length);
-
-	for(z=0;z<length-1;z++)
-	{
-		if(strncmp(&buf[z], "\r\n", 2) == 0)
-			dellen--;
-	}
-	WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(dellen));
-	free(buf);
-}
-
-/*
- * Clears all text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be cleared.
- */
-void API dw_mle_clear(HWND handle)
-{
-	unsigned long bytes;
-
-	dw_mle_query(handle, &bytes, NULL);
-
-	WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes));
-}
-
-/*
- * Sets the visible line of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be positioned.
- *          line: Line to be visible.
- */
-void API dw_mle_set_visible(HWND handle, int line)
-{
-	int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0);
-	WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt));
-}
-
-/*
- * Sets the editablity of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE.
- *          state: TRUE if it can be edited, FALSE for readonly.
- */
-void API dw_mle_set_editable(HWND handle, int state)
-{
-	WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0);
-}
-
-/*
- * Sets the word wrap state of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE.
- *          state: TRUE if it wraps, FALSE if it doesn't.
- */
-void API dw_mle_set_word_wrap(HWND handle, int state)
-{
-	WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0);
-}
-
-/*
- * Sets the current cursor position of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be positioned.
- *          point: Point to position cursor.
- */
-void API dw_mle_set(HWND handle, int point)
-{
-	WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point));
-}
-
-/*
- * Finds text in an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be cleared.
- *          text: Text to search for.
- *          point: Start point of search.
- *          flags: Search specific flags.
- */
-int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
-{
-	MLE_SEARCHDATA msd;
-
-	/* This code breaks with structure packing set to 1 (/Sp1 in VAC)
-	 * if this is needed we need to add a pragma here.
-	 */
-	msd.cb = sizeof(msd);
-	msd.pchFind = text;
-	msd.pchReplace = NULL;
-	msd.cchFind = strlen(text);
-	msd.cchReplace = 0;
-	msd.iptStart = point;
-	msd.iptStop = -1;
-
-	if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd))
-		return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0);
-	return 0;
-}
-
-/*
- * Stops redrawing of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to freeze.
- */
-void API dw_mle_freeze(HWND handle)
-{
-	WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0);
-}
-
-/*
- * Resumes redrawing of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to thaw.
- */
-void API dw_mle_thaw(HWND handle)
-{
-	WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0);
-}
-
-/*
- * Returns the range of the percent bar.
- * Parameters:
- *          handle: Handle to the percent bar to be queried.
- */
-unsigned int API dw_percent_query_range(HWND handle)
-{
-	return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
-}
-
-/*
- * Sets the percent bar position.
- * Parameters:
- *          handle: Handle to the percent bar to be set.
- *          position: Position of the percent bar withing the range.
- */
-void API dw_percent_set_pos(HWND handle, unsigned int position)
-{
-	_dw_int_set(handle, position);
-	WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)position);
-}
-
-/*
- * Returns the position of the slider.
- * Parameters:
- *          handle: Handle to the slider to be queried.
- */
-unsigned int API dw_slider_query_pos(HWND handle)
-{
-	return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
-}
-
-/*
- * Sets the slider position.
- * Parameters:
- *          handle: Handle to the slider to be set.
- *          position: Position of the slider withing the range.
- */
-void API dw_slider_set_pos(HWND handle, unsigned int position)
-{
-	dw_window_set_data(handle, "_dw_slider_value", (void *)position);
-	WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position);
-}
-
-/*
- * Returns the position of the scrollbar.
- * Parameters:
- *          handle: Handle to the scrollbar to be queried.
- */
-unsigned int API dw_scrollbar_query_pos(HWND handle)
-{
-	return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0);
-}
-
-/*
- * Sets the scrollbar position.
- * Parameters:
- *          handle: Handle to the scrollbar to be set.
- *          position: Position of the scrollbar withing the range.
- */
-void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
-{
-	dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
-	WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0);
-}
-
-/*
- * Sets the scrollbar range.
- * Parameters:
- *          handle: Handle to the scrollbar to be set.
- *          range: Maximum range value.
- *          visible: Visible area relative to the range.
- */
-void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
-{
-	unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value");
-	WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible));
-	WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0);
-	dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible);
-}
-
-/*
- * Sets the spinbutton value.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          position: Current value of the spinbutton.
- */
-void API dw_spinbutton_set_pos(HWND handle, long position)
-{
-	WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L);
-}
-
-/*
- * Sets the spinbutton limits.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          upper: Upper limit.
- *          lower: Lower limit.
- */
-void API dw_spinbutton_set_limits(HWND handle, long upper, long lower)
-{
-	WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower));
-}
-
-/*
- * Sets the entryfield character limit.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          limit: Number of characters the entryfield will take.
- */
-void API dw_entryfield_set_limit(HWND handle, ULONG limit)
-{
-	WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0);
-}
-
-
-/*
- * Returns the current value of the spinbutton.
- * Parameters:
- *          handle: Handle to the spinbutton to be queried.
- */
-long API dw_spinbutton_query(HWND handle)
-{
-	long tmpval = 0L;
-
-	WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L);
-    return tmpval;
-}
-
-/*
- * Returns the state of the checkbox.
- * Parameters:
- *          handle: Handle to the checkbox to be queried.
- */
-int API dw_checkbox_query(HWND handle)
-{
-	return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0);
-}
-
-/*
- * Sets the state of the checkbox.
- * Parameters:
- *          handle: Handle to the checkbox to be queried.
- *          value: TRUE for checked, FALSE for unchecked.
- */
-void API dw_checkbox_set(HWND handle, int value)
-{
-	WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
-}
-
-/*
- * Inserts an item into a tree window (widget) after another item.
- * Parameters:
- *          handle: Handle to the tree to be inserted.
- *          item: Handle to the item to be positioned after.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- *          parent: Parent handle or 0 if root.
- *          itemdata: Item specific data.
- */
-HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	ULONG        cbExtra;
-	PCNRITEM     pci;
-	RECORDINSERT ri;
-
-	if(!item)
-		item = (HTREEITEM)CMA_FIRST;
-
-	/* Calculate extra bytes needed for each record besides that needed for the
-	 * MINIRECORDCORE structure
-	 */
-
-	cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE);
-
-	/* Allocate memory for the parent record */
-
-	if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0)
-		return 0;
-
-	/* Fill in the parent record data */
-
-	pci->rc.cb          = sizeof(MINIRECORDCORE);
-	pci->rc.pszIcon     = strdup(title);
-	pci->rc.hptrIcon    = icon;
-
-	pci->hptrIcon       = icon;
-	pci->user           = itemdata;
-	pci->parent         = parent;
-
-	memset(&ri, 0, sizeof(RECORDINSERT));
-
-	ri.cb                 = sizeof(RECORDINSERT);
-	ri.pRecordOrder       = (PRECORDCORE)item;
-	ri.zOrder             = (USHORT)CMA_TOP;
-	ri.cRecordsInsert     = 1;
-	ri.fInvalidateRecord  = TRUE;
-
-	/* We are about to insert the child records. Set the parent record to be
-	 * the one we just inserted.
-	 */
-	ri.pRecordParent = (PRECORDCORE)parent;
-
-	/* Insert the record */
-	WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri));
-
-	return (HTREEITEM)pci;
-}
-
-/*
- * Inserts an item into a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree to be inserted.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- *          parent: Parent handle or 0 if root.
- *          itemdata: Item specific data.
- */
-HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata);
-}
-
-/*
- * Sets the text and icon of an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- */
-void API dw_tree_set(HWND handle, HTREEITEM item, char *title, unsigned long icon)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	if(!pci)
-		return;
-
-	if(pci->rc.pszIcon)
-		free(pci->rc.pszIcon);
-
-	pci->rc.pszIcon     = strdup(title);
-	pci->rc.hptrIcon    = icon;
-
-	pci->hptrIcon       = icon;
-
-	WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
-}
-
-/*
- * Gets the text an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-char * API dw_tree_get_title(HWND handle, HTREEITEM item)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(pci)
-		return pci->rc.pszIcon;
-	return NULL;
-}
-
-/*
- * Gets the text an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(pci)
-		return pci->parent;
-	return (HTREEITEM)0;
-}
-
-/*
- * Sets the item data of a tree item.
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- *          itemdata: User defined data to be associated with item.
- */
-void API dw_tree_set_data(HWND handle, HTREEITEM item, void *itemdata)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(!pci)
-		return;
-
-	pci->user = itemdata;
-}
-
-/*
- * Gets the item data of a tree item.
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-void * API dw_tree_get_data(HWND handle, HTREEITEM item)
-{
-	PCNRITEM pci = (PCNRITEM)item;
-
-	handle = handle; /* keep compiler happy */
-	if(!pci)
-		return NULL;
-	return pci->user;
-}
-
-/*
- * Sets this item as the active selection.
- * Parameters:
- *       handle: Handle to the tree window (widget) to be selected.
- *       item: Handle to the item to be selected.
- */
-void API dw_tree_item_select(HWND handle, HTREEITEM item)
-{
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if(pCore->flRecordAttr & CRA_SELECTED)
-			WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
-	WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
-	lastitem = 0;
-	lasthcnr = 0;
-}
-
-/*
- * Removes all nodes from a tree.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- */
-void API dw_tree_clear(HWND handle)
-{
-	dw_container_clear(handle, TRUE);
-}
-
-/*
- * Expands a node on a tree.
- * Parameters:
- *       handle: Handle to the tree window (widget).
- *       item: Handle to node to be expanded.
- */
-void API dw_tree_expand(HWND handle, HTREEITEM item)
-{
-	WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0);
-}
-
-/*
- * Collapses a node on a tree.
- * Parameters:
- *       handle: Handle to the tree window (widget).
- *       item: Handle to node to be collapsed.
- */
-void API dw_tree_collapse(HWND handle, HTREEITEM item)
-{
-	WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
-}
-
-/*
- * Removes a node from a tree.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- *       item: Handle to node to be deleted.
- */
-void API dw_tree_delete(HWND handle, HTREEITEM item)
-{
-	PCNRITEM     pci = (PCNRITEM)item;
-
-	if(!item)
-		return;
-
-	if(pci->rc.pszIcon)
-	{
-		free(pci->rc.pszIcon);
-		pci->rc.pszIcon = 0;
-	}
-
-	WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE));
-}
-
-/* Some OS/2 specific container structs */
-typedef struct _containerinfo {
-	int count;
-	void *data;
-	HWND handle;
-} ContainerInfo;
-
-/*
- * Sets up the container columns.
- * Parameters:
- *          handle: Handle to the container to be configured.
- *          flags: An array of unsigned longs with column flags.
- *          titles: An array of strings with column text titles.
- *          count: The number of columns (this should match the arrays).
- *          separator: The column number that contains the main separator.
- *                     (this item may only be used in OS/2)
- */
-int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
-{
-	PFIELDINFO details, first, left = NULL;
-	FIELDINFOINSERT detin;
-	CNRINFO cnri;
-	int z;
-	ULONG size = sizeof(RECORDCORE);
-	ULONG *offStruct = malloc(count * sizeof(ULONG));
-	ULONG *tempflags = malloc((count+1) * sizeof(ULONG));
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG *oldflags = blah ? blah->data : 0;
-
-	if(!offStruct || !tempflags)
-		return FALSE;
-
-	memcpy(tempflags, flags, count * sizeof(ULONG));
-	tempflags[count] = 0;
-
-	blah->data = tempflags;
-	blah->flags = separator;
-
-	if(oldflags)
-		free(oldflags);
-
-	while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO,  0, MPFROMSHORT(CMA_FIRST))) != NULL)
-	{
-		WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE));
-	}
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		offStruct[z] = size;
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L);
-
-	if(!first)
-	{
-		free(offStruct);
-		return FALSE;
-	}
-
-	for(z=0;z<count;z++)
-	{
-		if(z==separator-1)
-			left=details;
-		details->cb = sizeof(FIELDINFO);
-		details->flData = flags[z];
-		details->flTitle = CFA_FITITLEREADONLY;
-		details->pTitleData = titles[z];
-		details->offStruct = offStruct[z];
-		details = details->pNextFieldInfo;
-	}
-
-	detin.cb = sizeof(FIELDINFOINSERT);
-	detin.fInvalidateFieldInfo = FALSE;
-	detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
-	detin.cFieldInfoInsert = (ULONG)count;
-
-	WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin));
-
-	if(count > separator && separator > 0)
-	{
-		cnri.cb = sizeof(CNRINFO);
-		cnri.pFieldInfoLast = left;
-		cnri.xVertSplitbar  = 150;
-
-		WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
-	}
-
-	cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES;
-	cnri.slBitmapOrIcon.cx = 16;
-	cnri.slBitmapOrIcon.cy = 16;
-
-	WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
-
-	free(offStruct);
-	return TRUE;
-}
-
-/*
- * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
- * Parameters:
- *          handle: Handle to the container to be configured.
- *          flags: An array of unsigned longs with column flags.
- *          titles: An array of strings with column text titles.
- *          count: The number of columns (this should match the arrays).
- */
-int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
-{
-	char **newtitles = malloc(sizeof(char *) * (count + 2));
-	unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
-
-	newtitles[0] = "Icon";
-	newtitles[1] = "Filename";
-
-	newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
-	newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
-
-	memcpy(&newtitles[2], titles, sizeof(char *) * count);
-	memcpy(&newflags[2], flags, sizeof(unsigned long) * count);
-
-	dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0);
-
-	free(newtitles);
-	free(newflags);
-	return TRUE;
-}
-
-/*
- * Obtains an icon from a module (or header in GTK).
- * Parameters:
- *          module: Handle to module (DLL) in OS/2 and Windows.
- *          id: A unsigned long id int the resources on OS/2 and
- *              Windows, on GTK this is converted to a pointer
- *              to an embedded XPM.
- */
-unsigned long API dw_icon_load(unsigned long module, unsigned long id)
-{
-	return WinLoadPointer(HWND_DESKTOP,module,id);
-}
-
-/*
- * Obtains an icon from a file.
- * Parameters:
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (ICO on OS/2 or Windows, XPM on Unix)
- */
-unsigned long API dw_icon_load_from_file(char *filename)
-{
-	char *file = alloca(strlen(filename) + 5);
-
-	if(!file)
-		return 0;
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".ico");
-		if(access(file, 04) != 0)
-			return 0;
-	}
-	return WinLoadFileIcon(file, FALSE);
-}
-
-/*
- * Frees a loaded resource in OS/2 and Windows.
- * Parameters:
- *          handle: Handle to icon returned by dw_icon_load().
- */
-void API dw_icon_free(unsigned long handle)
-{
-	WinDestroyPointer(handle);
-}
-
-/*
- * Allocates memory used to populate a container.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          rowcount: The number of items to be populated.
- */
-void * API dw_container_alloc(HWND handle, int rowcount)
-{
-	WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG *flags = wd ? wd->data : 0;
-	int z, size = 0, totalsize, count = 0;
-	PRECORDCORE temp;
-	ContainerInfo *ci;
-	void *blah = NULL;
-
-	if(!flags || rowcount < 1)
-		return NULL;
-
-	while(flags[count])
-		count++;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	totalsize = size + sizeof(RECORDCORE);
-
-	z = 0;
-
-	if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0)))
-		return NULL;
-
-	temp = (PRECORDCORE)blah;
-
-	for(z=0;z<rowcount;z++)
-	{
-		temp->cb = totalsize;
-		temp = temp->preccNextRecord;
-	}
-
-	ci = malloc(sizeof(struct _containerinfo));
-
-	ci->count = rowcount;
-	ci->data = blah;
-	ci->handle = handle;
-
-	return (void *)ci;
-}
-
-/* Internal function that does the work for set_item and change_item */
-void _dw_container_set_item(HWND handle, PRECORDCORE temp, int column, int row, void *data)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
-	int z, currentcount;
-	CNRINFO cnr;
-    void *dest;
-
-	if(!flags)
-		return;
-
-	if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
-		return;
-
-	currentcount = cnr.cRecords;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<column;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-			size += sizeof(char *);
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-
-	totalsize = size + sizeof(RECORDCORE);
-
-	for(z=0;z<(row-currentcount);z++)
-		temp = temp->preccNextRecord;
-
-	dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
-
-	if(flags[column] & DW_CFA_BITMAPORICON)
-		memcpy(dest, data, sizeof(HPOINTER));
-	else if(flags[column] & DW_CFA_STRING)
-	{
-		char **newstr = (char **)data, **str = dest;
-
-		if(*str)
-			free(*str);
-
-		if(newstr && *newstr)
-			*str = strdup(*newstr);
-		else
-			*str = NULL;
-	}
-	else if(flags[column] & DW_CFA_ULONG)
-		memcpy(dest, data, sizeof(ULONG));
-	else if(flags[column] & DW_CFA_DATE)
-		memcpy(dest, data, sizeof(CDATE));
-	else if(flags[column] & DW_CFA_TIME)
-		memcpy(dest, data, sizeof(CTIME));
-}
-
-/* Internal function that free()s any strings allocated for a container item */
-void _dw_container_free_strings(HWND handle, PRECORDCORE temp)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
-	int z, count = 0;
-
-	if(!flags)
-		return;
-
-	while(flags[count])
-		count++;
-
-	/* Figure out the offsets to the items in the struct */
-	for(z=0;z<count;z++)
-	{
-		if(flags[z] & DW_CFA_BITMAPORICON)
-			size += sizeof(HPOINTER);
-		else if(flags[z] & DW_CFA_STRING)
-		{
-			char **str;
-
-			totalsize = size + sizeof(RECORDCORE);
-
-			str = (char **)(((ULONG)temp)+((ULONG)totalsize));
-
-			if(*str)
-			{
-				free(*str);
-				*str = NULL;
-			}
-			size += sizeof(char *);
-		}
-		else if(flags[z] & DW_CFA_ULONG)
-			size += sizeof(ULONG);
-		else if(flags[z] & DW_CFA_DATE)
-			size += sizeof(CDATE);
-		else if(flags[z] & DW_CFA_TIME)
-			size += sizeof(CTIME);
-	}
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
-{
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-
-	if(!ci)
-		return;
-
-	_dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data);
-}
-
-/*
- * Changes an existing item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_container_change_item(HWND handle, int column, 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)
-		{
-			_dw_container_set_item(handle, pCore, column, 0, data);
-			WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
-			return;
-		}
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-		count++;
-	}
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon)
-{
-	dw_container_set_item(handle, pointer, 0, row, (void *)&icon);
-	dw_container_set_item(handle, pointer, 1, row, (void *)&filename);
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
-{
-	dw_container_set_item(handle, pointer, column + 2, row, data);
-}
-
-/*
- * Sets the width of a column in the container.
- * Parameters:
- *          handle: Handle to window (widget) of container.
- *          column: Zero based column of width being set.
- *          width: Width of column in pixels.
- */
-void API dw_container_set_column_width(HWND handle, int column, int width)
-{
-	handle = handle; /* keep compiler happy */
-	column = column; /* keep compiler happy */
-	width = width; /* keep compiler happy */
-}
-
-/*
- * Sets the title 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.
- *          title: String title of the item.
- */
-void API dw_container_set_row_title(void *pointer, int row, char *title)
-{
-	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->pszIcon = title;
-	temp->pszName = title;
-	temp->pszText = title;
-}
-
-/*
- * Sets the title of a row in the container.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          rowcount: The number of rows to be inserted.
- */
-void API dw_container_insert(HWND handle, void *pointer, int rowcount)
-{
-	RECORDINSERT recin;
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-
-	if(!ci)
-		return;
-
-	recin.cb = sizeof(RECORDINSERT);
-	recin.pRecordOrder = (PRECORDCORE)CMA_END;
-	recin.pRecordParent = NULL;
-	recin.zOrder = CMA_TOP;
-	recin.fInvalidateRecord = TRUE;
-	recin.cRecordsInsert = rowcount;
-
-	_dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0);
-
-	free(ci);
-}
-
-/*
- * Removes all rows from a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- *       redraw: TRUE to cause the container to redraw immediately.
- */
-void API dw_container_clear(HWND handle, int redraw)
-{
-	PCNRITEM pCore;
-	int container = (int)dw_window_get_data(handle, "_dw_container");
-
-	if(hwndEmph == handle)
-		_clear_emphasis();
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if(container)
-			_dw_container_free_strings(handle, (PRECORDCORE)pCore);
-		else
-		{
-			/* Free icon text */
-			if(pCore->rc.pszIcon)
-			{
-				free(pCore->rc.pszIcon);
-				pCore->rc.pszIcon = 0;
-			}
-		}
-		pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/
-	}
-	_dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1);
-}
-
-/*
- * Removes the first x rows from a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be deleted from.
- *       rowcount: The number of rows to be deleted.
- */
-void API dw_container_delete(HWND handle, int rowcount)
-{
-	RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount);
-	int current = 1;
-
-	prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(last && current < rowcount)
-	{
-		_dw_container_free_strings(handle, last);
-		prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-		current++;
-	}
-
-	_dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1);
-	
-	free(prc);
-}
-
-/*
- * Scrolls container up or down.
- * Parameters:
- *       handle: Handle to the window (widget) to be scrolled.
- *       direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or
- *                  DW_SCROLL_BOTTOM. (rows is ignored for last two)
- *       rows: The number of rows to be scrolled.
- */
-void API dw_container_scroll(HWND handle, int direction, long rows)
-{
-	rows = rows; /* keep compiler happy */
-	switch(direction)
-	{
-	case DW_SCROLL_TOP:
-		WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000));
-        break;
-	case DW_SCROLL_BOTTOM:
-		WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000));
-		break;
-	}
-}
-
-/*
- * Starts a new query of a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be queried.
- *       flags: If this parameter is DW_CRA_SELECTED it will only
- *              return items that are currently selected.  Otherwise
- *              it will return all records in the container.
- */
-char * API dw_container_query_start(HWND handle, unsigned long flags)
-{
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-	if(pCore)
-	{
-		if(flags)
-		{
-			while(pCore)
-			{
-				if(pCore->flRecordAttr & flags)
-					return pCore->pszIcon;
-				pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-			}
-		}
-		else
-			return pCore->pszIcon;
-	}
-    return NULL;
-}
-
-/*
- * Continues an existing query of a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be queried.
- *       flags: If this parameter is DW_CRA_SELECTED it will only
- *              return items that are currently selected.  Otherwise
- *              it will return all records in the container.
- */
-char * API dw_container_query_next(HWND handle, unsigned long flags)
-{
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	if(pCore)
-	{
-		if(flags)
-		{
-			while(pCore)
-			{
-				if(pCore->flRecordAttr & flags)
-					return pCore->pszIcon;
-
-				pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-			}
-		}
-		else
-			return pCore->pszIcon;
-	}
-    return NULL;
-}
-
-/*
- * 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(HWND handle, char *text)
-{
-	RECTL viewport, item;
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-	while(pCore)
-	{
-		if((char *)pCore->pszIcon == text)
-		{
-			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 text speficied.
- * Parameters:
- *       handle: Handle to the window (widget).
- *       text:  Text usually returned by dw_container_query().
- */
-void API dw_container_delete_row(HWND handle, char *text)
-{
-	PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-
-	while(pCore)
-	{
-		if((char *)pCore->pszIcon == text)
-		{
-			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));
-	}
-}
-
-/*
- * Optimizes the column widths so that all data is visible.
- * Parameters:
- *       handle: Handle to the window (widget) to be optimized.
- */
-void API dw_container_optimize(HWND handle)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
-	RECTL item;
-	PRECORDCORE pCore = NULL;
-	int max = 0;
-
-	if(blah && !blah->flags)
-		return;
-
-	pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
-	while(pCore)
-	{
-		QUERYRECORDRECT qrr;
-		int vector;
-
-		qrr.cb = sizeof(QUERYRECORDRECT);
-		qrr.pRecord = pCore;
-		qrr.fRightSplitWindow = 0;
-		qrr.fsExtent = CMA_TEXT;
-
-		WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
-
-		vector = item.xRight - item.xLeft;
-
-		if(vector > max)
-			max = vector;
-
-		pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
-	}
-
-	if(max)
-	{
-		CNRINFO cnri;
-
-		cnri.cb = sizeof(CNRINFO);
-		cnri.xVertSplitbar  = max;
-
-		WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_XVERTSPLITBAR));
-	}
-}
-
-/*
- * Inserts an icon into the taskbar.
- * Parameters:
- *       handle: Window handle that will handle taskbar icon messages.
- *       icon: Icon handle to display in the taskbar.
- *       bubbletext: Text to show when the mouse is above the icon.
- */
-void dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext)
-{
-	handle = handle;
-	icon = icon;
-	bubbletext = bubbletext;
-	/* TODO */
-}
-
-/*
- * Deletes an icon from the taskbar.
- * Parameters:
- *       handle: Window handle that was used with dw_taskbar_insert().
- *       icon: Icon handle that was used with dw_taskbar_insert().
- */
-void dw_taskbar_delete(HWND handle, unsigned long icon)
-{
-	handle = handle;
-	icon = icon;
-	/* TODO */
-}
-
-/*
- * Creates a rendering context widget (window) to be packed.
- * Parameters:
- *       id: An id to be used with dw_window_from_id.
- * Returns:
- *       A handle to the widget or NULL on failure.
- */
-HWND API dw_render_new(unsigned long id)
-{
-	HWND hwndframe = WinCreateWindow(HWND_OBJECT,
-									 WC_FRAME,
-									 NULL,
-									 WS_VISIBLE |
-									 FS_NOBYTEALIGN,
-									 0,0,2000,1000,
-									 NULLHANDLE,
-									 HWND_TOP,
-									 id,
-									 NULL,
-									 NULL);
-	WinSubclassWindow(hwndframe, _RendProc);
-	return hwndframe;
-}
-
-/* Sets the current foreground drawing color.
- * Parameters:
- *       red: red value.
- *       green: green value.
- *       blue: blue value.
- */
-void API dw_color_foreground_set(unsigned long value)
-{
-	_foreground = value;
-}
-
-/* Sets the current background drawing color.
- * Parameters:
- *       red: red value.
- *       green: green value.
- *       blue: blue value.
- */
-void API dw_color_background_set(unsigned long value)
-{
-	_background = value;
-}
-
-HPS _set_hps(HPS hps)
-{
-	LONG alTable[2];
-
-	alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground);
-	alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background);
-
-	GpiCreateLogColorTable(hps,
-						   LCOL_RESET,
-						   LCOLF_CONSECRGB,
-						   16,
-						   2,
-						   alTable);
-	if(_foreground & DW_RGB_COLOR)
-		GpiSetColor(hps, 16);
-	else
-		GpiSetColor(hps, _internal_color(_foreground));
-	if(_background & DW_RGB_COLOR)
-		GpiSetBackColor(hps, 17);
-	else
-		GpiSetBackColor(hps, _internal_color(_background));
-	return hps;
-}
-
-HPS _set_colors(HWND handle)
-{
-	HPS hps = WinGetPS(handle);
-
-	_set_hps(hps);
-	return hps;
-}
-
-/* Draw a point on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
-{
-	HPS hps;
-	int height;
-	POINTL ptl;
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-        height = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-	}
-	else
-		return;
-
-	ptl.x = x;
-	ptl.y = height - y - 1;
-
-	GpiSetPel(hps, &ptl);
-	if(!pixmap)
-		WinReleasePS(hps);
-}
-
-/* Draw a line on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x1: First X coordinate.
- *       y1: First Y coordinate.
- *       x2: Second X coordinate.
- *       y2: Second Y coordinate.
- */
-void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
-{
-	HPS hps;
-	int height;
-	POINTL ptl[2];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-        height = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-	}
-	else
-		return;
-
-	ptl[0].x = x1;
-	ptl[0].y = height - y1 - 1;
-	ptl[1].x = x2;
-	ptl[1].y = height - y2 - 1;
-
-	GpiMove(hps, &ptl[0]);
-	GpiLine(hps, &ptl[1]);
-	
-	if(!pixmap)
-		WinReleasePS(hps);
-}
-
-
-void _CopyFontSettings(HPS hpsSrc, HPS hpsDst)
-{
-	FONTMETRICS fm;
-	FATTRS fat;
-	SIZEF sizf;
-
-	GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm);
-
-    memset(&fat, 0, sizeof(fat));
-
-	fat.usRecordLength  = sizeof(FATTRS);
-	fat.lMatch          = fm.lMatch;
-	strcpy(fat.szFacename, fm.szFacename);
-
-	GpiCreateLogFont(hpsDst, 0, 1L, &fat);
-	GpiSetCharSet(hpsDst, 1L);
-
-	sizf.cx = MAKEFIXED(fm.lEmInc,0);
-	sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0);
-	GpiSetCharBox(hpsDst, &sizf );
-}
-
-/* Draw text on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x: X coordinate.
- *       y: Y coordinate.
- *       text: Text to be displayed.
- */
-void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
-{
-	HPS hps;
-	int z, height;
-	RECTL rcl;
-	char fontname[128];
-	POINTL aptl[TXTBOX_COUNT];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-		height = _get_height(handle);
-		_GetPPFont(handle, fontname);
-	}
-	else if(pixmap)
-	{
-		HPS pixmaphps = WinGetPS(pixmap->handle);
-
-		hps = _set_hps(pixmap->hps);
-		height = pixmap->height;
-		_GetPPFont(pixmap->handle, fontname);
-		_CopyFontSettings(pixmaphps, hps);
-		WinReleasePS(pixmaphps);
-	}
-	else
-		return;
-
-	for(z=0;z<strlen(fontname);z++)
-	{
-		if(fontname[z]=='.')
-			break;
-	}
-
-	GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
-
-	rcl.xLeft = x;
-	rcl.yTop = height - y;
-	rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y);
-	rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x);
-
-	if(_background == DW_CLR_DEFAULT)
-		WinDrawText(hps, -1, text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
-	else
-		WinDrawText(hps, -1, text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT);
-
-	if(!pixmap)
-		WinReleasePS(hps);
-}
-
-/* Query the width and height of a text string.
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       text: Text to be queried.
- *       width: Pointer to a variable to be filled in with the width.
- *       height Pointer to a variable to be filled in with the height.
- */
-void API dw_font_text_extents(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
-{
-	HPS hps;
-	POINTL aptl[TXTBOX_COUNT];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-	}
-	else if(pixmap)
-	{
-		HPS pixmaphps = WinGetPS(pixmap->handle);
-
-		hps = _set_hps(pixmap->hps);
-		_CopyFontSettings(pixmaphps, hps);
-		WinReleasePS(pixmaphps);
-	}
-	else
-		return;
-
-	GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
-
-	if(width)
-		*width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x;
-
-	if(height)
-		*height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y;
-
-	if(!pixmap)
-		WinReleasePS(hps);
-}
-
-/* Draw a rectangle on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       fill: Fill box TRUE or FALSE.
- *       x: X coordinate.
- *       y: Y coordinate.
- *       width: Width of rectangle.
- *       height: Height of rectangle.
- */
-void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
-{
-	HPS hps;
-	int thisheight;
-	POINTL ptl[2];
-
-	if(handle)
-	{
-		hps = _set_colors(handle);
-        thisheight = _get_height(handle);
-	}
-	else if(pixmap)
-	{
-		hps = _set_hps(pixmap->hps);
-		thisheight = pixmap->height;
-	}
-	else
-		return;
-
-	ptl[0].x = x;
-	ptl[0].y = thisheight - y - 1;
-	ptl[1].x = x + width - 1;
-	ptl[1].y = thisheight - y - height;
-
-	GpiMove(hps, &ptl[0]);
-	GpiBox(hps, fill ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0);
-	
-	if(!pixmap)
-		WinReleasePS(hps);
-}
-
-/* Call this after drawing to the screen to make sure
- * anything you have drawn is visible.
- */
-void API dw_flush(void)
-{
-}
-
-/*
- * Creates a pixmap with given parameters.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       width: Width of the pixmap in pixels.
- *       height: Height of the pixmap in pixels.
- *       depth: Color depth of the pixmap.
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
-{
-	BITMAPINFOHEADER bmih;
-	SIZEL sizl = { 0, 0 };
-	HPIXMAP pixmap;
-	HDC hdc;
-	HPS hps;
-	ULONG ulFlags;
-    LONG cPlanes, cBitCount;
-
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hps = WinGetPS(handle);
-
-	hdc     = GpiQueryDevice(hps);
-	ulFlags = GpiQueryPS(hps, &sizl);
-
-	pixmap->handle = handle;
-	pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
-	pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	DevQueryCaps(hdc, CAPS_COLOR_PLANES  , 1L, &cPlanes);
-	if (!depth)
-	{
-		DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount);
-		depth = cBitCount;
-	}
-
-	memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
-	bmih.cbFix     = sizeof(BITMAPINFOHEADER);
-	bmih.cx        = (SHORT)width;
-	bmih.cy        = (SHORT)height;
-	bmih.cPlanes   = (SHORT)cPlanes;
-	bmih.cBitCount = (SHORT)depth;
-
-	pixmap->width = width; pixmap->height = height;
-
-	pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL);
-
-	GpiSetBitmap(pixmap->hps, pixmap->hbm);
-
-	if (depth>8)
-		GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL );
-
-	WinReleasePS(hps);
-
-	return pixmap;
-}
-
-/*
- * Creates a pixmap from a file.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (BMP on OS/2 or Windows, XPM on Unix)
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
-{
-	HPIXMAP pixmap;
-	char *file = alloca(strlen(filename) + 5);
-
-	if(!file || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".bmp");
-		if(access(file, 04) != 0)
-		{
-			free(pixmap);
-			return NULL;
-		}
-	}
-
-	/* Try to load the bitmap from file */
-	if(!_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height))
-	{
-		free(pixmap);
-		return NULL;
-	}
-
-	/* Success fill in other values */
-	pixmap->handle = handle;
-
-	return pixmap;
-}
-
-/*
- * Creates a pixmap from internal resource graphic specified by id.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       id: Resource ID associated with requested pixmap.
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id)
-{
-	BITMAPINFOHEADER bmih;
-	SIZEL sizl = { 0, 0 };
-	HPIXMAP pixmap;
-	HDC hdc;
-	HPS hps;
-	ULONG ulFlags;
-
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hps = WinGetPS(handle);
-
-	hdc     = GpiQueryDevice(hps);
-	ulFlags = GpiQueryPS(hps, &sizl);
-
-	pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
-	pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
-
-	pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0);
-
-	GpiQueryBitmapParameters(pixmap->hbm, &bmih);
-
-	GpiSetBitmap(pixmap->hps, pixmap->hbm);
-
-	pixmap->width = bmih.cx; pixmap->height = bmih.cy;
-
-	WinReleasePS(hps);
-
-	return pixmap;
-}
-
-/*
- * Destroys an allocated pixmap.
- * Parameters:
- *       pixmap: Handle to a pixmap returned by
- *               dw_pixmap_new..
- */
-void API dw_pixmap_destroy(HPIXMAP pixmap)
-{
-	GpiSetBitmap(pixmap->hps, NULLHANDLE);
-	GpiDeleteBitmap(pixmap->hbm);
-	GpiAssociate(pixmap->hps, NULLHANDLE);
-	GpiDestroyPS(pixmap->hps);
-	DevCloseDC(pixmap->hdc);
-	free(pixmap);
-}
-
-/*
- * Copies from one item to another.
- * Parameters:
- *       dest: Destination window handle.
- *       destp: Destination pixmap. (choose only one).
- *       xdest: X coordinate of destination.
- *       ydest: Y coordinate of destination.
- *       width: Width of area to copy.
- *       height: Height of area to copy.
- *       src: Source window handle.
- *       srcp: Source pixmap. (choose only one).
- *       xsrc: X coordinate of source.
- *       ysrc: Y coordinate of source.
- */
-void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
-{
-	HPS hpsdest;
-	HPS hpssrc;
-	POINTL ptl[4];
-    int destheight, srcheight;
-
-	if(dest)
-	{
-		hpsdest = WinGetPS(dest);
-		destheight = _get_height(dest);
-	}
-	else if(destp)
-	{
-		hpsdest = destp->hps;
-		destheight = destp->height;
-	}
-	else
-		return;
-
-	if(src)
-	{
-		hpssrc = WinGetPS(src);
-		srcheight = _get_height(src);
-	}
-	else if(srcp)
-	{
-		hpssrc = srcp->hps;
-		srcheight = srcp->height;
-	}
-	else
-	{
-		if(!destp)
-			WinReleasePS(hpsdest);
-		return;
-	}
-
-	ptl[0].x = xdest;
-	ptl[0].y = (destheight - ydest) - height;
-	ptl[1].x = ptl[0].x + width;
-	ptl[1].y = destheight - ydest;
-	ptl[2].x = xsrc;
-	ptl[2].y = srcheight - (ysrc + height);
-	ptl[3].x = ptl[2].x + width;
-	ptl[3].y = ptl[2].y + height;
-
-	GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE);
-
-	if(!destp)
-		WinReleasePS(hpsdest);
-	if(!srcp)
-		WinReleasePS(hpssrc);
-}
-
-/*
- * Emits a beep.
- * Parameters:
- *       freq: Frequency.
- *       dur: Duration.
- */
-void API dw_beep(int freq, int dur)
-{
-	DosBeep(freq, dur);
-}
-
-/* Open a shared library and return a handle.
- * Parameters:
- *         name: Base name of the shared library.
- *         handle: Pointer to a module handle,
- *                 will be filled in with the handle.
- */
-int API dw_module_load(char *name, HMOD *handle)
-{
-	char objnamebuf[300] = "";
-
-	return DosLoadModule(objnamebuf, sizeof(objnamebuf), name, handle);
-}
-
-/* Queries the address of a symbol within open handle.
- * Parameters:
- *         handle: Module handle returned by dw_module_load()
- *         name: Name of the symbol you want the address of.
- *         func: A pointer to a function pointer, to obtain
- *               the address.
- */
-int API dw_module_symbol(HMOD handle, char *name, void**func)
-{
-	return DosQueryProcAddr(handle, 0, name, (PFN*)func);
-}
-
-/* Frees the shared library previously opened.
- * Parameters:
- *         handle: Module handle returned by dw_module_load()
- */
-int API dw_module_close(HMOD handle)
-{
-	DosFreeModule(handle);
-	return 0;
-}
-
-/*
- * Returns the handle to an unnamed mutex semaphore.
- */
-HMTX API dw_mutex_new(void)
-{
-	HMTX mutex;
-
-	DosCreateMutexSem(NULL, &mutex, 0, FALSE);
-	return mutex;
-}
-
-/*
- * Closes a semaphore created by dw_mutex_new().
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_close(HMTX mutex)
-{
-	DosCloseMutexSem(mutex);
-}
-
-/*
- * Tries to gain access to the semaphore, if it can't it blocks.
- * If we are in a callback we must keep the message loop running
- * while blocking.
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_lock(HMTX mutex)
-{
-	if(_dwtid == dw_thread_id())
-	{
-		int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
-
-		while(rc == ERROR_TIMEOUT)
-		{
-			dw_main_sleep(10);
-			rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
-		}
-	}
-    else
-		DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT);
-}
-
-/*
- * Reliquishes the access to the semaphore.
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_unlock(HMTX mutex)
-{
-	DosReleaseMutexSem(mutex);
-}
-
-/*
- * Returns the handle to an unnamed event semaphore.
- */
-HEV API dw_event_new(void)
-{
-	HEV blah;
-
-	if(DosCreateEventSem (NULL, &blah, 0L, FALSE))
-		return 0;
-
-	return blah;
-}
-
-/*
- * Resets a semaphore created by dw_event_new().
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_reset(HEV eve)
-{
-	ULONG count;
-
-	if(DosResetEventSem(eve, &count))
-		return FALSE;
-	return TRUE;
-}
-
-/*
- * Posts a semaphore created by dw_event_new(). Causing all threads
- * waiting on this event in dw_event_wait to continue.
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_post(HEV eve)
-{
-	if(DosPostEventSem(eve))
-		return FALSE;
-	return TRUE;
-}
-
-
-/*
- * Waits on a semaphore created by dw_event_new(), until the
- * event gets posted or until the timeout expires.
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_wait(HEV eve, unsigned long timeout)
-{
-	int rc = DosWaitEventSem(eve, timeout);
-	if(!rc)
-		return 1;
-	if(rc == ERROR_TIMEOUT)
-		return -1;
-	return 0;
-}
-
-/*
- * Closes a semaphore created by dw_event_new().
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_close(HEV *eve)
-{
-	if(!eve || ~DosCloseEventSem(*eve))
-		return FALSE;
-	return TRUE;
-}
-
-/*
- * Encapsulate the message queues on OS/2.
- */
-void _dwthreadstart(void *data)
-{
-	HAB thishab = WinInitialize(0);
-	HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
-	void (*threadfunc)(void *) = NULL;
-	void **tmp = (void **)data;
-
-	threadfunc = (void (*)(void *))tmp[0];
-	threadfunc(tmp[1]);
-
-	free(tmp);
-
-	WinDestroyMsgQueue(thishmq);
-	WinTerminate(thishab);
-}
-
-/*
- * Creates a new thread with a starting point of func.
- * Parameters:
- *       func: Function which will be run in the new thread.
- *       data: Parameter(s) passed to the function.
- *       stack: Stack size of new thread (OS/2 and Windows only).
- */
-DWTID API dw_thread_new(void *func, void *data, int stack)
-{
-	void **tmp = malloc(sizeof(void *) * 2);
-
-	tmp[0] = func;
-	tmp[1] = data;
-
-	return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp);
-}
-
-/*
- * Ends execution of current thread immediately.
- */
-void API dw_thread_end(void)
-{
-	_endthread();
-}
-
-/*
- * Returns the current thread's ID.
- */
-DWTID API dw_thread_id(void)
-{
-	return (DWTID)_threadid;
-}
-
-/*
- * 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)
-{
-	/* Destroy the menu message window */
-	dw_window_destroy(hwndApp);
-
-	/* In case we are in a signal handler, don't
-	 * try to free memory that could possibly be
-	 * free()'d by the runtime already.
-	 */
-	Root = NULL;
-
-	exit(exitcode);
-}
-
-/*
- * Creates a splitbar window (widget) with given parameters.
- * Parameters:
- *       type: Value can be DW_VERT or DW_HORZ.
- *       topleft: Handle to the window to be top or left.
- *       bottomright:  Handle to the window to be bottom or right.
- * Returns:
- *       A handle to a splitbar window or NULL on failure.
- */
-HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
-{
-	HWND tmp = WinCreateWindow(HWND_OBJECT,
-							   SplitbarClassName,
-							   NULL,
-							   WS_VISIBLE | WS_CLIPCHILDREN,
-							   0,0,2000,1000,
-							   NULLHANDLE,
-							   HWND_TOP,
-							   id,
-							   NULL,
-							   NULL);
-	if(tmp)
-	{
-		HWND tmpbox = dw_box_new(DW_VERT, 0);
-        float *percent = malloc(sizeof(float));
-
-		dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0);
-		WinSetParent(tmpbox, tmp, FALSE);
-		dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox);
-
-		tmpbox = dw_box_new(DW_VERT, 0);
-		dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0);
-		WinSetParent(tmpbox, tmp, FALSE);
-		*percent = 50.0;
-		dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox);
-		dw_window_set_data(tmp, "_dw_percent", (void *)percent);
-		dw_window_set_data(tmp, "_dw_type", (void *)type);
-	}
-	return tmp;
-}
-
-/*
- * Sets the position of a splitbar (pecentage).
- * Parameters:
- *       handle: The handle to the splitbar returned by dw_splitbar_new().
- */
-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;
-
-	if(mypercent)
-		*mypercent = percent;
-
-	dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
-
-	_handle_splitbar_resize(handle, percent, type, width, height);
-}
-
-/*
- * Gets the position of a splitbar (pecentage).
- * Parameters:
- *       handle: The handle to the splitbar returned by dw_splitbar_new().
- */
-float API dw_splitbar_get(HWND handle)
-{
-	float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-
-	if(percent)
-		return *percent;
-	return 0.0;
-}
-
-/*
- * Pack windows (widgets) into a box from the start (or top).
- * Parameters:
- *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
- *       width: Width in pixels of the item or -1 to be self determined.
- *       height: Height in pixels of the item or -1 to be self determined.
- *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
- *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
- *       pad: Number of pixels of padding around the item.
- */
-void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
-{
-	Box *thisbox;
-	char *funcname = "dw_box_pack_start()";
-
-		/*
-		 * If you try and pack an item into itself VERY bad things can happen; like at least an
-		 * infinite loop on GTK! Lets be safe!
-		 */
-	if(box == item)
-	{
-		dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!",box,item);
-		return;
-	}
-
-	if(WinWindowFromID(box, FID_CLIENT))
-	{
-		box = WinWindowFromID(box, FID_CLIENT);
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-		hsize = TRUE;
-		vsize = TRUE;
-	}
-	else
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-	if(thisbox)
-	{
-		if(thisbox->type == DW_HORZ)
-			_dw_box_pack_end(box, item, width, height, hsize, vsize, pad, funcname);
-		else
-			_dw_box_pack_start(box, item, width, height, hsize, vsize, pad, funcname);
-	}
-}
-
-void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname)
-{
-	Box *thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-		HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z+1] = thisitem[z];
-		}
-
-		WinQueryClassName(item, 99, tmpbuf);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strncmp(tmpbuf, "#1", 3)==0)
-			tmpitem[0].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox(functionname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[0].type = TYPEITEM;
-		}
-
-		tmpitem[0].hwnd = item;
-		tmpitem[0].origwidth = tmpitem[0].width = width;
-		tmpitem[0].origheight = tmpitem[0].height = height;
-		tmpitem[0].pad = pad;
-		if(hsize)
-			tmpitem[0].hsize = SIZEEXPAND;
-		else
-			tmpitem[0].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[0].vsize = SIZEEXPAND;
-		else
-			tmpitem[0].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-		WinQueryClassName(item, 99, tmpbuf);
-		/* Don't set the ownership if it's an entryfield or spinbutton */
-		if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
-			WinSetOwner(item, box);
-		WinSetParent(frame ? frame : item, box, FALSE);
-	}
-}
-
-/* The following two functions graciously contributed by Peter Nielsen. */
-static ULONG _ParseBuildLevel (char* pchBuffer, ULONG ulSize) {
-	char* pchStart = pchBuffer;
-	char* pchEnd = pchStart + ulSize - 2;
-
-	while (pchEnd >= pchStart)
-	{
-		if ((pchEnd[0] == '#') && (pchEnd[1] == '@'))
-		{
-			*pchEnd-- = '\0';
-			while (pchEnd >= pchStart)
-			{
-				if ((pchEnd[0] == '@') && (pchEnd[1] == '#'))
-				{
-					ULONG ulMajor = 0;
-					ULONG ulMinor = 0;
-
-					char* pch = pchEnd + 2;
-					while (!isdigit ((int)*pch) && *pch)
-						pch++;
-
-					while (isdigit ((int)*pch))
-						ulMajor = ulMajor * 10 + *pch++ - '0';
-
-					if (*pch == '.')
-					{
-						while (isdigit ((int)*++pch))
-							ulMinor = ulMinor * 10 + *pch - '0';
-					}
-					return ((ulMajor << 16) | ulMinor);
-				}
-				pchEnd--;
-			}
-		}
-		pchEnd--;
-	}
-	return (0);
-}
-
-ULONG _GetSystemBuildLevel(void) {
-	/* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2.
-	 * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely.
-	 */
-	ULONG ulBootDrive = 0;
-	ULONG ulBuild = 0;
-	if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR)
-	{
-		char achFileName[11] = "C:\\OS2KRNL";
-		HFILE hfile;
-		ULONG ulResult;
-
-        achFileName[0] = (char)('A'+ulBootDrive-1);
-
-		if (DosOpen (achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR)
-		{
-			ULONG ulFileSize = 0;
-			if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR)
-			{
-				const ULONG ulFirstTry = min (256, ulFileSize);
-				if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR)
-				{
-					char *pchBuffer = malloc(ulFirstTry);
-					if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR)
-					{
-						ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry);
-						if (ulBuild == 0)
-						{
-							if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR)
-							{
-								free(pchBuffer);
-								pchBuffer = malloc(ulFileSize);
-
-								if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR)
-									ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize);
-							}
-						}
-					}
-					free(pchBuffer);
-				}
-			}
-			DosClose (hfile);
-		}
-	}
-	return (ulBuild);
-}
-
-/*
- * Sets the default focus item for a window/dialog.
- * Parameters:
- *         window: Toplevel window or dialog.
- *         defaultitem: Handle to the dialog item to be default.
- */
-void API dw_window_default(HWND window, HWND defaultitem)
-{
-	Box *thisbox = NULL;
-	HWND box;
-
-	box = WinWindowFromID(window, FID_CLIENT);
-	if(box)
-		thisbox = WinQueryWindowPtr(box, QWP_USER);
-
-	if(thisbox)
-		thisbox->defaultitem = defaultitem;
-}
-
-/*
- * Sets window to click the default dialog item when an ENTER is pressed.
- * Parameters:
- *         window: Window (widget) to look for the ENTER press.
- *         next: Window (widget) to move to next (or click)
- */
-void API dw_window_click_default(HWND window, HWND next)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(blah)
-		blah->clickdefault = next;
-}
-
-/*
- * Returns some information about the current operating environment.
- * Parameters:
- *       env: Pointer to a DWEnv struct.
- */
-void API dw_environment_query(DWEnv *env)
-{
-	ULONG Build;
-
-	if(!env)
-		return;
-
-	/* The default is OS/2 2.0 */
-	strcpy(env->osName,"OS/2");
-	env->MajorVersion = 2;
-	env->MinorVersion = 0;
-
-	Build = _GetSystemBuildLevel();
-	env->MinorBuild =  Build & 0xFFFF;
-	env->MajorBuild =  Build >> 16;
-
-	if (aulBuffer[0] == 20)
-	{
-		int i = (unsigned int)aulBuffer[1];
-		if (i > 20)
-		{
-			strcpy(env->osName,"Warp");
-			env->MajorVersion = (int)i/10;
-			env->MinorVersion = i-(((int)i/10)*10);
-		}
-		else if (i == 10)
-			env->MinorVersion = 1;
-	}
-	strcpy(env->buildDate, __DATE__);
-	strcpy(env->buildTime, __TIME__);
-	env->DWMajorVersion = DW_MAJOR_VERSION;
-	env->DWMinorVersion = DW_MINOR_VERSION;
-	env->DWSubVersion = DW_SUB_VERSION;
-}
-
-/* The next few functions are support functions for the OS/2 folder browser */
-void _populate_directory(HWND tree, HTREEITEM parent, char *path)
-{
-	FILEFINDBUF3 ffbuf;
-	HTREEITEM item;
-	ULONG count = 1;
-	HDIR hdir = HDIR_CREATE;
-
-	if(DosFindFirst(path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY,
-					&ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR)
-	{
-		while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR)
-		{
-			if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, ".."))
-			{
-				int len = strlen(path);
-				char *folder = malloc(len + ffbuf.cchName + 2);
-				HTREEITEM tempitem;
-
-				strcpy(folder, path);
-				strcpy(&folder[len-1], ffbuf.achName);
-
-				item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, (void *)parent);
-				tempitem = dw_tree_insert(tree, "", 0, item, 0);
-				dw_tree_set_data(tree, item, (void *)tempitem);
-			}
-		}
-		DosFindClose(hdir);
-	}
-}
-
-void _populate_tree_thread(void *data)
-{
-	HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree");
-	HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex");
-	int drive;
-	HTREEITEM items[26];
-	FSINFO  volinfo;
-
-	DosError(FERR_DISABLEHARDERR);
-
-	dw_mutex_lock(mtx);
-	for(drive=0;drive<26;drive++)
-	{
-		if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR)
-		{
-			char folder[5] = "C:\\", name[9] = "Drive C:";
-			HTREEITEM tempitem;
-
-			folder[0] = name[6] = 'A' + drive;
-
-			items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon(folder, TRUE), NULL, 0);
-			tempitem = dw_tree_insert(tree, "", 0, items[drive], 0);
-			dw_tree_set_data(tree, items[drive], (void *)tempitem);
-		}
-		else
-			items[drive] = 0;
-	}
-	dw_mutex_unlock(mtx);
-
-	DosError(FERR_ENABLEHARDERR);
-}
-
-int DWSIGNAL _dw_ok_func(HWND window, void *data)
-{
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-	void *treedata;
-
-	window = window;
-	if(!dwwait)
-		return FALSE;
-
-	dw_mutex_lock(mtx);
-	treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
-	dw_mutex_close(mtx);
-	dw_window_destroy((HWND)dwwait->data);
-	dw_dialog_dismiss((DWDialog *)data, treedata);
-	return FALSE;
-}
-
-int DWSIGNAL _dw_cancel_func(HWND window, void *data)
-{
-	DWDialog *dwwait = (DWDialog *)data;
-	HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
-
-	window = window;
-	if(!dwwait)
-		return FALSE;
-
-	dw_mutex_lock(mtx);
-	dw_mutex_close(mtx);
-	dw_window_destroy((HWND)dwwait->data);
-	dw_dialog_dismiss((DWDialog *)data, NULL);
-	return FALSE;
-}
-
-char *_tree_folder(HWND tree, HTREEITEM item)
-{
-	char *folder=strdup("");
-	HTREEITEM parent = item;
-
-	while(parent)
-	{
-		char *temp, *text = dw_tree_get_title(tree, parent);
-
-		if(text)
-		{
-			if(strncmp(text, "Drive ", 6) == 0)
-				text = &text[6];
-
-			temp = malloc(strlen(text) + strlen(folder) + 3);
-			strcpy(temp, text);
-			strcat(temp, "\\");
-			strcat(temp, folder);
-			free(folder);
-			folder = temp;
-		}
-		parent = dw_tree_get_parent(tree, parent);
-	}
-	return folder;
-}
-
-int DWSIGNAL _item_select(HWND window, HTREEITEM item, char *text, void *data, void *itemdata)
-{
-	DWDialog *dwwait = (DWDialog *)data;
-	char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
-
-	text = text; itemdata = itemdata;
-	if(treedata)
-		free(treedata);
-
-	treedata = _tree_folder(window, item);
-	dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata);
-
-	return FALSE;
-}
-
-int DWSIGNAL _tree_expand(HWND window, HTREEITEM item, void *data)
-{
-	HTREEITEM tempitem = (HTREEITEM)dw_tree_get_data(window, item);
-
-	data = data;
-	if(tempitem)
-	{
-		char *folder = _tree_folder(window, item);
-
-		dw_tree_set_data(window, item, 0);
-		dw_tree_delete(window, tempitem);
-
-		if(*folder)
-		{
-			strcat(folder, "*");
-			_populate_directory(window, item, folder);
-		}
-		free(folder);
-	}
-
-	return FALSE;
-}
-
-/*
- * Opens a file dialog and queries user selection.
- * Parameters:
- *       title: Title bar text for dialog.
- *       defpath: The default path of the open dialog.
- *       ext: Default file extention.
- *       flags: DW_FILE_OPEN or DW_FILE_SAVE.
- * Returns:
- *       NULL on error. A malloced buffer containing
- *       the file path on success.
- *       
- */
-char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
-{
-	if(flags == DW_DIRECTORY_OPEN)
-	{
-		HWND window, hbox, vbox, tree, button;
-		DWDialog *dwwait;
-		HMTX mtx = dw_mutex_new();
-
-		window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
-
-		vbox = dw_box_new(DW_VERT, 5);
-
-		dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
-
-		tree = dw_tree_new(60);
-
-		dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0);
-		dw_window_set_data(window, "_dw_mutex", (void *)mtx);
-		dw_window_set_data(window, "_dw_tree", (void *)tree);
-
-		hbox = dw_box_new(DW_HORZ, 0);
-
-		dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
-
-		dwwait = dw_dialog_new((void *)window);
-
-		dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait);
-		dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait);
-
-		button = dw_button_new("Ok", 1001L);
-		dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-		dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait);
-
-		button = dw_button_new("Cancel", 1002L);
-		dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
-		dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
-
-		dw_window_set_usize(window, 225, 300);
-		dw_window_show(window);
-
-		dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff);
-		return (char *)dw_dialog_wait(dwwait);
-	}
-	else
-	{
-		FILEDLG fild;
-		HWND hwndFile;
-		int len;
-
-		if(defpath)
-			strcpy(fild.szFullFile, defpath);
-		else
-			strcpy(fild.szFullFile, "");
-
-		len = strlen(fild.szFullFile);
-
-		if(len)
-		{
-			if(fild.szFullFile[len-1] != '\\')
-				strcat(fild.szFullFile, "\\");
-		}
-		strcat(fild.szFullFile, "*");
-
-		if(ext)
-		{
-			strcat(fild.szFullFile, ".");
-			strcat(fild.szFullFile, ext);
-		}
-
-		memset(&fild, 0, sizeof(FILEDLG));
-		fild.cbSize = sizeof(FILEDLG);
-		fild.fl = FDS_CENTER | FDS_OPEN_DIALOG;
-		fild.pszTitle = title;
-		fild.pszOKButton = ((flags & DW_FILE_SAVE) ? "Save" : "Open");
-		fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc;
-
-		hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild);
-		if(hwndFile)
-		{
-			switch(fild.lReturn)
-			{
-			case DID_OK:
-				return strdup(fild.szFullFile);
-			case DID_CANCEL:
-				return NULL;
-			}
-		}
-	}
-	return NULL;
-}
-
-/* Internal function to set drive and directory */
-int _SetPath(char *path)
-{
-#ifndef __WATCOMC__
-	if(strlen(path)	> 2)
-	{
-		if(path[1] == ':')
-		{
-			char drive = toupper(path[0]);
-			_chdrive((drive - 'A')+1);
-		}
-	}
-#endif
-	return chdir(path);
-}
-
-/*
- * Execute and external program in a seperate session.
- * Parameters:
- *       program: Program name with optional path.
- *       type: Either DW_EXEC_CON or DW_EXEC_GUI.
- *       params: An array of pointers to string arguements.
- * Returns:
- *       -1 on error.
- */
-int API dw_exec(char *program, int type, char **params)
-{
-	type = type; /* keep compiler happy */
-	return spawnvp(P_NOWAIT, program, (const char **)params);
-}
-
-/*
- * Loads a web browser pointed at the given URL.
- * Parameters:
- *       url: Uniform resource locator.
- */
-int API dw_browse(char *url)
-{
-	char *execargs[3], browser[1024], *olddir, *newurl = NULL;
-	int len, ret;
-
-	olddir = _getcwd(NULL, 1024);
-
-	PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
-						  "DefaultWorkingDir", NULL, browser, 1024);
-
-	if(browser[0])
-		_SetPath(browser);
-
-	PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
-						  "DefaultBrowserExe", NULL, browser, 1024);
-
-	len = strlen(browser) - strlen("explore.exe");
-
-	execargs[0] = browser;
-	execargs[1] = url;
-	execargs[2] = NULL;
-
-	/* Special case for Web Explorer, it requires file:/// instead
-	 * of file:// so I am handling it here.
-	 */
-	if(len > 0)
-	{
-		if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0)
-		{
-			int newlen, z;
-			newurl = malloc(strlen(url) + 2);
-			sprintf(newurl, "file:///%s", &url[7]);
-			newlen = strlen(newurl);
-			for(z=8;z<(newlen-8);z++)
-			{
-				if(newurl[z] == '|')
-					newurl[z] = ':';
-				if(newurl[z] == '/')
-					newurl[z] = '\\';
-			}
-			execargs[1] = newurl;
-		}
-	}
-
-	ret = dw_exec(browser, DW_EXEC_GUI, execargs);
-
-	if(olddir)
-	{
-		_SetPath(olddir);
-		free(olddir);
-	}
-	if(newurl)
-		free(newurl);
-	return ret;
-}
-
-/*
- * Returns a pointer to a static buffer which containes the
- * current user directory.  Or the root directory (C:\ on
- * OS/2 and Windows).
- */
-char * API dw_user_dir(void)
-{
-	static char _user_dir[1024] = "";
-
-	if(!_user_dir[0])
-	{
-		char *home = getenv("HOME");
-
-		if(home)
-			strcpy(_user_dir, home);
-		else
-			strcpy(_user_dir, "C:\\");
-	}
-	return _user_dir;
-}
-
-/*
- * Call a function from the window (widget)'s context.
- * Parameters:
- *       handle: Window handle of the widget.
- *       function: Function pointer to be called.
- *       data: Pointer to the data to be passed to the function.
- */
-void API dw_window_function(HWND handle, void *function, void *data)
-{
-	WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data);
-}
-
-/* Functions for managing the user data lists that are associated with
- * a given window handle.  Used in dw_window_set_data() and
- * dw_window_get_data().
- */
-UserData *_find_userdata(UserData **root, char *varname)
-{
-	UserData *tmp = *root;
-
-	while(tmp)
-	{
-		if(stricmp(tmp->varname, varname) == 0)
-			return tmp;
-		tmp = tmp->next;
-	}
-	return NULL;
-}
-
-int _new_userdata(UserData **root, char *varname, void *data)
-{
-	UserData *new = _find_userdata(root, varname);
-
-	if(new)
-	{
-		new->data = data;
-		return TRUE;
-	}
-	else
-	{
-		new = malloc(sizeof(UserData));
-		if(new)
-		{
-			new->varname = strdup(varname);
-			new->data = data;
-
-			new->next = NULL;
-
-			if (!*root)
-				*root = new;
-			else
-			{
-				UserData *prev = NULL, *tmp = *root;
-				while(tmp)
-				{
-					prev = tmp;
-					tmp = tmp->next;
-				}
-				if(prev)
-					prev->next = new;
-				else
-					*root = new;
-			}
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-int _remove_userdata(UserData **root, char *varname, int all)
-{
-	UserData *prev = NULL, *tmp = *root;
-
-	while(tmp)
-	{
-		if(all || stricmp(tmp->varname, varname) == 0)
-		{
-			if(!prev)
-			{
-				*root = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				if(!all)
-					return 0;
-				tmp = *root;
-			}
-			else
-			{
-				/* If all is true we should
-				 * never get here.
-				 */
-				prev->next = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				return 0;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-	return 0;
-}
-
-/*
- * Add a named user data item to a window handle.
- * Parameters:
- *       window: Window handle of signal to be called back.
- *       dataname: A string pointer identifying which signal to be hooked.
- *       data: User data to be passed to the handler function.
- */
-void API dw_window_set_data(HWND window, char *dataname, void *data)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(!blah)
-	{
-		if(!dataname)
-			return;
-
-		blah = calloc(1, sizeof(WindowData));
-		WinSetWindowPtr(window, QWP_USER, blah);
-	}
-
-	if(data)
-		_new_userdata(&(blah->root), dataname, data);
-	else
-	{
-		if(dataname)
-			_remove_userdata(&(blah->root), dataname, FALSE);
-		else
-			_remove_userdata(&(blah->root), NULL, TRUE);
-	}
-}
-
-/*
- * Gets a named user data item to a window handle.
- * Parameters:
- *       window: Window handle of signal to be called back.
- *       dataname: A string pointer identifying which signal to be hooked.
- *       data: User data to be passed to the handler function.
- */
-void *dw_window_get_data(HWND window, char *dataname)
-{
-	WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
-
-	if(blah && blah->root && dataname)
-	{
-		UserData *ud = _find_userdata(&(blah->root), dataname);
-		if(ud)
-			return ud->data;
-	}
-	return NULL;
-}
-
-/*
- * Add a callback to a timer event.
- * Parameters:
- *       interval: Milliseconds to delay between calls.
- *       sigfunc: The pointer to the function to be used as the callback.
- *       data: User data to be passed to the handler function.
- * Returns:
- *       Timer ID for use with dw_timer_disconnect(), 0 on error.
- */
-int API dw_timer_connect(int interval, void *sigfunc, void *data)
-{
-	if(sigfunc)
-	{
-		int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval);
-
-		if(timerid)
-		{
-			_new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data);
-			return timerid;
-		}
-	}
-	return 0;
-}
-
-/*
- * Removes timer callback.
- * Parameters:
- *       id: Timer ID returned by dw_timer_connect().
- */
-void API dw_timer_disconnect(int id)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	/* 0 is an invalid timer ID */
-	if(!id)
-		return;
-
-	WinStopTimer(dwhab, NULLHANDLE, id);
-
-	while(tmp)
-	{
-		if(tmp->id == id)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Add a callback to a window event.
- * 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.
- *       data: User data to be passed to the handler function.
- */
-void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
-{
-	ULONG message = 0, id = 0;
-
-	if(window && signame && sigfunc)
-	{
-		if((message = _findsigmessage(signame)) != 0)
-		{
-			/* Handle special case of the menu item */
-			if(message == WM_COMMAND && window < 65536)
-			{
-				char buffer[15];
-				HWND owner;
-
-				sprintf(buffer, "_dw_id%d", (int)window);
-				owner = (HWND)dw_window_get_data(hwndApp, buffer);
-
-				if(owner)
-				{
-					id = window;
-					window = owner;
-					dw_window_set_data(hwndApp, buffer, 0);
-				}
-				else
-				{
-					/* If it is a popup menu clear all entries */
-					dw_signal_disconnect_by_window(window);
-				}
-			}
-			_new_signal(message, window, id, sigfunc, data);
-		}
-	}
-}
-
-/*
- * Removes callbacks for a given window with given name.
- * Parameters:
- *       window: Window handle of callback to be removed.
- */
-void API dw_signal_disconnect_by_name(HWND window, char *signame)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-	ULONG message;
-
-	if(!window || !signame || (message = _findsigmessage(signame)) == 0)
-		return;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->message == message)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Removes all callbacks for a given window.
- * Parameters:
- *       window: Window handle of callback to be removed.
- */
-void API dw_signal_disconnect_by_window(HWND window)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Removes all callbacks for a given window with specified data.
- * Parameters:
- *       window: Window handle of callback to be removed.
- *       data: Pointer to the data to be compared against.
- */
-void API dw_signal_disconnect_by_data(HWND window, void *data)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->data == data)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-
+/*
+ * Dynamic Windows:
+ *          A GTK like implementation of the PM GUI
+ *
+ * (C) 2000-2011 Brian Smith <brian@dbsoft.org>
+ * (C) 2003-2008 Mark Hessling <m.hessling@qut.edu.au>
+ * (C) 2000 Achim Hasenmueller <achimha@innotek.de>
+ * (C) 2000 Peter Nielsen <peter@pmview.com>
+ * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit)
+ *
+ */
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#define INCL_GPI
+#define INCL_DEV
+#define INCL_SPL
+#define INCL_SPLDOSPRINT
+#define INCL_SPLERRORS
+
+#include <os2.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <process.h>
+#include <time.h>
+#include <io.h>
+#include <math.h>
+#ifndef __EMX__
+#include <direct.h>
+#endif
+#include <sys/time.h>
+#include <sys/stat.h>
+#include "dw.h"
+
+#define QWP_USER 0
+
+/* The toolkit headers don't seem to have this */
+BOOL APIENTRY WinStretchPointer(HPS hps, LONG x, LONG y, LONG cx, LONG cy, HPOINTER hptr, ULONG fs);
+
+MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
+MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
+MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2);
+void _do_resize(Box *thisbox, int x, int y);
+void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height);
+void _dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
+void _dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad, char *functionname);
+void _free_menu_data(HWND menu);
+
+char ClassName[] = "dynamicwindows";
+char SplitbarClassName[] = "dwsplitbar";
+char ScrollClassName[] = "dwscroll";
+char *DefaultFont = "9.WarpSans";
+
+HAB dwhab = 0;
+HMQ dwhmq = 0;
+DWTID _dwtid = 0;
+LONG _foreground = 0xAAAAAA, _background = DW_CLR_DEFAULT;
+
+HWND hwndApp = NULLHANDLE, hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE, hwndEmph = NULLHANDLE;
+HWND hwndTrayServer = NULLHANDLE, hwndTaskBar = NULLHANDLE;
+;
+PRECORDCORE pCoreEmph = NULL;
+ULONG aulBuffer[4];
+HWND lasthcnr = 0, lastitem = 0, popup = 0, desktop;
+HMOD wpconfig = 0;
+
+unsigned long _colors[] = {
+   CLR_BLACK,
+   CLR_DARKRED,
+   CLR_DARKGREEN,
+   CLR_BROWN,
+   CLR_DARKBLUE,
+   CLR_DARKPINK,
+   CLR_DARKCYAN,
+   CLR_PALEGRAY,
+   CLR_DARKGRAY,
+   CLR_RED,
+   CLR_GREEN,
+   CLR_YELLOW,
+   CLR_BLUE,
+   CLR_PINK,
+   CLR_CYAN,
+   CLR_WHITE
+};
+
+#define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40)
+
+#ifndef min
+#define min(a, b) (((a < b) ? a : b))
+#endif
+
+typedef struct _sighandler
+{
+   struct _sighandler   *next;
+   ULONG message;
+   HWND window;
+   int id;
+   void *signalfunction;
+   void *data;
+
+} SignalHandler;
+
+SignalHandler *Root = NULL;
+
+typedef struct
+{
+   ULONG message;
+   char name[30];
+
+} SignalList;
+
+/* List of signals and their equivilent OS/2 message */
+#define SIGNALMAX 16
+
+SignalList SignalTranslate[SIGNALMAX] = {
+   { WM_SIZE,         DW_SIGNAL_CONFIGURE },
+   { WM_CHAR,         DW_SIGNAL_KEY_PRESS },
+   { WM_BUTTON1DOWN,  DW_SIGNAL_BUTTON_PRESS },
+   { WM_BUTTON1UP,    DW_SIGNAL_BUTTON_RELEASE },
+   { WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
+   { WM_CLOSE,        DW_SIGNAL_DELETE },
+   { WM_PAINT,        DW_SIGNAL_EXPOSE },
+   { WM_COMMAND,      DW_SIGNAL_CLICKED },
+   { CN_ENTER,        DW_SIGNAL_ITEM_ENTER },
+   { CN_CONTEXTMENU,  DW_SIGNAL_ITEM_CONTEXT },
+   { LN_SELECT,       DW_SIGNAL_LIST_SELECT },
+   { CN_EMPHASIS,     DW_SIGNAL_ITEM_SELECT },
+   { WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
+   { SLN_SLIDERTRACK, DW_SIGNAL_VALUE_CHANGED },
+   { BKN_PAGESELECTED,DW_SIGNAL_SWITCH_PAGE },
+   { CN_EXPANDTREE,   DW_SIGNAL_TREE_EXPAND }
+};
+
+/* Internal function to keep a semi-unique ID within valid range */
+USHORT _GlobalID(void)
+{
+    static USHORT GlobalID = 9999;
+
+    GlobalID++;
+    if(GlobalID >= 65534)
+    {
+        GlobalID = 10000;
+    }
+    return GlobalID;
+}
+
+/* This function adds a signal handler callback into the linked list.
+ */
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
+{
+   SignalHandler *new = malloc(sizeof(SignalHandler));
+
+   new->message = message;
+   new->window = window;
+   new->id = id;
+   new->signalfunction = signalfunction;
+   new->data = data;
+   new->next = NULL;
+
+   if (!Root)
+      Root = new;
+   else
+   {
+      SignalHandler *prev = NULL, *tmp = Root;
+      while(tmp)
+      {
+         if(tmp->message == message &&
+            tmp->window == window &&
+            tmp->id == id &&
+            tmp->signalfunction == signalfunction)
+         {
+            tmp->data = data;
+            free(new);
+            return;
+         }
+         prev = tmp;
+         tmp = tmp->next;
+      }
+      if(prev)
+         prev->next = new;
+      else
+         Root = new;
+   }
+}
+
+/* Finds the message number for a given signal name */
+ULONG _findsigmessage(char *signame)
+{
+   int z;
+
+   for(z=0;z<SIGNALMAX;z++)
+   {
+      if(stricmp(signame, SignalTranslate[z].name) == 0)
+         return SignalTranslate[z].message;
+   }
+   return 0L;
+}
+
+typedef struct _CNRITEM
+{
+   MINIRECORDCORE rc;
+   HPOINTER       hptrIcon;
+   PVOID          user;
+   HTREEITEM      parent;
+
+} CNRITEM, *PCNRITEM;
+
+
+int _null_key(HWND window, int key, void *data)
+{
+   window = window; /* keep compiler happy */
+   key = key; /* keep compiler happy */
+   data = data; /* keep compiler happy */
+   return TRUE;
+}
+
+/* Find the desktop window handle */
+HWND _toplevel_window(HWND handle)
+{
+   HWND box, lastbox = WinQueryWindow(handle, QW_PARENT);
+
+   /* Find the toplevel window */
+   while((box = WinQueryWindow(lastbox, QW_PARENT)) != desktop && box > 0)
+   {
+      lastbox = box;
+   }
+   if(box > 0)
+      return lastbox;
+   return handle;
+}
+
+
+/* Returns height of specified window. */
+int _get_height(HWND handle)
+{
+   unsigned long height;
+   dw_window_get_pos_size(handle, NULL, NULL, NULL, &height);
+   return (int)height;
+}
+
+/* Find the height of the frame a desktop style window is sitting on */
+int _get_frame_height(HWND handle)
+{
+   while(handle)
+   {
+      HWND client;
+      if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
+      {
+            return _get_height(WinQueryWindow(handle, QW_PARENT));
+      }
+        handle = WinQueryWindow(handle, QW_PARENT);
+   }
+   return dw_screen_height();
+}
+
+/* A "safe" WinSendMsg() that tries multiple times in case the
+ * queue is blocked for one reason or another.
+ */
+MRESULT _dw_send_msg(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, int failure)
+{
+   MRESULT res;
+   int z = 0;
+
+   while((int)(res = WinSendMsg(hwnd, msg, mp1, mp2)) == failure)
+   {
+      z++;
+      if(z > 5000000)
+         return (MRESULT)failure;
+      dw_main_sleep(1);
+   }
+   return res;
+}
+
+/* Used in the slider and percent classes internally */
+unsigned int _dw_percent_get_range(HWND handle)
+{
+   return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
+}
+
+/* Return the entryfield child of a window */
+HWND _find_entryfield(HWND handle)
+{
+   HENUM henum;
+   HWND child, entry = 0;
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      char tmpbuf[100];
+
+      WinQueryClassName(child, 99, tmpbuf);
+
+      if(strncmp(tmpbuf, "#6", 3)==0)  /* Entryfield */
+      {
+         entry = child;
+         break;
+      }
+   }
+   WinEndEnumWindows(henum);
+   return entry;
+}
+
+/* This function changes the owner of buttons in to the
+ * dynamicwindows handle to fix a problem in notebooks.
+ */
+void _fix_button_owner(HWND handle, HWND dw)
+{
+   HENUM henum;
+   HWND child;
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      char tmpbuf[100];
+
+      WinQueryClassName(child, 99, tmpbuf);
+
+      if(strncmp(tmpbuf, "#3", 3)==0 && dw)  /* Button */
+         WinSetOwner(child, dw);
+      else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0)
+         dw = child;
+
+      _fix_button_owner(child, dw);
+   }
+   WinEndEnumWindows(henum);
+   return;
+}
+
+/* Free bitmap data associated with a window */
+void _free_bitmap(HWND handle)
+{
+   HBITMAP hbm = (HBITMAP)dw_window_get_data(handle, "_dw_bitmap");
+   HPS hps = (HPS)dw_window_get_data(handle, "_dw_hps");
+   HDC hdc = (HDC)dw_window_get_data(handle, "_dw_hdc");
+   HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap");
+   HPIXMAP disable = (HPIXMAP)dw_window_get_data(handle, "_dw_hpixmap_disabled");
+   HPOINTER icon = (HPOINTER)dw_window_get_data(handle, "_dw_button_icon");
+
+   if(icon)
+      WinDestroyPointer(icon);
+
+   if(pixmap)
+      dw_pixmap_destroy(pixmap);
+
+   if(disable)
+      dw_pixmap_destroy(disable);
+
+   if(hps)
+   {
+      GpiSetBitmap(hps, NULLHANDLE);
+      GpiAssociate(hps, NULLHANDLE);
+      GpiDestroyPS(hps);
+   }
+
+   if(hdc)
+      DevCloseDC(hdc);
+
+   if(hbm)
+      GpiDeleteBitmap(hbm);
+}
+
+/* This function removes any handlers on windows and frees
+ * the user memory allocated to it.
+ */
+void _free_window_memory(HWND handle)
+{
+   HENUM henum;
+   HWND child;
+   void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
+
+   dw_signal_disconnect_by_window(handle);
+
+   if((child = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
+      _free_menu_data(child);
+
+   if((child = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE)
+   {
+      Box *box = (Box *)WinQueryWindowPtr(child, QWP_USER);
+
+      if(box && !dw_window_get_data(handle, "_dw_box"))
+      {
+         if(box->count && box->items)
+            free(box->items);
+
+         WinSetWindowPtr(child, QWP_USER, 0);
+         free(box);
+      }
+   }
+
+   if(ptr)
+   {
+      WindowData *wd = (WindowData *)ptr;
+      char tmpbuf[100];
+
+      WinQueryClassName(handle, 99, tmpbuf);
+
+      if(strncmp(tmpbuf, "ColorSelectClass", 17)!=0)
+      {
+         /* If this window has an associate bitmap destroy it. */
+         _free_bitmap(handle);
+
+         if(strncmp(tmpbuf, "#1", 3)==0 && !WinWindowFromID(handle, FID_CLIENT))
+         {
+            Box *box = (Box *)ptr;
+
+            if(box->count && box->items)
+               free(box->items);
+         }
+         else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+         {
+            void *data = dw_window_get_data(handle, "_dw_percent");
+
+            if(data)
+               free(data);
+         }
+         else if(strncmp(tmpbuf, "#37", 4)==0)
+         {
+            dw_container_clear(handle, FALSE);
+            if(wd && dw_window_get_data(handle, "_dw_container"))
+            {
+               void *oldflags = wd->data;
+
+               wd->data = NULL;
+               free(oldflags);
+            }
+         }
+
+         if(wd->oldproc)
+            WinSubclassWindow(handle, wd->oldproc);
+
+         dw_window_set_data(handle, NULL, NULL);
+         WinSetWindowPtr(handle, QWP_USER, 0);
+         free(ptr);
+      }
+   }
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+      _free_window_memory(child);
+
+   WinEndEnumWindows(henum);
+   return;
+}
+
+void _free_menu_data(HWND menu)
+{
+   int i, count = (int)WinSendMsg(menu, MM_QUERYITEMCOUNT, 0, 0);
+
+   dw_signal_disconnect_by_name(menu, DW_SIGNAL_CLICKED);
+   _free_window_memory(menu);
+
+   for(i=0;i<count;i++)
+   {
+      SHORT menuid = (SHORT)WinSendMsg(menu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(i), 0);
+      MENUITEM mi;
+
+      /* Free the data associated with the ID */
+      if(menuid >= 30000)
+      {
+         char buffer[31] = {0};
+       
+         sprintf(buffer, "_dw_id%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_checkable%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_ischecked%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+         sprintf(buffer, "_dw_isdisabled%ld", menuid);
+         dw_window_set_data( hwndApp, buffer, NULL );
+      }
+      
+      /* Check any submenus */
+      if(WinSendMsg(menu, MM_QUERYITEM, MPFROMSHORT(menuid), MPFROMP(&mi))
+         && mi.hwndSubMenu)
+         _free_menu_data(mi.hwndSubMenu);
+   }
+}
+
+/* This function returns 1 if the window (widget) handle
+ * passed to it is a valid window that can gain input focus.
+ */
+int _validate_focus(HWND handle)
+{
+   char tmpbuf[100];
+
+   if(!handle)
+      return 0;
+
+   WinQueryClassName(handle, 99, tmpbuf);
+
+   if(!WinIsWindowEnabled(handle) ||
+      (strncmp(tmpbuf, "ColorSelectClass", 17) && dw_window_get_data(handle, "_dw_disabled")))
+      return 0;
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
+      strncmp(tmpbuf, "#3", 3)==0 ||  /* Button */
+      strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
+      strncmp(tmpbuf, "#7", 3)==0 ||  /* List box */
+      strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
+      strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */
+      strncmp(tmpbuf, "#37", 4)==0 || /* Container */
+      strncmp(tmpbuf, "#38", 4)== 0)  /* Slider */
+      return 1;
+   return 0;
+}
+
+int _focus_check_box(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=box->count-1;z>-1;z--)
+   {
+      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))
+            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] = "";
+
+            WinQueryClassName(box->items[z].hwnd, 99, tmpbuf);
+            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");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)WinQueryWindowPtr(mybox, QWP_USER);
+
+                  if(splitbox && _focus_check_box(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(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(scrollbox, handle, start == 3 ? 3 : 0, 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))
+            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] = "";
+
+            WinQueryClassName(box->items[z].hwnd, 99, 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;
+}
+
+/* This function finds the first widget in the
+ * layout and moves the current focus to it.
+ */
+int _initial_focus(HWND handle)
+{
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(handle, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+   else
+      return 1;
+
+   if(thisbox)
+      _focus_check_box(thisbox, handle, 3, 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)
+{
+   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(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);
+   }
+}
+
+/* This function will recursively search a box and add up the total height of it */
+void _count_size(HWND box, int type, int *xsize, int *xorigsize)
+{
+   int size = 0, origsize = 0, z;
+   Box *tmp = WinQueryWindowPtr(box, QWP_USER);
+
+   if(!tmp)
+   {
+      *xsize = *xorigsize = 0;
+      return;
+   }
+
+   if(type == tmp->type)
+   {
+      /* If the box is going in the direction we want, then we
+       * return the entire sum of the items.
+       */
+      for(z=0;z<tmp->count;z++)
+      {
+         if(tmp->items[z].type == TYPEBOX)
+         {
+            int s, os;
+
+            _count_size(tmp->items[z].hwnd, type, &s, &os);
+            size += s;
+            origsize += os;
+         }
+         else
+         {
+            size += (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
+            origsize += (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
+         }
+      }
+   }
+   else
+   {
+      /* If the box is not going in the direction we want, then we only
+       * want to return the maximum value.
+       */
+      int tmpsize = 0, tmporigsize = 0;
+
+      for(z=0;z<tmp->count;z++)
+      {
+         if(tmp->items[z].type == TYPEBOX)
+            _count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize);
+         else
+         {
+            tmpsize = (type == DW_HORZ ? tmp->items[z].width : tmp->items[z].height);
+            tmporigsize = (type == DW_HORZ ? tmp->items[z].origwidth : tmp->items[z].origheight);
+         }
+
+         if(tmpsize > size)
+            size = tmpsize;
+      }
+   }
+
+   *xsize = size;
+   *xorigsize = origsize;
+}
+
+
+/* Function: TrackRectangle
+ * Abstract: Tracks given rectangle.
+ *
+ * If rclBounds is NULL, then track rectangle on entire desktop.
+ * rclTrack is in window coorditates and will be mapped to
+ * desktop.
+ */
+
+BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds)
+{
+   TRACKINFO track;
+   APIRET rc;
+
+   track.cxBorder = 1;
+   track.cyBorder = 1;
+   track.cxGrid   = 1;
+   track.cyGrid   = 1;
+   track.cxKeyboard = 8;
+   track.cyKeyboard = 8;
+
+   if(!rclTrack)
+      return FALSE;
+
+   if(rclBounds)
+   {
+      track.rclBoundary = *rclBounds;
+   }
+   else
+   {
+      track.rclBoundary.yTop    =
+         track.rclBoundary.xRight  = 3000;
+      track.rclBoundary.yBottom =
+         track.rclBoundary.xLeft   = -3000;
+   }
+
+   track.rclTrack = *rclTrack;
+
+   WinMapWindowPoints(hwndBase,
+                  HWND_DESKTOP,
+                  (PPOINTL)&track.rclTrack,
+                  2);
+
+   track.ptlMinTrackSize.x = track.rclTrack.xRight
+      - track.rclTrack.xLeft;
+   track.ptlMinTrackSize.y = track.rclTrack.yTop
+      - track.rclTrack.yBottom;
+   track.ptlMaxTrackSize.x = track.rclTrack.xRight
+      - track.rclTrack.xLeft;
+   track.ptlMaxTrackSize.y = track.rclTrack.yTop
+      - track.rclTrack.yBottom;
+
+   track.fs = TF_MOVE | TF_ALLINBOUNDARY;
+
+   rc = WinTrackRect(HWND_DESKTOP, 0, &track);
+
+   if(rc)
+      *rclTrack = track.rclTrack;
+
+   return rc;
+}
+
+void _check_resize_notebook(HWND hwnd)
+{
+   char tmpbuf[100];
+
+   WinQueryClassName(hwnd, 99, tmpbuf);
+
+   /* If we have a notebook we resize the page again. */
+   if(strncmp(tmpbuf, "#40", 4)==0)
+   {
+      long x, y;
+      unsigned long width, height;
+      ULONG page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, 0, MPFROM2SHORT(BKA_FIRST, BKA_MAJOR));
+
+      while(page)
+      {
+         HWND pagehwnd = (HWND)WinSendMsg(hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0);
+         RECTL rc;
+
+         Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
+         if(pagebox)
+         {
+            dw_window_get_pos_size(hwnd, &x, &y, &width, &height);
+
+            rc.xLeft = x;
+            rc.yBottom = y;
+            rc.xRight = x + width;
+            rc.yTop = y + height;
+
+            WinSendMsg(hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
+
+            _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
+         }
+         page = (ULONG)WinSendMsg(hwnd, BKM_QUERYPAGEID, (MPARAM)page, MPFROM2SHORT(BKA_NEXT, BKA_MAJOR));
+      }
+
+   }
+}
+
+/* Return the OS/2 color from the DW color */
+unsigned long _internal_color(unsigned long color)
+{
+   if(color < 16)
+      return _colors[color];
+   return color;
+}
+
+unsigned long _os2_color(unsigned long color)
+{
+   return DW_RED_VALUE(color) << 16 | DW_GREEN_VALUE(color) << 8 | DW_BLUE_VALUE(color);
+}
+
+BOOL _MySetWindowPos(HWND hwnd, HWND parent, HWND behind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
+{
+   int height = _get_height(parent);
+
+   return WinSetWindowPos(hwnd, behind, x, height - y - cy, cx, cy, fl);
+}
+
+#define _DW_DEFAULT_SCROLLBAR_WIDTH 16
+
+/* This function calculates how much space the widgets and boxes require
+ * and does expansion as necessary.
+ */
+int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
+            int pass, int *usedpadx, int *usedpady)
+{
+   int z, currentx = 0, currenty = 0;
+   int uymax = 0, uxmax = 0;
+   int upymax = 0, upxmax = 0;
+   /* Used for the SIZEEXPAND */
+   int nux = *usedx, nuy = *usedy;
+   int nupx = *usedpadx, nupy = *usedpady;
+
+   (*usedx) += (thisbox->pad * 2);
+   (*usedy) += (thisbox->pad * 2);
+
+   if(thisbox->grouphwnd)
+   {
+      char *text = dw_window_get_text(thisbox->grouphwnd);
+
+      thisbox->grouppady = 0;
+
+      if(text)
+      {
+         dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
+         dw_free(text);
+      }
+
+      if(thisbox->grouppady)
+         thisbox->grouppady += 3;
+      else
+         thisbox->grouppady = 6;
+
+      thisbox->grouppadx = 6;
+
+      (*usedx) += thisbox->grouppadx;
+      (*usedpadx) += thisbox->grouppadx;
+      (*usedy) += thisbox->grouppady;
+      (*usedpady) += thisbox->grouppady;
+   }
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         int initialx, initialy;
+         Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+         initialx = x - (*usedx);
+         initialy = y - (*usedy);
+
+         if(tmp)
+         {
+            int newx, newy;
+            int nux = *usedx, nuy = *usedy;
+            int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
+
+            /* On the second pass we know how big the box needs to be and how
+             * much space we have, so we can calculate a ratio for the new box.
+             */
+            if(pass == 2)
+            {
+               int deep = *depth + 1;
+
+               _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
+
+               tmp->upx = upx - *usedpadx;
+               tmp->upy = upy - *usedpady;
+
+               newx = x - nux;
+               newy = y - nuy;
+
+               tmp->width = thisbox->items[z].width = initialx - newx;
+               tmp->height = thisbox->items[z].height = initialy - newy;
+
+               tmp->parentxratio = thisbox->xratio;
+               tmp->parentyratio = thisbox->yratio;
+
+               tmp->parentpad = tmp->pad;
+
+               /* Just in case */
+               tmp->xratio = thisbox->xratio;
+               tmp->yratio = thisbox->yratio;
+
+               if(thisbox->type == DW_VERT)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
+
+                  if((thisbox->items[z].width - tmppad)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].width-tmp->upx)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
+               }
+               if(thisbox->type == DW_HORZ)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
+
+                  if((thisbox->items[z].height-tmppad)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].height-tmp->upy)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
+               }
+
+               nux = *usedx; nuy = *usedy;
+               upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
+            }
+
+            (*depth)++;
+
+            _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
+
+            (*depth)--;
+
+            newx = x - nux;
+            newy = y - nuy;
+
+            tmp->minwidth = thisbox->items[z].width = initialx - newx;
+            tmp->minheight = thisbox->items[z].height = initialy - newy;
+         }
+      }
+
+      if(pass > 1 && *depth > 0)
+      {
+         if(thisbox->type == DW_VERT)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
+
+            if((thisbox->minwidth-tmppad) == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
+         }
+         else
+         {
+            if(thisbox->minwidth-thisbox->upx == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
+         }
+
+         if(thisbox->type == DW_HORZ)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
+
+            if((thisbox->minheight-tmppad) == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
+         }
+         else
+         {
+            if(thisbox->minheight-thisbox->upy == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
+         }
+
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+            if(tmp)
+            {
+               tmp->parentxratio = thisbox->items[z].xratio;
+               tmp->parentyratio = thisbox->items[z].yratio;
+            }
+         }
+      }
+      else
+      {
+         thisbox->items[z].xratio = thisbox->xratio;
+         thisbox->items[z].yratio = thisbox->yratio;
+      }
+
+      if(thisbox->type == DW_VERT)
+      {
+         int itemwidth = thisbox->items[z].width + (thisbox->items[z].pad*2);
+
+         if(itemwidth > uxmax)
+            uxmax = itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+         {
+            if(itemwidth > upxmax)
+               upxmax = itemwidth;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upxmax)
+               upxmax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].width == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].width = */
+         }
+         else
+         {
+            (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
+            else
+               (*usedpadx) += thisbox->items[z].pad*2;
+         }
+      }
+      if(thisbox->type == DW_HORZ)
+      {
+         int itemheight = thisbox->items[z].height + (thisbox->items[z].pad*2);
+
+         if(itemheight > uymax)
+            uymax = itemheight;
+         if(thisbox->items[z].vsize != SIZEEXPAND)
+         {
+            if(itemheight > upymax)
+               upymax = itemheight;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upymax)
+               upymax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].height == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].height = */
+         }
+         else
+         {
+            (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
+            else
+               (*usedpady) += thisbox->items[z].pad*2;
+         }
+      }
+   }
+
+   (*usedx) += uxmax;
+   (*usedy) += uymax;
+   (*usedpadx) += upxmax;
+   (*usedpady) += upymax;
+
+   currentx += thisbox->pad;
+   currenty += thisbox->pad;
+
+   if(thisbox->grouphwnd)
+   {
+      currentx += 3;
+      currenty += thisbox->grouppady - 3;
+   }
+
+   /* The second pass is for expansion and actual placement. */
+   if(pass > 1)
+   {
+      /* Any SIZEEXPAND items should be set to uxmax/uymax */
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
+            thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
+         if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
+            thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
+         /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+
+            if(tmp)
+            {
+               if(*depth > 0)
+               {
+                  float calcval;
+
+                  if(thisbox->type == DW_VERT)
+                  {
+                     calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->xratio = thisbox->xratio;
+                     else
+                        tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->width = thisbox->items[z].width;
+                  }
+                  if(thisbox->type == DW_HORZ)
+                  {
+                     calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->yratio = thisbox->yratio;
+                     else
+                        tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->height = thisbox->items[z].height;
+                  }
+               }
+
+               (*depth)++;
+
+               _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
+
+               (*depth)--;
+
+            }
+         }
+      }
+
+      for(z=0;z<(thisbox->count);z++)
+      {
+         int height = thisbox->items[z].height;
+         int width = thisbox->items[z].width;
+         int pad = thisbox->items[z].pad;
+         HWND handle = thisbox->items[z].hwnd;
+         int vectorx, vectory;
+
+         /* When upxmax != pad*2 then ratios are incorrect. */
+         vectorx = (int)((width*thisbox->items[z].xratio)-width);
+         vectory = (int)((height*thisbox->items[z].yratio)-height);
+
+         if(width > 0 && height > 0)
+         {
+            char tmpbuf[100];
+            /* This is a hack to fix rounding of the sizing */
+            if(*depth == 0)
+            {
+               vectorx++;
+               vectory++;
+            }
+
+            /* If this item isn't going to expand... reset the vectors to 0 */
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               vectory = 0;
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               vectorx = 0;
+
+            WinQueryClassName(handle, 99, tmpbuf);
+
+            if(strncmp(tmpbuf, "#2", 3)==0)
+            {
+               HWND frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
+               /* Make the combobox big enough to drop down. :) */
+               WinSetWindowPos(handle, HWND_TOP, 0, -100,
+                           width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               _MySetWindowPos(frame, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+            }
+            else if(strncmp(tmpbuf, "#6", 3)==0)
+            {
+               /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3,
+                           (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+            }
+            else if(strncmp(tmpbuf, "#40", 5)==0)
+            {
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               _check_resize_notebook(handle);
+            }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+            {
+                /* Handle special case of scrollbox */
+                int cx = width + vectorx;
+                int cy = height + vectory;
+                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                HWND box = (HWND)dw_window_get_data(handle, "_dw_resizebox");
+                HWND client = WinWindowFromID(handle, FID_CLIENT);
+                HWND vscroll = WinWindowFromID(handle, FID_VERTSCROLL);
+                HWND hscroll = WinWindowFromID(handle, FID_HORZSCROLL);
+                Box *contentbox = (Box *)WinQueryWindowPtr(box, QWP_USER);
+                int origx, origy;
+                unsigned int hpos = (unsigned int)WinSendMsg(hscroll, SBM_QUERYPOS, 0, 0);
+                unsigned int vpos = (unsigned int)WinSendMsg(vscroll, SBM_QUERYPOS, 0, 0);
+
+                /* Position the scrollbox parts */
+                _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad, cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(client, HWND_TOP, 0, _DW_DEFAULT_SCROLLBAR_WIDTH, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(hscroll, HWND_TOP, 0, 0, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+                WinSetWindowPos(vscroll, HWND_TOP, cx - _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, _DW_DEFAULT_SCROLLBAR_WIDTH, cy - _DW_DEFAULT_SCROLLBAR_WIDTH, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                origx = cx = cx - _DW_DEFAULT_SCROLLBAR_WIDTH;
+                origy = cy = cy - _DW_DEFAULT_SCROLLBAR_WIDTH;
+
+                /* Get the required space for the box */
+                _resize_box(contentbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+                if(cx < usedx)
+                {
+                    cx = usedx;
+                }
+                if(cy < usedy)
+                {
+                    cy = usedy;
+                }
+
+                /* Setup vertical scroller */
+                WinSendMsg(vscroll, SBM_SETSCROLLBAR, (MPARAM)vpos, MPFROM2SHORT(0, (unsigned short)usedy - origy));
+                WinSendMsg(vscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origy, usedy), 0);
+                if(vpos > usedy)
+                {
+                    vpos = usedy;
+                    WinSendMsg(vscroll, SBM_SETPOS, (MPARAM)vpos, 0);
+                }
+
+                /* Setup horizontal scroller */
+                WinSendMsg(hscroll, SBM_SETSCROLLBAR, (MPARAM)hpos, MPFROM2SHORT(0, (unsigned short)usedx - origx));
+                WinSendMsg(hscroll, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)origx, usedx), 0);
+                if(hpos > usedx)
+                {
+                    hpos = usedx;
+                    WinSendMsg(hscroll, SBM_SETPOS, (MPARAM)hpos, 0);
+                }
+
+                /* Position the scrolled box */
+                WinSetWindowPos(box, HWND_TOP, 0, -(cy - origy), cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+                dw_window_set_data(handle, "_dw_cy", (void *)(cy - origy));
+
+                /* Layout the content of the scrollbox */
+                _do_resize(contentbox, cx, cy);
+            }
+            else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            {
+               /* Then try the bottom or right box */
+               float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+               int type = (int)dw_window_get_data(handle, "_dw_type");
+               int cx = width + vectorx;
+               int cy = height + vectory;
+
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           cx, cy, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+
+               if(cx > 0 && cy > 0 && percent)
+                  _handle_splitbar_resize(handle, *percent, type, cx, cy);
+            }
+            else
+            {
+               _MySetWindowPos(handle, thisbox->hwnd, HWND_TOP, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER);
+               if(thisbox->items[z].type == TYPEBOX)
+               {
+                  Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER);
+
+                  if(boxinfo && boxinfo->grouphwnd)
+                     WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0,
+                                 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE);
+
+               }
+
+            }
+
+            if(thisbox->type == DW_HORZ)
+               currentx += width + vectorx + (pad * 2);
+            if(thisbox->type == DW_VERT)
+               currenty += height + vectory + (pad * 2);
+         }
+      }
+   }
+   return 0;
+}
+
+void _do_resize(Box *thisbox, int x, int y)
+{
+   if(x != 0 && y != 0)
+   {
+      if(thisbox)
+      {
+         int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+         if(usedx-usedpadx == 0 || usedy-usedpady == 0)
+            return;
+
+         thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
+         thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
+
+         usedx = usedy = usedpadx = usedpady = depth = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
+      }
+   }
+}
+
+/* This procedure handles WM_QUERYTRACKINFO requests from the frame */
+MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(hWnd, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox && !thisbox->titlebar)
+   {
+      switch(msg)
+      {
+      case WM_QUERYTRACKINFO:
+         {
+            if(blah && *blah)
+            {
+               PTRACKINFO ptInfo;
+               int res;
+               PFNWP myfunc = *blah;
+               res = (int)myfunc(hWnd, msg, mp1, mp2);
+
+               ptInfo = (PTRACKINFO)(mp2);
+
+               ptInfo->ptlMinTrackSize.y = 8;
+               ptInfo->ptlMinTrackSize.x = 8;
+
+               return (MRESULT)res;
+            }
+         }
+      }
+   }
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+void _Top(HPS hpsPaint, RECTL rclPaint)
+{
+   POINTL ptl1, ptl2;
+
+   ptl1.x = rclPaint.xLeft;
+   ptl2.y = ptl1.y = rclPaint.yTop - 1;
+   ptl2.x = rclPaint.xRight - 1;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
+}
+
+/* Left hits the bottom */
+void _Left(HPS hpsPaint, RECTL rclPaint)
+{
+   POINTL ptl1, ptl2;
+
+   ptl2.x = ptl1.x = rclPaint.xLeft;
+   ptl1.y = rclPaint.yTop - 1;
+   ptl2.y = rclPaint.yBottom;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
+}
+
+void _Bottom(HPS hpsPaint, RECTL rclPaint)
+{
+   POINTL ptl1, ptl2;
+
+   ptl1.x = rclPaint.xRight - 1;
+   ptl1.y = ptl2.y = rclPaint.yBottom;
+   ptl2.x = rclPaint.xLeft;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
+}
+
+/* Right hits the top */
+void _Right(HPS hpsPaint, RECTL rclPaint)
+{
+   POINTL ptl1, ptl2;
+
+   ptl2.x = ptl1.x = rclPaint.xRight - 1;
+   ptl1.y = rclPaint.yBottom + 1;
+   ptl2.y = rclPaint.yTop - 1;
+   GpiMove(hpsPaint, &ptl1);
+   GpiLine(hpsPaint, &ptl2);
+}
+
+/* This procedure handles drawing of a status border */
+MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   if(msg == WM_MOUSEMOVE && _wndproc(hWnd, msg, mp1, mp2))
+      return MPFROMSHORT(FALSE);
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+
+      switch(msg)
+      {
+      case WM_PAINT:
+         {
+            HPS hpsPaint;
+            RECTL rclPaint;
+            char buf[1024];
+
+            hpsPaint = WinBeginPaint(hWnd, 0, 0);
+            WinQueryWindowRect(hWnd, &rclPaint);
+            WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+
+            GpiSetColor(hpsPaint, CLR_DARKGRAY);
+            _Top(hpsPaint, rclPaint);
+            _Left(hpsPaint, rclPaint);
+
+            GpiSetColor(hpsPaint, CLR_WHITE);
+            _Right(hpsPaint, rclPaint);
+            _Bottom(hpsPaint, rclPaint);
+
+            WinQueryWindowText(hWnd, 1024, buf);
+            rclPaint.xLeft += 3;
+            rclPaint.xRight--;
+            rclPaint.yTop--;
+            rclPaint.yBottom++;
+
+            GpiSetColor(hpsPaint, CLR_BLACK);
+            WinDrawText(hpsPaint, -1, buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
+            WinEndPaint(hpsPaint);
+
+            return (MRESULT)TRUE;
+         }
+      }
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* This procedure handles pointer changes */
+MRESULT EXPENTRY _textproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   if(msg == WM_MOUSEMOVE &&_wndproc(hWnd, msg, mp1, mp2))
+      return MPFROMSHORT(FALSE);
+
+   if(blah && *blah)
+   {
+      PFNWP myfunc = *blah;
+
+      return myfunc(hWnd, msg, mp1, mp2);
+   }
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* This procedure handles scrollbox */
+MRESULT EXPENTRY _scrollwndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   switch(msg)
+   {
+      case WM_PAINT:
+         {
+            HPS hpsPaint;
+            RECTL rclPaint;
+
+            hpsPaint = WinBeginPaint(hWnd, 0, 0);
+            WinQueryWindowRect(hWnd, &rclPaint);
+            WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY);
+            WinEndPaint(hpsPaint);
+
+            break;
+         }
+   case WM_HSCROLL:
+   case WM_VSCROLL:
+      {
+         MPARAM res;
+         int *pos, min, max, page, which = SHORT2FROMMP(mp2);
+         HWND handle, client = WinWindowFromID(hWnd, FID_CLIENT);
+         HWND box = (HWND)dw_window_get_data(hWnd, "_dw_resizebox");
+         HWND hscroll = WinWindowFromID(hWnd, FID_HORZSCROLL);
+         HWND vscroll = WinWindowFromID(hWnd, FID_VERTSCROLL);
+            int hpos = dw_scrollbar_get_pos(hscroll);
+            int vpos = dw_scrollbar_get_pos(vscroll);
+         int cy = (int)dw_window_get_data(hWnd, "_dw_cy");
+            RECTL rect;
+
+         WinQueryWindowRect(client, &rect);
+
+         if(msg == WM_VSCROLL)
+         {
+            page = rect.yTop - rect.yBottom;
+            handle = vscroll;
+                pos = &vpos;
+         }
+         else
+         {
+            page = rect.xRight - rect.xLeft;
+            handle = hscroll;
+                pos = &hpos;
+         }
+
+         res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
+         min = SHORT1FROMMP(res);
+         max = SHORT2FROMMP(res);
+
+         switch(which)
+         {
+         case SB_SLIDERTRACK:
+                *pos = SHORT1FROMMP(mp2);
+                break;
+         case SB_LINEUP:
+            (*pos)--;
+            if(*pos < min)
+               *pos = min;
+                break;
+         case SB_LINEDOWN:
+            (*pos)++;
+            if(*pos > max)
+               *pos = max;
+                break;
+         case SB_PAGEUP:
+            (*pos) -= page;
+            if(*pos < min)
+               *pos = min;
+                break;
+         case SB_PAGEDOWN:
+            (*pos) += page;
+            if(*pos > max)
+               *pos = max;
+            break;
+         }
+            WinSendMsg(handle, SBM_SETPOS, (MPARAM)*pos, 0);
+            /* Position the scrolled box */
+            WinSetWindowPos(box, HWND_TOP, -hpos, -(cy - vpos), 0, 0, SWP_MOVE);
+         break;
+      }
+   }
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+void _click_default(HWND handle)
+{
+   char tmpbuf[100];
+
+   WinQueryClassName(handle, 99, tmpbuf);
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if(strncmp(tmpbuf, "#3", 3)==0)
+   {
+      /* Generate click on default item */
+      SignalHandler *tmp = Root;
+
+      /* Find any callbacks for this function */
+      while(tmp)
+      {
+         if(tmp->message == WM_COMMAND)
+         {
+            int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+            /* Make sure it's the right window, and the right ID */
+            if(tmp->window == handle)
+            {
+               clickfunc(tmp->window, tmp->data);
+               tmp = NULL;
+            }
+         }
+         if(tmp)
+            tmp= tmp->next;
+      }
+   }
+   else
+      WinSetFocus(HWND_DESKTOP, handle);
+}
+
+#define ENTRY_CUT   60901
+#define ENTRY_COPY  60902
+#define ENTRY_PASTE 60903
+#define ENTRY_UNDO  60904
+#define ENTRY_SALL  60905
+
+/* Originally just intended for entryfields, it now serves as a generic
+ * procedure for handling TAB presses to change input focus on controls.
+ */
+MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+   char tmpbuf[100];
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   WinQueryClassName(hWnd, 99, tmpbuf);
+
+   /* These are the window classes which should get a menu */
+   if(strncmp(tmpbuf, "#2", 3)==0 ||  /* Combobox */
+      strncmp(tmpbuf, "#6", 3)==0 ||  /* Entryfield */
+      strncmp(tmpbuf, "#10", 4)==0 || /* MLE */
+      strncmp(tmpbuf, "#32", 4)==0)   /* Spinbutton */
+   {
+      switch(msg)
+      {
+      case WM_CONTEXTMENU:
+         {
+            HMENUI hwndMenu = dw_menu_new(0L);
+            long x, y;
+
+            if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))
+            {
+               dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, -1, 0L);
+               dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L);
+            }
+            dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 0L, TRUE, -1, 0L);
+            if((strncmp(tmpbuf, "#10", 4)!=0  && !dw_window_get_data(hWnd, "_dw_disabled")) || (strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0)))
+            {
+               dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, -1, 0L);
+               dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, -1, 0L);
+            }
+            dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, -1, 0L);
+            dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 0L, TRUE, -1, 0L);
+
+            WinSetFocus(HWND_DESKTOP, hWnd);
+            dw_pointer_query_pos(&x, &y);
+            dw_menu_popup(&hwndMenu, hWnd, x, y);
+         }
+         break;
+      case WM_COMMAND:
+         {
+            ULONG command = COMMANDMSG(&msg)->cmd;
+
+            /* MLE */
+            if(strncmp(tmpbuf, "#10", 4)==0)
+            {
+               switch(command)
+               {
+               case ENTRY_CUT:
+                  return WinSendMsg(hWnd, MLM_CUT, 0, 0);
+               case ENTRY_COPY:
+                  return WinSendMsg(hWnd, MLM_COPY, 0, 0);
+               case ENTRY_PASTE:
+                  return WinSendMsg(hWnd, MLM_PASTE, 0, 0);
+               case ENTRY_UNDO:
+                  return WinSendMsg(hWnd, MLM_UNDO, 0, 0);
+               case ENTRY_SALL:
+                  {
+                     ULONG len = (ULONG)WinSendMsg(hWnd, MLM_QUERYTEXTLENGTH, 0, 0);
+                     return WinSendMsg(hWnd, MLM_SETSEL, 0, (MPARAM)len);
+                  }
+               }
+            }
+            else /* Other */
+            {
+               HWND handle = hWnd;
+
+               /* Get the entryfield handle from multi window controls */
+               if(strncmp(tmpbuf, "#2", 3)==0)
+                  handle = WinWindowFromID(hWnd, 667);
+
+               if(handle)
+               {
+                  switch(command)
+                  {
+                  case ENTRY_CUT:
+                     return WinSendMsg(handle, EM_CUT, 0, 0);
+                  case ENTRY_COPY:
+                     return WinSendMsg(handle, EM_COPY, 0, 0);
+                  case ENTRY_PASTE:
+                     return WinSendMsg(handle, EM_PASTE, 0, 0);
+                  case ENTRY_SALL:
+                     {
+                        LONG len = WinQueryWindowTextLength(hWnd);
+                        return WinSendMsg(hWnd, EM_SETSEL, MPFROM2SHORT(0, (SHORT)len), 0);
+                     }
+                  }
+               }
+            }
+         }
+         break;
+      }
+   }
+
+   switch(msg)
+   {
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      {
+         if(strncmp(tmpbuf, "#32", 4)==0)
+            _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
+      }
+      break;
+   case WM_CONTROL:
+      {
+         if(strncmp(tmpbuf, "#38", 4)==0)
+            _run_event(hWnd, msg, mp1, mp2);
+      }
+      break;
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
+         _click_default(blah->clickdefault);
+      /* When you hit escape we get this value and the
+       * window hangs for reasons unknown. (in an MLE)
+       */
+      else if(SHORT1FROMMP(mp2) == 283)
+         return (MRESULT)TRUE;
+
+      break;
+   case WM_SIZE:
+      {
+         /* If it's a slider... make sure it shows the correct value */
+         if(strncmp(tmpbuf, "#38", 4)==0)
+            WinPostMsg(hWnd, WM_USER+7, 0, 0);
+      }
+      break;
+   case WM_USER+7:
+      {
+         int pos = (int)dw_window_get_data(hWnd, "_dw_slider_value");
+         WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)pos);
+      }
+      break;
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/*  Deal with combobox specifics and enhancements */
+MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER);
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CONTEXTMENU:
+   case WM_COMMAND:
+      return _entryproc(hWnd, msg, mp1, mp2);
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      /* A Similar problem to the MLE, if ESC just return */
+      if(SHORT1FROMMP(mp2) == 283)
+         return (MRESULT)TRUE;
+      break;
+   }
+
+   if(blah && blah->oldproc)
+      return blah->oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* Enhance the standard OS/2 MLE control */
+MRESULT EXPENTRY _mleproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   switch(msg)
+   {
+   case WM_VSCROLL:
+      if(SHORT2FROMMP(mp2) == SB_SLIDERTRACK)
+      {
+         USHORT pos = SHORT1FROMMP(mp2);
+
+         WinSendMsg(hWnd, msg, mp1, MPFROM2SHORT(pos, SB_SLIDERPOSITION));
+      }
+      break;
+   }
+   return _entryproc(hWnd, msg, mp1, mp2);
+}
+
+/* Handle special messages for the spinbutton's entryfield */
+MRESULT EXPENTRY _spinentryproc(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_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CONTEXTMENU:
+   case WM_COMMAND:
+      return _entryproc(hWnd, msg, mp1, mp2);
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+int _dw_int_pos(HWND hwnd)
+{
+   int pos = (int)dw_window_get_data(hwnd, "_dw_percent_value");
+   int range = _dw_percent_get_range(hwnd);
+   float fpos = (float)pos;
+   float frange = (float)range;
+   float fnew = (fpos/1000.0)*frange;
+   return (int)fnew;
+}
+
+void _dw_int_set(HWND hwnd, int pos)
+{
+   int inew, range = _dw_percent_get_range(hwnd);
+   if(range)
+   {
+      float fpos = (float)pos;
+      float frange = (float)range;
+      float fnew = (fpos/frange)*1000.0;
+      inew = (int)fnew;
+      dw_window_set_data(hwnd, "_dw_percent_value", (void *)inew);
+   }
+}
+
+/* Handle size changes in the percent class */
+MRESULT EXPENTRY _percentproc(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_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_SIZE:
+      WinPostMsg(hWnd, WM_USER+7, 0, 0);
+      break;
+   case WM_USER+7:
+      WinSendMsg(hWnd, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)_dw_int_pos(hWnd));
+      break;
+   }
+
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* Handle correct painting of a combobox with the WS_CLIPCHILDREN
+ * flag enabled, and also handle TABs to switch input focus.
+ */
+MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+   PFNWP oldproc = 0;
+
+   if(blah)
+      oldproc = blah->oldproc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault)
+         _click_default(blah->clickdefault);
+      break;
+   case WM_BUTTON1DBLCLK:
+   case WM_BUTTON2DBLCLK:
+   case WM_BUTTON3DBLCLK:
+      if(dw_window_get_data(hWnd, "_dw_disabled"))
+         return (MRESULT)TRUE;
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
+         return (MRESULT)TRUE;
+      _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
+      break;
+   case WM_SETFOCUS:
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   case WM_PAINT:
+      {
+         HWND entry, frame = (HWND)dw_window_get_data(hWnd, "_dw_combo_box"), parent = WinQueryWindow(frame, QW_PARENT);
+         HPS hpsPaint;
+         POINTL ptl;
+         unsigned long width, height, thumbheight = 0;
+         ULONG color;
+
+         if((entry = (HWND)dw_window_get_data(hWnd, "_dw_comboentry")) != NULLHANDLE)
+            dw_window_get_pos_size(entry, 0, 0, 0, &thumbheight);
+
+         if(!thumbheight)
+            thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW);
+
+         /* Add 6 because it has a thick border like the entryfield */
+         thumbheight += 6;
+
+         color = (ULONG)dw_window_get_data(parent, "_dw_fore");
+         dw_window_get_pos_size(hWnd, 0, 0, &width, &height);
+
+         if(height > thumbheight)
+         {
+            hpsPaint = WinGetPS(hWnd);
+            if(color)
+               GpiSetColor(hpsPaint, _internal_color(color-1));
+            else
+               GpiSetColor(hpsPaint, CLR_PALEGRAY);
+
+            ptl.x = ptl.y = 0;
+            GpiMove(hpsPaint, &ptl);
+
+            ptl.x = width;
+            ptl.y = height - thumbheight;
+            GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0);
+
+            WinReleasePS(hpsPaint);
+         }
+      }
+      break;
+   }
+   if(oldproc)
+      return oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+void _GetPPFont(HWND hwnd, char *buff)
+{
+    ULONG AttrFound;
+    BYTE  AttrValue[128];
+    ULONG cbRetLen;
+
+    cbRetLen = WinQueryPresParam(hwnd,
+                                 PP_FONTNAMESIZE,
+                                 0,
+                                 &AttrFound,
+                                 sizeof(AttrValue),
+                                 &AttrValue,
+                                 QPF_NOINHERIT);
+
+    if(PP_FONTNAMESIZE == AttrFound && cbRetLen)
+    {
+        memcpy(buff, AttrValue, cbRetLen);
+    }
+}
+
+int _HandleScroller(HWND handle, int pos, int which)
+{
+   MPARAM res;
+   int min, max, page;
+
+   if(which == SB_SLIDERTRACK)
+      return pos;
+
+   pos = dw_scrollbar_get_pos(handle);
+   res = WinSendMsg(handle, SBM_QUERYRANGE, 0, 0);
+
+   min = SHORT1FROMMP(res);
+   max = SHORT2FROMMP(res);
+   page = (int)dw_window_get_data(handle, "_dw_scrollbar_visible");
+
+   switch(which)
+   {
+   case SB_LINEUP:
+      pos = pos - 1;
+      if(pos < min)
+         pos = min;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_LINEDOWN:
+      pos = pos + 1;
+      if(pos > max)
+         pos = max;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_PAGEUP:
+      pos = pos - page;
+      if(pos < min)
+         pos = min;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   case SB_PAGEDOWN:
+      pos = pos + page;
+      if(pos > max)
+         pos = max;
+      dw_scrollbar_set_pos(handle, pos);
+      return pos;
+   }
+   return -1;
+}
+
+void _clear_emphasis(void)
+{
+   if(hwndEmph && WinIsWindow(dwhab, hwndEmph) && pCoreEmph)
+      WinSendMsg(hwndEmph, CM_SETRECORDEMPHASIS, pCoreEmph, MPFROM2SHORT(FALSE, CRA_SOURCE));
+   hwndEmph = NULLHANDLE;
+   pCoreEmph = NULL;
+}
+
+/* Find the desktop window handle */
+HWND _menu_owner(HWND handle)
+{
+   HWND menuowner = NULLHANDLE, lastowner = (HWND)dw_window_get_data(handle, "_dw_owner");
+   int menubar = (int)dw_window_get_data(handle, "_dw_menubar");
+
+   /* Find the toplevel window */
+   while(!menubar && (menuowner = (HWND)dw_window_get_data(lastowner, "_dw_owner")) != NULLHANDLE)
+   {
+      menubar = (int)dw_window_get_data(lastowner, "_dw_menubar");
+      lastowner = menuowner;
+   }
+   if(menuowner && menubar)
+   {
+      HWND client = WinWindowFromID(menuowner, FID_CLIENT);
+
+      return client ? client : menuowner;
+   }
+   return NULLHANDLE;
+}
+
+MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   int result = -1;
+   SignalHandler *tmp = Root;
+   ULONG origmsg = msg;
+
+   if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN)
+      msg = WM_BUTTON1DOWN;
+   if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP)
+      msg = WM_BUTTON1UP;
+   if(msg == WM_VSCROLL || msg == WM_HSCROLL)
+      msg = WM_CONTROL;
+
+   /* Find any callbacks for this function */
+   while(tmp)
+   {
+      if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1)
+      {
+         switch(msg)
+         {
+         case WM_SETFOCUS:
+            {
+               if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1))
+               {
+                  int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+                  if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd)
+                  {
+                     result = setfocusfunc(tmp->window, tmp->data);
+                     tmp = NULL;
+                  }
+               }
+            }
+            break;
+         case WM_TIMER:
+            {
+               int (* API timerfunc)(void *) = (int (* API)(void *))tmp->signalfunction;
+               if(tmp->id == (int)mp1)
+               {
+                  if(!timerfunc(tmp->data))
+                     dw_timer_disconnect(tmp->id);
+                  tmp = NULL;
+               }
+               result = 0;
+            }
+            break;
+         case WM_SIZE:
+            {
+               int (* API sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))tmp->signalfunction;
+
+               if((hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) && SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2))
+               {
+                  result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_BUTTON1DOWN:
+            {
+               POINTS pts = (*((POINTS*)&mp1));
+               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int button = 0;
+
+                  switch(origmsg)
+                  {
+                  case WM_BUTTON1DOWN:
+                     button = 1;
+                     break;
+                  case WM_BUTTON2DOWN:
+                     button = 2;
+                     break;
+                  case WM_BUTTON3DOWN:
+                     button = 3;
+                     break;
+                  }
+
+                  result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_BUTTON1UP:
+            {
+               POINTS pts = (*((POINTS*)&mp1));
+               int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int button = 0;
+
+                  switch(origmsg)
+                  {
+                  case WM_BUTTON1UP:
+                     button = 1;
+                     break;
+                  case WM_BUTTON2UP:
+                     button = 2;
+                     break;
+                  case WM_BUTTON3UP:
+                     button = 3;
+                     break;
+                  }
+
+                  result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_MOUSEMOVE:
+            {
+               int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window)
+               {
+                  int keys = 0;
+                  SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1);
+
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)
+                     keys = DW_BUTTON1_MASK;
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
+                     keys |= DW_BUTTON2_MASK;
+                  if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
+                     keys |= DW_BUTTON3_MASK;
+
+                  result = motionfunc(tmp->window, x, _get_height(hWnd) - y, keys, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CHAR:
+            {
+               int (* API keypressfunc)(HWND, char, int, int, void *) = (int (* API)(HWND, char, int, int, void *))tmp->signalfunction;
+
+               if((hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window) && !(SHORT1FROMMP(mp1) & KC_KEYUP))
+               {
+                  int vk;
+                  char ch = 0;
+
+                  if(SHORT1FROMMP(mp1) & KC_CHAR)
+                     ch = (char)SHORT1FROMMP(mp2);
+                  if(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)
+                     vk = SHORT2FROMMP(mp2);
+                  else
+                     vk = SHORT1FROMMP(mp2) + 128;
+
+                  /* This is a hack to fix shift presses showing
+                   * up as tabs!
+                   */
+                  if(ch == '\t' && !(SHORT1FROMMP(mp1) & KC_CHAR))
+                  {
+                     ch = 0;
+                     vk = VK_SHIFT;
+                  }
+
+                  result = keypressfunc(tmp->window, ch, vk,
+                                   SHORT1FROMMP(mp1) & (KC_ALT | KC_SHIFT | KC_CTRL), tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CLOSE:
+            {
+               int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+
+               if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
+               {
+                  result = closefunc(tmp->window, tmp->data);
+                  if(result)
+                     result = FALSE;
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_PAINT:
+            {
+               HPS hps;
+               DWExpose exp;
+               int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))tmp->signalfunction;
+               RECTL  rc;
+
+               if(hWnd == tmp->window)
+               {
+                  int height = _get_height(hWnd);
+
+                  hps = WinBeginPaint(hWnd, 0L, &rc);
+                  exp.x = rc.xLeft;
+                  exp.y = height - rc.yTop - 1;
+                  exp.width = rc.xRight - rc. xLeft;
+                  exp.height = rc.yTop - rc.yBottom;
+                  result = exposefunc(hWnd, &exp, tmp->data);
+                  WinEndPaint(hps);
+               }
+            }
+            break;
+         case WM_COMMAND:
+            {
+               int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))tmp->signalfunction;
+               ULONG command = COMMANDMSG(&msg)->cmd;
+
+               if(tmp->id && command == tmp->id)
+               {
+                  HWND menuowner = _menu_owner(tmp->window);
+
+                  if(menuowner == hWnd || menuowner == NULLHANDLE)
+                  {
+                     result = clickfunc(tmp->window, tmp->data);
+                     tmp = NULL;
+                  }
+               }
+               else if(tmp->window < 65536 && command == tmp->window)
+               {
+                  result = clickfunc(popup ?  popup : tmp->window, tmp->data);
+                  tmp = NULL;
+               }
+            }
+            break;
+         case WM_CONTROL:
+            if(origmsg == WM_VSCROLL || origmsg == WM_HSCROLL || tmp->message == SHORT2FROMMP(mp1) ||
+               (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE))
+            {
+               int svar = SLN_SLIDERTRACK;
+               int id = SHORT1FROMMP(mp1);
+               HWND notifyhwnd = dw_window_from_id(hWnd, id);
+
+               if(origmsg == WM_CONTROL)
+                  svar = SHORT2FROMMP(mp1);
+
+               switch(svar)
+               {
+               case CN_ENTER:
+                  {
+                     int (* API containerselectfunc)(HWND, char *, void *) = (int (* API)(HWND, char *, void *))tmp->signalfunction;
+                     char *text = NULL;
+
+                     if(mp2)
+                     {
+                        PRECORDCORE pre;
+
+                        pre = ((PNOTIFYRECORDENTER)mp2)->pRecord;
+                        if(pre)
+                           text = pre->pszIcon;
+                     }
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        result = containerselectfunc(tmp->window, text, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_EXPANDTREE:
+                  {
+                     int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))tmp->signalfunction;
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        result = treeexpandfunc(tmp->window, (HTREEITEM)mp2, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_CONTEXTMENU:
+                  {
+                     int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
+                     char *text = NULL;
+                     void *user = NULL;
+                     LONG x,y;
+
+                     if(mp2)
+                     {
+                        PCNRITEM pci;
+
+                        pci = (PCNRITEM)mp2;
+
+                        text = pci->rc.pszIcon;
+                        user = pci->user;
+                     }
+
+                     dw_pointer_query_pos(&x, &y);
+
+                     if(tmp->window == notifyhwnd)
+                     {
+                        int container = (int)dw_window_get_data(tmp->window, "_dw_container");
+
+                        if(mp2)
+                        {
+                           if(!container)
+                           {
+                              NOTIFYRECORDEMPHASIS pre;
+
+                              dw_tree_item_select(tmp->window, (HTREEITEM)mp2);
+                              pre.pRecord = mp2;
+                              pre.fEmphasisMask = CRA_CURSORED;
+                              pre.hwndCnr = tmp->window;
+                              _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
+                              pre.pRecord->flRecordAttr |= CRA_CURSORED;
+                           }
+                           else
+                           {
+                              if(pCoreEmph)
+                                 _clear_emphasis();
+                              hwndEmph = tmp->window;
+                              pCoreEmph = mp2;
+                              WinSendMsg(tmp->window, CM_SETRECORDEMPHASIS, mp2, MPFROM2SHORT(TRUE, CRA_SOURCE));
+                           }
+                        }
+                        result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case CN_EMPHASIS:
+                  {
+                     PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2;
+                     static int emph_recurse = 0;
+
+                     if(!emph_recurse)
+                     {
+                        emph_recurse = 1;
+
+                        if(mp2)
+                        {
+                           if(tmp->window == pre->hwndCnr)
+                           {
+                              PCNRITEM pci = (PCNRITEM)pre->pRecord;
+
+                              if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED))
+                              {
+                                 int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))tmp->signalfunction;
+
+                                 if(dw_window_get_data(tmp->window, "_dw_container"))
+                                    result = treeselectfunc(tmp->window, 0, pci->rc.pszIcon, tmp->data, 0);
+                                 else
+                                 {
+                                    if(lasthcnr == tmp->window && lastitem == (HWND)pci)
+                                    {
+                                       lasthcnr = 0;
+                                       lastitem = 0;
+                                    }
+                                    else
+                                    {
+                                       lasthcnr = tmp->window;
+                                       lastitem = (HWND)pci;
+                                       result = treeselectfunc(tmp->window, (HTREEITEM)pci, pci->rc.pszIcon, tmp->data, pci->user);
+                                    }
+                                 }
+                                 tmp = NULL;
+                              }
+                           }
+                        }
+                        emph_recurse = 0;
+                     }
+                  }
+                  break;
+               case LN_SELECT:
+                  {
+                     char classbuf[100];
+
+                     WinQueryClassName(tmp->window, 99, classbuf);
+
+                     if(strncmp(classbuf, "#38", 4) == 0)
+                     {
+                        int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+
+                        if(tmp->window == hWnd || tmp->window == notifyhwnd)
+                        {
+                           static int lastvalue = -1;
+                           static HWND lasthwnd = NULLHANDLE;
+                           int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+                           if(lastvalue != ulValue || lasthwnd != tmp->window)
+                           {
+                              result = valuechangedfunc(tmp->window, ulValue, tmp->data);
+                              lastvalue = ulValue;
+                              lasthwnd = tmp->window;
+                           }
+                           tmp = NULL;
+                        }
+                     }
+                     else
+                     {
+                        int (* API listboxselectfunc)(HWND, int, void *) = (int (* API )(HWND, int, void *))tmp->signalfunction;
+                        static int _recursing = 0;
+
+                        if(_recursing == 0 && (tmp->window == notifyhwnd || (!id && tmp->window == (HWND)mp2)))
+                        {
+                           char buf1[500];
+                           int index = dw_listbox_selected(tmp->window);
+
+                           dw_listbox_get_text(tmp->window, index, buf1, 500);
+
+                           _recursing = 1;
+
+                           if(id && strncmp(classbuf, "#2", 3)==0)
+                           {
+                              char *buf2;
+
+                              buf2 = dw_window_get_text(tmp->window);
+
+                              /* This is to make sure the listboxselect function doesn't
+                               * get called if the user is modifying the entry text.
+                               */
+                              if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0)
+                                 result = listboxselectfunc(tmp->window, index, tmp->data);
+
+                              if(buf2)
+                                 free(buf2);
+                           }
+                           else
+                              result = listboxselectfunc(tmp->window, index, tmp->data);
+
+                           _recursing = 0;
+                           tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
+               case SLN_SLIDERTRACK:
+                  {
+                     int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))tmp->signalfunction;
+
+                     if(origmsg == WM_CONTROL)
+                     {
+                        /* Handle Slider control */
+                        if(tmp->window == hWnd || tmp->window == notifyhwnd)
+                        {
+                           static int lastvalue = -1;
+                           static HWND lasthwnd = NULLHANDLE;
+                           int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+                           if(lastvalue != ulValue || lasthwnd != tmp->window)
+                           {
+                              dw_window_set_data(tmp->window, "_dw_slider_value", (void *)ulValue);
+                              result = valuechangedfunc(tmp->window, ulValue, tmp->data);
+                              lastvalue = ulValue;
+                              lasthwnd = tmp->window;
+                           }
+                           tmp = NULL;
+                        }
+                     }
+                     else
+                     {
+                        /* Handle scrollbar control */
+                        if(tmp->window > 65535 && tmp->window == notifyhwnd)
+                        {
+                           int pos = _HandleScroller(tmp->window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));;
+
+                           if(pos > -1)
+                           {
+                              dw_window_set_data(tmp->window, "_dw_scrollbar_value", (void *)pos);
+                              result = valuechangedfunc(tmp->window, pos, tmp->data);
+                           }
+                           result = 0;
+                           tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
+               case BKN_PAGESELECTED:
+                  {
+                     PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
+
+                     if(psn && tmp->window == psn->hwndBook)
+                     {
+                        int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))tmp->signalfunction;
+
+                        result = switchpagefunc(tmp->window, psn->ulPageIdNew, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               }
+            }
+            break;
+         }
+      }
+
+      if(tmp)
+         tmp = tmp->next;
+
+   }
+   return (MRESULT)result;
+}
+
+/* Gets a DW_RGB value from the three spinbuttons */
+unsigned long _dw_color_spin_get(HWND window)
+{
+   HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
+   long red, green, blue;
+
+   red = dw_spinbutton_get_pos(button);
+   button = (HWND)dw_window_get_data(window, "_dw_green_spin");
+   green = dw_spinbutton_get_pos(button);
+   button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
+   blue = dw_spinbutton_get_pos(button);
+
+   return DW_RGB(red, green, blue);
+}
+
+/* Set the three spinbuttons from a DW_RGB value */
+void _dw_color_spin_set(HWND window, unsigned long value)
+{
+   HWND button = (HWND)dw_window_get_data(window, "_dw_red_spin");
+   dw_window_set_data(window, "_dw_updating", (void *)1);
+   dw_spinbutton_set_pos(button, DW_RED_VALUE(value));
+   button = (HWND)dw_window_get_data(window, "_dw_green_spin");
+   dw_spinbutton_set_pos(button, DW_GREEN_VALUE(value));
+   button = (HWND)dw_window_get_data(window, "_dw_blue_spin");
+   dw_spinbutton_set_pos(button, DW_BLUE_VALUE(value));
+   dw_window_set_data(window, "_dw_updating", NULL);
+}
+
+/* Sets the color selection control to be a DW_RGB value */
+void _dw_col_set(HWND col, unsigned long value)
+{
+   WinSendMsg(col, 0x0602, MPFROMLONG(_os2_color(value)), 0);
+   if(!IS_WARP4())
+      WinSendMsg(col, 0x1384, MPFROMLONG(_os2_color(value)), 0);
+}
+
+/* Handles control messages sent to the box (owner). */
+MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   Box *blah = WinQueryWindowPtr(hWnd, QWP_USER);
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hWnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_VSCROLL:
+   case WM_HSCROLL:
+      if(_run_event(hWnd, msg, mp1, mp2))
+      {
+         HWND window = WinWindowFromID(hWnd, (ULONG)mp1);
+         _HandleScroller(window, (int)SHORT1FROMMP(mp2), (int)SHORT2FROMMP(mp2));
+      }
+      break;
+      /* Handles Color Selection control messages */
+   case 0x0601:
+   case 0x130C:
+      {
+         HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
+         unsigned long val = (unsigned long)mp1;
+
+         if(window)
+            _dw_color_spin_set(window, DW_RGB((val & 0xFF0000) >> 16, (val & 0xFF00) >> 8, val & 0xFF));
+      }
+      break;
+   case WM_CONTROL:
+      if((SHORT2FROMMP(mp1) == SPBN_CHANGE || SHORT2FROMMP(mp1) == SPBN_ENDSPIN))
+      {
+         HWND window = (HWND)dw_window_get_data(hWnd, "_dw_window");
+
+         if(window && !dw_window_get_data(window, "_dw_updating"))
+         {
+            unsigned long val = _dw_color_spin_get(window);
+            HWND col = (HWND)dw_window_get_data(window, "_dw_col");
+
+            _dw_col_set(col, val);
+         }
+      }
+      _run_event(hWnd, msg, mp1, mp2);
+      break;
+   }
+
+   if(blah && blah->oldproc)
+      return blah->oldproc(hWnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+/* The main window procedure for Dynamic Windows, all the resizing code is done here. */
+MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   int result = -1;
+   static int command_active = 0;
+   void (* API windowfunc)(PVOID) = 0L;
+
+   if(!command_active)
+   {
+        /* Make sure we don't end up in infinite recursion */
+      command_active = 1;
+
+      result = (int)_run_event(hWnd, msg, mp1, mp2);
+
+      command_active = 0;
+   }
+
+   /* Now that any handlers are done... do normal processing */
+   switch( msg )
+   {
+   case WM_ERASEBACKGROUND:
+      return 0;
+
+   case WM_PAINT:
+      {
+      HPS    hps;
+      RECTL  rc;
+
+      hps = WinBeginPaint( hWnd, 0L, &rc );
+      WinEndPaint( hps );
+      break;
+      }
+
+   case WM_SIZE:
+      {
+         Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
+
+         if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2))
+            return (MPARAM)TRUE;
+
+         if(mybox && mybox->flags != DW_MINIMIZED)
+         {
+            /* Hide the window when recalculating to reduce
+             * CPU load.
+             */
+            WinShowWindow(hWnd, FALSE);
+
+            if(mybox->items)
+                WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SWP_MOVE | SWP_SIZE);
+
+            _do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
+
+            WinShowWindow(hWnd, TRUE);
+         }
+      }
+      break;
+   case WM_MINMAXFRAME:
+      {
+         Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER);
+         SWP *swp = (SWP *)mp1;
+
+         if(mybox && (swp->fl & SWP_MINIMIZE))
+            mybox->flags = DW_MINIMIZED;
+
+         if(mybox && (swp->fl & SWP_RESTORE))
+         {
+            if(!mybox->titlebar && mybox->hwndtitle)
+               WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE);
+            mybox->flags = 0;
+         }
+
+         if(mybox && (swp->fl & (SWP_MAXIMIZE | SWP_RESTORE)))
+         {
+            int z;
+            SWP swp2;
+
+            WinQueryWindowPos(swp->hwnd, &swp2);
+
+            if(swp2.cx == swp->cx && swp2.cy == swp->cy)
+               return FALSE;
+
+            mybox->flags = 0;
+
+            /* Hide the window when recalculating to reduce
+             * CPU load.
+             */
+            WinShowWindow(hWnd, FALSE);
+
+            _do_resize(mybox, swp->cx, swp->cy);
+
+            if(mybox->count == 1 && mybox->items[0].type == TYPEBOX)
+            {
+               mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER);
+
+               for(z=0;z<mybox->count;z++)
+                  _check_resize_notebook(mybox->items[z].hwnd);
+
+            }
+
+            WinShowWindow(hWnd, TRUE);
+         }
+      }
+      break;
+   case WM_CONTROL:
+      switch(SHORT2FROMMP(mp1))
+      {
+      case BKN_PAGESELECTEDPENDING:
+         {
+            PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2;
+            HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0);
+            Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER);
+            long x, y;
+            unsigned long width, height;
+            RECTL rc;
+
+            if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur)
+            {
+               dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height);
+
+               rc.xLeft = x;
+               rc.yBottom = y;
+               rc.xRight = x + width;
+               rc.yTop = y + height;
+
+               WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE);
+
+               _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom);
+            }
+         }
+         break;
+      }
+      break;
+   case WM_CLOSE:
+      if(result == -1)
+      {
+         dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
+         return (MRESULT)TRUE;
+      }
+      break;
+   case WM_MOUSEMOVE:
+      {
+         HPOINTER pointer;
+
+         if((pointer = (HPOINTER)dw_window_get_data(hWnd, "_dw_pointer")) ||
+            (pointer = (HPOINTER)dw_window_get_data(_toplevel_window(hWnd), "_dw_pointer")))
+         {
+            WinSetPointer(HWND_DESKTOP, pointer);
+            return MRFROMSHORT(TRUE);
+         }
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_USER:
+      windowfunc = (void (* API)(void *))mp1;
+
+      if(windowfunc)
+         windowfunc((void *)mp2);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      break;
+   case WM_DESTROY:
+      {
+         HWND parent = WinQueryWindow(hWnd, QW_PARENT);
+
+         /* Free memory before destroying */
+         if(parent && WinWindowFromID(parent, FID_CLIENT) == hWnd)
+            _free_window_memory(parent);
+         else
+            _free_window_memory(hWnd);
+      }
+      break;
+   case WM_MENUEND:
+      /* Delay removing the signal until we've executed
+       * the signal handler.
+       */
+      WinPostMsg(hWnd, WM_USER+2, mp1, mp2);
+      break;
+   case WM_DDE_INITIATEACK:
+       /* aswer dde server */
+       hwndTrayServer = (HWND)mp1;
+       break;
+   case WM_BUTTON1DOWN | 0x2000:
+   case WM_BUTTON2DOWN | 0x2000:
+   case WM_BUTTON3DOWN | 0x2000:
+   case WM_BUTTON1UP | 0x2000:
+   case WM_BUTTON2UP | 0x2000:
+   case WM_BUTTON3UP | 0x2000:
+       if(hwndTaskBar)
+           result = (int)_run_event(hwndTaskBar, msg & ~0x2000, mp1, mp2);
+       break;
+   case WM_USER+2:
+      _clear_emphasis();
+      if(dw_window_get_data((HWND)mp2, "_dw_popup"))
+         _free_menu_data((HWND)mp2);
+      break;
+   }
+
+   if(result != -1)
+      return (MRESULT)result;
+   else
+      return WinDefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+void _changebox(Box *thisbox, int percent, int type)
+{
+   int z;
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
+         _changebox(tmp, percent, type);
+      }
+      else
+      {
+         if(type == DW_HORZ)
+         {
+            if(thisbox->items[z].hsize == SIZEEXPAND)
+               thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
+         }
+         else
+         {
+            if(thisbox->items[z].vsize == SIZEEXPAND)
+               thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
+         }
+      }
+   }
+}
+
+void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
+{
+   float ratio = (float)percent/(float)100.0;
+   HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+   HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+   Box *tmp = WinQueryWindowPtr(handle1, QWP_USER);
+
+   WinShowWindow(handle1, FALSE);
+   WinShowWindow(handle2, FALSE);
+
+   if(type == DW_HORZ)
+   {
+      int newx = (int)((float)x * ratio) - (SPLITBAR_WIDTH/2);
+
+      WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, newx - 1, y - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newx);
+
+      tmp = WinQueryWindowPtr(handle2, QWP_USER);
+
+      newx = x - newx - SPLITBAR_WIDTH;
+
+      WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, newx - 1, y - 1);
+   }
+   else
+   {
+      int newy = (int)((float)y * ratio) - (SPLITBAR_WIDTH/2);
+
+      WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      tmp = WinQueryWindowPtr(handle2, QWP_USER);
+
+      newy = y - newy - SPLITBAR_WIDTH;
+
+      WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newy);
+   }
+
+   WinShowWindow(handle1, TRUE);
+   WinShowWindow(handle2, TRUE);
+}
+
+
+/* This handles any activity on the splitbars (sizers) */
+MRESULT EXPENTRY _splitwndproc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   switch (msg)
+   {
+   case WM_ACTIVATE:
+   case WM_SETFOCUS:
+      return (MRESULT)(FALSE);
+
+   case WM_PAINT:
+      {
+         HPS hps;
+         POINTL ptl[2];
+         RECTL rcl;
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int start = (int)dw_window_get_data(hwnd, "_dw_start");
+
+         hps = WinBeginPaint(hwnd, 0, 0);
+
+         WinQueryWindowRect(hwnd, &rcl);
+
+         if(type == DW_HORZ)
+         {
+            ptl[0].x = rcl.xLeft + start;
+            ptl[0].y = rcl.yBottom;
+            ptl[1].x = rcl.xRight + start + 3;
+            ptl[1].y = rcl.yTop;
+         }
+         else
+         {
+            ptl[0].x = rcl.xLeft;
+            ptl[0].y = rcl.yBottom + start;
+            ptl[1].x = rcl.xRight;
+            ptl[1].y = rcl.yTop + start + 3;
+         }
+
+
+         GpiSetColor(hps, CLR_PALEGRAY);
+         GpiMove(hps, &ptl[0]);
+         GpiBox(hps, DRO_OUTLINEFILL, &ptl[1], 0, 0);
+         WinEndPaint(hps);
+      }
+      return MRFROMSHORT(FALSE);
+
+   case WM_MOUSEMOVE:
+      {
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+
+         if(type == DW_HORZ)
+            WinSetPointer(HWND_DESKTOP,
+                       WinQuerySysPointer(HWND_DESKTOP,
+                                     SPTR_SIZEWE,
+                                     FALSE));
+         else
+            WinSetPointer(HWND_DESKTOP,
+                       WinQuerySysPointer(HWND_DESKTOP,
+                                     SPTR_SIZENS,
+                                     FALSE));
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_BUTTON1DOWN:
+      {
+         APIRET rc;
+         RECTL  rclFrame;
+         RECTL  rclBounds;
+         float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int start = (int)dw_window_get_data(hwnd, "_dw_start");
+
+         WinQueryWindowRect(hwnd, &rclFrame);
+         WinQueryWindowRect(hwnd, &rclBounds);
+
+         WinMapWindowPoints(hwnd, HWND_DESKTOP,
+                        (PPOINTL)&rclBounds, 2);
+
+
+         if(type == DW_HORZ)
+         {
+            rclFrame.xLeft = start;
+            rclFrame.xRight = start + SPLITBAR_WIDTH;
+         }
+         else
+         {
+            rclFrame.yBottom = start;
+            rclFrame.yTop = start + SPLITBAR_WIDTH;
+         }
+
+         if(percent)
+         {
+            rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds);
+
+            if(rc == TRUE)
+            {
+               int width = (rclBounds.xRight - rclBounds.xLeft);
+               int height = (rclBounds.yTop - rclBounds.yBottom);
+
+               if(type == DW_HORZ)
+               {
+                  start = rclFrame.xLeft - rclBounds.xLeft;
+                  if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
+                     *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
+               }
+               else
+               {
+                  start = rclFrame.yBottom - rclBounds.yBottom;
+                  if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
+                     *percent = 100.0 - (((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0);
+               }
+               _handle_splitbar_resize(hwnd, *percent, type, width, height);
+               _handle_splitbar_resize(hwnd, *percent, type, width, height);
+            }
+         }
+      }
+      return MRFROMSHORT(FALSE);
+   }
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* Function: BubbleProc
+ * Abstract: Subclass procedure for bubble help
+ */
+MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   MRESULT res;
+   PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER);
+
+   if(proc)
+      res = proc(hwnd, msg, mp1, mp2);
+   else
+      res = WinDefWindowProc(hwnd, msg, mp1, mp2);
+
+   if(msg == WM_PAINT)
+   {
+      POINTL ptl;
+      HPS hpsTemp;
+      RECTL rcl;
+      int height, width;
+
+      WinQueryWindowRect(hwnd, &rcl);
+      height = rcl.yTop - rcl.yBottom - 1;
+      width = rcl.xRight - rcl.xLeft - 1;
+
+      /* Draw a border around the bubble help */
+      hpsTemp = WinGetPS(hwnd);
+      GpiSetColor(hpsTemp, CLR_BLACK);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = ptl.y = 0;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.x = 0;
+      ptl.y = height;
+      GpiLine(hpsTemp, &ptl);
+      ptl.x = width;
+      ptl.y = height;
+      GpiMove(hpsTemp, &ptl);
+      ptl.y = 0;
+      ptl.x = width;
+      GpiLine(hpsTemp, &ptl);
+      WinReleasePS(hpsTemp);
+   }
+   return res;
+}
+
+MRESULT EXPENTRY _button_draw(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, PFNWP oldproc, int indent)
+{
+   HPIXMAP pixmap = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap");
+   HPIXMAP disable = (HPIXMAP)dw_window_get_data(hwnd, "_dw_hpixmap_disabled");
+   HPOINTER icon = (HPOINTER)dw_window_get_data(hwnd, "_dw_button_icon");
+   MRESULT res;
+   unsigned long width, height;
+   int x = 5, y = 5;
+
+   dw_window_get_pos_size(hwnd, NULL, NULL, &width, &height);
+
+   if(!oldproc)
+      res = WinDefWindowProc(hwnd, msg, mp1, mp2);
+   res = oldproc(hwnd, msg, mp1, mp2);
+
+   if(icon)
+   {
+      ULONG halftone = DP_NORMAL;
+      HPS hps = WinGetPS(hwnd);
+      POINTERINFO pi;
+      int cx, cy;
+
+      if(dw_window_get_data(hwnd, "_dw_disabled"))
+         halftone = DP_HALFTONED;
+
+      cx = width - 10;
+      cy = height - 10;
+
+      if(WinQueryPointerInfo(icon, &pi))
+      {
+         BITMAPINFOHEADER sl;
+         int newcx = cx, newcy = cy;
+
+         /* Check the mini icon first */
+         if(GpiQueryBitmapParameters(pi.hbmMiniColor, &sl))
+         {
+            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
+            {
+               newcx = sl.cx;
+               newcy = sl.cy;
+            }
+         }
+         /* Check the normal icon second */
+         if(GpiQueryBitmapParameters(pi.hbmColor, &sl))
+         {
+            if(sl.cx && sl.cy && cx > sl.cx && cy > sl.cy)
+            {
+               newcx = sl.cx;
+               newcy = sl.cy;
+            }
+         }
+         cx = newcx; cy = newcy;
+         x = (width - cx)/2;
+         y = (height - cy)/2;
+      }
+      WinStretchPointer(hps, x + indent, y - indent, cx, cy, icon, halftone);
+      WinReleasePS(hps);
+   }
+   else if(pixmap)
+   {
+      x = (width - pixmap->width)/2;
+      y = (height - pixmap->height)/2;
+
+      if(disable && dw_window_get_data(hwnd, "_dw_disabled"))
+         dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, disable, 0, 0);
+      else
+         dw_pixmap_bitblt(hwnd, 0, x + indent, y + indent, pixmap->width, pixmap->height, 0, pixmap, 0, 0);
+   }
+   return res;
+}
+
+/* Function: BtProc
+ * Abstract: Subclass procedure for buttons
+ */
+
+MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   BubbleButton *bubble;
+   PFNWP oldproc;
+
+   bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
+
+   if(!bubble)
+      return WinDefWindowProc(hwnd, msg, mp1, mp2);
+
+   oldproc = bubble->pOldProc;
+
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_PAINT:
+      return _button_draw(hwnd, msg, mp1, mp2, oldproc, 0);
+   case BM_SETHILITE:
+      return _button_draw(hwnd, msg, mp1, mp2, oldproc, (int)mp1);
+   case WM_SETFOCUS:
+      if(mp2)
+         _run_event(hwnd, msg, mp1, mp2);
+      else
+         WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0);
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+   case WM_BUTTON1DBLCLK:
+   case WM_BUTTON2DBLCLK:
+   case WM_BUTTON3DBLCLK:
+      if(dw_window_get_data(hwnd, "_dw_disabled"))
+         return (MRESULT)FALSE;
+      break;
+   case WM_BUTTON1UP:
+      {
+         SignalHandler *tmp = Root;
+
+         if(WinIsWindowEnabled(hwnd) && !dw_window_get_data(hwnd, "_dw_disabled"))
+         {
+            /* Find any callbacks for this function */
+            while(tmp)
+            {
+               if(tmp->message == WM_COMMAND)
+               {
+                  /* Make sure it's the right window, and the right ID */
+                  if(tmp->window == hwnd)
+                  {
+                     /* Due to the fact that if we run the function
+                      * here, finishing actions on the button will occur
+                      * after we run the signal handler.  So we post the
+                      * message so the button can finish what it needs to
+                      * do before we run our handler.
+                      */
+                     WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
+                     tmp = NULL;
+                  }
+               }
+               if(tmp)
+                  tmp= tmp->next;
+            }
+         }
+      }
+      break;
+   case WM_USER:
+      {
+            SignalHandler *tmp = (SignalHandler *)mp1;
+         int (* API clickfunc)(HWND, void *) = NULL;
+
+         if(tmp)
+         {
+            clickfunc = (int (* API)(HWND, void *))tmp->signalfunction;
+
+            clickfunc(tmp->window, tmp->data);
+         }
+      }
+        break;
+   case WM_CHAR:
+      {
+         /* A button press should also occur for an ENTER or SPACE press
+          * while the button has the active input focus.
+          */
+         if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ')
+         {
+            SignalHandler *tmp = Root;
+
+            /* Find any callbacks for this function */
+            while(tmp)
+            {
+               if(tmp->message == WM_COMMAND)
+               {
+                  /* Make sure it's the right window, and the right ID */
+                  if(tmp->window == hwnd)
+                  {
+                     WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0);
+                     tmp = NULL;
+                  }
+               }
+               if(tmp)
+                  tmp= tmp->next;
+            }
+         }
+         if(SHORT1FROMMP(mp2) == '\t')
+         {
+            if(CHARMSG(&msg)->fs & KC_SHIFT)
+               _shift_focus_back(hwnd);
+            else
+               _shift_focus(hwnd);
+            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);
+            return FALSE;
+         }
+         else if(!(CHARMSG(&msg)->fs & KC_KEYUP) && (CHARMSG(&msg)->vkey == VK_RIGHT || CHARMSG(&msg)->vkey == VK_DOWN))
+         {
+            _shift_focus(hwnd);
+            return FALSE;
+         }
+      }
+      break;
+   case 0x041f:
+      if (hwndBubble)
+      {
+         WinDestroyWindow(hwndBubble);
+         hwndBubble = 0;
+      }
+      break;
+
+   case 0x041e:
+
+      if(!*bubble->bubbletext)
+         break;
+
+      if(hwndBubble)
+      {
+         WinDestroyWindow(hwndBubble);
+         hwndBubble = 0;
+      }
+
+      if(!hwndBubble)
+      {
+         HPS   hpsTemp = 0;
+         LONG  lHight;
+         LONG  lWidth;
+         POINTL txtPointl[TXTBOX_COUNT];
+         POINTL ptlWork = {0,0};
+         ULONG ulColor = CLR_YELLOW;
+         void *blah;
+
+         hwndBubbleLast   = hwnd;
+         hwndBubble = WinCreateWindow(HWND_DESKTOP,
+                               WC_STATIC,
+                               "",
+                               SS_TEXT |
+                               DT_CENTER |
+                               DT_VCENTER,
+                                         0,0,0,0,
+                               HWND_DESKTOP,
+                               HWND_TOP,
+                               0,
+                               NULL,
+                               NULL);
+
+         WinSetPresParam(hwndBubble,
+                     PP_FONTNAMESIZE,
+                     strlen(DefaultFont)+1,
+                     DefaultFont);
+
+
+         WinSetPresParam(hwndBubble,
+                     PP_BACKGROUNDCOLORINDEX,
+                     sizeof(ulColor),
+                     &ulColor);
+
+         WinSetWindowText(hwndBubble,
+                      bubble->bubbletext);
+
+         WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1);
+
+         hpsTemp = WinGetPS(hwndBubble);
+         GpiQueryTextBox(hpsTemp,
+                     strlen(bubble->bubbletext),
+                     bubble->bubbletext,
+                     TXTBOX_COUNT,
+                     txtPointl);
+         WinReleasePS(hpsTemp);
+
+         lWidth = txtPointl[TXTBOX_TOPRIGHT].x -
+            txtPointl[TXTBOX_TOPLEFT ].x + 8;
+
+         lHight = txtPointl[TXTBOX_TOPLEFT].y -
+            txtPointl[TXTBOX_BOTTOMLEFT].y + 8;
+
+         ptlWork.y -= lHight;
+
+         blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc);
+
+         if(blah)
+            WinSetWindowPtr(hwndBubble, QWP_USER, blah);
+
+         WinSetWindowPos(hwndBubble,
+                     HWND_TOP,
+                     ptlWork.x,
+                     ptlWork.y,
+                     lWidth,
+                     lHight,
+                     SWP_SIZE | SWP_MOVE | SWP_SHOW);
+      }
+      break;
+   }
+
+   if(!oldproc)
+      return WinDefWindowProc(hwnd, msg, mp1, mp2);
+   return oldproc(hwnd, msg, mp1, mp2);
+}
+
+MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
+{
+   int res = 0;
+   res = (int)_run_event(hwnd, msg, mp1, mp2);
+   switch(msg)
+   {
+   case WM_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_BUTTON1DOWN:
+   case WM_BUTTON2DOWN:
+   case WM_BUTTON3DOWN:
+      if(res == -1)
+          WinSetFocus(HWND_DESKTOP, hwnd);
+      else if(res)
+         return (MPARAM)TRUE;
+   }
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+MRESULT EXPENTRY _TreeProc(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_MOUSEMOVE:
+      if(_wndproc(hwnd, msg, mp1, mp2))
+         return MPFROMSHORT(FALSE);
+      break;
+   case WM_PAINT:
+      {
+         HPS hps;
+         RECTL rcl;
+         POINTL ptl[2];
+
+         if(oldproc)
+            oldproc(hwnd, msg, mp1, mp2);
+
+         hps = WinBeginPaint(hwnd, 0, 0);
+         WinQueryWindowRect(hwnd, &rcl);
+         ptl[0].x = rcl.xLeft + 1;
+         ptl[0].y = rcl.yBottom + 1;
+         ptl[1].x = rcl.xRight - 1;
+         ptl[1].y = rcl.yTop - 1;
+
+         GpiSetColor(hps, CLR_BLACK);
+         GpiMove(hps, &ptl[0]);
+         GpiBox(hps, DRO_OUTLINE, &ptl[1], 0, 0);
+         WinEndPaint(hps);
+      }
+      return MRFROMSHORT(FALSE);
+   case WM_SETFOCUS:
+      _run_event(hwnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      if(SHORT1FROMMP(mp2) == '\t')
+      {
+         if(CHARMSG(&msg)->fs & KC_SHIFT)
+            _shift_focus_back(hwnd);
+         else
+            _shift_focus(hwnd);
+         return FALSE;
+      }
+      break;
+   }
+
+   _run_event(hwnd, msg, mp1, mp2);
+
+   if(oldproc)
+      return oldproc(hwnd, msg, mp1, mp2);
+
+   return WinDefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/*
+ * Initializes the Dynamic Windows engine.
+ * Parameters:
+ *           newthread: True if this is the only thread.
+ *                      False if there is already a message loop running.
+ */
+int API dw_init(int newthread, int argc, char *argv[])
+{
+   APIRET rc;
+   char objnamebuf[300] = "";
+
+   argc = argc; /* keep compiler happy */
+   argv = argv; /* keep compiler happy */
+   if(newthread)
+   {
+      dwhab = WinInitialize(0);
+      dwhmq = WinCreateMsgQueue(dwhab, 0);
+   }
+
+   rc = WinRegisterClass(dwhab, ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32);
+   rc = WinRegisterClass(dwhab, SplitbarClassName, _splitwndproc, 0L, 32);
+   rc = WinRegisterClass(dwhab, ScrollClassName, _scrollwndproc, 0L, 32);
+
+   /* Get the OS/2 version. */
+   DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
+
+   desktop = WinQueryDesktopWindow(dwhab, NULLHANDLE);
+
+   if(!IS_WARP4())
+      DefaultFont = strdup("8.Helv");
+   else
+      DefaultFont = strdup(DefaultFont);
+
+   /* This is a window that hangs around as long as the
+    * application does and handles menu messages.
+    */
+   hwndApp = dw_window_new(HWND_OBJECT, "", 0);
+   /* Attempt to locate a tray server */
+   WinDdeInitiate(hwndApp, "SystrayServer", "TRAY", NULL);
+
+   DosLoadModule(objnamebuf, sizeof(objnamebuf), "WPCONFIG", &wpconfig);
+
+   return rc;
+}
+
+/*
+ * Runs a message loop for Dynamic Windows.
+ */
+void API dw_main(void)
+{
+   QMSG qmsg;
+
+   _dwtid = dw_thread_id();
+
+   while(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+   }
+
+   WinDestroyMsgQueue(dwhmq);
+   WinTerminate(dwhab);
+}
+
+/*
+ * Runs a message loop for Dynamic Windows, for a period of milliseconds.
+ * Parameters:
+ *           milliseconds: Number of milliseconds to run the loop for.
+ */
+void API dw_main_sleep(int milliseconds)
+{
+   QMSG qmsg;
+#ifdef __EMX__
+   struct timeval tv, start;
+
+   gettimeofday(&start, NULL);
+   gettimeofday(&tv, NULL);
+
+   while(((tv.tv_sec - start.tv_sec)*1000) + ((tv.tv_usec - start.tv_usec)/1000) <= milliseconds)
+   {
+      if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
+      {
+         WinGetMsg(dwhab, &qmsg, 0, 0, 0);
+         if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+            _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+         WinDispatchMsg(dwhab, &qmsg);
+      }
+      else
+         DosSleep(1);
+      gettimeofday(&tv, NULL);
+   }
+#else
+   double start = (double)clock();
+
+   while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
+   {
+      if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE))
+      {
+         WinGetMsg(dwhab, &qmsg, 0, 0, 0);
+         if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+            _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+         WinDispatchMsg(dwhab, &qmsg);
+      }
+      else
+         DosSleep(1);
+   }
+#endif
+}
+
+/*
+ * Processes a single message iteration and returns.
+ */
+void API dw_main_iteration(void)
+{
+   QMSG qmsg;
+
+   _dwtid = dw_thread_id();
+
+   if(WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+   }
+}
+
+/*
+ * Free's memory allocated by dynamic windows.
+ * Parameters:
+ *           ptr: Pointer to dynamic windows allocated
+ *                memory to be free()'d.
+ */
+void API dw_free(void *ptr)
+{
+   free(ptr);
+}
+
+/*
+ * Allocates and initializes a dialog struct.
+ * Parameters:
+ *           data: User defined data to be passed to functions.
+ */
+DWDialog * API dw_dialog_new(void *data)
+{
+   DWDialog *tmp = malloc(sizeof(DWDialog));
+
+   tmp->eve = dw_event_new();
+   dw_event_reset(tmp->eve);
+   tmp->data = data;
+   tmp->done = FALSE;
+   tmp->result = NULL;
+
+    return tmp;
+}
+
+/*
+ * Accepts a dialog struct and returns the given data to the
+ * initial called of dw_dialog_wait().
+ * Parameters:
+ *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
+ *           result: Data to be returned by dw_dialog_wait().
+ */
+int API dw_dialog_dismiss(DWDialog *dialog, void *result)
+{
+   dialog->result = result;
+   dw_event_post(dialog->eve);
+   dialog->done = TRUE;
+   return 0;
+}
+
+/*
+ * Accepts a dialog struct waits for dw_dialog_dismiss() to be
+ * called by a signal handler with the given dialog struct.
+ * Parameters:
+ *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
+ */
+void * API dw_dialog_wait(DWDialog *dialog)
+{
+   QMSG qmsg;
+   void *tmp;
+
+   while (WinGetMsg(dwhab, &qmsg, 0, 0, 0))
+   {
+      if(qmsg.msg == WM_TIMER && qmsg.hwnd == NULLHANDLE)
+         _run_event(qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2);
+      WinDispatchMsg(dwhab, &qmsg);
+      if(dialog->done)
+         break;
+   }
+   dw_event_close(&dialog->eve);
+   tmp = dialog->result;
+   free(dialog);
+   return tmp;
+}
+
+/*
+ * Displays a debug message on the console...
+ * Parameters:
+ *           format: printf style format string.
+ *           ...: Additional variables for use in the format.
+ */
+void API dw_debug(char *format, ...)
+{
+   va_list args;
+   char outbuf[1024];
+
+   va_start(args, format);
+   vsprintf(outbuf, format, args);
+   va_end(args);
+   
+   fprintf(stderr, "%s", outbuf);
+}
+
+/*
+ * Displays a Message Box with given text and title..
+ * Parameters:
+ *           title: The title of the message box.
+ *           flags: flags to indicate buttons and icon
+ *           format: printf style format string.
+ *           ...: Additional variables for use in the format.
+ */
+int API dw_messagebox(char *title, int flags, char *format, ...)
+{
+   va_list args;
+   char outbuf[1024];
+   int rc;
+
+   va_start(args, format);
+   vsprintf(outbuf, format, args);
+   va_end(args);
+
+   rc = WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, outbuf, title, 0, flags | MB_MOVEABLE);
+   if(rc == MBID_OK)
+      return DW_MB_RETURN_OK;
+   else if(rc == MBID_YES)
+      return DW_MB_RETURN_YES;
+   else if(rc == MBID_NO)
+      return DW_MB_RETURN_NO;
+   else if(rc == MBID_CANCEL)
+      return DW_MB_RETURN_CANCEL;
+   else return 0;
+}
+
+/*
+ * Makes the window topmost.
+ * Parameters:
+ *           handle: The window handle to make topmost.
+ */
+int API dw_window_raise(HWND handle)
+{
+   return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
+}
+
+/*
+ * Makes the window bottommost.
+ * Parameters:
+ *           handle: The window handle to make bottommost.
+ */
+int API dw_window_lower(HWND handle)
+{
+   return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER);
+}
+
+/*
+ * Makes the window visible.
+ * Parameters:
+ *           handle: The window handle to make visible.
+ */
+int API dw_window_show(HWND handle)
+{
+   int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW);
+   HSWITCH hswitch;
+   SWCNTRL swcntrl;
+
+   _fix_button_owner(_toplevel_window(handle), 0);
+   WinSetFocus(HWND_DESKTOP, handle);
+   _initial_focus(handle);
+
+   /* If this window has a  switch list entry make sure it is visible */
+   hswitch = WinQuerySwitchHandle(handle, 0);
+   if(hswitch)
+   {
+      WinQuerySwitchEntry(hswitch, &swcntrl);
+      swcntrl.uchVisibility = SWL_VISIBLE;
+      WinChangeSwitchEntry(hswitch, &swcntrl);
+   }
+   if(WinWindowFromID(handle, FID_CLIENT))
+   {
+      WindowData *blah = WinQueryWindowPtr(handle, QWP_USER);
+
+      if(blah && !(blah->flags & DW_OS2_NEW_WINDOW))
+      {
+         ULONG cx = dw_screen_width(), cy = dw_screen_height();
+         int newx, newy, changed = 0;
+         SWP swp;
+
+         blah->flags |= DW_OS2_NEW_WINDOW;
+
+         WinQueryWindowPos(handle, &swp);
+
+         newx = swp.x;
+         newy = swp.y;
+
+         if((swp.x+swp.cx) > cx)
+         {
+            newx = (cx - swp.cx)/2;
+            changed = 1;
+         }
+         if((swp.y+swp.cy) > cy)
+         {
+            newy = (cy - swp.cy)/2;
+            changed = 1;
+         }
+         if(changed)
+            WinSetWindowPos(handle, NULLHANDLE, newx, newy, 0, 0, SWP_MOVE);
+      }
+   }
+   return rc;
+}
+
+/*
+ * Minimizes or Iconifies a top-level window.
+ * Parameters:
+ *           handle: The window handle to minimize.
+ */
+int API dw_window_minimize(HWND handle)
+{
+   HWND hwndclient = WinWindowFromID(handle, FID_CLIENT);
+
+   if(hwndclient)
+   {
+      Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER);
+
+      if(box)
+      {
+         if(!box->titlebar && box->hwndtitle)
+            WinSetParent(box->hwndtitle, handle, FALSE);
+      }
+   }
+
+   return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE);
+}
+
+/*
+ * Makes the window invisible.
+ * Parameters:
+ *           handle: The window handle to make visible.
+ */
+int API dw_window_hide(HWND handle)
+{
+   HSWITCH hswitch;
+   SWCNTRL swcntrl;
+
+   /* If this window has a  switch list entry make sure it is invisible */
+   hswitch = WinQuerySwitchHandle(handle, 0);
+   if(hswitch)
+   {
+      WinQuerySwitchEntry(hswitch, &swcntrl);
+      swcntrl.uchVisibility = SWL_INVISIBLE;
+      WinChangeSwitchEntry(hswitch, &swcntrl);
+   }
+   return WinShowWindow(handle, FALSE);
+}
+
+/*
+ * Destroys a window and all of it's children.
+ * Parameters:
+ *           handle: The window handle to destroy.
+ */
+int API dw_window_destroy(HWND handle)
+{
+   HWND frame, menu, parent = WinQueryWindow(handle, QW_PARENT);
+   Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
+
+   if(!handle)
+      return -1;
+
+   frame = (HWND)dw_window_get_data(handle, "_dw_combo_box");
+
+   if((menu = WinWindowFromID(handle, FID_MENU)) != NULLHANDLE)
+      _free_menu_data(menu);
+
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != desktop)
+   {
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+     if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem, *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return 0;
+
+         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+
+         thisbox->items = tmpitem;
+         free(thisitem);
+         thisbox->count--;
+      }
+      _free_window_memory(frame ? frame : handle);
+   }
+   return WinDestroyWindow(frame ? frame : handle);
+}
+
+/* Causes entire window to be invalidated and redrawn.
+ * Parameters:
+ *           handle: Toplevel window handle to be redrawn.
+ */
+void API dw_window_redraw(HWND handle)
+{
+   HWND client = WinWindowFromID(handle, FID_CLIENT);
+   HWND window = client ? client : handle;
+   Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
+
+   _fix_button_owner(_toplevel_window(handle), 0);
+   if(window && mybox)
+   {
+      unsigned long width, height;
+
+      dw_window_get_pos_size(window, NULL, NULL, &width, &height);
+
+      if(mybox->items)
+          WinSetWindowPos(mybox->items[0].hwnd, HWND_TOP, 0, 0, width, height, SWP_MOVE | SWP_SIZE);
+
+      WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, FALSE);
+      _do_resize(mybox, width, height);
+      WinShowWindow(client && mybox->items ? mybox->items[0].hwnd : handle, TRUE);
+   }
+}
+
+/*
+ * Changes a window's parent to newparent.
+ * Parameters:
+ *           handle: The window handle to destroy.
+ *           newparent: The window's new parent window.
+ */
+void API dw_window_reparent(HWND handle, HWND newparent)
+{
+   HWND blah = WinWindowFromID(newparent, FID_CLIENT);
+   WinSetParent(handle, blah ? blah : newparent, TRUE);
+}
+
+/* Allows the user to choose a font using the system's font chooser dialog.
+ * Parameters:
+ *       currfont: current font
+ * Returns:
+ *       A malloced buffer with the selected font or NULL on error.
+ */
+char * API dw_font_choose(char *currfont)
+{
+    FONTDLG fd = { 0 };
+    char *buf = calloc(1,100);
+    int size = 9;
+
+    /* Fill in the family name if possible */
+    if(currfont)
+    {
+        char *name = strchr(currfont, '.');
+        if(name)
+        {
+            int newsize = atoi(currfont);
+            if(newsize > 0)
+                size = newsize;
+            name++;
+            strcpy(buf, name);
+            strcpy(fd.fAttrs.szFacename, name);
+        }
+        else
+        {
+            strcpy(buf, currfont);
+            strcpy(fd.fAttrs.szFacename, currfont);
+        }
+    }
+
+    /* Fill in the font dialog struct */
+    fd.cbSize = sizeof(fd);
+    fd.hpsScreen = WinGetScreenPS(HWND_DESKTOP);
+    fd.pszTitle = "Choose Font";
+    fd.clrFore = CLR_BLACK;
+    fd.clrBack = CLR_WHITE;
+    fd.pszFamilyname = buf;
+    fd.usFamilyBufLen = 100;
+    fd.fxPointSize = MAKEFIXED(size,0);
+    fd.fl = FNTS_INITFROMFATTRS;
+
+    /* Show the dialog and wait for a response */
+    if(!WinFontDlg(HWND_DESKTOP, HWND_OBJECT, &fd) || fd.lReturn != DID_OK)
+    {
+        WinReleasePS(fd.hpsScreen);
+        free(buf);
+        return NULL;
+    }
+    WinReleasePS(fd.hpsScreen);
+    /* Figure out what the user selected and return that */
+    size = FIXEDINT(fd.fxPointSize);
+    sprintf(buf, "%d.%s", size, fd.fAttrs.szFacename);
+    return buf;
+}
+
+/*
+ * Sets the default font used on text based widgets.
+ * Parameters:
+ *           fontname: Font name in Dynamic Windows format.
+ */
+void API dw_font_set_default(char *fontname)
+{
+    char *oldfont = DefaultFont;
+    
+    DefaultFont = strdup(fontname);
+    free(oldfont);
+}
+
+/*
+ * Sets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ */
+int API dw_window_set_font(HWND handle, char *fontname)
+{
+   HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   return WinSetPresParam(group ? group : handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+}
+
+/*
+ * Gets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ */
+char * API dw_window_get_font(HWND handle)
+{
+   char *str = (char *)alloca(50);
+   HWND group = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   if(str && WinQueryPresParam(group ? group : handle, PP_FONTNAMESIZE, 0, NULL, 50, str, QPF_NOINHERIT))
+      return strdup(str);
+   return NULL;
+}
+
+/* Internal version */
+int _dw_window_set_color(HWND handle, ULONG fore, ULONG back)
+{
+   if((fore & DW_RGB_COLOR) == DW_RGB_COLOR)
+   {
+      RGB2 rgb2;
+
+      rgb2.bBlue = DW_BLUE_VALUE(fore);
+      rgb2.bGreen = DW_GREEN_VALUE(fore);
+      rgb2.bRed = DW_RED_VALUE(fore);
+      rgb2.fcOptions = 0;
+
+      WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2);
+
+   }
+   else if(fore != DW_CLR_DEFAULT)
+   {
+      fore = _internal_color(fore);
+
+      WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore);
+   }
+   if((back & DW_RGB_COLOR) == DW_RGB_COLOR)
+   {
+      RGB2 rgb2;
+
+      rgb2.bBlue = DW_BLUE_VALUE(back);
+      rgb2.bGreen = DW_GREEN_VALUE(back);
+      rgb2.bRed = DW_RED_VALUE(back);
+      rgb2.fcOptions = 0;
+
+      WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2);
+      return 0;
+   }
+   else if(back != DW_CLR_DEFAULT)
+   {
+      back = _internal_color(back);
+
+      WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
+   }
+   return 0;
+}
+/*
+ * Sets the colors used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fore: Foreground color in DW_RGB format or a default color index.
+ *          back: Background color in DW_RGB format or a default color index.
+ */
+int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
+{
+   dw_window_set_data(handle, "_dw_fore", (void *)(fore+1));
+   dw_window_set_data(handle, "_dw_back", (void *)(back+1));
+
+   return _dw_window_set_color(handle, fore, back);
+}
+
+/*
+ * Sets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          border: Size of the window border in pixels.
+ */
+int API dw_window_set_border(HWND handle, int border)
+{
+   WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border));
+   return 0;
+}
+
+/*
+ * Captures the mouse input to this window.
+ * Parameters:
+ *       handle: Handle to receive mouse input.
+ */
+void API dw_window_capture(HWND handle)
+{
+   WinSetCapture(HWND_DESKTOP, handle);
+}
+
+/*
+ * Releases previous mouse capture.
+ */
+void API dw_window_release(void)
+{
+   WinSetCapture(HWND_DESKTOP, NULLHANDLE);
+}
+
+/*
+ * Tracks this window movement.
+ * Parameters:
+ *       handle: Handle to frame to be tracked.
+ */
+void API dw_window_track(HWND handle)
+{
+   WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0);
+}
+
+/*
+ * Changes the appearance of the mouse pointer.
+ * Parameters:
+ *       handle: Handle to widget for which to change.
+ *       cursortype: ID of the pointer you want.
+ */
+void API dw_window_set_pointer(HWND handle, int pointertype)
+{
+   HPOINTER pointer = pointertype < 65535 ?
+      WinQuerySysPointer(HWND_DESKTOP, pointertype, FALSE)
+      : (HPOINTER)pointertype;
+
+   if(!pointertype)
+      dw_window_set_data(handle, "_dw_pointer", 0);
+   else
+   {
+      WinSetPointer(HWND_DESKTOP, pointer);
+
+      if(handle != HWND_DESKTOP)
+         dw_window_set_data(handle, "_dw_pointer", (void *)pointer);
+   }
+}
+
+/*
+ * Create a new Window Frame.
+ * Parameters:
+ *       owner: The Owner's window handle or HWND_DESKTOP.
+ *       title: The Window title.
+ *       flStyle: Style flags, see the PM reference.
+ */
+HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle)
+{
+   HWND hwndframe;
+   Box *newbox = calloc(1, sizeof(Box));
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   ULONG winStyle = 0L;
+
+   newbox->pad = 0;
+   newbox->type = DW_VERT;
+   newbox->count = 0;
+
+   flStyle |= FCF_NOBYTEALIGN;
+
+   if(flStyle & DW_FCF_TITLEBAR)
+      newbox->titlebar = 1;
+   else
+      flStyle |= FCF_TITLEBAR;
+
+   if(!(flStyle & FCF_SHELLPOSITION))
+      blah->flags |= DW_OS2_NEW_WINDOW;
+
+   if(flStyle & WS_MAXIMIZED)
+   {
+      winStyle |= WS_MAXIMIZED;
+      flStyle &= ~WS_MAXIMIZED;
+   }
+   if(flStyle & WS_MINIMIZED)
+   {
+      winStyle |= WS_MINIMIZED;
+      flStyle &= ~WS_MINIMIZED;
+   }
+
+   hwndframe = WinCreateStdWindow(hwndOwner, winStyle, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &newbox->hwnd);
+   newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR);
+   if(!newbox->titlebar && newbox->hwndtitle)
+      WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE);
+   blah->oldproc = WinSubclassWindow(hwndframe, _sizeproc);
+   WinSetWindowPtr(hwndframe, QWP_USER, blah);
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+
+   return hwndframe;
+}
+
+/*
+ * Create a new Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ */
+HWND API dw_box_new(int type, int pad)
+{
+   Box *newbox = calloc(1, sizeof(Box));
+
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+   newbox->grouphwnd = NULLHANDLE;
+
+   newbox->hwnd = WinCreateWindow(HWND_OBJECT,
+                           WC_FRAME,
+                           NULL,
+                           WS_VISIBLE | WS_CLIPCHILDREN |
+                           FS_NOBYTEALIGN,
+                           0,0,2000,1000,
+                           NULLHANDLE,
+                           HWND_TOP,
+                           0L,
+                           NULL,
+                           NULL);
+
+   newbox->oldproc = WinSubclassWindow(newbox->hwnd, _controlproc);
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+   dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   return newbox->hwnd;
+}
+
+/*
+ * Create a new scroll Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ */
+HWND API dw_scrollbox_new(int type, int pad)
+{
+   HWND hwndframe, box = dw_box_new(type, pad);
+   HWND client, tmpbox = dw_box_new(DW_VERT, 0);
+   Box *blah = calloc(sizeof(Box), 1);
+   dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0);
+   hwndframe = WinCreateWindow(HWND_OBJECT, ScrollClassName, "", WS_VISIBLE | WS_CLIPCHILDREN,
+                               0, 0, 2000, 1000, NULLHANDLE, HWND_TOP, 0, NULL, NULL);
+   WinCreateWindow(hwndframe, WC_SCROLLBAR, "", WS_VISIBLE | SBS_AUTOTRACK | SBS_VERT,
+                   0,0,2000,1000, hwndframe, HWND_TOP, FID_VERTSCROLL, NULL, NULL);
+   WinCreateWindow(hwndframe, WC_SCROLLBAR, "", WS_VISIBLE | SBS_AUTOTRACK | SBS_HORZ,
+                   0,0,2000,1000, hwndframe, HWND_TOP, FID_HORZSCROLL, NULL, NULL);
+   client = WinCreateWindow(hwndframe, WC_FRAME, "", WS_VISIBLE | WS_CLIPCHILDREN,
+                      0,0,2000,1000, NULLHANDLE, HWND_TOP, FID_CLIENT, NULL, NULL);
+   WinSetParent(tmpbox, client, FALSE);
+   WinSetWindowPtr(client, QWP_USER, blah);
+   dw_window_set_data(hwndframe, "_dw_resizebox", (void *)tmpbox);
+   dw_window_set_data(hwndframe, "_dw_box", (void *)box);
+   dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   dw_window_set_color(client, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   return hwndframe;
+}
+
+/*
+ * Returns the position of the scrollbar in the scrollbox
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_pos( HWND handle, int orient )
+{
+   HWND scroll;
+
+   if(orient == DW_VERT)
+   {
+      scroll = WinWindowFromID(handle, FID_VERTSCROLL);
+   }
+   else
+   {
+      scroll = WinWindowFromID(handle, FID_HORZSCROLL);
+   }
+   return (int)WinSendMsg(scroll, SBM_QUERYPOS, 0, 0);
+}
+
+/*
+ * Gets the range for the scrollbar in the scrollbox.
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_range( HWND handle, int orient )
+{
+   HWND scroll;
+
+   if(orient == DW_VERT)
+   {
+      scroll = WinWindowFromID(handle, FID_VERTSCROLL);
+   }
+   else
+   {
+      scroll = WinWindowFromID(handle, FID_HORZSCROLL);
+   }
+   return SHORT2FROMMP(WinSendMsg(scroll, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
+}
+
+/*
+ * Create a new Group Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ *       title: Text to be displayined in the group outline.
+ */
+HWND API dw_groupbox_new(int type, int pad, char *title)
+{
+   Box *newbox = calloc(1, sizeof(Box));
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+
+   newbox->hwnd = WinCreateWindow(HWND_OBJECT,
+                           WC_FRAME,
+                           NULL,
+                           WS_VISIBLE |
+                           FS_NOBYTEALIGN,
+                           0,0,2000,1000,
+                           NULLHANDLE,
+                           HWND_TOP,
+                           0L,
+                           NULL,
+                           NULL);
+
+   newbox->grouphwnd = WinCreateWindow(newbox->hwnd,
+                              WC_STATIC,
+                              title,
+                              WS_VISIBLE | SS_GROUPBOX |
+                              WS_GROUP,
+                              0,0,2000,1000,
+                              NULLHANDLE,
+                              HWND_TOP,
+                              0L,
+                              NULL,
+                              NULL);
+
+   WinSetWindowPtr(newbox->hwnd, QWP_USER, newbox);
+   dw_window_set_color(newbox->hwnd, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY);
+   dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   dw_window_set_font(newbox->grouphwnd, DefaultFont);
+   dw_window_set_data(newbox->hwnd, "_dw_buddy", (void *)newbox->grouphwnd);
+   return newbox->hwnd;
+}
+
+/*
+ * Create a new MDI Frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND API dw_mdi_new(unsigned long id)
+{
+   HWND hwndframe;
+   ULONG back = CLR_DARKGRAY;
+
+   hwndframe = WinCreateWindow(HWND_OBJECT,
+                        WC_FRAME,
+                        NULL,
+                        WS_VISIBLE | WS_CLIPCHILDREN |
+                        FS_NOBYTEALIGN,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   /* Make the MDI Client area the same color as Windows and Unix */
+   WinSetPresParam(hwndframe, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back);
+   return hwndframe;
+}
+
+/*
+ * Create a bitmap object to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_bitmap_new(ULONG id)
+{
+   return WinCreateWindow(HWND_OBJECT,
+                     WC_STATIC,
+                     NULL,
+                     WS_VISIBLE | SS_TEXT,
+                     0,0,2000,1000,
+                     NULLHANDLE,
+                     HWND_TOP,
+                     id,
+                     NULL,
+                     NULL);
+}
+
+/*
+ * Create a notebook object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_notebook_new(ULONG id, int top)
+{
+   ULONG flags;
+   HWND tmp;
+
+   if(top)
+      flags = BKS_MAJORTABTOP;
+   else
+      flags = BKS_MAJORTABBOTTOM;
+
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_NOTEBOOK,
+                    NULL,
+                    WS_VISIBLE |
+#ifdef BKS_TABBEDDIALOG
+                    BKS_TABBEDDIALOG |
+#endif
+                    flags,
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id,
+                    NULL,
+                    NULL);
+
+   /* Fix tab sizes on Warp 3 */
+   if(!IS_WARP4())
+   {
+      /* best sizes to be determined by trial and error */
+      WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB));
+   }
+
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a menu object to be popped up.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HMENUI API dw_menu_new(ULONG id)
+{
+   HMENUI tmp = WinCreateWindow(HWND_OBJECT,
+                         WC_MENU,
+                         NULL,
+                         WS_VISIBLE,
+                         0,0,2000,1000,
+                         NULLHANDLE,
+                         HWND_TOP,
+                         id,
+                         NULL,
+                         NULL);
+   return tmp;
+}
+
+/*
+ * Create a menubar on a window.
+ * Parameters:
+ *       location: Handle of a window frame to be attached to.
+ */
+HMENUI API dw_menubar_new(HWND location)
+{
+   HMENUI tmp = WinCreateWindow(location,
+                         WC_MENU,
+                         NULL,
+                         WS_VISIBLE | MS_ACTIONBAR,
+                         0,0,2000,1000,
+                         location,
+                         HWND_TOP,
+                         FID_MENU,
+                         NULL,
+                         NULL);
+   dw_window_set_data(tmp, "_dw_owner", (void *)location);
+   dw_window_set_data(tmp, "_dw_menubar", (void *)location);
+   return tmp;
+}
+
+/*
+ * Destroys a menu created with dw_menubar_new or dw_menu_new.
+ * Parameters:
+ *       menu: Handle of a menu.
+ */
+void API dw_menu_destroy(HMENUI *menu)
+{
+   if(menu)
+      WinDestroyWindow(*menu);
+}
+
+/* Internal function to make sure menu ID isn't in use */
+int _menuid_allocated(int id)
+{
+   SignalHandler *tmp = Root;
+
+   while(tmp)
+   {
+     if(tmp->id == id)
+        return TRUE;   
+     tmp = tmp->next;
+   }
+   return FALSE;
+}
+
+/*
+ * Adds a menuitem or submenu to an existing menu.
+ * Parameters:
+ *       menu: The handle the the existing menu.
+ *       title: The title text on the menu item to be added.
+ *       id: An ID to be used for message passing.
+ *       flags: Extended attributes to set on the menu.
+ *       end: If TRUE memu is positioned at the end of the menu.
+ *       check: If TRUE menu is "check"able.
+ *       flags: Extended attributes to set on the menu.
+ *       submenu: Handle to an existing menu to be a submenu or NULL.
+ */
+HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
+{
+   MENUITEM miSubMenu;
+   char buffer[30];
+   int is_checked, is_disabled;
+
+   if ( !menux || !WinIsWindow(dwhab, menux) )
+      return NULLHANDLE;
+
+   if ( end )
+      miSubMenu.iPosition=MIT_END;
+   else
+      miSubMenu.iPosition=0;
+   /*
+    * Handle flags
+   */
+   miSubMenu.afAttribute = 0;
+   is_checked = (flags & DW_MIS_CHECKED) ? 1 : 0;
+   if ( is_checked )
+      miSubMenu.afAttribute |= MIA_CHECKED;
+   is_disabled = (flags & DW_MIS_DISABLED) ? 1 : 0;
+   if ( is_disabled )
+      miSubMenu.afAttribute |= MIA_DISABLED;
+
+   if (title && *title)
+   {
+      /* Code to autogenerate a menu ID if not specified or invalid
+       * First pool is smaller for transient popup menus 
+       */
+      if(id == (ULONG)-1)
+      {
+         static ULONG tempid = 61000;
+         
+         tempid++;
+         id = tempid;
+         
+         if(tempid > 65500)
+            tempid = 61000;
+      }
+      /* Special internal case */
+      else if(id > 60000 && check == -1)
+      {
+          check = 0;
+      }
+      /* Second pool is larger for more static windows */
+      else if(!id || id >= 30000)
+      {
+         static ULONG menuid = 30000;
+         
+         do
+         {
+            menuid++;
+            if(menuid > 60000)
+               menuid = 30000;
+         }
+         while(_menuid_allocated(menuid));
+         id = menuid;
+      }
+      miSubMenu.afStyle = MIS_TEXT;
+   }
+   else
+      miSubMenu.afStyle = MIS_SEPARATOR;
+   miSubMenu.id=id;
+   miSubMenu.hwndSubMenu = submenu;
+   miSubMenu.hItem=NULLHANDLE;
+
+   WinSendMsg(menux, MM_INSERTITEM, MPFROMP(&miSubMenu), MPFROMP(title));
+
+   sprintf(buffer, "_dw_id%d", (int)id);
+   dw_window_set_data(hwndApp, buffer, (void *)menux);
+   sprintf(buffer, "_dw_checkable%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)check );
+   sprintf(buffer, "_dw_ischecked%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)is_checked );
+   sprintf(buffer, "_dw_isdisabled%ld", id);
+   dw_window_set_data( hwndApp, buffer, (void *)is_disabled );
+
+   if ( submenu )
+      dw_window_set_data(submenu, "_dw_owner", (void *)menux);
+   return (HWND)id;
+}
+
+/*
+ * Sets the state of a menu item check.
+ * Deprecated; use dw_menu_item_set_state()
+ * Parameters:
+ *       menu: The handle the the existing menu.
+ *       id: Menuitem id.
+ *       check: TRUE for checked FALSE for not checked.
+ */
+void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check)
+{
+   if ( check )
+      WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED));
+   else
+      WinSendMsg(menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE),MPFROM2SHORT(MIA_CHECKED, 0));
+}
+
+/*
+ * Sets the state of a menu item.
+ * Parameters:
+ *       menu: The handle to the existing menu.
+ *       id: Menuitem id.
+ *       flags: DW_MIS_ENABLED/DW_MIS_DISABLED
+ *              DW_MIS_CHECKED/DW_MIS_UNCHECKED
+ */
+void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state)
+{
+   char buffer1[30],buffer2[30];
+   int check;
+   int disabled;
+   USHORT fAttribute=0;
+
+   sprintf( buffer1, "_dw_ischecked%ld", id );
+   check = (int)dw_window_get_data( hwndApp, buffer1 );
+   sprintf( buffer2, "_dw_isdisabled%ld", id );
+   disabled = (int)dw_window_get_data( hwndApp, buffer2 );
+
+   if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) )
+   {
+      /*
+       * If we are changing state of "checked" base our setting on the passed flag...
+       */
+      if ( state & DW_MIS_CHECKED )
+      {
+         fAttribute |= MIA_CHECKED;
+         check = 1;
+      }
+      else
+      {
+         check = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "checked" state.
+       */
+      if ( check )
+      {
+         fAttribute |= MIA_CHECKED;
+      }
+   }
+   if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) )
+   {
+      if ( state & DW_MIS_DISABLED )
+      {
+         fAttribute |= MIA_DISABLED;
+         disabled = 1;
+      }
+      else
+      {
+         disabled = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "disabled" state.
+       */
+      if ( disabled )
+      {
+         fAttribute |= MIA_DISABLED;
+      }
+   }
+   WinSendMsg( menux, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), MPFROM2SHORT( MIA_CHECKED|MIA_DISABLED, fAttribute ) );
+   /*
+    * Keep our internal checked state consistent
+    */
+   dw_window_set_data( hwndApp, buffer1, (void *)check );
+   dw_window_set_data( hwndApp, buffer2, (void *)disabled );
+}
+
+/*
+ * Pops up a context menu at given x and y coordinates.
+ * Parameters:
+ *       menu: The handle the the existing menu.
+ *       parent: Handle to the window initiating the popup.
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
+{
+   if(menu)
+   {
+      popup = parent;
+      dw_window_set_data(*menu, "_dw_popup", (void *)1);
+      WinPopupMenu(HWND_DESKTOP, parent, *menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN);
+   }
+}
+
+/*
+ * Returns the current X and Y coordinates of the mouse pointer.
+ * Parameters:
+ *       x: Pointer to variable to store X coordinate.
+ *       y: Pointer to variable to store Y coordinate.
+ */
+void API dw_pointer_query_pos(long *x, long *y)
+{
+   POINTL ptl;
+
+   WinQueryPointerPos(HWND_DESKTOP, &ptl);
+   if(x && y)
+   {
+      *x = ptl.x;
+      *y = dw_screen_height() - ptl.y;
+   }
+}
+
+/*
+ * Sets the X and Y coordinates of the mouse pointer.
+ * Parameters:
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_pointer_set_pos(long x, long y)
+{
+   WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y);
+}
+
+
+/*
+ * Create a container object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_container_new(ULONG id, int multi)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_CONTAINER,
+                        NULL,
+                        WS_VISIBLE | CCS_READONLY |
+                        (multi ? CCS_EXTENDSEL : CCS_SINGLESEL) |
+                        CCS_AUTOPOSITION,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_data(tmp, "_dw_container", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a tree object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_tree_new(ULONG id)
+{
+   CNRINFO cnrinfo;
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_CONTAINER,
+                        NULL,
+                        WS_VISIBLE | CCS_READONLY |
+                        CCS_SINGLESEL | CCS_AUTOPOSITION,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+
+   cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE;
+   cnrinfo.slBitmapOrIcon.cx = 16;
+   cnrinfo.slBitmapOrIcon.cy = 16;
+   cnrinfo.cyLineSpacing = 0;
+   cnrinfo.cxTreeIndent = 16;
+   cnrinfo.cxTreeLine = 1;
+
+   WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON |
+                                          CMA_LINESPACING | CMA_CXTREEINDENT | CMA_CXTREELINE));
+   blah->oldproc = WinSubclassWindow(tmp, _TreeProc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new static text window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_text_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        text,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _textproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
+}
+
+/*
+ * Create a new status text window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_status_text_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        text,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _statusproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
+}
+
+#ifndef MLS_LIMITVSCROLL
+#define MLS_LIMITVSCROLL           0x00000080L
+#endif
+
+/*
+ * Create a new Multiline Editbox window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_mle_new(ULONG id)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_MLE,
+                        "",
+                        WS_VISIBLE |
+                        MLS_BORDER | MLS_IGNORETAB |
+                        MLS_VSCROLL |
+                        MLS_LIMITVSCROLL,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   WinSendMsg(tmp, MLM_FORMAT, (MPARAM)MLFIE_NOTRANS, 0);
+   blah->oldproc = WinSubclassWindow(tmp, _mleproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new Entryfield window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_entryfield_new(char *text, ULONG id)
+{
+
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_ENTRYFIELD,
+                        text,
+                        WS_VISIBLE | ES_MARGIN |
+                        ES_AUTOSCROLL | WS_TABSTOP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
+}
+
+/*
+ * Create a new Entryfield (password) window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_entryfield_password_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_ENTRYFIELD,
+                        text,
+                        WS_VISIBLE | ES_MARGIN | ES_UNREADABLE |
+                        ES_AUTOSCROLL | WS_TABSTOP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
+}
+
+/*
+ * Create a new Combobox window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the combpbox widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_combobox_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND frame = dw_box_new(DW_HORZ, 0);
+   HWND tmp = WinCreateWindow(frame,
+                        WC_COMBOBOX,
+                        text,
+                        WS_VISIBLE | CBS_DROPDOWN | WS_GROUP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   HENUM henum = WinBeginEnumWindows(tmp);
+   HWND child, last = NULLHANDLE;
+
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      WindowData *moreblah = calloc(1, sizeof(WindowData));
+      moreblah->oldproc = WinSubclassWindow(child, _comboentryproc);
+      WinSetWindowPtr(child, QWP_USER, moreblah);
+      dw_window_set_color(child, DW_CLR_BLACK, DW_CLR_WHITE);
+      last = child;
+   }
+   WinEndEnumWindows(henum);
+   blah->oldproc = WinSubclassWindow(tmp, _comboproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   dw_window_set_data(tmp, "_dw_comboentry", (void *)last);
+   dw_window_set_data(tmp, "_dw_combo_box", (void *)frame);
+   WinSetOwner(tmp, frame);
+   return tmp;
+}
+
+/*
+ * Create a new button window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_button_new(char *text, ULONG id)
+{
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        text,
+                        WS_VISIBLE,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+
+   bubble->id = id;
+   bubble->bubbletext[0] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
+}
+
+/* Function: GenResIDStr
+** Abstract: Generate string '#nnnn' for a given ID for using with Button
+**           controls
+*/
+
+void _GenResIDStr(CHAR *buff, ULONG ulID)
+{
+   char *str;
+   int  slen = 0;
+
+   *buff++ = '#';
+
+   str = buff;
+
+   do
+   {
+      *str++ = (ulID % 10) + '0';
+      ulID /= 10;
+      slen++;
+   }
+   while(ulID);
+
+   *str-- = 0;
+
+   for(; str > buff; str--, buff++)
+   {
+      *buff ^= *str;
+      *str  ^= *buff;
+      *buff ^= *str;
+   }
+}
+
+
+/*
+ * Create a new bitmap button window (widget) to be packed.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID of a bitmap in the resource file.
+ */
+HWND API dw_bitmapbutton_new(char *text, ULONG id)
+{
+   char idbuf[256], *name = NULL;
+   HWND tmp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HPOINTER icon = WinLoadPointer(HWND_DESKTOP, 0L, id);
+
+   if(!icon)
+   {
+      name = idbuf;
+      _GenResIDStr(idbuf, id);
+   }
+
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_BUTTON,
+                    name,
+                    WS_VISIBLE | BS_PUSHBUTTON |
+                    BS_NOPOINTERFOCUS | BS_AUTOSIZE |
+                    (icon ? 0 : BS_BITMAP),
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id,
+                    NULL,
+                    NULL);
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from a file.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ */
+HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
+{
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        "",
+                        WS_VISIBLE | BS_PUSHBUTTON |
+                        BS_AUTOSIZE | BS_NOPOINTERFOCUS,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   char *file = alloca(strlen(filename) + 5);
+   HPIXMAP pixmap = NULL, disabled = NULL;
+   HPOINTER icon = 0;
+
+   if(file && (pixmap = calloc(1,sizeof(struct _hpixmap))))
+   {
+      int z, j, lim, len;
+      LONG fore;
+
+      strcpy(file, filename);
+
+      /* check if we can read from this file (it exists and read permission) */
+      if(access(file, 04) == 0)
+      {
+         len = strlen( file );
+         if(len > 4)
+         {
+            if(stricmp(file + len - 4, ".ico") == 0)
+               icon = WinLoadFileIcon(file, FALSE);
+            else
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+         }
+      }
+      else
+      {
+         /* Try with .ico extension first...*/
+         strcat(file, ".ico");
+         if(access(file, 04) == 0)
+            icon = WinLoadFileIcon(file, FALSE);
+         else
+         {
+            strcpy(file, filename);
+            strcat(file, ".bmp");
+            if(access(file, 04) == 0)
+               _load_bitmap_file(file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height);
+         }
+      }
+
+      if(icon)
+      {
+         free(pixmap);
+         pixmap = NULL;
+      }
+      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;
+      }
+   }
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   else
+   {
+      dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
+      dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
+   }
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from data.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       data: The contents of the image
+ *            (BMP or ICO on OS/2 or Windows, XPM on Unix)
+ *       len: length of str
+ */
+HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len)
+{
+   FILE *fp;
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        "",
+                        WS_VISIBLE | BS_PUSHBUTTON |
+                        BS_AUTOSIZE | BS_NOPOINTERFOCUS,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   char *file;
+   HPIXMAP pixmap = NULL, disabled = NULL;
+   HPOINTER icon = 0;
+
+   if ( ( pixmap = calloc( 1, sizeof(struct _hpixmap) ) ) )
+   {
+      int z, j, lim;
+      LONG fore;
+      file = tmpnam( NULL );
+      if ( file != NULL )
+      {
+         fp = fopen( file, "wb" );
+         if ( fp != NULL )
+         {
+            fwrite( data, 1, len, fp );
+            fclose( fp );
+            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+            {
+               _load_bitmap_file( file, tmp, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height );
+            }
+            else /* otherwise its assumed to be an ico */
+            {
+               icon = WinLoadFileIcon(file, FALSE);
+            }
+         }
+         else
+         {
+            unlink( file );
+            return 0;
+         }
+         unlink( file );
+      }
+
+      if ( icon )
+      {
+         free(pixmap);
+         pixmap = NULL;
+      }
+      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;
+      }
+   }
+
+   bubble->id = id;
+   strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
+   bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+
+   if(icon)
+      dw_window_set_data(tmp, "_dw_button_icon", (void *)icon);
+   else
+   {
+      dw_window_set_data(tmp, "_dw_hpixmap", (void *)pixmap);
+      dw_window_set_data(tmp, "_dw_hpixmap_disabled", (void *)disabled);
+   }
+   dw_window_set_data(tmp, "_dw_bitmapbutton", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a new spinbutton window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_spinbutton_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_SPINBUTTON,
+                        text,
+                        WS_VISIBLE | SPBS_MASTER,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   HWND entry = _find_entryfield(tmp);
+   WinSendMsg(tmp, SPBM_SETLIMITS, MPFROMLONG(65536), MPFROMLONG(-65536));
+   WinSendMsg(tmp, SPBM_SETCURRENTVALUE, MPFROMLONG(atoi(text)), 0L);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   blah = calloc(sizeof(WindowData), 1);
+   blah->oldproc = WinSubclassWindow(entry, _spinentryproc);
+   WinSetWindowPtr(entry, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(entry, DW_CLR_BLACK, DW_CLR_WHITE);
+   dw_window_set_data(tmp, "_dw_buddy", (void *)entry);
+   return tmp;
+}
+
+/*
+ * Create a new radiobutton window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_radiobutton_new(char *text, ULONG id)
+{
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        text,
+                        WS_VISIBLE |
+                        BS_AUTORADIOBUTTON,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
+}
+
+
+/*
+ * Create a new slider window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if slider is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_slider_new(int vertical, int increments, ULONG id)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   SLDCDATA sldcData = { 0, 0, 0, 0, 0 };
+   HWND tmp;
+
+   sldcData.cbSize = sizeof(SLDCDATA);
+    sldcData.usScale1Increments = increments;
+
+   tmp = WinCreateWindow(HWND_OBJECT,
+                    WC_SLIDER,
+                    "",
+                    WS_VISIBLE | SLS_SNAPTOINCREMENT |
+                    (vertical ? SLS_VERTICAL : SLS_HORIZONTAL),
+                    0,0,2000,1000,
+                    NULLHANDLE,
+                    HWND_TOP,
+                    id ? id : _GlobalID(),
+                    &sldcData,
+                    NULL);
+
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   return tmp;
+}
+
+/*
+ * Create a new scrollbar window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if scrollbar is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_scrollbar_new(int vertical, ULONG id)
+{
+   return WinCreateWindow(HWND_OBJECT,
+                     WC_SCROLLBAR,
+                     "",
+                     WS_VISIBLE | SBS_AUTOTRACK |
+                     (vertical ? SBS_VERT : SBS_HORZ),
+                     0,0,2000,1000,
+                     NULLHANDLE,
+                     HWND_TOP,
+                     id ? id : _GlobalID(),
+                     NULL,
+                     NULL);
+}
+
+/*
+ * Create a new percent bar window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_percent_new(ULONG id)
+{
+   WindowData *blah = calloc(1, sizeof(WindowData));
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_SLIDER,
+                        "",
+                        WS_VISIBLE | SLS_READONLY
+                        | SLS_RIBBONSTRIP,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _percentproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_disable(tmp);
+   return tmp;
+}
+
+/*
+ * Create a new checkbox window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_checkbox_new(char *text, ULONG id)
+{
+   BubbleButton *bubble = calloc(sizeof(BubbleButton), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_BUTTON,
+                        text,
+                        WS_VISIBLE | BS_AUTOCHECKBOX,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   bubble->id = id;
+   bubble->bubbletext[0] = '\0';
+   bubble->pOldProc = WinSubclassWindow(tmp, _BtProc);
+   WinSetWindowPtr(tmp, QWP_USER, bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+   return tmp;
+}
+
+/*
+ * Create a new listbox window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       multi: Multiple select TRUE or FALSE.
+ */
+HWND API dw_listbox_new(ULONG id, int multi)
+{
+   WindowData *blah = calloc(sizeof(WindowData), 1);
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_LISTBOX,
+                        NULL,
+                        WS_VISIBLE | LS_NOADJUSTPOS |
+                        (multi ? LS_MULTIPLESEL : 0),
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id ? id : _GlobalID(),
+                        NULL,
+                        NULL);
+   blah->oldproc = WinSubclassWindow(tmp, _entryproc);
+   WinSetWindowPtr(tmp, QWP_USER, blah);
+   dw_window_set_font(tmp, DefaultFont);
+   dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE);
+   return tmp;
+}
+
+/*
+ * Sets the icon used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon.
+ */
+void API dw_window_set_icon(HWND handle, HICN icon)
+{
+   HPOINTER hptr = icon < 65536 ? WinLoadPointer(HWND_DESKTOP,NULLHANDLE,icon) : (HPOINTER)icon;
+   WinSendMsg(handle, WM_SETICON, (MPARAM)hptr, 0);
+}
+
+/* Internal function to load a bitmap from a file and return handles
+ * to the bitmap, presentation space etc.
+ */
+int _load_bitmap_file(char *file, HWND handle, HBITMAP *hbm, HDC *hdc, HPS *hps, unsigned long *width, unsigned long *height)
+{
+   HFILE BitmapFileHandle = NULLHANDLE; /* handle for the file */
+   ULONG OpenAction = 0;
+   PBYTE BitmapFileBegin; /* pointer to the first byte of bitmap data  */
+   FILESTATUS BitmapStatus;
+   ULONG cbRead;
+   PBITMAPFILEHEADER2 pBitmapFileHeader;
+   PBITMAPINFOHEADER2 pBitmapInfoHeader;
+   ULONG ScanLines, ulFlags;
+   HPS hps1;
+   HDC hdc1;
+   SIZEL sizl = { 0, 0 };
+
+   /* open bitmap file */
+   DosOpen(file, &BitmapFileHandle, &OpenAction, 0L,
+         FILE_ARCHIVED | FILE_NORMAL | FILE_READONLY,
+         OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+         OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
+         OPEN_FLAGS_NOINHERIT, 0L);
+
+   if(!BitmapFileHandle)
+      return 0;
+
+   /* find out how big the file is  */
+   DosQueryFileInfo(BitmapFileHandle, 1, &BitmapStatus,
+                sizeof(BitmapStatus));
+
+   /* allocate memory to load the bitmap */
+   DosAllocMem((PPVOID)&BitmapFileBegin, (ULONG)BitmapStatus.cbFile,
+            PAG_READ | PAG_WRITE | PAG_COMMIT);
+
+   /* read bitmap file into memory buffer */
+   DosRead(BitmapFileHandle, (PVOID)BitmapFileBegin,
+         BitmapStatus.cbFile, &cbRead);
+
+   /* access first bytes as bitmap header */
+   pBitmapFileHeader = (PBITMAPFILEHEADER2)BitmapFileBegin;
+
+   /* check if it's a valid bitmap data file */
+   if((pBitmapFileHeader->usType != BFT_BITMAPARRAY) &&
+      (pBitmapFileHeader->usType != BFT_BMAP))
+   {
+      /* free memory of bitmap file buffer */
+      DosFreeMem(BitmapFileBegin);
+      /* close the bitmap file */
+      DosClose(BitmapFileHandle);
+      return 0;
+   }
+
+   /* check if it's a file with multiple bitmaps */
+   if(pBitmapFileHeader->usType == BFT_BITMAPARRAY)
+   {
+      /* we'll just use the first bitmap and ignore the others */
+      pBitmapFileHeader = &(((PBITMAPARRAYFILEHEADER2)BitmapFileBegin)->bfh2);
+   }
+
+   /* set pointer to bitmap information block */
+   pBitmapInfoHeader = &pBitmapFileHeader->bmp2;
+
+   /* find out if it's the new 2.0 format or the old format */
+   /* and query number of lines */
+   if(pBitmapInfoHeader->cbFix == sizeof(BITMAPINFOHEADER))
+   {
+      *height = ScanLines = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cy;
+      *width = (ULONG)((PBITMAPINFOHEADER)pBitmapInfoHeader)->cx;
+   }
+   else
+   {
+      *height = ScanLines = pBitmapInfoHeader->cy;
+      *width = pBitmapInfoHeader->cx;
+   }
+
+   /* now we need a presentation space, get it from static control */
+   hps1 = WinGetPS(handle);
+
+   hdc1    = GpiQueryDevice(hps1);
+   ulFlags = GpiQueryPS(hps1, &sizl);
+
+   *hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc1);
+   *hps = GpiCreatePS (dwhab, *hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   /* create bitmap now using the parameters from the info block */
+   *hbm = GpiCreateBitmap(*hps, pBitmapInfoHeader, 0L, NULL, NULL);
+
+   /* select the new bitmap into presentation space */
+   GpiSetBitmap(*hps, *hbm);
+
+   /* now copy the bitmap data into the bitmap */
+   GpiSetBitmapBits(*hps, 0L, ScanLines,
+                BitmapFileBegin + pBitmapFileHeader->offBits,
+                (PBITMAPINFO2)pBitmapInfoHeader);
+
+   WinReleasePS(hps1);
+
+   /* free memory of bitmap file buffer */
+   DosFreeMem(BitmapFileBegin);
+   /* close the bitmap file */
+   DosClose(BitmapFileHandle);
+   return 1;
+}
+
+/*
+ * Sets the bitmap used for a given static window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon,
+ *           (pass 0 if you use the filename param)
+ *       filename: a path to a file (Bitmap on OS/2 or
+ *                 Windows and a pixmap on Unix, pass
+ *                 NULL if you use the id param)
+ */
+void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
+{
+   HBITMAP hbm;
+   HPS     hps;
+
+   /* Destroy any old bitmap data */
+   _free_bitmap(handle);
+
+   /* If id is non-zero use the resource */
+   if ( id )
+   {
+      hps = WinGetPS( handle );
+      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+   }
+   else if ( filename )
+   {
+      HDC hdc;
+      unsigned long width, height;
+      char *file = alloca(strlen(filename) + 5);
+
+      if(!file)
+         return;
+
+      strcpy(file, filename);
+
+      /* check if we can read from this file (it exists and read permission) */
+      if(access(file, 04) != 0)
+      {
+         /* Try with .bmp extention */
+         strcat(file, ".bmp");
+         if(access(file, 04) != 0)
+            return;
+      }
+
+      if(!_load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height))
+         return;
+
+      dw_window_set_data(handle, "_dw_hps", (void *)hps);
+      dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
+      dw_window_set_data(handle, "_dw_width", (void *)width);
+      dw_window_set_data(handle, "_dw_height", (void *)height);
+   }
+   else
+      return;
+
+   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
+   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
+   if ( id )
+      WinReleasePS(hps);
+   dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+}
+
+/*
+ * Sets the bitmap used for a given static window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon,
+ *           (pass 0 if you use the filename param)
+ *       filename: a path to a file (Bitmap on OS/2 or
+ *                 Windows and a pixmap on Unix, pass
+ *                 NULL if you use the id param)
+ */
+void API dw_window_set_bitmap_from_data(HWND handle, unsigned long id, char *data, int len)
+{
+   HBITMAP hbm;
+   HPS     hps;
+   HDC hdc;
+   unsigned long width, height;
+   char *file;
+   FILE *fp;
+
+   /* Destroy any old bitmap data */
+   _free_bitmap(handle);
+
+   /* If id is non-zero use the resource */
+   if ( id )
+   {
+      hps = WinGetPS( handle );
+      hbm = GpiLoadBitmap( hps, NULLHANDLE, id, 0, 0 );
+   }
+   else if ( data )
+   {
+      file = tmpnam( NULL );
+      if ( file != NULL )
+      {
+         fp = fopen( file, "wb" );
+         if ( fp != NULL )
+         {
+            fwrite( data, 1, len, fp );
+            fclose( fp );
+            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+               _load_bitmap_file(file, handle, &hbm, &hdc, &hps, &width, &height);
+            else /* otherwise its assumed to be an ico */
+            {
+               /* con't use ICO ? */
+               unlink( file );
+               return;
+            }
+         }
+         else
+         {
+            unlink( file );
+            return;
+         }
+         unlink( file );
+      }
+
+      dw_window_set_data(handle, "_dw_hps", (void *)hps);
+      dw_window_set_data(handle, "_dw_hdc", (void *)hdc);
+      dw_window_set_data(handle, "_dw_width", (void *)width);
+      dw_window_set_data(handle, "_dw_height", (void *)height);
+   }
+   else
+      return;
+
+   WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f);
+   WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL );
+   if ( id )
+      WinReleasePS(hps);
+   dw_window_set_data(handle, "_dw_bitmap", (void *)hbm);
+}
+
+/*
+ * Sets the text used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       text: The text associsated with a given window.
+ */
+void API dw_window_set_text(HWND handle, char *text)
+{
+   HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   WinSetWindowText(entryfield ? entryfield : handle, text);
+}
+
+/*
+ * Gets the text used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ * Returns:
+ *       text: The text associsated with a given window.
+ */
+char * API dw_window_get_text(HWND handle)
+{
+   HWND entryfield = (HWND)dw_window_get_data(handle, "_dw_buddy");
+   int len = WinQueryWindowTextLength(entryfield ? entryfield : handle);
+   char *tempbuf = calloc(1, len + 2);
+
+   WinQueryWindowText(entryfield ? entryfield : handle, len + 1, tempbuf);
+
+   return tempbuf;
+}
+
+/*
+ * Disables given window (widget).
+ * Parameters:
+ *       handle: Handle to the window.
+ */
+void API dw_window_disable(HWND handle)
+{
+   char tmpbuf[100];
+
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, DW_MIS_DISABLED);
+      return;
+   }
+
+   if(dw_window_get_data(handle, "_dw_disabled"))
+      return;
+
+   WinQueryClassName(handle, 99, tmpbuf);
+   dw_window_set_data(handle, "_dw_disabled", (void *)1);
+
+   if(tmpbuf[0] == '#')
+   {
+      int val = atoi(&tmpbuf[1]);
+      HWND hwnd;
+
+      switch(val)
+      {
+      case 2:
+      case 6:
+      case 10:
+      case 32:
+      case 7:
+         hwnd = _find_entryfield(handle);
+         _dw_window_set_color(hwnd ? hwnd : handle, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+         dw_signal_connect(hwnd ? hwnd : handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+            if(val == 2)
+            dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         if(hwnd)
+            dw_window_set_data(hwnd, "_dw_disabled", (void *)1);
+         return;
+      case 3:
+         if(dw_window_get_data(handle, "_dw_bitmapbutton") && !dw_window_get_data(handle, "_dw_hpixmap"))
+            WinEnableWindow(handle, FALSE);
+         else if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
+            WinInvalidateRect(handle, NULL, FALSE);
+         else
+            _dw_window_set_color(handle, DW_CLR_DARKGRAY, DW_CLR_PALEGRAY);
+         dw_signal_connect(handle, DW_SIGNAL_KEY_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         dw_signal_connect(handle, DW_SIGNAL_BUTTON_PRESS, DW_SIGNAL_FUNC(_null_key), (void *)100);
+         return;
+      }
+   }
+   WinEnableWindow(handle, FALSE);
+}
+
+/*
+ * Enables given window (widget).
+ * Parameters:
+ *       handle: Handle to the window.
+ */
+void API dw_window_enable(HWND handle)
+{
+   ULONG fore = (ULONG)dw_window_get_data(handle, "_dw_fore");
+   ULONG back = (ULONG)dw_window_get_data(handle, "_dw_back");
+   HWND hwnd = _find_entryfield(handle);
+
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, DW_MIS_ENABLED);
+      return;
+   }
+
+   dw_window_set_data(handle, "_dw_disabled", 0);
+   if(hwnd)
+      dw_window_set_data(hwnd, "_dw_disabled", 0);
+   if(fore && back)
+      _dw_window_set_color(hwnd ? hwnd : handle, fore-1, back-1);
+   dw_signal_disconnect_by_data(handle, (void *)100);
+   WinEnableWindow(handle, TRUE);
+   if(dw_window_get_data(handle, "_dw_bitmapbutton") && dw_window_get_data(handle, "_dw_hpixmap_disabled"))
+      WinInvalidateRect(handle, NULL, FALSE);
+}
+
+/*
+ * Gets the child window handle with specified ID.
+ * Parameters:
+ *       handle: Handle to the parent window.
+ *       id: Integer ID of the child.
+ */
+HWND API dw_window_from_id(HWND handle, int id)
+{
+   HENUM henum;
+   HWND child;
+   char tmpbuf[100];
+
+   henum = WinBeginEnumWindows(handle);
+   while((child = WinGetNextWindow(henum)) != NULLHANDLE)
+   {
+      int windowid = WinQueryWindowUShort(child, QWS_ID);
+      HWND found;
+
+      WinQueryClassName(child, 99, tmpbuf);
+
+      /* If the child is a box (frame) then recurse into it */
+      if(strncmp(tmpbuf, "#1", 3)==0)
+         if((found = dw_window_from_id(child, id)) != NULLHANDLE)
+            return found;
+
+      if(windowid && windowid == id)
+      {
+         WinEndEnumWindows(henum);
+         return child;
+      }
+   }
+   WinEndEnumWindows(henum);
+   return NULLHANDLE;
+}
+
+/* Internal box packing function called by the other 3 functions */
+void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
+{
+   Box *thisbox;
+   
+      /*
+       * If you try and pack an item into itself VERY bad things can happen; like at least an
+       * infinite loop on GTK! Lets be safe!
+       */
+   if(box == item)
+   {
+      dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
+      return;
+   }
+
+   if(WinWindowFromID(box, FID_CLIENT))
+   {
+      HWND intbox = (HWND)dw_window_get_data(box, "_dw_box");
+      if(intbox)
+      {
+         box = intbox;
+      }
+      else
+      {
+         box = WinWindowFromID(box, FID_CLIENT);
+         hsize = vsize = TRUE;
+      }
+   }
+   
+   thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox)
+   {
+      int z, x = 0;
+      Item *tmpitem, *thisitem = thisbox->items;
+      char tmpbuf[100];
+      HWND frame = (HWND)dw_window_get_data(item, "_dw_combo_box");
+
+      /* Do some sanity bounds checking */
+      if(index < 0)
+        index = 0;
+      if(index > thisbox->count)
+        index = thisbox->count;
+        
+      tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
+
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(z == index)
+            x++;
+         tmpitem[x] = thisitem[z];
+         x++;
+      }
+
+
+      WinQueryClassName(item, 99, tmpbuf);
+
+      if(vsize && !height)
+         height = 1;
+      if(hsize && !width)
+         width = 1;
+
+      if(strncmp(tmpbuf, "#1", 3)==0)
+         tmpitem[index].type = TYPEBOX;
+      else
+      {
+         if ( width == 0 && hsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
+         if ( height == 0 && vsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
+
+         tmpitem[index].type = TYPEITEM;
+      }
+
+      tmpitem[index].hwnd = item;
+      tmpitem[index].origwidth = tmpitem[index].width = width;
+      tmpitem[index].origheight = tmpitem[index].height = height;
+      tmpitem[index].pad = pad;
+      if(hsize)
+         tmpitem[index].hsize = SIZEEXPAND;
+      else
+         tmpitem[index].hsize = SIZESTATIC;
+
+      if(vsize)
+         tmpitem[index].vsize = SIZEEXPAND;
+      else
+         tmpitem[index].vsize = SIZESTATIC;
+
+      thisbox->items = tmpitem;
+
+      if(thisbox->count)
+         free(thisitem);
+
+      thisbox->count++;
+
+      WinQueryClassName(item, 99, tmpbuf);
+      /* Don't set the ownership if it's an entryfield or spinbutton */
+      if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0 && strncmp(tmpbuf, "#2", 3)!=0)
+         WinSetOwner(item, box);
+      WinSetParent(frame ? frame : item, box, FALSE);
+   }
+}
+
+/*
+ * Pack windows (widgets) into a box at an arbitrary location.
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       index: 0 based index of packed items. 
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad)
+{
+    _dw_box_pack(box, item, index, width, height, hsize, vsize, pad, "dw_box_pack_at_index()");
+}
+
+/*
+ * Pack windows (widgets) into a box from the start (or top).
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
+{
+    /* 65536 is the table limit on GTK... 
+     * seems like a high enough value we will never hit it here either.
+     */
+    _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()");
+}
+
+/*
+ * Pack windows (widgets) into a box from the end (or bottom).
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
+{
+    _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
+}
+
+/*
+ * Sets the size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          width: New width in pixels.
+ *          height: New height in pixels.
+ */
+void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
+{
+   WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE);
+}
+
+/*
+ * Returns the width of the screen.
+ */
+int API dw_screen_width(void)
+{
+   return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN);
+}
+
+/*
+ * Returns the height of the screen.
+ */
+int API dw_screen_height(void)
+{
+   return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN);
+}
+
+/* This should return the current color depth */
+unsigned long API dw_color_depth_get(void)
+{
+   HDC hdc = WinOpenWindowDC(HWND_DESKTOP);
+   long colors;
+
+   DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors);
+   DevCloseDC(hdc);
+   return colors;
+}
+
+
+/*
+ * Sets the position of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ */
+void API dw_window_set_pos(HWND handle, LONG x, LONG y)
+{
+   int myy = _get_frame_height(handle) - (y + _get_height(handle));
+
+   WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE);
+}
+
+/*
+ * Sets the position and size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ *          width: Width of the widget.
+ *          height: Height of the widget.
+ */
+void API dw_window_set_pos_size(HWND handle, LONG x, LONG y, ULONG width, ULONG height)
+{
+   int myy = _get_frame_height(handle) - (y + height);
+
+   WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+}
+
+/*
+ * Gets the position and size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ *          width: Width of the widget.
+ *          height: Height of the widget.
+ */
+void API dw_window_get_pos_size(HWND handle, LONG *x, LONG *y, ULONG *width, ULONG *height)
+{
+   SWP swp;
+   WinQueryWindowPos(handle, &swp);
+   if(x)
+      *x = swp.x;
+   if(y)
+      *y = _get_frame_height(handle) - (swp.y + swp.cy);
+   if(width)
+      *width = swp.cx;
+   if(height)
+      *height = swp.cy;
+}
+
+/*
+ * Sets the style of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          width: New width in pixels.
+ *          height: New height in pixels.
+ */
+void API dw_window_set_style(HWND handle, ULONG style, ULONG mask)
+{
+   if(handle < 65536)
+   {
+      char buffer[30];
+      HMENUI mymenu;
+      
+      sprintf(buffer, "_dw_id%ld", handle);
+      mymenu = (HMENUI)dw_window_get_data(hwndApp, buffer);
+      
+      if(mymenu && WinIsWindow(dwhab, mymenu))
+          dw_menu_item_set_state(mymenu, handle, style & mask);
+   }
+   else
+      WinSetWindowBits(handle, QWL_STYLE, style, mask);
+}
+
+/*
+ * Adds a new page to specified notebook.
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          flags: Any additional page creation flags.
+ *          front: If TRUE page is added at the beginning.
+ */
+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));
+}
+
+/*
+ * Remove a page from a notebook.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ *          pageid: ID of the page to be destroyed.
+ */
+void API dw_notebook_page_destroy(HWND handle, unsigned int pageid)
+{
+   HWND pagehwnd = (HWND)WinSendMsg(handle, BKM_QUERYPAGEWINDOWHWND,
+                                    MPFROMLONG(pageid), 0L);
+   WinSendMsg(handle, BKM_DELETEPAGE,
+            MPFROMLONG(pageid),  (MPARAM)BKA_SINGLE);
+   if(pagehwnd)
+      dw_window_destroy(pagehwnd);
+}
+
+/*
+ * Queries the currently visible page ID.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ */
+unsigned long API dw_notebook_page_get(HWND handle)
+{
+   return (unsigned long)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR));
+}
+
+/*
+ * Sets the currently visibale page ID.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ *          pageid: ID of the page to be made visible.
+ */
+void API dw_notebook_page_set(HWND handle, unsigned int pageid)
+{
+   WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L);
+}
+
+/*
+ * Sets the text on the specified notebook tab.
+ * Parameters:
+ *          handle: Notebook handle.
+ *          pageid: Page ID of the tab to set.
+ *          text: Pointer to the text to set.
+ */
+void API dw_notebook_page_set_text(HWND handle, ULONG pageid, char *text)
+{
+   WinSendMsg(handle, BKM_SETTABTEXT,
+            MPFROMLONG(pageid),  MPFROMP(text));
+}
+
+/*
+ * Sets the text on the specified notebook tab status area.
+ * Parameters:
+ *          handle: Notebook handle.
+ *          pageid: Page ID of the tab to set.
+ *          text: Pointer to the text to set.
+ */
+void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text)
+{
+   WinSendMsg(handle, BKM_SETSTATUSLINETEXT,
+            MPFROMLONG(pageid),  MPFROMP(text));
+}
+
+/*
+ * Packs the specified box into the notebook page.
+ * Parameters:
+ *          handle: Handle to the notebook to be packed.
+ *          pageid: Page ID in the notebook which is being packed.
+ *          page: Box handle to be packed.
+ */
+void API dw_notebook_pack(HWND handle, ULONG pageid, HWND page)
+{
+   HWND tmpbox = dw_box_new(DW_VERT, 0);
+
+   dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
+   WinSubclassWindow(tmpbox, _wndproc);
+   WinSendMsg(handle, BKM_SETPAGEWINDOWHWND,
+            MPFROMLONG(pageid),  MPFROMHWND(tmpbox));
+}
+
+/*
+ * Appends the specified text to the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be appended to.
+ *          text: Text to append into listbox.
+ */
+void API dw_listbox_append(HWND handle, char *text)
+{
+   WinSendMsg(handle,
+            LM_INSERTITEM,
+            MPFROMSHORT(LIT_END),
+            MPFROMP(text));
+}
+
+/*
+ * Inserts the specified text into the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be inserted into.
+ *          text: Text to insert into listbox.
+ *          pos: 0-based position to insert text
+ */
+void API dw_listbox_insert(HWND handle, char *text, int pos)
+{
+   WinSendMsg(handle,
+            LM_INSERTITEM,
+            MPFROMSHORT(pos),
+            MPFROMP(text));
+}
+
+/*
+ * Appends the specified text items to the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be appended to.
+ *          text: Text strings to append into listbox.
+ *          count: Number of text strings to append
+ */
+void API dw_listbox_list_append(HWND handle, char **text, int count)
+{
+   int i;
+   for(i=0;i<count;i++)
+      WinSendMsg(handle,
+               LM_INSERTITEM,
+               MPFROMSHORT(LIT_END),
+               MPFROMP(text[i]));
+}
+
+/*
+ * Clears the listbox's (or combobox) list of all entries.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ */
+void API dw_listbox_clear(HWND handle)
+{
+   WinSendMsg(handle,
+            LM_DELETEALL, 0L, 0L);
+}
+
+/*
+ * Returns the listbox's item count.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ */
+int API dw_listbox_count(HWND handle)
+{
+   return (int)WinSendMsg(handle,
+                     LM_QUERYITEMCOUNT,0L, 0L);
+}
+
+/*
+ * Sets the topmost item in the viewport.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ *          top: Index to the top item.
+ */
+void API dw_listbox_set_top(HWND handle, int top)
+{
+   WinSendMsg(handle,
+            LM_SETTOPINDEX,
+            MPFROMSHORT(top),
+            0L);
+}
+
+/*
+ * Copies the given index item's text into buffer.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          index: Index into the list to be queried.
+ *          buffer: Buffer where text will be copied.
+ *          length: Length of the buffer (including NULL).
+ */
+void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
+{
+   WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer);
+}
+
+/*
+ * Sets the text of a given listbox entry.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          index: Index into the list to be queried.
+ *          buffer: Buffer where text will be copied.
+ */
+void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
+{
+   WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer);
+}
+
+/*
+ * Returns the index to the item in the list currently selected.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ */
+int API dw_listbox_selected(HWND handle)
+{
+      return (unsigned int)WinSendMsg(handle,
+                              LM_QUERYSELECTION,
+                              MPFROMSHORT(LIT_CURSOR),
+                              0);
+}
+
+/*
+ * Returns the index to the current selected item or -1 when done.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          where: Either the previous return or -1 to restart.
+ */
+int API dw_listbox_selected_multi(HWND handle, int where)
+{
+   int place = where;
+
+   if(where == -1)
+      place = LIT_FIRST;
+
+   place = (int)WinSendMsg(handle,
+                     LM_QUERYSELECTION,
+                     MPFROMSHORT(place),0L);
+   if(place == LIT_NONE)
+      return -1;
+   return place;
+}
+
+/*
+ * Sets the selection state of a given index.
+ * Parameters:
+ *          handle: Handle to the listbox to be set.
+ *          index: Item index.
+ *          state: TRUE if selected FALSE if unselected.
+ */
+void API dw_listbox_select(HWND handle, int index, int state)
+{
+   char tmpbuf[100];
+
+   WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state);
+
+   WinQueryClassName(handle, 99, tmpbuf);
+
+   /* If we are setting a combobox call the event handler manually */
+   if(strncmp(tmpbuf, "#6", 3)==0)
+      _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle);
+}
+
+/*
+ * Deletes the item with given index from the list.
+ * Parameters:
+ *          handle: Handle to the listbox to be set.
+ *          index: Item index.
+ */
+void API dw_listbox_delete(HWND handle, int index)
+{
+   WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0);
+}
+
+/*
+ * Adds text to an MLE box and returns the current point.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          buffer: Text buffer to be imported.
+ *          startpoint: Point to start entering text.
+ */
+unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
+{
+   long point = startpoint < 0 ? 0 : startpoint;
+   PBYTE mlebuf;
+
+   /* Work around 64K limit */
+   if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
+   {
+      int amount, len = strlen(buffer), written = 0;
+
+      while(written < len)
+      {
+         int z, x = 0;
+
+         if((len - written) > 65535)
+            amount = 65535;
+         else
+            amount = len - written;
+
+         /* Remove Carriage Returns \r */
+         for(z=0;z<amount;z++)
+         {
+             if(buffer[z] != '\r')
+             {
+                 mlebuf[x] = buffer[z];
+                 x++;
+             }
+         }
+
+         if(point < 0)
+             point = 0;
+         WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(x));
+         WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(x));
+
+         written += amount;
+      }
+      DosFreeMem(mlebuf);
+   }
+   return point;
+}
+
+/*
+ * Grabs text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          buffer: Text buffer to be exported.
+ *          startpoint: Point to start grabbing text.
+ *          length: Amount of text to be grabbed.
+ */
+void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
+{
+   PBYTE mlebuf;
+
+   /* Work around 64K limit */
+   if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE))
+   {
+      int amount, copied, written = 0;
+
+      while(written < length)
+      {
+         if((length - written) > 65535)
+            amount = 65535;
+         else
+            amount = length - written;
+
+         WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount));
+         copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount));
+
+         if(copied)
+         {
+            memcpy(&buffer[written], mlebuf, copied);
+
+            written += copied;
+         }
+         else
+            break;
+      }
+      DosFreeMem(mlebuf);
+   }
+}
+
+/*
+ * Obtains information about an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          bytes: A pointer to a variable to return the total bytes.
+ *          lines: A pointer to a variable to return the number of lines.
+ */
+void API dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines)
+{
+   if(bytes)
+      *bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0);
+   if(lines)
+      *lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0);
+}
+
+/*
+ * Deletes text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be deleted from.
+ *          startpoint: Point to start deleting text.
+ *          length: Amount of text to be deleted.
+ */
+void API dw_mle_delete(HWND handle, int startpoint, int length)
+{
+   WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(length));
+}
+
+/*
+ * Clears all text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be cleared.
+ */
+void API dw_mle_clear(HWND handle)
+{
+   unsigned long bytes;
+
+   dw_mle_get_size(handle, &bytes, NULL);
+
+   WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes));
+}
+
+/*
+ * Sets the visible line of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be positioned.
+ *          line: Line to be visible.
+ */
+void API dw_mle_set_visible(HWND handle, int line)
+{
+   int tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line), 0);
+   WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(tmppnt), MPFROMLONG(tmppnt));
+}
+
+/*
+ * Sets the editablity of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: TRUE if it can be edited, FALSE for readonly.
+ */
+void API dw_mle_set_editable(HWND handle, int state)
+{
+   WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0);
+}
+
+/*
+ * Sets the word wrap state of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: TRUE if it wraps, FALSE if it doesn't.
+ */
+void API dw_mle_set_word_wrap(HWND handle, int state)
+{
+   WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0);
+}
+
+/*
+ * Sets the current cursor position of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be positioned.
+ *          point: Point to position cursor.
+ */
+void API dw_mle_set_cursor(HWND handle, int point)
+{
+   WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point));
+}
+
+/*
+ * Finds text in an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be cleared.
+ *          text: Text to search for.
+ *          point: Start point of search.
+ *          flags: Search specific flags.
+ */
+int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
+{
+   MLE_SEARCHDATA msd;
+
+   /* This code breaks with structure packing set to 1 (/Sp1 in VAC)
+    * if this is needed we need to add a pragma here.
+    */
+   msd.cb = sizeof(msd);
+   msd.pchFind = text;
+   msd.pchReplace = NULL;
+   msd.cchFind = strlen(text);
+   msd.cchReplace = 0;
+   msd.iptStart = point;
+   msd.iptStop = -1;
+
+   if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd))
+      return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0);
+   return 0;
+}
+
+/*
+ * Stops redrawing of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to freeze.
+ */
+void API dw_mle_freeze(HWND handle)
+{
+   WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0);
+}
+
+/*
+ * Resumes redrawing of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to thaw.
+ */
+void API dw_mle_thaw(HWND handle)
+{
+   WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0);
+}
+
+/* Internal version that can be called from _percentthread */
+void _dw_percent_set_pos(HWND handle, unsigned int position)
+{
+   int range = _dw_percent_get_range(handle);
+
+   if(range)
+   {
+      int mypos = (((float)position)/100)*range;
+
+      if(mypos >= range)
+          mypos = range - 1;
+  
+      _dw_int_set(handle, mypos);
+      WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)mypos);
+   }
+}
+
+/* Move the percentage bar backwards to simulate indeterminate */
+void _percentthread(void *data)
+{
+   HWND percent = (HWND)data;
+
+   if(percent)
+   {
+       HAB thishab = WinInitialize(0);
+       HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
+
+       int pos = 100;
+
+       do
+       {
+           pos--;
+           if(pos < 1)
+               pos = 100;
+           _dw_percent_set_pos(percent, pos);
+           DosSleep(100);
+       }
+       while(dw_window_get_data(percent, "_dw_ind"));
+
+       WinDestroyMsgQueue(thishmq);
+       WinTerminate(thishab);
+   }
+}
+
+/*
+ * Sets the percent bar position.
+ * Parameters:
+ *          handle: Handle to the percent bar to be set.
+ *          position: Position of the percent bar withing the range.
+ */
+void API dw_percent_set_pos(HWND handle, unsigned int position)
+{
+   /* OS/2 doesn't really support indeterminate... */
+   if(position == DW_PERCENT_INDETERMINATE)
+   {
+       if(!dw_window_get_data(handle, "_dw_ind"))
+       {
+           /* So we fake it with a thread */
+           dw_window_set_data(handle, "_dw_ind", (void *)1);
+           _beginthread(_percentthread, NULL, 100, (void *)handle);
+       }
+   }
+   else
+   {
+       /* Make sure we are no longer indeterminate */
+       dw_window_set_data(handle, "_dw_ind", NULL);
+      /* Otherwise set the position as usual */
+       _dw_percent_set_pos(handle, position);
+   }
+}
+
+/*
+ * Returns the position of the slider.
+ * Parameters:
+ *          handle: Handle to the slider to be queried.
+ */
+unsigned int API dw_slider_get_pos(HWND handle)
+{
+   return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0);
+}
+
+/*
+ * Sets the slider position.
+ * Parameters:
+ *          handle: Handle to the slider to be set.
+ *          position: Position of the slider withing the range.
+ */
+void API dw_slider_set_pos(HWND handle, unsigned int position)
+{
+   dw_window_set_data(handle, "_dw_slider_value", (void *)position);
+   WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position);
+}
+
+/*
+ * Returns the position of the scrollbar.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be queried.
+ */
+unsigned int API dw_scrollbar_get_pos(HWND handle)
+{
+   return (unsigned int)WinSendMsg(handle, SBM_QUERYPOS, 0, 0);
+}
+
+/*
+ * Sets the scrollbar position.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          position: Position of the scrollbar withing the range.
+ */
+void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
+{
+   dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
+   WinSendMsg(handle, SBM_SETPOS, (MPARAM)position, 0);
+}
+
+/*
+ * Sets the scrollbar range.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          range: Maximum range value.
+ *          visible: Visible area relative to the range.
+ */
+void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
+{
+   unsigned int pos = (unsigned int)dw_window_get_data(handle, "_dw_scrollbar_value");
+   WinSendMsg(handle, SBM_SETSCROLLBAR, (MPARAM)pos, MPFROM2SHORT(0, (unsigned short)range - visible));
+   WinSendMsg(handle, SBM_SETTHUMBSIZE, MPFROM2SHORT((unsigned short)visible, range), 0);
+   dw_window_set_data(handle, "_dw_scrollbar_visible", (void *)visible);
+}
+
+/*
+ * Sets the spinbutton value.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          position: Current value of the spinbutton.
+ */
+void API dw_spinbutton_set_pos(HWND handle, long position)
+{
+   WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L);
+}
+
+/*
+ * Sets the spinbutton limits.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          upper: Upper limit.
+ *          lower: Lower limit.
+ */
+void API dw_spinbutton_set_limits(HWND handle, long upper, long lower)
+{
+   WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower));
+}
+
+/*
+ * Sets the entryfield character limit.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          limit: Number of characters the entryfield will take.
+ */
+void API dw_entryfield_set_limit(HWND handle, ULONG limit)
+{
+   WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0);
+}
+
+
+/*
+ * Returns the current value of the spinbutton.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be queried.
+ */
+long API dw_spinbutton_get_pos(HWND handle)
+{
+   long tmpval = 0L;
+
+   WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L);
+   return tmpval;
+}
+
+/*
+ * Returns the state of the checkbox.
+ * Parameters:
+ *          handle: Handle to the checkbox to be queried.
+ */
+int API dw_checkbox_get(HWND handle)
+{
+   return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0);
+}
+
+/*
+ * Sets the state of the checkbox.
+ * Parameters:
+ *          handle: Handle to the checkbox to be queried.
+ *          value: TRUE for checked, FALSE for unchecked.
+ */
+void API dw_checkbox_set(HWND handle, int value)
+{
+   WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
+}
+
+/*
+ * Inserts an item into a tree window (widget) after another item.
+ * Parameters:
+ *          handle: Handle to the tree to be inserted.
+ *          item: Handle to the item to be positioned after.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ *          parent: Parent handle or 0 if root.
+ *          itemdata: Item specific data.
+ */
+HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   ULONG        cbExtra;
+   PCNRITEM     pci;
+   RECORDINSERT ri;
+
+   if(!item)
+      item = (HTREEITEM)CMA_FIRST;
+
+   /* Calculate extra bytes needed for each record besides that needed for the
+    * MINIRECORDCORE structure
+    */
+
+   cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE);
+
+   /* Allocate memory for the parent record */
+
+   if((pci = (PCNRITEM)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1), 0)) == 0)
+      return 0;
+
+   /* Fill in the parent record data */
+
+   pci->rc.cb          = sizeof(MINIRECORDCORE);
+   pci->rc.pszIcon     = strdup(title);
+   pci->rc.hptrIcon    = icon;
+
+   pci->hptrIcon       = icon;
+   pci->user           = itemdata;
+   pci->parent         = parent;
+
+   memset(&ri, 0, sizeof(RECORDINSERT));
+
+   ri.cb                 = sizeof(RECORDINSERT);
+   ri.pRecordOrder       = (PRECORDCORE)item;
+   ri.zOrder             = (USHORT)CMA_TOP;
+   ri.cRecordsInsert     = 1;
+   ri.fInvalidateRecord  = TRUE;
+
+   /* We are about to insert the child records. Set the parent record to be
+    * the one we just inserted.
+    */
+   ri.pRecordParent = (PRECORDCORE)parent;
+
+   /* Insert the record */
+   WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri));
+
+   return (HTREEITEM)pci;
+}
+
+/*
+ * Inserts an item into a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree to be inserted.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ *          parent: Parent handle or 0 if root.
+ *          itemdata: Item specific data.
+ */
+HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   return dw_tree_insert_after(handle, (HTREEITEM)CMA_END, title, icon, parent, itemdata);
+}
+
+/*
+ * Sets the text and icon of an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ */
+void API dw_tree_item_change(HWND handle, HTREEITEM item, char *title, HICN icon)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   if(!pci)
+      return;
+
+   if(pci->rc.pszIcon)
+      free(pci->rc.pszIcon);
+
+   pci->rc.pszIcon     = strdup(title);
+   pci->rc.hptrIcon    = icon;
+
+   pci->hptrIcon       = icon;
+
+   WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+char * API dw_tree_get_title(HWND handle, HTREEITEM item)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(pci)
+      return pci->rc.pszIcon;
+   return NULL;
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(pci)
+      return pci->parent;
+   return (HTREEITEM)0;
+}
+
+/*
+ * Sets the item data of a tree item.
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ *          itemdata: User defined data to be associated with item.
+ */
+void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(!pci)
+      return;
+
+   pci->user = itemdata;
+}
+
+/*
+ * Gets the item data of a tree item.
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+void * API dw_tree_item_get_data(HWND handle, HTREEITEM item)
+{
+   PCNRITEM pci = (PCNRITEM)item;
+
+   handle = handle; /* keep compiler happy */
+   if(!pci)
+      return NULL;
+   return pci->user;
+}
+
+/*
+ * Sets this item as the active selection.
+ * Parameters:
+ *       handle: Handle to the tree window (widget) to be selected.
+ *       item: Handle to the item to be selected.
+ */
+void API dw_tree_item_select(HWND handle, HTREEITEM item)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(pCore)
+   {
+      if(pCore->flRecordAttr & CRA_SELECTED)
+         WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+   WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
+   lastitem = 0;
+   lasthcnr = 0;
+}
+
+/*
+ * Removes all nodes from a tree.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be cleared.
+ */
+void API dw_tree_clear(HWND handle)
+{
+   dw_container_clear(handle, TRUE);
+}
+
+/*
+ * Expands a node on a tree.
+ * Parameters:
+ *       handle: Handle to the tree window (widget).
+ *       item: Handle to node to be expanded.
+ */
+void API dw_tree_item_expand(HWND handle, HTREEITEM item)
+{
+   WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0);
+}
+
+/*
+ * Collapses a node on a tree.
+ * Parameters:
+ *       handle: Handle to the tree window (widget).
+ *       item: Handle to node to be collapsed.
+ */
+void API dw_tree_item_collapse(HWND handle, HTREEITEM item)
+{
+   WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
+}
+
+/*
+ * Removes a node from a tree.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be cleared.
+ *       item: Handle to node to be deleted.
+ */
+void API dw_tree_item_delete(HWND handle, HTREEITEM item)
+{
+   PCNRITEM     pci = (PCNRITEM)item;
+
+   if(!item)
+      return;
+
+   if(pci->rc.pszIcon)
+   {
+      free(pci->rc.pszIcon);
+      pci->rc.pszIcon = 0;
+   }
+
+   WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE));
+}
+
+/* Some OS/2 specific container structs */
+typedef struct _containerinfo {
+   int count;
+   void *data;
+   HWND handle;
+} ContainerInfo;
+
+/*
+ * Sets up the container columns.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          flags: An array of unsigned longs with column flags.
+ *          titles: An array of strings with column text titles.
+ *          count: The number of columns (this should match the arrays).
+ *          separator: The column number that contains the main separator.
+ *                     (this item may only be used in OS/2)
+ */
+int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
+{
+   PFIELDINFO details, first, left = NULL;
+   FIELDINFOINSERT detin;
+   CNRINFO cnri;
+   int z;
+   ULONG size = sizeof(RECORDCORE);
+   ULONG *offStruct = malloc(count * sizeof(ULONG));
+   ULONG *tempflags = malloc((count+1) * sizeof(ULONG));
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *oldflags = blah ? blah->data : 0;
+
+   if(!offStruct || !tempflags)
+      return FALSE;
+
+   memcpy(tempflags, flags, count * sizeof(ULONG));
+   tempflags[count] = 0;
+
+   blah->data = tempflags;
+   blah->flags = separator;
+
+   if(oldflags)
+      free(oldflags);
+
+   while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO,  0, MPFROMSHORT(CMA_FIRST))) != NULL)
+   {
+      WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE));
+   }
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      offStruct[z] = size;
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L);
+
+   if(!first)
+   {
+      free(offStruct);
+      return FALSE;
+   }
+
+   for(z=0;z<count;z++)
+   {
+      if(z==separator-1)
+         left=details;
+      details->cb = sizeof(FIELDINFO);
+      details->flData = flags[z];
+      details->flTitle = CFA_FITITLEREADONLY;
+      details->pTitleData = titles[z];
+      details->offStruct = offStruct[z];
+      details = details->pNextFieldInfo;
+   }
+
+   detin.cb = sizeof(FIELDINFOINSERT);
+   detin.fInvalidateFieldInfo = FALSE;
+   detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
+   detin.cFieldInfoInsert = (ULONG)count;
+
+   WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin));
+
+   if(count > separator && separator > 0)
+   {
+      cnri.cb = sizeof(CNRINFO);
+      cnri.pFieldInfoLast = left;
+      cnri.xVertSplitbar  = 150;
+
+      WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR));
+   }
+
+   cnri.flWindowAttr = CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES;
+   cnri.slBitmapOrIcon.cx = 16;
+   cnri.slBitmapOrIcon.cy = 16;
+
+   WinSendMsg(handle, CM_SETCNRINFO, &cnri, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
+
+   free(offStruct);
+   return DW_ERROR_NONE;
+}
+
+/*
+ * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          flags: An array of unsigned longs with column flags.
+ *          titles: An array of strings with column text titles.
+ *          count: The number of columns (this should match the arrays).
+ */
+int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
+{
+   char **newtitles = malloc(sizeof(char *) * (count + 2));
+   unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2));
+
+   newtitles[0] = "Icon";
+   newtitles[1] = "Filename";
+
+   newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR;
+   newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR;
+
+   memcpy(&newtitles[2], titles, sizeof(char *) * count);
+   memcpy(&newflags[2], flags, sizeof(unsigned long) * count);
+
+   dw_container_setup(handle, newflags, newtitles, count + 2, count ? 2 : 0);
+
+   free(newtitles);
+   free(newflags);
+   return DW_ERROR_NONE;
+}
+
+/*
+ * Obtains an icon from a module (or header in GTK).
+ * Parameters:
+ *          module: Handle to module (DLL) in OS/2 and Windows.
+ *          id: A unsigned long id int the resources on OS/2 and
+ *              Windows, on GTK this is converted to a pointer
+ *              to an embedded XPM.
+ */
+HICN API dw_icon_load(unsigned long module, unsigned long id)
+{
+   return WinLoadPointer(HWND_DESKTOP,module,id);
+}
+
+/*
+ * Obtains an icon from a file.
+ * Parameters:
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (ICO on OS/2 or Windows, XPM on Unix)
+ */
+HICN API dw_icon_load_from_file(char *filename)
+{
+   char *file = alloca(strlen(filename) + 5);
+
+   if(!file)
+      return 0;
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if(access(file, 04) != 0)
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".ico");
+      if(access(file, 04) != 0)
+         return 0;
+   }
+   return WinLoadFileIcon(file, FALSE);
+}
+
+/*
+ * Obtains an icon from data
+ * Parameters:
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (ICO on OS/2 or Windows, XPM on Unix)
+ */
+HICN API dw_icon_load_from_data(char *data, int len)
+{
+   HICN icon=0;
+   char *file;
+   FILE *fp;
+
+   if ( !data )
+      return 0;
+   file = tmpnam( NULL );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+         icon = WinLoadFileIcon( file, FALSE );
+      }
+      else
+      {
+         unlink( file );
+         return 0;
+      }
+      unlink( file );
+   }
+   return icon;
+}
+
+/*
+ * Frees a loaded resource in OS/2 and Windows.
+ * Parameters:
+ *          handle: Handle to icon returned by dw_icon_load().
+ */
+void API dw_icon_free(HICN handle)
+{
+   WinDestroyPointer(handle);
+}
+
+/*
+ * Allocates memory used to populate a container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          rowcount: The number of items to be populated.
+ */
+void * API dw_container_alloc(HWND handle, int rowcount)
+{
+   WindowData *wd = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *flags = wd ? wd->data : 0;
+   int z, size = 0, totalsize, count = 0;
+   PRECORDCORE temp;
+   ContainerInfo *ci;
+   void *blah = NULL;
+
+   if(!flags || rowcount < 1)
+      return NULL;
+
+   while(flags[count])
+      count++;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   totalsize = size + sizeof(RECORDCORE);
+
+   z = 0;
+
+   if(!(blah = (void *)_dw_send_msg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount), 0)))
+      return NULL;
+
+   temp = (PRECORDCORE)blah;
+
+   for(z=0;z<rowcount;z++)
+   {
+      temp->cb = totalsize;
+      temp = temp->preccNextRecord;
+   }
+
+   ci = malloc(sizeof(struct _containerinfo));
+
+   ci->count = rowcount;
+   ci->data = blah;
+   ci->handle = handle;
+
+   return (void *)ci;
+}
+
+/* Internal function that does the work for set_item and change_item */
+void _dw_container_set_item(HWND handle, PRECORDCORE temp, int column, int row, void *data)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
+   int z, currentcount;
+   CNRINFO cnr;
+    void *dest;
+
+   if(!flags)
+      return;
+
+   if(!_dw_send_msg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)), 0))
+      return;
+
+   currentcount = cnr.cRecords;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<column;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+         size += sizeof(char *);
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+
+   totalsize = size + sizeof(RECORDCORE);
+
+   for(z=0;z<(row-currentcount);z++)
+      temp = temp->preccNextRecord;
+
+   dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+      memcpy(dest, data, sizeof(HPOINTER));
+   else if(flags[column] & DW_CFA_STRING)
+   {
+      char **newstr = (char **)data, **str = dest;
+
+      if(*str)
+         free(*str);
+
+      if(newstr && *newstr)
+         *str = strdup(*newstr);
+      else
+         *str = NULL;
+   }
+   else if(flags[column] & DW_CFA_ULONG)
+      memcpy(dest, data, sizeof(ULONG));
+   else if(flags[column] & DW_CFA_DATE)
+      memcpy(dest, data, sizeof(CDATE));
+   else if(flags[column] & DW_CFA_TIME)
+      memcpy(dest, data, sizeof(CTIME));
+}
+
+/* Internal function that free()s any strings allocated for a container item */
+void _dw_container_free_strings(HWND handle, PRECORDCORE temp)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG totalsize, size = 0, *flags = blah ? blah->data : 0;
+   int z, count = 0;
+
+   if(!flags)
+      return;
+
+   while(flags[count])
+      count++;
+
+   /* Figure out the offsets to the items in the struct */
+   for(z=0;z<count;z++)
+   {
+      if(flags[z] & DW_CFA_BITMAPORICON)
+         size += sizeof(HPOINTER);
+      else if(flags[z] & DW_CFA_STRING)
+      {
+         char **str;
+
+         totalsize = size + sizeof(RECORDCORE);
+
+         str = (char **)(((ULONG)temp)+((ULONG)totalsize));
+
+         if(*str)
+         {
+            free(*str);
+            *str = NULL;
+         }
+         size += sizeof(char *);
+      }
+      else if(flags[z] & DW_CFA_ULONG)
+         size += sizeof(ULONG);
+      else if(flags[z] & DW_CFA_DATE)
+         size += sizeof(CDATE);
+      else if(flags[z] & DW_CFA_TIME)
+         size += sizeof(CTIME);
+   }
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
+{
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+
+   if(!ci)
+      return;
+
+   _dw_container_set_item(handle, (PRECORDCORE)ci->data, column, row, data);
+}
+
+/*
+ * Changes an existing item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_container_change_item(HWND handle, int column, 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)
+      {
+         _dw_container_set_item(handle, pCore, column, 0, data);
+         WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      count++;
+   }
+}
+
+/*
+ * Changes an existing item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_change_item(HWND handle, int column, int row, void *data)
+{
+   dw_container_change_item(handle, column + 2, row, data);
+}
+
+/*
+ * Changes an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon)
+{
+   dw_container_change_item(handle, 0, row, (void *)&icon);
+   dw_container_change_item(handle, 1, row, (void *)&filename);
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon)
+{
+   dw_container_set_item(handle, pointer, 0, row, (void *)&icon);
+   dw_container_set_item(handle, pointer, 1, row, (void *)&filename);
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
+{
+   dw_container_set_item(handle, pointer, column + 2, row, data);
+}
+
+/*
+ * Gets column type for a container column
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column.
+ */
+int API dw_container_get_column_type(HWND handle, int column)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   ULONG *flags = blah ? blah->data : 0;
+   int rc;
+
+   if(!flags)
+      return 0;
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+      rc = DW_CFA_BITMAPORICON;
+   else if(flags[column] & DW_CFA_STRING)
+      rc = DW_CFA_STRING;
+   else if(flags[column] & DW_CFA_ULONG)
+      rc = DW_CFA_ULONG;
+   else if(flags[column] & DW_CFA_DATE)
+      rc = DW_CFA_DATE;
+   else if(flags[column] & DW_CFA_TIME)
+      rc = DW_CFA_TIME;
+   else
+      rc = 0;
+   return rc;
+}
+
+/*
+ * Gets column type for a filesystem container column
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column.
+ */
+int API dw_filesystem_get_column_type(HWND handle, int column)
+{
+   return dw_container_get_column_type( handle, column + 2 );
+}
+
+/*
+ * Sets the alternating row colors for container window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          oddcolor: Odd row background color in DW_RGB format or a default color index.
+ *          evencolor: Even row background color in DW_RGB format or a default color index.
+ *                    DW_RGB_TRANSPARENT will disable coloring rows.
+ *                    DW_CLR_DEFAULT will use the system default alternating row colors.
+ */
+void API dw_container_set_stripe(HWND handle, unsigned long oddcolor, unsigned long evencolor)
+{
+    /* Don't think this is possible on OS/2 */
+}
+
+/*
+ * Sets the width of a column in the container.
+ * Parameters:
+ *          handle: Handle to window (widget) of container.
+ *          column: Zero based column of width being set.
+ *          width: Width of column in pixels.
+ */
+void API dw_container_set_column_width(HWND handle, int column, int width)
+{
+   handle = handle; /* keep compiler happy */
+   column = column; /* keep compiler happy */
+   width = width; /* keep compiler happy */
+}
+
+/*
+ * Sets the title 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.
+ *          title: String title of the item.
+ */
+void API dw_container_set_row_title(void *pointer, int row, char *title)
+{
+   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->pszIcon = title;
+   temp->pszName = title;
+   temp->pszText = title;
+}
+
+/*
+ * Changes the title of a row already inserted in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          row: Zero based row of data being set.
+ *          title: String title of the item.
+ */
+void API dw_container_change_row_title(HWND handle, int row, char *title)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   int count = 0;
+
+   while(pCore)
+   {
+      if(count == row)
+      {
+         pCore->pszIcon = title;
+         pCore->pszName = title;
+         pCore->pszText = title;
+
+         WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pCore, MPFROM2SHORT(1, CMA_NOREPOSITION | CMA_TEXTCHANGED));
+         return;
+      }
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      count++;
+   }
+}
+
+/* Internal function to get the first item with given flags */
+PRECORDCORE _dw_container_start(HWND handle, unsigned long flags)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+       while(pCore)
+       {
+           if(pCore->flRecordAttr & flags)
+           {
+               return pCore;
+           }
+           pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+       }
+   }
+   return NULL;
+}
+
+/*
+ * Sets the title of a row in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          rowcount: The number of rows to be inserted.
+ */
+void API dw_container_insert(HWND handle, void *pointer, int rowcount)
+{
+   RECORDINSERT recin;
+   ContainerInfo *ci = (ContainerInfo *)pointer;
+   PRECORDCORE pCore;
+
+   if(!ci)
+      return;
+
+   recin.cb = sizeof(RECORDINSERT);
+   recin.pRecordOrder = (PRECORDCORE)CMA_END;
+   recin.pRecordParent = NULL;
+   recin.zOrder = CMA_TOP;
+   recin.fInvalidateRecord = TRUE;
+   recin.cRecordsInsert = rowcount;
+
+   _dw_send_msg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin), 0);
+
+   free(ci);
+
+   if((pCore = _dw_container_start(handle, CRA_CURSORED)))
+   {
+       NOTIFYRECORDEMPHASIS pre;
+
+       pre.pRecord = pCore;
+       pre.fEmphasisMask = CRA_CURSORED;
+       pre.hwndCnr = handle;
+       _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
+       pre.pRecord->flRecordAttr |= CRA_CURSORED;
+   }
+}
+
+/*
+ * Removes all rows from a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be cleared.
+ *       redraw: TRUE to cause the container to redraw immediately.
+ */
+void API dw_container_clear(HWND handle, int redraw)
+{
+   PCNRITEM pCore;
+   int container = (int)dw_window_get_data(handle, "_dw_container");
+
+   if(hwndEmph == handle)
+      _clear_emphasis();
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(pCore)
+   {
+      if(container)
+         _dw_container_free_strings(handle, (PRECORDCORE)pCore);
+      else
+      {
+         /* Free icon text */
+         if(pCore->rc.pszIcon)
+         {
+            free(pCore->rc.pszIcon);
+            pCore->rc.pszIcon = 0;
+         }
+      }
+      pCore = (PCNRITEM)pCore->rc.preccNextRecord;/*WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));*/
+   }
+   _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE), -1);
+}
+
+/*
+ * Removes the first x rows from a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be deleted from.
+ *       rowcount: The number of rows to be deleted.
+ */
+void API dw_container_delete(HWND handle, int rowcount)
+{
+   RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount);
+   int current = 1;
+
+   prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   while(last && current < rowcount)
+   {
+      _dw_container_free_strings(handle, last);
+      prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+      current++;
+   }
+
+   _dw_send_msg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE), -1);
+
+   free(prc);
+}
+
+/*
+ * Scrolls container up or down.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be scrolled.
+ *       direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or
+ *                  DW_SCROLL_BOTTOM. (rows is ignored for last two)
+ *       rows: The number of rows to be scrolled.
+ */
+void API dw_container_scroll(HWND handle, int direction, long rows)
+{
+   rows = rows; /* keep compiler happy */
+   switch(direction)
+   {
+   case DW_SCROLL_TOP:
+      WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000));
+        break;
+   case DW_SCROLL_BOTTOM:
+      WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000));
+      break;
+   }
+}
+
+/*
+ * Starts a new query of a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       flags: If this parameter is DW_CRA_SELECTED it will only
+ *              return items that are currently selected.  Otherwise
+ *              it will return all records in the container.
+ */
+char * API dw_container_query_start(HWND handle, unsigned long flags)
+{
+   PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+      if(flags)
+      {
+         while(pCore)
+         {
+            if(pCore->flRecordAttr & flags)
+            {
+               dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+               return pCore->pszIcon;
+            }
+            pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+         }
+      }
+      else
+      {
+         dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+         return pCore->pszIcon;
+      }
+   }
+   return NULL;
+}
+
+/*
+ * Continues an existing query of a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       flags: If this parameter is DW_CRA_SELECTED it will only
+ *              return items that are currently selected.  Otherwise
+ *              it will return all records in the container.
+ */
+char * API dw_container_query_next(HWND handle, unsigned long flags)
+{
+   PRECORDCORE pCore = (PRECORDCORE)dw_window_get_data(handle, "_dw_pcore");
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+
+   if(pCore)
+   {
+      if(flags)
+      {
+         while(pCore)
+         {
+            if(pCore->flRecordAttr & flags)
+            {
+               dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+               return pCore->pszIcon;
+            }
+
+            pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+         }
+      }
+      else
+      {
+         dw_window_set_data(handle, "_dw_pcore", (void *)pCore);
+         return pCore->pszIcon;
+      }
+   }
+    return NULL;
+}
+
+/*
+ * 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(HWND handle, char *text)
+{
+   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(pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      {
+         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 text speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       text:  Text usually returned by dw_container_query().
+ */
+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((textcomp && pCore->pszIcon && strcmp(pCore->pszIcon, text) == 0) || (!textcomp && (char *)pCore->pszIcon == text))
+      {
+         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));
+   }
+}
+
+/*
+ * Optimizes the column widths so that all data is visible.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be optimized.
+ */
+void API dw_container_optimize(HWND handle)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(handle, QWP_USER);
+   RECTL item;
+   PRECORDCORE pCore = NULL;
+   int max = 0;
+
+   if(blah && !blah->flags)
+      return;
+
+   pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
+   while(pCore)
+   {
+      QUERYRECORDRECT qrr;
+      int vector;
+
+      qrr.cb = sizeof(QUERYRECORDRECT);
+      qrr.pRecord = pCore;
+      qrr.fRightSplitWindow = 0;
+      qrr.fsExtent = CMA_TEXT;
+
+      WinSendMsg(handle, CM_QUERYRECORDRECT, (MPARAM)&item, (MPARAM)&qrr);
+
+      vector = item.xRight - item.xLeft;
+
+      if(vector > max)
+         max = vector;
+
+      pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+   }
+
+   if(max)
+   {
+      CNRINFO cnri;
+
+      cnri.cb = sizeof(CNRINFO);
+      cnri.xVertSplitbar  = max;
+
+      WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_XVERTSPLITBAR));
+   }
+}
+
+/*
+ * Inserts an icon into the taskbar.
+ * Parameters:
+ *       handle: Window handle that will handle taskbar icon messages.
+ *       icon: Icon handle to display in the taskbar.
+ *       bubbletext: Text to show when the mouse is above the icon.
+ */
+void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext)
+{
+    /* Make sure we have our server */
+    if(!hwndTrayServer)
+        return;
+
+    WinSendMsg(hwndApp, WM_SETICON, (MPARAM)icon, 0);
+    hwndTaskBar = handle;
+    WinPostMsg(hwndTrayServer, WM_USER+1, (MPARAM)hwndApp, (MPARAM)icon);
+}
+
+/*
+ * Deletes an icon from the taskbar.
+ * Parameters:
+ *       handle: Window handle that was used with dw_taskbar_insert().
+ *       icon: Icon handle that was used with dw_taskbar_insert().
+ */
+void API dw_taskbar_delete(HWND handle, HICN icon)
+{
+    /* Make sure we have our server */
+    if(!hwndTrayServer)
+        return;
+
+    WinPostMsg(hwndTrayServer, WM_USER+2, (MPARAM)hwndApp, (MPARAM)0);
+    hwndTaskBar = NULLHANDLE;
+}
+
+/*
+ * Creates a rendering context widget (window) to be packed.
+ * Parameters:
+ *       id: An id to be used with dw_window_from_id.
+ * Returns:
+ *       A handle to the widget or NULL on failure.
+ */
+HWND API dw_render_new(unsigned long id)
+{
+   HWND hwndframe = WinCreateWindow(HWND_OBJECT,
+                            WC_FRAME,
+                            NULL,
+                            WS_VISIBLE |
+                            FS_NOBYTEALIGN,
+                            0,0,2000,1000,
+                            NULLHANDLE,
+                            HWND_TOP,
+                            id,
+                            NULL,
+                            NULL);
+   WinSubclassWindow(hwndframe, _RendProc);
+   return hwndframe;
+}
+
+/* Sets the current foreground drawing color.
+ * Parameters:
+ *       red: red value.
+ *       green: green value.
+ *       blue: blue value.
+ */
+void API dw_color_foreground_set(unsigned long value)
+{
+   _foreground = value;
+}
+
+/* Sets the current background drawing color.
+ * Parameters:
+ *       red: red value.
+ *       green: green value.
+ *       blue: blue value.
+ */
+void API dw_color_background_set(unsigned long value)
+{
+   _background = value;
+}
+
+int DWSIGNAL _dw_color_cancel_func(HWND window, void *data)
+{
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   void *val;
+
+   window = (HWND)dwwait->data;
+   val = dw_window_get_data(window, "_dw_val");
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy(window);
+   dw_dialog_dismiss((DWDialog *)data, val);
+   return FALSE;
+}
+
+int DWSIGNAL _dw_color_ok_func(HWND window, void *data)
+{
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   unsigned long val;
+
+   window = (HWND)dwwait->data;
+   val = _dw_color_spin_get(window);
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy(window);
+   dw_dialog_dismiss((DWDialog *)data, (void *)val);
+   return FALSE;
+}
+
+/* Allows the user to choose a color using the system's color chooser dialog.
+ * Parameters:
+ *       value: current color
+ * Returns:
+ *       The selected color or the current color if cancelled.
+ */
+unsigned long API dw_color_choose(unsigned long value)
+{
+   HWND window, hbox, vbox, col, button, text;
+   DWDialog *dwwait;
+   HMTX mtx = dw_mutex_new();
+
+   window = dw_window_new( HWND_DESKTOP, "Choose Color", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+
+   vbox = dw_box_new(DW_VERT, 5);
+
+   dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, FALSE, FALSE, 0);
+   dw_window_set_style(hbox, 0, WS_CLIPCHILDREN);
+
+   col = WinCreateWindow(vbox, "ColorSelectClass", "", WS_VISIBLE | WS_GROUP, 0, 0, 390, 300, vbox, HWND_TOP, 266, NULL,NULL);
+   dw_box_pack_start(hbox, col, 390, 300, FALSE, FALSE, 0);
+
+   dw_window_set_data(hbox, "_dw_window", (void *)window);
+   dw_window_set_data(window, "_dw_mutex", (void *)mtx);
+   dw_window_set_data(window, "_dw_col", (void *)col);
+   dw_window_set_data(window, "_dw_val", (void *)value);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+   dw_window_set_data(hbox, "_dw_window", (void *)window);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+   text = dw_text_new("Red:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1001L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_red_spin", (void *)button);
+
+   text = dw_text_new("Green:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1002L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_green_spin", (void *)button);
+
+   text = dw_text_new("Blue:", 0);
+   dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+   dw_box_pack_start(hbox, text, 30, 20, FALSE, FALSE, 3);
+
+   button = dw_spinbutton_new("", 1003L);
+   dw_spinbutton_set_limits(button, 255, 0);
+   dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+   WinSetOwner(button, hbox);
+   dw_window_set_data(window, "_dw_blue_spin", (void *)button);
+
+   hbox = dw_box_new(DW_HORZ, 0);
+
+   dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+   dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0);
+
+   button = dw_button_new("Ok", 1001L);
+   dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+   dwwait = dw_dialog_new((void *)window);
+
+   dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_ok_func), (void *)dwwait);
+
+   button = dw_button_new("Cancel", 1002L);
+   dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+   dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
+   dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_color_cancel_func), (void *)dwwait);
+
+   dw_window_set_size(window, 400, 400);
+
+   _dw_col_set(col, value);
+   _dw_color_spin_set(window, value);
+
+   dw_window_show(window);
+
+   return (unsigned long)dw_dialog_wait(dwwait);
+}
+
+HPS _set_hps(HPS hps)
+{
+   LONG alTable[2];
+
+   alTable[0] = DW_RED_VALUE(_foreground) << 16 | DW_GREEN_VALUE(_foreground) << 8 | DW_BLUE_VALUE(_foreground);
+   alTable[1] = DW_RED_VALUE(_background) << 16 | DW_GREEN_VALUE(_background) << 8 | DW_BLUE_VALUE(_background);
+
+   GpiCreateLogColorTable(hps,
+                     LCOL_RESET,
+                     LCOLF_CONSECRGB,
+                     16,
+                     2,
+                     alTable);
+   if(_foreground & DW_RGB_COLOR)
+      GpiSetColor(hps, 16);
+   else
+      GpiSetColor(hps, _internal_color(_foreground));
+   if(_background & DW_RGB_COLOR)
+      GpiSetBackColor(hps, 17);
+   else
+      GpiSetBackColor(hps, _internal_color(_background));
+   return hps;
+}
+
+HPS _set_colors(HWND handle)
+{
+   HPS hps = WinGetPS(handle);
+
+   _set_hps(hps);
+   return hps;
+}
+
+/* Draw a point on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
+{
+   HPS hps;
+   int height;
+   POINTL ptl;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+        height = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      height = pixmap->height;
+   }
+   else
+      return;
+
+   ptl.x = x;
+   ptl.y = height - y - 1;
+
+   GpiSetPel(hps, &ptl);
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* Draw a line on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x1: First X coordinate.
+ *       y1: First Y coordinate.
+ *       x2: Second X coordinate.
+ *       y2: Second Y coordinate.
+ */
+void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
+{
+   HPS hps;
+   int height;
+   POINTL ptl[2];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+        height = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      height = pixmap->height;
+   }
+   else
+      return;
+
+   ptl[0].x = x1;
+   ptl[0].y = height - y1 - 1;
+   ptl[1].x = x2;
+   ptl[1].y = height - y2 - 1;
+
+   GpiMove(hps, &ptl[0]);
+   GpiLine(hps, &ptl[1]);
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+
+void _CopyFontSettings(HPS hpsSrc, HPS hpsDst)
+{
+   FONTMETRICS fm;
+   FATTRS fat;
+   SIZEF sizf;
+
+   GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm);
+
+   memset(&fat, 0, sizeof(fat));
+
+   fat.usRecordLength  = sizeof(FATTRS);
+   fat.lMatch          = fm.lMatch;
+   strcpy(fat.szFacename, fm.szFacename);
+
+   GpiCreateLogFont(hpsDst, 0, 1L, &fat);
+   GpiSetCharSet(hpsDst, 1L);
+
+   sizf.cx = MAKEFIXED(fm.lEmInc,0);
+   sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0);
+   GpiSetCharBox(hpsDst, &sizf );
+}
+
+/* Draw text on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       text: Text to be displayed.
+ */
+void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
+{
+    HPS hps;
+    int z, height;
+    RECTL rcl;
+    char fontname[128];
+    POINTL aptl[TXTBOX_COUNT];
+
+    if(handle)
+    {
+        hps = _set_colors(handle);
+        height = _get_height(handle);
+        _GetPPFont(handle, fontname);
+    }
+    else if(pixmap)
+    {
+        HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle);
+
+        hps = _set_hps(pixmap->hps);
+        height = pixmap->height;
+        _GetPPFont(pixmap->font ? pixmap->font : pixmap->handle, fontname);
+        _CopyFontSettings(pixmaphps, hps);
+        WinReleasePS(pixmaphps);
+    }
+    else
+        return;
+
+    for(z=0;z<strlen(fontname);z++)
+    {
+        if(fontname[z]=='.')
+            break;
+    }
+
+    GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
+
+    rcl.xLeft = x;
+    rcl.yTop = height - y;
+    rcl.yBottom = rcl.yTop - (aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y);
+    rcl.xRight = rcl.xLeft + (aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x);
+
+    if(_background == DW_CLR_DEFAULT)
+        WinDrawText(hps, -1, text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS);
+    else
+        WinDrawText(hps, -1, text, &rcl, _internal_color(_foreground), _internal_color(_background), DT_VCENTER | DT_LEFT | DT_ERASERECT);
+
+    if(!pixmap)
+        WinReleasePS(hps);
+}
+
+/* Query the width and height of a text string.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       text: Text to be queried.
+ *       width: Pointer to a variable to be filled in with the width.
+ *       height Pointer to a variable to be filled in with the height.
+ */
+void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
+{
+   HPS hps;
+   POINTL aptl[TXTBOX_COUNT];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+   }
+   else if(pixmap)
+   {
+      HPS pixmaphps = WinGetPS(pixmap->font ? pixmap->font : pixmap->handle);
+
+      hps = _set_hps(pixmap->hps);
+      _CopyFontSettings(pixmaphps, hps);
+      WinReleasePS(pixmaphps);
+   }
+   else
+      return;
+
+   GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl);
+
+   if(width)
+      *width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x;
+
+   if(height)
+      *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y;
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* Draw a polygon on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the polygon or DW_DRAW_DEFAULT (0).
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       width: Width of rectangle.
+ *       height: Height of rectangle.
+ */
+void API dw_draw_polygon( HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y )
+{
+   HPS hps;
+   int thisheight;
+   POINTL *pptl;
+   POINTL start;
+   int i;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+      thisheight = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+   if ( npoints == 0 )
+      return;
+   pptl = (POINTL *)malloc(sizeof(POINTL)*npoints);
+   if ( pptl == NULL )
+      return;
+   /*
+    * For a filled polygon we need to start an area
+    */
+   if ( flags & DW_DRAW_FILL )
+      GpiBeginArea( hps, 0L );
+   if ( npoints )
+   {
+      /*
+       * Move to the first point of the polygon
+       */
+      start.x = x[0];
+      start.y = thisheight - y[0] - 1;
+      GpiMove( hps, &start );
+      /*
+       * Convert the remainder of the x and y points
+       */
+      for ( i = 1; i < npoints; i++ )
+      {
+         pptl[i-1].x = x[i];
+         pptl[i-1].y = thisheight - y[i] - 1;
+      }
+      GpiPolyLine( hps, npoints-1, pptl );
+
+      if ( flags & DW_DRAW_FILL )
+         GpiEndArea( hps );
+   }
+   if ( !pixmap )
+      WinReleasePS(hps);
+   free( pptl );
+}
+
+/* Draw a rectangle on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the box or DW_DRAW_DEFAULT (0).
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       width: Width of rectangle.
+ *       height: Height of rectangle.
+ */
+void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
+{
+   HPS hps;
+   int thisheight;
+   POINTL ptl[2];
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+        thisheight = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+
+   ptl[0].x = x;
+   ptl[0].y = thisheight - y - 1;
+   ptl[1].x = x + width - 1;
+   ptl[1].y = thisheight - y - height;
+
+   GpiMove(hps, &ptl[0]);
+   GpiBox(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0);
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* VisualAge doesn't seem to have this */
+#ifndef M_PI
+#define M_PI            3.14159265358979323846
+#endif
+
+/* Draw an arc on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the arc or DW_DRAW_DEFAULT (0).
+ *              DW_DRAW_FULL will draw a complete circle/elipse.
+ *       xorigin: X coordinate of center of arc.
+ *       yorigin: Y coordinate of center of arc.
+ *       x1: X coordinate of first segment of arc.
+ *       y1: Y coordinate of first segment of arc.
+ *       x2: X coordinate of second segment of arc.
+ *       y2: Y coordinate of second segment of arc.
+ */
+void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
+{
+   HPS hps;
+   int thisheight;
+   ARCPARAMS ap = { 1, 1, 0, 0 };
+   POINTL pts[2];
+   double r, a1, a2, a;
+
+   if(handle)
+   {
+      hps = _set_colors(handle);
+      thisheight = _get_height(handle);
+   }
+   else if(pixmap)
+   {
+      hps = _set_hps(pixmap->hps);
+      thisheight = pixmap->height;
+   }
+   else
+      return;
+
+   /* Handle full circle/ellipse */
+   if(flags & DW_DRAW_FULL)
+   {
+       pts[0].x = xorigin;
+       pts[0].y = thisheight - yorigin - 1;
+       GpiMove(hps, pts);
+       ap.lP = (x2 - x1)/2;
+       ap.lQ = (y2 - y1)/2;
+       /* Setup the arc info on the presentation space */
+       GpiSetArcParams(hps, &ap);
+       GpiFullArc(hps, (flags & DW_DRAW_FILL) ? DRO_OUTLINEFILL : DRO_OUTLINE, MAKEFIXED(1, 1));
+   }
+   else
+   {
+       /* For a filled arc we need to start an area */
+       if(flags & DW_DRAW_FILL)
+           GpiBeginArea(hps, 0L);
+
+       /* Setup the default arc info on the presentation space */
+       GpiSetArcParams(hps, &ap);
+       pts[0].x = x1;
+       pts[0].y = thisheight - y1 - 1;
+       /* Move to the initial position */
+       GpiMove(hps, pts);
+       /* Calculate the midpoint */
+       r = 0.5 * (hypot((double)(y1 - yorigin), (double)(x1 - xorigin)) +
+                  hypot((double)(y2 - yorigin), (double)(x2 - xorigin)));
+       a1 = atan2((double)(y1 - yorigin), (double)(x1 - xorigin));
+       a2 = atan2((double)(y2 - yorigin), (double)(x2 - xorigin));
+       if(a2 < a1)
+           a2 += M_PI * 2;
+       a = (a1 + a2) / 2.;
+       /* Prepare to draw */
+       pts[0].x = (int)(xorigin + r * cos(a));
+       pts[0].y = thisheight - (int)(yorigin + r * sin(a)) - 1;
+       pts[1].x = x2;
+       pts[1].y = thisheight - y2 - 1;
+       /* Actually draw the arc */
+       GpiPointArc(hps, pts);
+       if(flags & DW_DRAW_FILL)
+           GpiEndArea(hps);
+   }
+
+   if(!pixmap)
+      WinReleasePS(hps);
+}
+
+/* Call this after drawing to the screen to make sure
+ * anything you have drawn is visible.
+ */
+void API dw_flush(void)
+{
+}
+
+/*
+ * Creates a pixmap with given parameters.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       width: Width of the pixmap in pixels.
+ *       height: Height of the pixmap in pixels.
+ *       depth: Color depth of the pixmap.
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
+{
+   BITMAPINFOHEADER bmih;
+   SIZEL sizl = { 0, 0 };
+   HPIXMAP pixmap;
+   HDC hdc;
+   HPS hps;
+   ULONG ulFlags;
+    LONG cPlanes, cBitCount;
+
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hps = WinGetPS(handle);
+
+   hdc     = GpiQueryDevice(hps);
+   ulFlags = GpiQueryPS(hps, &sizl);
+
+   pixmap->handle = handle;
+   pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
+   pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   DevQueryCaps(hdc, CAPS_COLOR_PLANES  , 1L, &cPlanes);
+   if (!depth)
+   {
+      DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount);
+      depth = cBitCount;
+   }
+
+   memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
+   bmih.cbFix     = sizeof(BITMAPINFOHEADER);
+   bmih.cx        = (SHORT)width;
+   bmih.cy        = (SHORT)height;
+   bmih.cPlanes   = (SHORT)cPlanes;
+   bmih.cBitCount = (SHORT)depth;
+
+   pixmap->width = width; pixmap->height = height;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL);
+
+   GpiSetBitmap(pixmap->hps, pixmap->hbm);
+
+   if (depth>8)
+      GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL );
+
+   WinReleasePS(hps);
+
+   return pixmap;
+}
+
+/*
+ * Creates a pixmap from a file.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
+{
+   HPIXMAP pixmap;
+   char *file = alloca(strlen(filename) + 5);
+
+   if ( !file || !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
+      return NULL;
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if ( access(file, 04) != 0 )
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".bmp");
+      if ( access(file, 04) != 0 )
+      {
+         free(pixmap);
+         return NULL;
+      }
+   }
+
+   /* Try to load the bitmap from file */
+   if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
+   {
+      free(pixmap);
+      return NULL;
+   }
+
+   /* Success fill in other values */
+   pixmap->handle = handle;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a pixmap from memory.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       data: Source of the image data
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ *       le: length of data
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len)
+{
+   HPIXMAP pixmap;
+   char *file;
+   FILE *fp;
+
+   if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
+      return NULL;
+
+   file = tmpnam( NULL );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+         if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+         {
+            /* Try to load the bitmap from file */
+            if ( !_load_bitmap_file(file, handle, &pixmap->hbm, &pixmap->hdc, &pixmap->hps, &pixmap->width, &pixmap->height) )
+            {
+               free(pixmap);
+               return NULL;
+            }
+         }
+         else /* otherwise its assumed to be an ico */
+         {
+            /* con't use ICO ? */
+            unlink( file );
+            return NULL;
+         }
+      }
+      else
+      {
+         unlink( file );
+         return NULL;
+      }
+      unlink( file );
+   }
+
+   /* Success fill in other values */
+   pixmap->handle = handle;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a bitmap mask for rendering bitmaps with transparent backgrounds
+ */
+void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color )
+{
+   if ( pixmap )
+   {
+      pixmap->transcolor = _internal_color(color);
+   }
+}
+
+/*
+ * Creates a pixmap from internal resource graphic specified by id.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       id: Resource ID associated with requested pixmap.
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id)
+{
+   BITMAPINFOHEADER bmih;
+   SIZEL sizl = { 0, 0 };
+   HPIXMAP pixmap;
+   HDC hdc;
+   HPS hps;
+   ULONG ulFlags;
+
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hps = WinGetPS(handle);
+
+   hdc     = GpiQueryDevice(hps);
+   ulFlags = GpiQueryPS(hps, &sizl);
+
+   pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc);
+   pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC);
+
+   pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0);
+
+   GpiQueryBitmapParameters(pixmap->hbm, &bmih);
+
+   GpiSetBitmap(pixmap->hps, pixmap->hbm);
+
+   pixmap->width = bmih.cx; pixmap->height = bmih.cy;
+   pixmap->transcolor = DW_CLR_DEFAULT;
+
+   WinReleasePS(hps);
+
+   return pixmap;
+}
+
+/*
+ * Sets the font used by a specified pixmap.
+ * Normally the pixmap font is obtained from the associated window handle.
+ * However this can be used to override that, or for pixmaps with no window.
+ * Parameters:
+ *          pixmap: Handle to a pixmap returned by dw_pixmap_new() or
+ *                  passed to the application via a callback.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname)
+{
+    if(pixmap && fontname && *fontname)
+    {
+        if(!pixmap->font)
+            pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL);
+        WinSetPresParam(pixmap->font, PP_FONTNAMESIZE, strlen(fontname)+1, fontname);
+        return DW_ERROR_NONE;
+    }
+    return DW_ERROR_GENERAL;
+}
+
+/*
+ * Destroys an allocated pixmap.
+ * Parameters:
+ *       pixmap: Handle to a pixmap returned by
+ *               dw_pixmap_new..
+ */
+void API dw_pixmap_destroy(HPIXMAP pixmap)
+{
+    if(pixmap->font)
+        WinDestroyWindow(pixmap->font);
+    GpiSetBitmap(pixmap->hps, NULLHANDLE);
+    GpiDeleteBitmap(pixmap->hbm);
+    GpiAssociate(pixmap->hps, NULLHANDLE);
+    GpiDestroyPS(pixmap->hps);
+    DevCloseDC(pixmap->hdc);
+    free(pixmap);
+}
+
+/*
+ * Copies from one item to another.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of area to copy.
+ *       height: Height of area to copy.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ */
+void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+{
+    dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1);
+}
+
+/*
+ * Copies from one surface to another allowing for stretching.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of the target area.
+ *       height: Height of the target area.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ *       srcwidth: Width of area to copy.
+ *       srcheight: Height of area to copy.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
+{
+   HPS hpsdest;
+   HPS hpssrc;
+   POINTL ptl[4];
+   int dheight, sheight;
+   int count = 3;
+   
+   /* Do some sanity checks */
+   if((srcheight == -1 || srcwidth == -1) && srcheight != srcwidth)
+      return DW_ERROR_GENERAL;
+
+   if(dest)
+   {
+      hpsdest = WinGetPS(dest);
+      dheight = _get_height(dest);
+   }
+   else if(destp)
+   {
+      hpsdest = destp->hps;
+      dheight = destp->height;
+   }
+   else
+      return DW_ERROR_GENERAL;
+
+   if(src)
+   {
+      hpssrc = WinGetPS(src);
+      sheight = _get_height(src);
+   }
+   else if(srcp)
+   {
+      hpssrc = srcp->hps;
+      sheight = srcp->height;
+   }
+   else
+   {
+      if(!destp)
+         WinReleasePS(hpsdest);
+      return DW_ERROR_GENERAL;
+   }
+
+   ptl[0].x = xdest;
+   ptl[0].y = dheight - (ydest + height);
+   ptl[1].x = xdest + width;
+   ptl[1].y = dheight - ydest;
+   ptl[2].x = xsrc;
+   ptl[2].y = sheight - (ysrc + (srcheight != -1 ? srcheight : height));
+   if(srcwidth != -1 && srcheight != -1)
+   {
+      count = 4;
+      ptl[3].x = xsrc + srcwidth;
+      ptl[3].y = sheight - ysrc;
+   }
+
+   /* Handle transparency if requested */
+   if(srcp && srcp->transcolor != DW_CLR_DEFAULT)
+   {
+       IMAGEBUNDLE newIb, oldIb;
+       /* Transparent color is put into the background color */
+       GpiSetBackColor(hpsdest, srcp->transcolor);
+       GpiQueryAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, (PBUNDLE)&oldIb);
+       newIb.usBackMixMode = BM_SRCTRANSPARENT;
+       GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&newIb);
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
+       GpiSetAttrs(hpsdest, PRIM_IMAGE, IBB_BACK_MIX_MODE, 0, (PBUNDLE)&oldIb);
+   }
+   else
+   {
+       /* Otherwise use the regular BitBlt call */
+       GpiBitBlt(hpsdest, hpssrc, count, ptl, ROP_SRCCOPY, BBO_IGNORE);
+   }
+
+   if(!destp)
+      WinReleasePS(hpsdest);
+   if(!srcp)
+      WinReleasePS(hpssrc);
+   return DW_ERROR_NONE;
+}
+
+/* Run DosBeep() in a separate thread so it doesn't block */
+void _beepthread(void *data)
+{
+   int *info = (int *)data;
+
+   if(data)
+   {
+      DosBeep(info[0], info[1]);
+      free(data);
+   }
+}
+
+/*
+ * Emits a beep.
+ * Parameters:
+ *       freq: Frequency.
+ *       dur: Duration.
+ */
+void API dw_beep(int freq, int dur)
+{
+   int *info = malloc(sizeof(int) * 2);
+
+   if(info)
+   {
+      info[0] = freq;
+      info[1] = dur;
+
+      _beginthread(_beepthread, NULL, 100, (void *)info);
+   }
+}
+
+/* Open a shared library and return a handle.
+ * Parameters:
+ *         name: Base name of the shared library.
+ *         handle: Pointer to a module handle,
+ *                 will be filled in with the handle.
+ */
+int API dw_module_load(char *name, HMOD *handle)
+{
+   char objnamebuf[300] = "";
+
+   return DosLoadModule(objnamebuf, sizeof(objnamebuf), name, handle);
+}
+
+/* Queries the address of a symbol within open handle.
+ * Parameters:
+ *         handle: Module handle returned by dw_module_load()
+ *         name: Name of the symbol you want the address of.
+ *         func: A pointer to a function pointer, to obtain
+ *               the address.
+ */
+int API dw_module_symbol(HMOD handle, char *name, void**func)
+{
+   return DosQueryProcAddr(handle, 0, name, (PFN*)func);
+}
+
+/* Frees the shared library previously opened.
+ * Parameters:
+ *         handle: Module handle returned by dw_module_load()
+ */
+int API dw_module_close(HMOD handle)
+{
+   DosFreeModule(handle);
+   return 0;
+}
+
+/*
+ * Returns the handle to an unnamed mutex semaphore.
+ */
+HMTX API dw_mutex_new(void)
+{
+   HMTX mutex;
+
+   DosCreateMutexSem(NULL, &mutex, 0, FALSE);
+   return mutex;
+}
+
+/*
+ * Closes a semaphore created by dw_mutex_new().
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_close(HMTX mutex)
+{
+   DosCloseMutexSem(mutex);
+}
+
+/*
+ * Tries to gain access to the semaphore, if it can't it blocks.
+ * If we are in a callback we must keep the message loop running
+ * while blocking.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_lock(HMTX mutex)
+{
+   if(_dwtid == dw_thread_id())
+   {
+      int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
+
+      while(rc == ERROR_TIMEOUT)
+      {
+         dw_main_sleep(10);
+         rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN);
+      }
+   }
+    else
+      DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT);
+}
+
+/*
+ * Tries to gain access to the semaphore.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ * Returns:
+ *       DW_ERROR_NONE on success, DW_ERROR_TIMEOUT if it is already locked.
+ */
+int API dw_mutex_trylock(HMTX mutex)
+{
+    if(DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR)
+        return DW_ERROR_NONE;
+    return DW_ERROR_TIMEOUT;
+}
+
+/*
+ * Reliquishes the access to the semaphore.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_unlock(HMTX mutex)
+{
+   DosReleaseMutexSem(mutex);
+}
+
+/*
+ * Returns the handle to an unnamed event semaphore.
+ */
+HEV API dw_event_new(void)
+{
+   HEV blah;
+
+   if(DosCreateEventSem (NULL, &blah, 0L, FALSE))
+      return 0;
+
+   return blah;
+}
+
+/*
+ * Resets a semaphore created by dw_event_new().
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_reset(HEV eve)
+{
+   ULONG count;
+
+   if(DosResetEventSem(eve, &count))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
+}
+
+/*
+ * Posts a semaphore created by dw_event_new(). Causing all threads
+ * waiting on this event in dw_event_wait to continue.
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_post(HEV eve)
+{
+   if(DosPostEventSem(eve))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
+}
+
+
+/*
+ * Waits on a semaphore created by dw_event_new(), until the
+ * event gets posted or until the timeout expires.
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_wait(HEV eve, unsigned long timeout)
+{
+   int rc = DosWaitEventSem(eve, timeout);
+   if(!rc)
+      return DW_ERROR_NONE;
+   if(rc == ERROR_TIMEOUT)
+      return DW_ERROR_TIMEOUT;
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Closes a semaphore created by dw_event_new().
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_close(HEV *eve)
+{
+   if(!eve || ~DosCloseEventSem(*eve))
+      return DW_ERROR_GENERAL;
+   return DW_ERROR_NONE;
+}
+
+/* Create a named event semaphore which can be
+ * opened from other processes.
+ * Parameters:
+ *         eve: Pointer to an event handle to receive handle.
+ *         name: Name given to semaphore which can be opened
+ *               by other processes.
+ */
+HEV API dw_named_event_new(char *name)
+{
+   char *semname = malloc(strlen(name)+8);
+   HEV ev = 0;
+
+   if(!semname)
+      return 0;
+
+   strcpy(semname, "\\sem32\\");
+   strcat(semname, name);
+
+   DosCreateEventSem(semname, &ev, 0L, FALSE);
+
+   free(semname);
+   return ev;
+}
+
+/* Open an already existing named event semaphore.
+ * Parameters:
+ *         eve: Pointer to an event handle to receive handle.
+ *         name: Name given to semaphore which can be opened
+ *               by other processes.
+ */
+HEV API dw_named_event_get(char *name)
+{
+   char *semname = malloc(strlen(name)+8);
+   HEV ev;
+
+   if(!semname)
+      return 0;
+
+   strcpy(semname, "\\sem32\\");
+   strcat(semname, name);
+
+   DosOpenEventSem(semname, &ev);
+
+   free(semname);
+   return ev;
+}
+
+/* Resets the event semaphore so threads who call wait
+ * on this semaphore will block.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_reset(HEV eve)
+{
+   ULONG count;
+
+   return DosResetEventSem(eve, &count);
+}
+
+/* Sets the posted state of an event semaphore, any threads
+ * waiting on the semaphore will no longer block.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_post(HEV eve)
+{
+   return DosPostEventSem(eve);
+}
+
+
+/* Waits on the specified semaphore until it becomes
+ * posted, or returns immediately if it already is posted.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ *         timeout: Number of milliseconds before timing out
+ *                  or -1 if indefinite.
+ */
+int API dw_named_event_wait(HEV eve, unsigned long timeout)
+{
+   int rc;
+
+   rc = DosWaitEventSem(eve, timeout);
+   switch (rc)
+   {
+   case ERROR_INVALID_HANDLE:
+      rc = DW_ERROR_NON_INIT;
+      break;
+   case ERROR_NOT_ENOUGH_MEMORY:
+      rc = DW_ERROR_NO_MEM;
+      break;
+   case ERROR_INTERRUPT:
+      rc = DW_ERROR_INTERRUPT;
+      break;
+   case ERROR_TIMEOUT:
+      rc = DW_ERROR_TIMEOUT;
+      break;
+   }
+
+   return rc;
+}
+
+/* Release this semaphore, if there are no more open
+ * handles on this semaphore the semaphore will be destroyed.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_close(HEV eve)
+{
+   int rc;
+
+   rc = DosCloseEventSem(eve);
+   switch (rc)
+   {
+   case ERROR_INVALID_HANDLE:
+      rc = DW_ERROR_NON_INIT;
+      break;
+
+   case ERROR_SEM_BUSY:
+      rc = DW_ERROR_INTERRUPT;
+      break;
+   }
+
+   return rc;
+}
+
+/*
+ * Allocates a shared memory region with a name.
+ * Parameters:
+ *         handle: A pointer to receive a SHM identifier.
+ *         dest: A pointer to a pointer to receive the memory address.
+ *         size: Size in bytes of the shared memory region to allocate.
+ *         name: A string pointer to a unique memory name.
+ */
+HSHM API dw_named_memory_new(void **dest, int size, char *name)
+{
+   char namebuf[1024];
+
+   sprintf(namebuf, "\\sharemem\\%s", name);
+
+   if(DosAllocSharedMem((void *)dest, namebuf, size, PAG_COMMIT | PAG_WRITE | PAG_READ) != NO_ERROR)
+      return 0;
+
+   return 1;
+}
+
+/*
+ * Aquires shared memory region with a name.
+ * Parameters:
+ *         dest: A pointer to a pointer to receive the memory address.
+ *         size: Size in bytes of the shared memory region to requested.
+ *         name: A string pointer to a unique memory name.
+ */
+HSHM API dw_named_memory_get(void **dest, int size, char *name)
+{
+   char namebuf[1024];
+
+   size = size;
+   sprintf(namebuf, "\\sharemem\\%s", name);
+
+   if(DosGetNamedSharedMem((void *)dest, namebuf, PAG_READ | PAG_WRITE) != NO_ERROR)
+      return 0;
+
+   return 1;
+}
+
+/*
+ * Frees a shared memory region previously allocated.
+ * Parameters:
+ *         handle: Handle obtained from DB_named_memory_allocate.
+ *         ptr: The memory address aquired with DB_named_memory_allocate.
+ */
+int API dw_named_memory_free(HSHM handle, void *ptr)
+{
+   handle = handle;
+
+   if(DosFreeMem(ptr) != NO_ERROR)
+      return -1;
+   return 0;
+}
+
+/*
+ * Encapsulate the message queues on OS/2.
+ */
+void _dwthreadstart(void *data)
+{
+   HAB thishab = WinInitialize(0);
+   HMQ thishmq = WinCreateMsgQueue(dwhab, 0);
+   void (* API threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+
+   threadfunc = (void (* API)(void *))tmp[0];
+   threadfunc(tmp[1]);
+
+   free(tmp);
+
+   WinDestroyMsgQueue(thishmq);
+   WinTerminate(thishab);
+}
+
+/*
+ * Creates a new thread with a starting point of func.
+ * Parameters:
+ *       func: Function which will be run in the new thread.
+ *       data: Parameter(s) passed to the function.
+ *       stack: Stack size of new thread (OS/2 and Windows only).
+ */
+DWTID API dw_thread_new(void *func, void *data, int stack)
+{
+   void **tmp = malloc(sizeof(void *) * 2);
+
+   tmp[0] = func;
+   tmp[1] = data;
+
+   return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp);
+}
+
+/*
+ * Ends execution of current thread immediately.
+ */
+void API dw_thread_end(void)
+{
+   _endthread();
+}
+
+/*
+ * Returns the current thread's ID.
+ */
+DWTID API dw_thread_id(void)
+{
+   return (DWTID)_threadid;
+}
+
+/*
+ * 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)
+{
+   /* Destroy the menu message window */
+   dw_window_destroy(hwndApp);
+
+   /* In case we are in a signal handler, don't
+    * try to free memory that could possibly be
+    * free()'d by the runtime already.
+    */
+   Root = NULL;
+
+   DosFreeModule(wpconfig);
+   exit(exitcode);
+}
+
+/*
+ * Creates a splitbar window (widget) with given parameters.
+ * Parameters:
+ *       type: Value can be DW_VERT or DW_HORZ.
+ *       topleft: Handle to the window to be top or left.
+ *       bottomright:  Handle to the window to be bottom or right.
+ * Returns:
+ *       A handle to a splitbar window or NULL on failure.
+ */
+HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
+{
+   HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        SplitbarClassName,
+                        NULL,
+                        WS_VISIBLE | WS_CLIPCHILDREN,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+   if(tmp)
+   {
+      HWND tmpbox = dw_box_new(DW_VERT, 0);
+        float *percent = malloc(sizeof(float));
+
+      dw_box_pack_start(tmpbox, topleft, 1, 1, TRUE, TRUE, 0);
+      WinSetParent(tmpbox, tmp, FALSE);
+      dw_window_set_data(tmp, "_dw_topleft", (void *)tmpbox);
+
+      tmpbox = dw_box_new(DW_VERT, 0);
+      dw_box_pack_start(tmpbox, bottomright, 1, 1, TRUE, TRUE, 0);
+      WinSetParent(tmpbox, tmp, FALSE);
+      *percent = 50.0;
+      dw_window_set_data(tmp, "_dw_bottomright", (void *)tmpbox);
+      dw_window_set_data(tmp, "_dw_percent", (void *)percent);
+      dw_window_set_data(tmp, "_dw_type", (void *)type);
+   }
+   return tmp;
+}
+
+/*
+ * Sets the position of a splitbar (pecentage).
+ * Parameters:
+ *       handle: The handle to the splitbar returned by dw_splitbar_new().
+ */
+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;
+
+   if(mypercent)
+      *mypercent = percent;
+
+   dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+
+   _handle_splitbar_resize(handle, percent, type, width, height);
+}
+
+/*
+ * Gets the position of a splitbar (pecentage).
+ * Parameters:
+ *       handle: The handle to the splitbar returned by dw_splitbar_new().
+ */
+float API dw_splitbar_get(HWND handle)
+{
+   float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+
+   if(percent)
+      return *percent;
+   return 0.0;
+}
+
+/* The following two functions graciously contributed by Peter Nielsen. */
+static ULONG _ParseBuildLevel (char* pchBuffer, ULONG ulSize) {
+   char* pchStart = pchBuffer;
+   char* pchEnd = pchStart + ulSize - 2;
+
+   while (pchEnd >= pchStart)
+   {
+      if ((pchEnd[0] == '#') && (pchEnd[1] == '@'))
+      {
+         *pchEnd-- = '\0';
+         while (pchEnd >= pchStart)
+         {
+            if ((pchEnd[0] == '@') && (pchEnd[1] == '#'))
+            {
+               ULONG ulMajor = 0;
+               ULONG ulMinor = 0;
+
+               char* pch = pchEnd + 2;
+               while (!isdigit ((int)*pch) && *pch)
+                  pch++;
+
+               while (isdigit ((int)*pch))
+                  ulMajor = ulMajor * 10 + *pch++ - '0';
+
+               if (*pch == '.')
+               {
+                  while (isdigit ((int)*++pch))
+                     ulMinor = ulMinor * 10 + *pch - '0';
+               }
+               return ((ulMajor << 16) | ulMinor);
+            }
+            pchEnd--;
+         }
+      }
+      pchEnd--;
+   }
+   return (0);
+}
+
+ULONG _GetSystemBuildLevel(void) {
+   /* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2.
+    * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely.
+    */
+   ULONG ulBootDrive = 0;
+   ULONG ulBuild = 0;
+   if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR)
+   {
+      char achFileName[11] = "C:\\OS2KRNL";
+      HFILE hfile;
+      ULONG ulResult;
+
+        achFileName[0] = (char)('A'+ulBootDrive-1);
+
+      if (DosOpen (achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR)
+      {
+         ULONG ulFileSize = 0;
+         if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR)
+         {
+            const ULONG ulFirstTry = min (256, ulFileSize);
+            if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR)
+            {
+               char *pchBuffer = malloc(ulFirstTry);
+               if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR)
+               {
+                  ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry);
+                  if (ulBuild == 0)
+                  {
+                     if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR)
+                     {
+                        free(pchBuffer);
+                        pchBuffer = malloc(ulFileSize);
+
+                        if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR)
+                           ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize);
+                     }
+                  }
+               }
+               free(pchBuffer);
+            }
+         }
+         DosClose (hfile);
+      }
+   }
+   return (ulBuild);
+}
+
+/*
+ * Sets the default focus item for a window/dialog.
+ * Parameters:
+ *         window: Toplevel window or dialog.
+ *         defaultitem: Handle to the dialog item to be default.
+ */
+void API dw_window_default(HWND window, HWND defaultitem)
+{
+   Box *thisbox = NULL;
+   HWND box;
+
+   box = WinWindowFromID(window, FID_CLIENT);
+   if(box)
+      thisbox = WinQueryWindowPtr(box, QWP_USER);
+
+   if(thisbox)
+      thisbox->defaultitem = defaultitem;
+}
+
+/*
+ * Sets window to click the default dialog item when an ENTER is pressed.
+ * Parameters:
+ *         window: Window (widget) to look for the ENTER press.
+ *         next: Window (widget) to move to next (or click)
+ */
+void API dw_window_click_default(HWND window, HWND next)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(blah)
+      blah->clickdefault = next;
+}
+
+/*
+ * Gets the contents of the default clipboard as text.
+ * Parameters:
+ *       None.
+ * Returns:
+ *       Pointer to an allocated string of text or NULL if clipboard empty or contents could not
+ *       be converted to text.
+ */
+char *dw_clipboard_get_text()
+{
+    APIRET rc;
+    char *retbuf = NULL;
+    ULONG fmtInfo;
+
+    WinOpenClipbrd(dwhab);
+
+    rc = WinQueryClipbrdFmtInfo(dwhab, CF_TEXT, &fmtInfo);
+    if (rc) /* Text data in clipboard */
+    {
+        PSZ pszClipText = (PSZ)WinQueryClipbrdData(dwhab, CF_TEXT); /* Query data handle */
+        retbuf = strdup(pszClipText);
+    }
+    WinCloseClipbrd(dwhab);
+    return retbuf;
+}
+
+/*
+ * Sets the contents of the default clipboard to the supplied text.
+ * Parameters:
+ *       Text.
+ */
+void dw_clipboard_set_text( char *str, int len )
+{
+    APIRET rc;
+    static PVOID shared;
+
+    WinOpenClipbrd(dwhab); /* Open clipboard */
+    WinEmptyClipbrd(dwhab); /* Empty clipboard */
+
+    /* Ok, clipboard wants giveable unnamed shared memory */
+
+    shared = NULL;
+    rc = DosAllocSharedMem(&shared, NULL, len, OBJ_GIVEABLE | PAG_COMMIT | PAG_READ | PAG_WRITE);
+
+    if (rc == 0)
+    {
+        memcpy(shared, str, len);
+
+        WinSetClipbrdData(dwhab, (ULONG)shared, CF_TEXT, CFI_POINTER);
+    }
+
+    WinCloseClipbrd(dwhab); /* Close clipboard */
+    return;
+}
+
+/*
+ * Returns some information about the current operating environment.
+ * Parameters:
+ *       env: Pointer to a DWEnv struct.
+ */
+void API dw_environment_query(DWEnv *env)
+{
+   ULONG Build;
+
+   if(!env)
+      return;
+
+   /* The default is OS/2 2.0 */
+   strcpy(env->osName,"OS/2");
+   env->MajorVersion = 2;
+   env->MinorVersion = 0;
+
+   Build = _GetSystemBuildLevel();
+   env->MinorBuild =  Build & 0xFFFF;
+   env->MajorBuild =  Build >> 16;
+
+   if (aulBuffer[0] == 20)
+   {
+      int i = (unsigned int)aulBuffer[1];
+      if (i > 20)
+      {
+         strcpy(env->osName,"Warp");
+         env->MajorVersion = (int)i/10;
+         env->MinorVersion = i-(((int)i/10)*10);
+      }
+      else if (i == 10)
+         env->MinorVersion = 1;
+   }
+   strcpy(env->buildDate, __DATE__);
+   strcpy(env->buildTime, __TIME__);
+   env->DWMajorVersion = DW_MAJOR_VERSION;
+   env->DWMinorVersion = DW_MINOR_VERSION;
+#ifdef VER_REV
+   env->DWSubVersion = VER_REV;
+#else
+   env->DWSubVersion = DW_SUB_VERSION;
+#endif
+}
+
+/* The next few functions are support functions for the OS/2 folder browser */
+void _populate_directory(HWND tree, HTREEITEM parent, char *path)
+{
+   FILEFINDBUF3 ffbuf;
+   HTREEITEM item;
+   ULONG count = 1;
+   HDIR hdir = HDIR_CREATE;
+
+   if(DosFindFirst(path, &hdir, FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED | MUST_HAVE_DIRECTORY,
+               &ffbuf, sizeof(FILEFINDBUF3), &count, FIL_STANDARD) == NO_ERROR)
+   {
+      while(DosFindNext(hdir, &ffbuf, sizeof(FILEFINDBUF3), &count) == NO_ERROR)
+      {
+         if(strcmp(ffbuf.achName, ".") && strcmp(ffbuf.achName, ".."))
+         {
+            int len = strlen(path);
+            char *folder = malloc(len + ffbuf.cchName + 2);
+            HTREEITEM tempitem;
+
+            strcpy(folder, path);
+            strcpy(&folder[len-1], ffbuf.achName);
+
+            item = dw_tree_insert(tree, ffbuf.achName, WinLoadFileIcon(folder, TRUE), parent, (void *)parent);
+            tempitem = dw_tree_insert(tree, "", 0, item, 0);
+            dw_tree_item_set_data(tree, item, (void *)tempitem);
+         }
+      }
+      DosFindClose(hdir);
+   }
+}
+
+void API _populate_tree_thread(void *data)
+{
+   HWND window = (HWND)data, tree = (HWND)dw_window_get_data(window, "_dw_tree");
+   HMTX mtx = (HMTX)dw_window_get_data(window, "_dw_mutex");
+   int drive;
+   HTREEITEM items[26];
+   FSINFO  volinfo;
+
+   DosError(FERR_DISABLEHARDERR);
+
+   dw_mutex_lock(mtx);
+   for(drive=0;drive<26;drive++)
+   {
+      if(DosQueryFSInfo(drive+1, FSIL_VOLSER,(PVOID)&volinfo, sizeof(FSINFO)) == NO_ERROR)
+      {
+         char folder[5] = "C:\\", name[9] = "Drive C:";
+         HTREEITEM tempitem;
+
+         folder[0] = name[6] = 'A' + drive;
+
+         items[drive] = dw_tree_insert(tree, name, WinLoadFileIcon(folder, TRUE), NULL, 0);
+         tempitem = dw_tree_insert(tree, "", 0, items[drive], 0);
+         dw_tree_item_set_data(tree, items[drive], (void *)tempitem);
+      }
+      else
+         items[drive] = 0;
+   }
+   dw_mutex_unlock(mtx);
+
+   DosError(FERR_ENABLEHARDERR);
+}
+
+int DWSIGNAL _dw_ok_func(HWND window, void *data)
+{
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+   void *treedata;
+
+   window = window;
+   if(!dwwait)
+      return FALSE;
+
+   dw_mutex_lock(mtx);
+   treedata = dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
+   dw_mutex_close(mtx);
+   dw_window_destroy((HWND)dwwait->data);
+   dw_dialog_dismiss((DWDialog *)data, treedata);
+   return FALSE;
+}
+
+int DWSIGNAL _dw_cancel_func(HWND window, void *data)
+{
+   DWDialog *dwwait = (DWDialog *)data;
+   HMTX mtx = (HMTX)dw_window_get_data((HWND)dwwait->data, "_dw_mutex");
+
+   window = window;
+   if(!dwwait)
+      return FALSE;
+
+   dw_mutex_lock(mtx);
+   dw_mutex_close(mtx);
+   dw_window_destroy((HWND)dwwait->data);
+   dw_dialog_dismiss((DWDialog *)data, NULL);
+   return FALSE;
+}
+
+char *_tree_folder(HWND tree, HTREEITEM item)
+{
+   char *folder=strdup("");
+   HTREEITEM parent = item;
+
+   while(parent)
+   {
+      char *temp, *text = dw_tree_get_title(tree, parent);
+
+      if(text)
+      {
+         if(strncmp(text, "Drive ", 6) == 0)
+            text = &text[6];
+
+         temp = malloc(strlen(text) + strlen(folder) + 3);
+         strcpy(temp, text);
+         strcat(temp, "\\");
+         strcat(temp, folder);
+         free(folder);
+         folder = temp;
+      }
+      parent = dw_tree_get_parent(tree, parent);
+   }
+   return folder;
+}
+
+int DWSIGNAL _item_select(HWND window, HTREEITEM item, char *text, void *data, void *itemdata)
+{
+   DWDialog *dwwait = (DWDialog *)data;
+   char *treedata = (char *)dw_window_get_data((HWND)dwwait->data, "_dw_tree_selected");
+
+   text = text; itemdata = itemdata;
+   if(treedata)
+      free(treedata);
+
+   treedata = _tree_folder(window, item);
+   dw_window_set_data((HWND)dwwait->data, "_dw_tree_selected", (void *)treedata);
+
+   return FALSE;
+}
+
+int DWSIGNAL _tree_expand(HWND window, HTREEITEM item, void *data)
+{
+   HTREEITEM tempitem = (HTREEITEM)dw_tree_item_get_data(window, item);
+
+   data = data;
+   if(tempitem)
+   {
+      char *folder = _tree_folder(window, item);
+
+      dw_tree_item_set_data(window, item, 0);
+      dw_tree_item_delete(window, tempitem);
+
+      if(*folder)
+      {
+         strcat(folder, "*");
+         _populate_directory(window, item, folder);
+      }
+      free(folder);
+   }
+
+   return FALSE;
+}
+
+/*
+ * Opens a file dialog and queries user selection.
+ * Parameters:
+ *       title: Title bar text for dialog.
+ *       defpath: The default path of the open dialog.
+ *       ext: Default file extention.
+ *       flags: DW_FILE_OPEN or DW_FILE_SAVE.
+ * Returns:
+ *       NULL on error. A malloced buffer containing
+ *       the file path on success.
+ *
+ */
+char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
+{
+   if(flags == DW_DIRECTORY_OPEN)
+   {
+      HWND window, hbox, vbox, tree, button;
+      DWDialog *dwwait;
+      HMTX mtx = dw_mutex_new();
+
+      window = dw_window_new( HWND_DESKTOP, title, FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_SIZEBORDER | FCF_MINMAX);
+
+      vbox = dw_box_new(DW_VERT, 5);
+
+      dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+      tree = dw_tree_new(60);
+
+      dw_box_pack_start(vbox, tree, 1, 1, TRUE, TRUE, 0);
+      dw_window_set_data(window, "_dw_mutex", (void *)mtx);
+      dw_window_set_data(window, "_dw_tree", (void *)tree);
+
+      hbox = dw_box_new(DW_HORZ, 0);
+
+      dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+      dwwait = dw_dialog_new((void *)window);
+
+      dw_signal_connect(tree, DW_SIGNAL_ITEM_SELECT, DW_SIGNAL_FUNC(_item_select), (void *)dwwait);
+      dw_signal_connect(tree, DW_SIGNAL_TREE_EXPAND, DW_SIGNAL_FUNC(_tree_expand), (void *)dwwait);
+
+      button = dw_button_new("Ok", 1001L);
+      dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+      dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_ok_func), (void *)dwwait);
+
+      button = dw_button_new("Cancel", 1002L);
+      dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+      dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
+      dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_cancel_func), (void *)dwwait);
+
+      dw_window_set_size(window, 225, 300);
+      dw_window_show(window);
+
+      dw_thread_new((void *)_populate_tree_thread, (void *)window, 0xff);
+      return (char *)dw_dialog_wait(dwwait);
+   }
+   else
+   {
+      FILEDLG fild = { 0 };
+      HWND hwndFile;
+      int len;
+      struct stat buf;
+
+      if(defpath)
+      {
+          if(DosQueryPathInfo(defpath, FIL_QUERYFULLNAME, fild.szFullFile, sizeof(fild.szFullFile)))
+              strcpy(fild.szFullFile, defpath);
+      };
+
+      len = strlen(fild.szFullFile);
+
+      /* If we have a defpath */
+      if(len)
+      {
+          /* Check to see if it exists */
+          if(stat(fild.szFullFile, &buf) == 0)
+          {
+              /* If it is a directory... make sure there is a trailing \ */
+              if(buf.st_mode & S_IFDIR)
+              {
+                  if(fild.szFullFile[len-1] != '\\')
+                      strcat(fild.szFullFile, "\\");
+                  /* Set len to 0 so the wildcard gets added below */
+                  len = 0;
+              }
+          }
+      }
+
+      /* If we need a wildcard (defpath isn't a file) */
+      if(!len)
+      {
+          /* Add a * to get all files... */
+          strcat(fild.szFullFile, "*");
+
+          /* If an extension was requested... */
+          if(ext)
+          {
+              /* Limit the results further */
+              strcat(fild.szFullFile, ".");
+              strcat(fild.szFullFile, ext);
+          }
+      }
+
+      /* Setup the structure */
+      fild.cbSize = sizeof(FILEDLG);
+      fild.fl = FDS_CENTER | FDS_OPEN_DIALOG;
+      fild.pszTitle = title;
+      fild.pszOKButton = ((flags & DW_FILE_SAVE) ? "Save" : "Open");
+      fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc;
+
+      hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild);
+      if(hwndFile)
+      {
+         switch(fild.lReturn)
+         {
+         case DID_OK:
+            return strdup(fild.szFullFile);
+         case DID_CANCEL:
+            return NULL;
+         }
+      }
+   }
+   return NULL;
+}
+
+/* Internal function to set drive and directory */
+int _SetPath(char *path)
+{
+#ifndef __WATCOMC__
+   if(strlen(path)   > 2)
+   {
+      if(path[1] == ':')
+      {
+         char drive = toupper(path[0]);
+         _chdrive((drive - 'A')+1);
+      }
+   }
+#endif
+   return chdir(path);
+}
+
+/*
+ * Execute and external program in a seperate session.
+ * Parameters:
+ *       program: Program name with optional path.
+ *       type: Either DW_EXEC_CON or DW_EXEC_GUI.
+ *       params: An array of pointers to string arguements.
+ * Returns:
+ *       -1 on error.
+ */
+int API dw_exec(char *program, int type, char **params)
+{
+   type = type; /* keep compiler happy */
+   return spawnvp(P_NOWAIT, program, params);
+}
+
+/*
+ * Loads a web browser pointed at the given URL.
+ * Parameters:
+ *       url: Uniform resource locator.
+ */
+int API dw_browse(char *url)
+{
+   char *execargs[3], browser[1024], *olddir, *newurl = NULL;
+   int len, ret;
+
+   olddir = _getcwd(NULL, 1024);
+
+   PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
+                    "DefaultWorkingDir", NULL, browser, 1024);
+
+   if(browser[0])
+      _SetPath(browser);
+
+   PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS",
+                    "DefaultBrowserExe", NULL, browser, 1024);
+
+   len = strlen(browser) - strlen("explore.exe");
+
+   execargs[0] = browser;
+   execargs[1] = url;
+   execargs[2] = NULL;
+
+   /* Special case for Web Explorer, it requires file:/// instead
+    * of file:// so I am handling it here.
+    */
+   if(len > 0)
+   {
+      if(stricmp(&browser[len], "explore.exe") == 0 && stricmp(url, "file://") == 0)
+      {
+         int newlen, z;
+         newurl = malloc(strlen(url) + 2);
+         sprintf(newurl, "file:///%s", &url[7]);
+         newlen = strlen(newurl);
+         for(z=8;z<(newlen-8);z++)
+         {
+            if(newurl[z] == '|')
+               newurl[z] = ':';
+            if(newurl[z] == '/')
+               newurl[z] = '\\';
+         }
+         execargs[1] = newurl;
+      }
+   }
+
+   ret = dw_exec(browser, DW_EXEC_GUI, execargs);
+
+   if(olddir)
+   {
+      _SetPath(olddir);
+      free(olddir);
+   }
+   if(newurl)
+      free(newurl);
+   return ret;
+}
+
+/*
+ * Causes the embedded HTML widget to take action.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       action: One of the DW_HTML_* constants.
+ */
+void API dw_html_action(HWND handle, int action)
+{
+   handle = handle;
+   action = action;
+}
+
+/*
+ * Render raw HTML code in the embedded HTML widget..
+ * Parameters:
+ *       handle: Handle to the window.
+ *       string: String buffer containt HTML code to
+ *               be rendered.
+ * Returns:
+ *       0 on success.
+ */
+int API dw_html_raw(HWND handle, char *string)
+{
+   handle = handle;
+   string = string;
+   return -1;
+}
+
+/*
+ * Render file or web page in the embedded HTML widget..
+ * Parameters:
+ *       handle: Handle to the window.
+ *       url: Universal Resource Locator of the web or
+ *               file object to be rendered.
+ * Returns:
+ *       0 on success.
+ */
+int API dw_html_url(HWND handle, char *url)
+{
+   handle = handle;
+   url = url;
+   return -1;
+}
+
+/*
+ * Create a new HTML window (widget) to be packed.
+ * Not available under OS/2, eCS
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_html_new(unsigned long id)
+{
+   id = id;
+   return dw_box_new(DW_HORZ, 0);
+}
+
+typedef struct _dwprint 
+{
+    HDC hdc;
+    char *printername;
+    int (* API drawfunc)(HPRINT, HPIXMAP, int, void *);
+    void *drawdata;
+    unsigned long flags;
+    unsigned int startpage, endpage;
+    char *jobname;
+} DWPrint;
+
+/* Internal functions to handle the print dialog */
+int DWSIGNAL _dw_printer_cancel_func(HWND window, void *data)
+{
+    DWPrint *print = (DWPrint *)data;
+    DWDialog *dwwait = (DWDialog *)print->printername;
+
+    window = (HWND)dwwait->data;
+
+    dw_window_destroy(window);
+    dw_dialog_dismiss(dwwait, NULL);
+    return FALSE;
+}
+
+int DWSIGNAL _dw_printer_ok_func(HWND window, void *data)
+{
+    DWPrint *print = (DWPrint *)data;
+    DWDialog *dwwait = (DWDialog *)print->printername;
+    HWND printerlist, startspin, endspin;
+    char *result = NULL;
+
+    window = (HWND)dwwait->data;
+    printerlist = (HWND)dw_window_get_data(window, "_dw_list");
+    startspin = (HWND)dw_window_get_data(window, "_dw_start_spin");
+    endspin = (HWND)dw_window_get_data(window, "_dw_end_spin");
+    if(printerlist)
+    {
+        char printername[32] = "";
+        int selected = dw_listbox_selected(printerlist);
+
+        /* Get the name of the selected printer */
+        if(selected != DW_ERROR_UNKNOWN)
+        {
+            dw_listbox_get_text(printerlist, selected, printername, 32);
+            if(printername[0])
+                print->printername = result = strdup(printername);
+        }
+        /* Get the start and end positions */
+        print->startpage = (unsigned int)dw_spinbutton_get_pos(startspin);
+        print->endpage = (unsigned int)dw_spinbutton_get_pos(endspin);
+
+        /* If the start is bigger than end... swap them */
+        if(print->startpage > print->endpage)
+        {
+            print->endpage = print->startpage;
+            print->startpage = (unsigned int)dw_spinbutton_get_pos(endspin);
+        }
+    }
+
+    dw_window_destroy(window);
+    dw_dialog_dismiss(dwwait, (void *)result);
+    return FALSE;
+}
+
+/* Borrowed functions which should probably be rewritten */
+BOOL _ExtractLogAddress(char * LogAddress, char * DetailStr)
+{
+    char *p;
+
+    p = DetailStr;
+    while(*p++ != ';'); /* Gets to first ';' and one char beyond */
+    while(*p++ != ';'); /* Gets to second ';' and one char beyond */
+    while(*p != ';') *LogAddress++ = *p++;
+    *LogAddress = '\0';
+    return TRUE;
+}
+
+BOOL _ExtractDriverName(char * DriverName, char * DetailStr)
+{
+    char *p;
+
+    p = DetailStr;
+    while(*p++ != ';'); /* Gets to first ';' and one char beyond */
+    while(*p != '.' && *p != ';' && *p != ',')
+        *DriverName++ = *p++;
+    *DriverName = '\0';
+    return TRUE;
+}
+
+/* EMX Doesn't seem to define this? */
+#ifndef NERR_BufTooSmall
+#define NERR_BufTooSmall 2123
+#endif
+
+/*
+ * Creates a new print object.
+ * Parameters:
+ *       jobname: Name of the print job to show in the queue.
+ *       flags: Flags to initially configure the print object.
+ *       pages: Number of pages to print.
+ *       drawfunc: The pointer to the function to be used as the callback.
+ *       drawdata: User data to be passed to the handler function.
+ * Returns:
+ *       A handle to the print object or NULL on failure.
+ */
+HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata)
+{
+    char printername[32], tmpbuf[20];
+    HWND window, hbox, vbox, printerlist, button, text;
+    DWDialog *dwwait;
+    DWPrint *print;
+    PVOID pBuf = NULL;
+    ULONG fsType = SPL_PR_QUEUE;
+    ULONG cbBuf, cRes, cTotal, cbNeeded;
+    SPLERR splerr = 0 ;
+    PPRINTERINFO pRes ;    /* Check the default printer for now... want a printer list in the future */
+    int cb = PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "PRINTER", "", printername, 32);
+
+    if(!drawfunc || !(print = calloc(1, sizeof(DWPrint))))
+        return NULL;
+    
+    print->drawfunc = drawfunc;
+    print->drawdata = drawdata;
+    print->jobname = jobname ? jobname : "Dynamic Windows Print Job";
+    print->startpage = 1;
+    print->endpage = pages;
+    print->flags = flags;
+
+    /* Check to see how much space we need for the printer list */
+    splerr = SplEnumPrinter(NULL, 0, fsType, NULL, 0, &cRes, &cTotal, &cbNeeded ,NULL);
+
+    if(splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall)
+    {
+        /* Allocate memory for the buffer using the count of bytes that were returned in cbNeeded. */
+        DosAllocMem(&pBuf, cbNeeded, PAG_READ|PAG_WRITE|PAG_COMMIT);
+
+        /* Set count of bytes in buffer to value used to allocate buffer. */
+        cbBuf = cbNeeded;
+
+        /* Call function again with the correct buffer size. */
+        splerr = SplEnumPrinter(NULL, 0, fsType, pBuf, cbBuf, &cRes, &cTotal, &cbNeeded, NULL);
+    }
+
+    /* Make sure we got a valid result */
+    if(cb > 2)
+        printername[cb-2] = '\0';
+    else
+        printername[0] = '\0';
+
+    /* If we didnt' get a printer list or default printer abort */
+    if(!cRes && !printername[0])
+    {
+        /* Show an error and return failure */
+        dw_messagebox("Printing", DW_MB_ERROR | DW_MB_OK, "No printers detected.");
+        free(print);
+        return NULL;
+    }
+
+    /* Create the print dialog */
+    window = dw_window_new(HWND_DESKTOP, "Choose Printer", FCF_SHELLPOSITION | FCF_TITLEBAR | FCF_DLGBORDER | FCF_CLOSEBUTTON | FCF_SYSMENU);
+
+    vbox = dw_box_new(DW_VERT, 5);
+
+    dw_box_pack_start(window, vbox, 0, 0, TRUE, TRUE, 0);
+
+    printerlist = dw_listbox_new(0, FALSE);
+    dw_box_pack_start(vbox, printerlist, 1, 1, TRUE, TRUE, 0);
+
+    /* If there are any returned structures in the buffer... */
+    if(pBuf && cRes)
+    {
+        int count = 0;
+
+        pRes = (PPRINTERINFO)pBuf ;
+        while(cRes--)
+        {
+            dw_listbox_append(printerlist, pRes[cRes].pszPrintDestinationName);
+            /* If this is the default printer... select it by default */
+            if(strcmp(pRes[cRes].pszPrintDestinationName, printername) == 0)
+                dw_listbox_select(printerlist, count, TRUE);
+            count++;
+        }
+    }
+    else
+    {
+        /* Otherwise just add the default */
+        dw_listbox_append(printerlist, printername);
+        dw_listbox_select(printerlist, 0, TRUE);
+    }
+
+    /* Free any unneeded memory */
+    if(pBuf)
+        DosFreeMem(pBuf);
+
+    dw_window_set_data(window, "_dw_list", (void *)printerlist);
+
+    /* Start spinbutton */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+    text = dw_text_new("Start page:", 0);
+    dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+    dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3);
+
+    button = dw_spinbutton_new("1", 0);
+    dw_spinbutton_set_limits(button, 1, pages);
+    dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+    dw_window_set_data(window, "_dw_start_spin", (void *)button);
+
+    /* End spinbutton */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+
+    text = dw_text_new("End page:", 0);
+    dw_window_set_style(text, DW_DT_VCENTER, DW_DT_VCENTER);
+    dw_box_pack_start(hbox, text, 70, 20, FALSE, FALSE, 3);
+
+    sprintf(tmpbuf, "%d", pages);
+    button = dw_spinbutton_new(tmpbuf, 0);
+    dw_spinbutton_set_limits(button, 1, pages);
+    dw_box_pack_start(hbox, button, 20, 20, TRUE, FALSE, 3);
+    dw_window_set_data(window, "_dw_end_spin", (void *)button);
+
+    /* Ok and Cancel buttons */
+    hbox = dw_box_new(DW_HORZ, 0);
+
+    dw_box_pack_start(vbox, hbox, 0, 0, TRUE, FALSE, 0);
+    dw_box_pack_start(hbox, 0, 100, 1, TRUE, FALSE, 0);
+
+    button = dw_button_new("Ok", 0);
+    dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+    dwwait = dw_dialog_new((void *)window);
+    /* Save it temporarily there until we need it */
+    print->printername = (char *)dwwait;
+
+    dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_ok_func), (void *)print);
+
+    button = dw_button_new("Cancel", 0);
+    dw_box_pack_start(hbox, button, 50, 30, TRUE, FALSE, 3);
+
+    dw_signal_connect(button, DW_SIGNAL_CLICKED, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print);
+    dw_signal_connect(window, DW_SIGNAL_DELETE, DW_SIGNAL_FUNC(_dw_printer_cancel_func), (void *)print);
+
+    dw_window_set_size(window, 300, 400);
+
+    dw_window_show(window);
+
+    print->printername = dw_dialog_wait(dwwait);
+
+    /* The user picked a printer */
+    if(print->printername)
+    {
+        char PrintDetails[256];
+        char DriverName[32];
+        char LogAddress[32];
+        DEVOPENSTRUC dop;
+
+        /* Get the printer information string */
+        cb = PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER_PRINTER", print->printername, "", PrintDetails, 256);
+        _ExtractLogAddress(LogAddress, PrintDetails);
+        _ExtractDriverName(DriverName, PrintDetails);
+        dop.pszDriverName = DriverName;
+        dop.pszLogAddress = LogAddress;
+        dop.pdriv = NULL;
+        dop.pszDataType = "PM_Q_STD";
+        /* Attempt to open a device context and return a handle to it */
+        print->hdc = DevOpenDC(dwhab, OD_QUEUED, "*", 4L, (PDEVOPENDATA) &dop, (HDC)NULL);
+        if(print->hdc)
+            return print;
+    }
+    /* The user canceled */
+    if(print->printername)
+        free(print->printername);
+    free(print);
+    return NULL;
+}
+
+/*
+ * Runs the print job, causing the draw page callbacks to fire.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ *       flags: Flags to run the print job.
+ * Returns:
+ *       DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success.
+ */
+int API dw_print_run(HPRINT print, unsigned long flags)
+{
+    DWPrint *p = print;
+    HPIXMAP pixmap;
+    int x, result = DW_ERROR_UNKNOWN;
+    SIZEL sizl = { 0, 0 };
+    
+    if(!p)
+        return result;
+        
+    if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+        return result;
+
+    /* Start the job */
+    DevEscape(p->hdc, DEVESC_STARTDOC, strlen(p->jobname), p->jobname, NULL, NULL);
+
+    pixmap->font = WinCreateWindow(HWND_OBJECT, WC_FRAME, NULL, 0,0,0,1,1, NULLHANDLE, HWND_TOP,0, NULL, NULL);
+    pixmap->hdc = p->hdc;
+    pixmap->hps = GpiCreatePS(dwhab, p->hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
+    pixmap->transcolor = DW_RGB_TRANSPARENT;
+    pixmap->width = sizl.cx;
+    pixmap->height = sizl.cy;
+    dw_pixmap_set_font(pixmap, DefaultFont);
+
+    /* Cycle through each page */
+    for(x=p->startpage-1; x<p->endpage && p->drawfunc; x++)
+    {
+        p->drawfunc(print, pixmap, x, p->drawdata);
+        /* Next page */
+        DevEscape(p->hdc, DEVESC_NEWFRAME, 0, NULL, NULL, NULL);
+    }
+    /* Signal that we are done */
+    DevEscape(p->hdc, DEVESC_ENDDOC, 0, NULL, NULL, NULL);
+    /* Determine the completion code */
+    if(p->drawfunc)
+        result = DW_ERROR_NONE;
+    /* Free memory */
+    dw_pixmap_destroy(pixmap);
+    if(p->printername)
+        free(p->printername);
+    free(p);
+    return result;
+}
+
+/*
+ * Cancels the print job, typically called from a draw page callback.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ */
+void API dw_print_cancel(HPRINT print)
+{
+    DWPrint *p = print;
+    
+    if(p)
+        p->drawfunc = NULL;
+}
+
+/*
+ * Returns a pointer to a static buffer which containes the
+ * current user directory.  Or the root directory (C:\ on
+ * OS/2 and Windows).
+ */
+char * API dw_user_dir(void)
+{
+   static char _user_dir[1024] = "";
+
+   if(!_user_dir[0])
+   {
+      char *home = getenv("HOME");
+
+      if(home)
+         strcpy(_user_dir, home);
+      else
+         strcpy(_user_dir, "C:\\");
+   }
+   return _user_dir;
+}
+
+/*
+ * Call a function from the window (widget)'s context.
+ * Parameters:
+ *       handle: Window handle of the widget.
+ *       function: Function pointer to be called.
+ *       data: Pointer to the data to be passed to the function.
+ */
+void API dw_window_function(HWND handle, void *function, void *data)
+{
+   WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data);
+}
+
+/* Functions for managing the user data lists that are associated with
+ * a given window handle.  Used in dw_window_set_data() and
+ * dw_window_get_data().
+ */
+UserData *_find_userdata(UserData **root, char *varname)
+{
+   UserData *tmp = *root;
+
+   while(tmp)
+   {
+      if(stricmp(tmp->varname, varname) == 0)
+         return tmp;
+      tmp = tmp->next;
+   }
+   return NULL;
+}
+
+int _new_userdata(UserData **root, char *varname, void *data)
+{
+   UserData *new = _find_userdata(root, varname);
+
+   if(new)
+   {
+      new->data = data;
+      return TRUE;
+   }
+   else
+   {
+      new = malloc(sizeof(UserData));
+      if(new)
+      {
+         new->varname = strdup(varname);
+         new->data = data;
+
+         new->next = NULL;
+
+         if (!*root)
+            *root = new;
+         else
+         {
+            UserData *prev = *root, *tmp = prev->next;
+
+            while(tmp)
+            {
+               prev = tmp;
+               tmp = tmp->next;
+            }
+            prev->next = new;
+         }
+         return TRUE;
+      }
+   }
+   return FALSE;
+}
+
+int _remove_userdata(UserData **root, char *varname, int all)
+{
+   UserData *prev = NULL, *tmp = *root;
+
+   while(tmp)
+   {
+      if(all || stricmp(tmp->varname, varname) == 0)
+      {
+         if(!prev)
+         {
+            *root = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            if(!all)
+               return 0;
+            tmp = *root;
+         }
+         else
+         {
+            /* If all is true we should
+             * never get here.
+             */
+            prev->next = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            return 0;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+   return 0;
+}
+
+/*
+ * Add a named user data item to a window handle.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       dataname: A string pointer identifying which signal to be hooked.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_window_set_data(HWND window, char *dataname, void *data)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(!blah)
+   {
+      if(!dataname)
+         return;
+
+      blah = calloc(1, sizeof(WindowData));
+      WinSetWindowPtr(window, QWP_USER, blah);
+   }
+
+   if(data)
+      _new_userdata(&(blah->root), dataname, data);
+   else
+   {
+      if(dataname)
+         _remove_userdata(&(blah->root), dataname, FALSE);
+      else
+         _remove_userdata(&(blah->root), NULL, TRUE);
+   }
+}
+
+/*
+ * Gets a named user data item to a window handle.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       dataname: A string pointer identifying which signal to be hooked.
+ *       data: User data to be passed to the handler function.
+ */
+void * API dw_window_get_data(HWND window, char *dataname)
+{
+   WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER);
+
+   if(blah && blah->root && dataname)
+   {
+      UserData *ud = _find_userdata(&(blah->root), dataname);
+      if(ud)
+         return ud->data;
+   }
+   return NULL;
+}
+
+/*
+ * Add a callback to a timer event.
+ * Parameters:
+ *       interval: Milliseconds to delay between calls.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       data: User data to be passed to the handler function.
+ * Returns:
+ *       Timer ID for use with dw_timer_disconnect(), 0 on error.
+ */
+int API dw_timer_connect(int interval, void *sigfunc, void *data)
+{
+   if(sigfunc)
+   {
+      int timerid = WinStartTimer(dwhab, NULLHANDLE, 0, interval);
+
+      if(timerid)
+      {
+         _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data);
+         return timerid;
+      }
+   }
+   return 0;
+}
+
+/*
+ * Removes timer callback.
+ * Parameters:
+ *       id: Timer ID returned by dw_timer_connect().
+ */
+void API dw_timer_disconnect(int id)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   /* 0 is an invalid timer ID */
+   if(!id)
+      return;
+
+   WinStopTimer(dwhab, NULLHANDLE, id);
+
+   while(tmp)
+   {
+      if(tmp->id == id)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Add a callback to a window event.
+ * 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.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
+{
+   ULONG message = 0, id = 0;
+
+   if(window && signame && sigfunc)
+   {
+      if((message = _findsigmessage(signame)) != 0)
+      {
+         /* Handle special case of the menu item */
+         if(message == WM_COMMAND && window < 65536)
+         {
+            char buffer[15];
+            HWND owner;
+
+            sprintf(buffer, "_dw_id%d", (int)window);
+            owner = (HWND)dw_window_get_data(hwndApp, buffer);
+
+            /* Make sure there are no dupes from popups */
+            dw_signal_disconnect_by_window(window);
+
+            if(owner)
+            {
+               id = window;
+               window = owner;
+            }
+         }
+         _new_signal(message, window, id, sigfunc, data);
+      }
+   }
+}
+
+/*
+ * Removes callbacks for a given window with given name.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ */
+void API dw_signal_disconnect_by_name(HWND window, char *signame)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+   ULONG message;
+
+   if(!window || !signame || (message = _findsigmessage(signame)) == 0)
+      return;
+
+   while(tmp)
+   {
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Removes all callbacks for a given window.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ */
+void API dw_signal_disconnect_by_window(HWND window)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if((window < 65536 && tmp->id == window) || tmp->window == window)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Removes all callbacks for a given window with specified data.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ *       data: Pointer to the data to be compared against.
+ */
+void API dw_signal_disconnect_by_data(HWND window, void *data)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+
+
+/*
+ * Create a new static text window (widget) to be packed.
+ * Not available under OS/2, eCS
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_calendar_new(ULONG id)
+{
+    char *text = "dummy calendar";
+    WindowData *blah = calloc(sizeof(WindowData), 1);
+    HWND tmp = WinCreateWindow(HWND_OBJECT,
+                        WC_STATIC,
+                        text,
+                        WS_VISIBLE | SS_TEXT,
+                        0,0,2000,1000,
+                        NULLHANDLE,
+                        HWND_TOP,
+                        id,
+                        NULL,
+                        NULL);
+    blah->oldproc = WinSubclassWindow(tmp, _textproc);
+    WinSetWindowPtr(tmp, QWP_USER, blah);
+    dw_window_set_font(tmp, DefaultFont);
+    dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY);
+    WinSetWindowText(tmp, text);
+    return tmp;
+}
+
+/*
+ * The following are stubs
+ */
+void API dw_calendar_set_date( HWND window, unsigned int year, unsigned int month, unsigned int day )
+{
+    char tmp[30];
+    sprintf( tmp, "%4.4d-%2.2d-%2.2d", year, month, day);
+    WinSetWindowText(window, tmp);
+}
+
+void API dw_calendar_get_date( HWND window, unsigned int *year, unsigned int *month, unsigned int *day )
+{
+    window = window;
+    *year = *month = *day = 0;
+}
--- a/packinst/packinst.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/packinst/packinst.c	Sun Nov 13 07:22:43 2011 -0600
@@ -106,7 +106,7 @@
    char entry[8096], entrydata[8096];
    int z;
 
-   printf("Packinst- version 2.1 (c) 1999-2003 DBSoft\n\n");
+   printf("Packinst- version 2.1 (c) 1999-2011 DBSoft\n\n");
    if(argc!=2)
       {
          printf("Usage: Packinst <filename.cfg>\n");
--- a/rexx.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/rexx.c	Sun Nov 13 07:22:43 2011 -0600
@@ -786,12 +786,12 @@
 	return 0;
 }
 
-int EXPENTRY rexx_dw_window_set_usize(PCSZ Name, ULONG ArgCount, RXSTRING Args[], PCSZ Queuename, PRXSTRING Retstr)
+int EXPENTRY rexx_dw_window_set_size(PCSZ Name, ULONG ArgCount, RXSTRING Args[], PCSZ Queuename, PRXSTRING Retstr)
 {
 	if(ArgCount < 3)
 		return 40;
 
-	dw_window_set_usize((HWND)atol(Args[0].strptr),atol(Args[1].strptr),atol(Args[2].strptr));
+	dw_window_set_size((HWND)atol(Args[0].strptr),atol(Args[1].strptr),atol(Args[2].strptr));
 
 	Retstr->strlength = 0;
 	return 0;
@@ -901,12 +901,12 @@
 	return 0;
 }
 
-int EXPENTRY rexx_dw_checkbox_query(PCSZ Name, ULONG ArgCount, RXSTRING Args[], PCSZ Queuename, PRXSTRING Retstr)
+int EXPENTRY rexx_dw_checkbox_get(PCSZ Name, ULONG ArgCount, RXSTRING Args[], PCSZ Queuename, PRXSTRING Retstr)
 {
 	if(ArgCount < 1)
 		return 40;
 
-	sprintf(Retstr->strptr, "%lu", (ULONG)dw_checkbox_query((HWND)atol(Args[0].strptr)));
+	sprintf(Retstr->strptr, "%lu", (ULONG)dw_checkbox_get((HWND)atol(Args[0].strptr)));
 
 	Retstr->strlength = strlen(Retstr->strptr);
 	return 0;
@@ -995,7 +995,7 @@
 	if(buffer)
 	{
 		point = dw_mle_import(hwndMLE, buffer, point);
-		dw_mle_set(hwndMLE, 0);
+		dw_mle_set_cursor(hwndMLE, 0);
 		free(buffer);
 	}
 
@@ -1233,7 +1233,7 @@
 
 	checkbox  = (HWND)atol(Args[0].strptr);
 
-	if(dw_checkbox_query(checkbox))
+	if(dw_checkbox_get(checkbox))
 		strcpy(Retstr->strptr, "1");
 	else
 		strcpy(Retstr->strptr, "0");
@@ -1378,7 +1378,7 @@
 	RexxRegisterFunctionExe("dw_listbox_select", &rexx_dw_listbox_select);
 	RexxRegisterFunctionExe("dw_listbox_selected", &rexx_dw_listbox_selected);
 	RexxRegisterFunctionExe("dw_window_set_pos", &rexx_dw_window_set_pos);
-	RexxRegisterFunctionExe("dw_window_set_usize", &rexx_dw_window_set_usize);
+	RexxRegisterFunctionExe("dw_window_set_size", &rexx_dw_window_set_size);
 	RexxRegisterFunctionExe("dw_window_set_pos_size", &rexx_dw_window_set_pos_size);
 	RexxRegisterFunctionExe("dw_window_set_style", &rexx_dw_window_set_style);
 	RexxRegisterFunctionExe("dw_window_set_icon", &rexx_dw_window_set_icon);
@@ -1386,7 +1386,7 @@
 	RexxRegisterFunctionExe("dw_window_set_text", &rexx_dw_window_set_text);
 	RexxRegisterFunctionExe("dw_window_enable", &rexx_dw_window_enable);
 	RexxRegisterFunctionExe("dw_window_disable", &rexx_dw_window_disable);
-	RexxRegisterFunctionExe("dw_checkbox_query", &rexx_dw_checkbox_query);
+	RexxRegisterFunctionExe("dw_checkbox_get", &rexx_dw_checkbox_get);
 	RexxRegisterFunctionExe("dw_checkbox_set", &rexx_dw_checkbox_set);
 	RexxRegisterFunctionExe("dw_screen_width", &rexx_dw_screen_width);
 	RexxRegisterFunctionExe("dw_screen_height", &rexx_dw_screen_height);
@@ -1449,7 +1449,7 @@
 	RexxDeregisterFunction("dw_listbox_select");
 	RexxDeregisterFunction("dw_listbox_selected");
 	RexxDeregisterFunction("dw_window_set_pos");
-	RexxDeregisterFunction("dw_window_set_usize");
+	RexxDeregisterFunction("dw_window_set_size");
 	RexxDeregisterFunction("dw_window_set_pos_size");
 	RexxDeregisterFunction("dw_window_set_style");
 	RexxDeregisterFunction("dw_window_set_icon");
@@ -1458,7 +1458,7 @@
 	RexxDeregisterFunction("dw_window_enable");
 	RexxDeregisterFunction("dw_window_disable");
 	RexxDeregisterFunction("dw_checkbox_set");
-	RexxDeregisterFunction("dw_checkbox_query");
+	RexxDeregisterFunction("dw_checkbox_get");
 	RexxDeregisterFunction("dw_screen_width");
 	RexxDeregisterFunction("dw_screen_height");
 	RexxDeregisterFunction("dw_yesno");
--- a/win/dw.c	Fri Feb 18 09:04:25 2011 -0600
+++ b/win/dw.c	Sun Nov 13 07:22:43 2011 -0600
@@ -1,8516 +1,10985 @@
-/*
-/*
- * Dynamic Windows:
- *          A GTK like implementation of the Win32 GUI
- *
- * (C) 2000-2003 Brian Smith <dbsoft@technologist.com>
- * (C) 2003 Mark Hessling <m.hessling@qut.edu.au>
- *
- */
-#define _WIN32_IE 0x0500
-#ifdef WINNT_COMPAT
-#define WINVER 0x400
-#else
-#define WINVER 0x500
-#endif
-#include <windows.h>
-#include <windowsx.h>
-#include <commctrl.h>
-#include <shlwapi.h>
-#include <shlobj.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <process.h>
-#include <time.h>
-#include "dw.h"
-
-HWND popup = (HWND)NULL, hwndBubble = (HWND)NULL, hwndBubbleLast, DW_HWND_OBJECT = (HWND)NULL;
-
-HINSTANCE DWInstance = NULL;
-
-DWORD dwVersion = 0, dwComctlVer = 0;
-DWTID _dwtid = -1;
-
-#define PACKVERSION(major,minor) MAKELONG(minor,major)
-
-#define IS_IE5PLUS (dwComctlVer >= PACKVERSION(5,80))
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
-int main(int argc, char *argv[]);
-
-#define ICON_INDEX_LIMIT 200
-HICON lookup[200];
-HIMAGELIST hSmall  = 0, hLarge = 0;
-
-/* Special flag used for internal tracking */
-#define DW_CFA_RESERVED (1 << 30)
-
-#define THREAD_LIMIT 128
-COLORREF _foreground[THREAD_LIMIT];
-COLORREF _background[THREAD_LIMIT];
-HPEN _hPen[THREAD_LIMIT];
-HBRUSH _hBrush[THREAD_LIMIT];
-
-BYTE _red[] = { 	0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77,
-			  0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 };
-BYTE _green[] = {	0x00, 0x00, 0xbb, 0xaa, 0x00, 0x00, 0xbb, 0xaa, 0x77,
-			  0x00, 0xff, 0xee, 0x00, 0x00, 0xee, 0xff, 0xaa, 0x00 };
-BYTE _blue[] = { 	0x00, 0x00, 0x00, 0x00, 0xcc, 0xbb, 0xbb, 0xaa, 0x77,
-		      0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0xff, 0xaa, 0x00};
-
-HBRUSH _colors[18];
-
-
-void _resize_notebook_page(HWND handle, int pageid);
-void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
-int _lookup_icon(HWND handle, HICON hicon, int type);
-HFONT _acquire_font(HWND handle, char *fontname);
-
-typedef struct _sighandler
-{
-	struct _sighandler	*next;
-	ULONG message;
-	HWND window;
-	int id;
-	void *signalfunction;
-	void *data;
-
-} SignalHandler;
-
-SignalHandler *Root = NULL;
-int _index;
-
-typedef struct
-{
-	ULONG message;
-	char name[30];
-
-} SignalList;
-
-static int in_checkbox_handler = 0;
-
-/* List of signals and their equivilent Win32 message */
-#define SIGNALMAX 17
-
-SignalList SignalTranslate[SIGNALMAX] = {
-	{ WM_SIZE,         DW_SIGNAL_CONFIGURE },
-	{ WM_CHAR,         DW_SIGNAL_KEY_PRESS },
-	{ WM_LBUTTONDOWN,  DW_SIGNAL_BUTTON_PRESS },
-	{ WM_LBUTTONUP,    DW_SIGNAL_BUTTON_PRESS },
-	{ WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
-	{ WM_CLOSE,        DW_SIGNAL_DELETE },
-	{ WM_PAINT,        DW_SIGNAL_EXPOSE },
-	{ WM_COMMAND,      DW_SIGNAL_CLICKED },
-	{ NM_DBLCLK,       DW_SIGNAL_ITEM_ENTER },
-	{ NM_RCLICK,       DW_SIGNAL_ITEM_CONTEXT },
-	{ LBN_SELCHANGE,   DW_SIGNAL_LIST_SELECT },
-	{ TVN_SELCHANGED,  DW_SIGNAL_ITEM_SELECT },
-	{ WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
-	{ WM_VSCROLL,      DW_SIGNAL_VALUE_CHANGED },
-	{ TCN_SELCHANGE,   DW_SIGNAL_SWITCH_PAGE },
-	{ LVN_COLUMNCLICK, DW_SIGNAL_COLUMN_CLICK },
-	{ TVN_ITEMEXPANDED,DW_SIGNAL_TREE_EXPAND }
-};
-
-#ifdef BUILD_DLL
-void Win32_Set_Instance(HINSTANCE hInstance)
-{
-	DWInstance = hInstance;
-}
-#else
-char **_convertargs(int *count, char *start)
-{
-	char *tmp, *argstart, **argv;
-	int loc = 0, inquotes = 0;
-
-	(*count) = 1;
-
-	tmp = start;
-
-	/* Count the number of entries */
-	if(*start)
-	{
-		(*count)++;
-
-		while(*tmp)
-		{
-			if(*tmp == '"' && inquotes)
-				inquotes = 0;
-			else if(*tmp == '"' && !inquotes)
-				inquotes = 1;
-			else if(*tmp == ' ' && !inquotes)
-			{
-				/* Push past any white space */
-				while(*(tmp+1) == ' ')
-					tmp++;
-				/* If we aren't at the end of the command
-				 * line increment the count.
-				 */
-				if(*(tmp+1))
-					(*count)++;
-			}
-			tmp++;
-		}
-	}
-
-	argv = (char **)malloc(sizeof(char *) * ((*count)+1));
-	argv[0] = malloc(260);
-	GetModuleFileName(DWInstance, argv[0], 260);
-
-	argstart = tmp = start;
-
-	if(*start)
-	{
-		loc = 1;
-
-		while(*tmp)
-		{
-			if(*tmp == '"' && inquotes)
-			{
-				*tmp = 0;
-				inquotes = 0;
-			}
-			else if(*tmp == '"' && !inquotes)
-			{
-				argstart = tmp+1;
-				inquotes = 1;
-			}
-			else if(*tmp == ' ' && !inquotes)
-			{
-				*tmp = 0;
-				argv[loc] = strdup(argstart);
-
-				/* Push past any white space */
-				while(*(tmp+1) == ' ')
-					tmp++;
-
-				/* Move the start pointer */
-				argstart = tmp+1;
-
-				/* If we aren't at the end of the command
-				 * line increment the count.
-				 */
-				if(*(tmp+1))
-					loc++;
-			}
-			tmp++;
-		}
-		if(*argstart)
-			argv[loc] = strdup(argstart);
-	}
-	argv[loc+1] = NULL;
-	return argv;
-}
-
-/* Ok this is a really big hack but what the hell ;) */
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
-{
-	char **argv;
-	int argc;
-
-	DWInstance = hInstance;
-
-	argv = _convertargs(&argc, lpCmdLine);
-
-	return main(argc, argv);
-}
-#endif
-
-/* This should return true for WinNT/2K/XP and false on Win9x */
-int IsWinNT(void)
-{
-	static int isnt = -1;
-
-	if(isnt == -1)
-	{
-		if (GetVersion() < 0x80000000)
-			isnt = 1;
-		else
-			isnt = 0;
-	}
-	return isnt;
-}
-
-DWORD GetDllVersion(LPCTSTR lpszDllName)
-{
-
-	HINSTANCE hinstDll;
-	DWORD dwVersion = 0;
-
-	hinstDll = LoadLibrary(lpszDllName);
-
-	if(hinstDll)
-	{
-		DLLGETVERSIONPROC pDllGetVersion;
-
-		pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
-
-		/* Because some DLLs might not implement this function, you
-		 * must test for it explicitly. Depending on the particular
-		 * DLL, the lack of a DllGetVersion function can be a useful
-		 * indicator of the version.
-		 */
-		if(pDllGetVersion)
-		{
-			DLLVERSIONINFO dvi;
-			HRESULT hr;
-
-			ZeroMemory(&dvi, sizeof(dvi));
-			dvi.cbSize = sizeof(dvi);
-
-            hr = (*pDllGetVersion)(&dvi);
-
-			if(SUCCEEDED(hr))
-			{
-				dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
-			}
-		}
-
-		FreeLibrary(hinstDll);
-	}
-    return dwVersion;
-}
-
-/* This function adds a signal handler callback into the linked list.
- */
-void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
-{
-	SignalHandler *new = malloc(sizeof(SignalHandler));
-
-	new->message = message;
-	new->window = window;
-	new->id = id;
-	new->signalfunction = signalfunction;
-	new->data = data;
-	new->next = NULL;
-
-	if (!Root)
-		Root = new;
-	else
-	{
-		SignalHandler *prev = NULL, *tmp = Root;
-		while(tmp)
-		{
-			if(tmp->message == message &&
-			   tmp->window == window &&
-			   tmp->id == id &&
-			   tmp->signalfunction == signalfunction)
-			{
-				tmp->data = data;
-				free(new);
-				return;
-			}
-			prev = tmp;
-			tmp = tmp->next;
-		}
-		if(prev)
-			prev->next = new;
-		else
-			Root = new;
-	}
-}
-
-/* Finds the message number for a given signal name */
-ULONG _findsigmessage(char *signame)
-{
-	int z;
-
-	for(z=0;z<SIGNALMAX;z++)
-	{
-		if(stricmp(signame, SignalTranslate[z].name) == 0)
-			return SignalTranslate[z].message;
-	}
-	return 0L;
-}
-
-/* This function removes and handlers on windows and frees
- * the user memory allocated to it.
- */
-BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam)
-{
-	ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-	HFONT oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
-	HICON oldicon = (HICON)SendMessage(handle, WM_GETICON, 0, 0);
-	char tmpbuf[100];
-
-	/* Delete font, icon and bitmap GDI objects in use */
-	if(oldfont)
-		DeleteObject(oldfont);
-	if(oldicon)
-		DeleteObject(oldicon);
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
-	{
-		HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
-
-		if(oldbitmap)
-			DeleteObject(oldbitmap);
-	}
-	if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
-	{
-		HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
-
-		if(oldbitmap)
-			DeleteObject(oldbitmap);
-	}
-	else if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
-	{
-		Box *box = (Box *)thiscinfo;
-
-		if(box->count && box->items)
-			free(box->items);
-	}
-	else if(strnicmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-	{
-		void *data = dw_window_get_data(handle, "_dw_percent");
-
-		if(data)
-			free(data);
-	}
-	else if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)==0)
-	{
-		dw_tree_clear(handle);
-	}
-	else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL)+1)==0) /* Notebook */
-	{
-		NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-
-		if(array)
-		{
-			int z, refid = -1;
-
-			for(z=0;z<256;z++)
-			{
-				if(array[z])
-				{
-					_free_window_memory(array[z]->hwnd, 0);
-					EnumChildWindows(array[z]->hwnd, _free_window_memory, 0);
-					DestroyWindow(array[z]->hwnd);
-					free(array[z]);
-				}
-			}
-			free(array);
-		}
-	}
-
-	dw_signal_disconnect_by_window(handle);
-
-	if(thiscinfo)
-	{
-		SubclassWindow(handle, thiscinfo->pOldProc);
-
-		/* Delete the brush so as not to leak GDI objects */
-		if(thiscinfo->hbrush)
-			DeleteObject(thiscinfo->hbrush);
-
-		/* Free user data linked list memory */
-		if(thiscinfo->root)
-			dw_window_set_data(handle, NULL, NULL);
-
-		SetWindowLongPtr(handle, GWLP_USERDATA, 0);
-		free(thiscinfo);
-	}
-	return TRUE;
-}
-
-void _free_menu_data(HMENU menu)
-{
-#ifndef WINNT_COMPAT
-	int i, count = GetMenuItemCount(menu);
-
-	for(i=0;i<count;i++)
-	{
-		MENUITEMINFO mii;
-
-		mii.cbSize = sizeof(MENUITEMINFO);
-		mii.fMask = MIIM_SUBMENU;
-
-		if(GetMenuItemInfo(menu, i, TRUE, &mii)
-		   && mii.hSubMenu)
-			_free_menu_data(mii.hSubMenu);
-	}
-#endif
-	dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED);
-}
-
-/* Convert to our internal color scheme */
-ULONG _internal_color(ULONG color)
-{
-	if(color == DW_CLR_DEFAULT)
-		return DW_RGB_TRANSPARENT;
-	if(color < 18)
-		return DW_RGB(_red[color], _green[color], _blue[color]);
-	return color;
-}
-
-/* This function returns 1 if the window (widget) handle
- * passed to it is a valid window that can gain input focus.
- */
-int _validate_focus(HWND handle)
-{
-	char tmpbuf[100];
-
-	if(!handle)
-		return 0;
-
-	if(!IsWindowEnabled(handle))
-		return 0;
-
-	GetClassName(handle, tmpbuf, 99);
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1)==0 ||          /* Entryfield */
-	   strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0 ||      /* Button */
-	   strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0 ||  /* Combobox */
-	   strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME)+1)==0 ||    /* List box */
-	   strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0 ||            /* Spinbutton */
-	   strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0 ||        /* Slider */
-	   strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)== 0 ||             /* Container */
-	   strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)== 0)               /* Tree */
-		return 1;
-	return 0;
-}
-
-HWND _normalize_handle(HWND handle)
-{
-	char tmpbuf[100] = "";
-
-	GetClassName(handle, tmpbuf, 99);
-	if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) /* Spinner */
-	{
-		ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-		if(cinfo && cinfo->buddy)
-			return cinfo->buddy;
-	}
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) /* Combobox */
-	{
-		ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-		if(cinfo && cinfo->buddy)
-			return cinfo->buddy;
-	}
-	return handle;
-}
-
-int _focus_check_box(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=box->count-1;z>-1;z--)
-	{
-		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))
-				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
-			{
-				char tmpbuf[100] = "";
-
-				GetClassName(box->items[z].hwnd, tmpbuf, 99);
-
-				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 *)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");
-
-					if(mybox)
-					{
-						Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
-
-						if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
-							return 1;
-					}
-				}
-				else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(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(notebox, handle, start == 3 ? 3 : 0, 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))
-				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
-			{
-				char tmpbuf[100] = "";
-
-				GetClassName(box->items[z].hwnd, tmpbuf, 99);
-
-				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 *)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(strnicmp(tmpbuf, WC_TABCONTROL, strlen(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;
-						}
-					}
-				}
-			}
-		}
-	}
-	return 0;
-}
-
-/* This function finds the first widget in the
- * layout and moves the current focus to it.
- */
-void _initial_focus(HWND handle)
-{
-	Box *thisbox;
-	char tmpbuf[100];
-
-	if(!handle)
-		return;
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, ClassName, strlen(ClassName))!=0)
-		return;
-
-
-	if(handle)
-		thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	if(thisbox)
-	{
-		_focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
-	}
-}
-
-HWND _toplevel_window(HWND handle)
-{
-	HWND box, lastbox = GetParent(handle);
-
-	/* Find the toplevel window */
-	while((box = GetParent(lastbox)))
-	{
-		lastbox = box;
-	}
-	if(lastbox)
-		return lastbox;
-	return handle;
-}
-
-/* This function finds the current widget in the
- * layout and moves the current focus to the next item.
- */
-void _shift_focus(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(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);
-	}
-}
-
-/* ResetWindow:
- *         Resizes window to the exact same size to trigger
- *         recalculation of frame.
- */
-void _ResetWindow(HWND hwndFrame)
-{
-	RECT rcl;
-
-	GetWindowRect(hwndFrame, &rcl);
-	SetWindowPos(hwndFrame, HWND_TOP, 0, 0, rcl.right - rcl.left,
-				 rcl.bottom - rcl.top - 1, SWP_NOMOVE | SWP_NOZORDER);
-	SetWindowPos(hwndFrame, HWND_TOP, 0, 0, rcl.right - rcl.left,
-				 rcl.bottom - rcl.top, SWP_NOMOVE | SWP_NOZORDER);
-}
-
-/* This function calculates how much space the widgets and boxes require
- * and does expansion as necessary.
- */
-int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
-				int pass, int *usedpadx, int *usedpady)
-{
-	int z, currentx = 0, currenty = 0;
-	int uymax = 0, uxmax = 0;
-	int upymax = 0, upxmax = 0;
-	/* Used for the SIZEEXPAND */
-	int nux = *usedx, nuy = *usedy;
-	int nupx = *usedpadx, nupy = *usedpady;
-
-	(*usedx) += (thisbox->pad * 2);
-	(*usedy) += (thisbox->pad * 2);
-
-	if(thisbox->grouphwnd)
-	{
-		char *text = dw_window_get_text(thisbox->grouphwnd);
-
-		thisbox->grouppady = 0;
-
-		if(text)
-		{
-			dw_font_text_extents(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
-			dw_free(text);
-		}
-
-		if(thisbox->grouppady)
-			thisbox->grouppady += 3;
-		else
-			thisbox->grouppady = 6;
-
-		thisbox->grouppadx = 6;
-
-		(*usedx) += thisbox->grouppadx;
-		(*usedpadx) += thisbox->grouppadx;
-		(*usedy) += thisbox->grouppady;
-		(*usedpady) += thisbox->grouppady;
-	}
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			int initialx, initialy;
-			Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-			initialx = x - (*usedx);
-			initialy = y - (*usedy);
-
-			if(tmp)
-			{
-				int newx, newy;
-				int nux = *usedx, nuy = *usedy;
-				int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
-
-				/* On the second pass we know how big the box needs to be and how
-				 * much space we have, so we can calculate a ratio for the new box.
-				 */
-				if(pass == 2)
-				{
-					int deep = *depth + 1;
-
-					_resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
-
-					tmp->upx = upx - *usedpadx;
-					tmp->upy = upy - *usedpady;
-
-					newx = x - nux;
-					newy = y - nuy;
-
-					tmp->width = thisbox->items[z].width = initialx - newx;
-					tmp->height = thisbox->items[z].height = initialy - newy;
-
-					tmp->parentxratio = thisbox->xratio;
-					tmp->parentyratio = thisbox->yratio;
-
-					tmp->parentpad = tmp->pad;
-
-					/* Just in case */
-					tmp->xratio = thisbox->xratio;
-					tmp->yratio = thisbox->yratio;
-
-					if(thisbox->type == DW_VERT)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
-
-						if((thisbox->items[z].width - tmppad)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].width-tmp->upx)!=0)
-							tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
-					}
-					if(thisbox->type == DW_HORZ)
-					{
-						int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
-
-						if((thisbox->items[z].height-tmppad)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
-					}
-					else
-					{
-						if((thisbox->items[z].height-tmp->upy)!=0)
-							tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
-					}
-
-					nux = *usedx; nuy = *usedy;
-					upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
-				}
-
-				(*depth)++;
-
-				_resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
-
-				(*depth)--;
-
-				newx = x - nux;
-				newy = y - nuy;
-
-				tmp->minwidth = thisbox->items[z].width = initialx - newx;
-				tmp->minheight = thisbox->items[z].height = initialy - newy;
-			}
-		}
-
-		if(pass > 1 && *depth > 0)
-		{
-			if(thisbox->type == DW_VERT)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
-
-				if((thisbox->minwidth-tmppad) == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
-			}
-			else
-			{
-				if(thisbox->minwidth-thisbox->upx == 0)
-					thisbox->items[z].xratio = 1.0;
-				else
-					thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
-			}
-
-			if(thisbox->type == DW_HORZ)
-			{
-				int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
-
-				if((thisbox->minheight-tmppad) == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
-			}
-			else
-			{
-				if(thisbox->minheight-thisbox->upy == 0)
-					thisbox->items[z].yratio = 1.0;
-				else
-					thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
-			}
-
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-				if(tmp)
-				{
-					tmp->parentxratio = thisbox->items[z].xratio;
-					tmp->parentyratio = thisbox->items[z].yratio;
-				}
-			}
-		}
-		else
-		{
-			thisbox->items[z].xratio = thisbox->xratio;
-			thisbox->items[z].yratio = thisbox->yratio;
-		}
-
-		if(thisbox->type == DW_VERT)
-		{
-			int itemwidth = (thisbox->items[z].pad*2) + thisbox->items[z].width;
-
-			if(itemwidth > uxmax)
-				uxmax = itemwidth;
-			if(thisbox->items[z].hsize != SIZEEXPAND)
-			{
-				if(itemwidth > upxmax)
-					upxmax = itemwidth;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upxmax)
-					upxmax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].width == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].width = */
-			}
-			else
-			{
-				(*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					(*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
-				else
-					(*usedpadx) += thisbox->items[z].pad*2;
-			}
-		}
-		if(thisbox->type == DW_HORZ)
-		{
-			int itemheight = (thisbox->items[z].pad*2) + thisbox->items[z].height;
-
-			if(itemheight > uymax)
-				uymax = itemheight;
-			if(thisbox->items[z].vsize != SIZEEXPAND)
-			{
-				if(itemheight > upymax)
-					upymax = itemheight;
-			}
-			else
-			{
-				if(thisbox->items[z].pad*2 > upymax)
-					upymax = thisbox->items[z].pad*2;
-			}
-		}
-		else
-		{
-			if(thisbox->items[z].height == -1)
-			{
-				/* figure out how much space this item requires */
-				/* thisbox->items[z].height = */
-			}
-			else
-			{
-				(*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					(*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
-				else
-					(*usedpady) += thisbox->items[z].pad*2;
-			}
-		}
-	}
-
-	(*usedx) += uxmax;
-	(*usedy) += uymax;
-	(*usedpadx) += upxmax;
-	(*usedpady) += upymax;
-
-	currentx += thisbox->pad;
-	currenty += thisbox->pad;
-
-	if(thisbox->grouphwnd)
-	{
-		currentx += 3;
-		currenty += thisbox->grouppady - 3;
-	}
-
-	/* The second pass is for expansion and actual placement. */
-	if(pass > 1)
-	{
-		/* Any SIZEEXPAND items should be set to uxmax/uymax */
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
-				thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
-			if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
-				thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
-			/* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
-			if(thisbox->items[z].type == TYPEBOX)
-			{
-				Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-
-				if(tmp)
-				{
-					if(*depth > 0)
-					{
-						float calcval;
-
-						if(thisbox->type == DW_VERT)
-						{
-							calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->xratio = thisbox->xratio;
-							else
-								tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->width = thisbox->items[z].width;
-						}
-						if(thisbox->type == DW_HORZ)
-						{
-							calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
-							if(calcval == 0.0)
-								tmp->yratio = thisbox->yratio;
-							else
-								tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
-							tmp->height = thisbox->items[z].height;
-						}
-					}
-
-					(*depth)++;
-
-					_resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
-
-					(*depth)--;
-
-				}
-			}
-		}
-
-		for(z=0;z<(thisbox->count);z++)
-		{
-			int height = thisbox->items[z].height;
-			int width = thisbox->items[z].width;
-			int pad = thisbox->items[z].pad;
-			HWND handle = thisbox->items[z].hwnd;
-			int vectorx, vectory;
-
-			/* When upxmax != pad*2 then ratios are incorrect. */
-			vectorx = (int)((width*thisbox->items[z].xratio)-width);
-			vectory = (int)((height*thisbox->items[z].yratio)-height);
-
-			if(width > 0 && height > 0)
-			{
-				char tmpbuf[100];
-				/* This is a hack to fix rounding of the sizing */
-				if(*depth == 0)
-				{
-					vectorx++;
-					vectory++;
-				}
-
-				/* If this item isn't going to expand... reset the vectors to 0 */
-				if(thisbox->items[z].vsize != SIZEEXPAND)
-					vectory = 0;
-				if(thisbox->items[z].hsize != SIZEEXPAND)
-					vectorx = 0;
-
-				GetClassName(handle, tmpbuf, 99);
-
-				if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-				{
-					/* Handle special case Combobox */
-					MoveWindow(handle, currentx + pad, currenty + pad,
-							   width + vectorx, (height + vectory) + 400, FALSE);
-				}
-				else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
-				{
-					/* Handle special case Spinbutton */
-					ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-					MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad,
-							   20, height + vectory, FALSE);
-
-					if(cinfo)
-					{
-						MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
-								   (width + vectorx) - 20, height + vectory, FALSE);
-					}
-				}
-				else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
-				{
-					/* Then try the bottom or right box */
-					float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-					int type = (int)dw_window_get_data(handle, "_dw_type");
-					int cx = width + vectorx;
-					int cy = height + vectory;
-
-					MoveWindow(handle, currentx + pad, currenty + pad,
-							   cx, cy, FALSE);
-
-					if(cx > 0 && cy > 0 && percent)
-						_handle_splitbar_resize(handle, *percent, type, cx, cy);
-				}
-				else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
-				{
-					/* Handle special case Vertically Center static text */
-					ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-					if(cinfo && cinfo->vcenter)
-					{
-						/* We are centered so calculate a new position */
-						char tmpbuf[1024];
-						int textheight, diff, total = height + vectory;
-
-						GetWindowText(handle, tmpbuf, 1023);
-
-						/* Figure out how big the text is */
-						dw_font_text_extents(handle, 0, tmpbuf, 0, &textheight);
-
-						diff = (total - textheight) / 2;
-
-						MoveWindow(handle, currentx + pad, currenty + pad + diff,
-								   width + vectorx, height + vectory - diff, FALSE);
-					}
-					else
-					{
-						MoveWindow(handle, currentx + pad, currenty + pad,
-								   width + vectorx, height + vectory, FALSE);
-					}
-				}
-				else
-				{
-					/* Everything else */
-					MoveWindow(handle, currentx + pad, currenty + pad,
-							   width + vectorx, height + vectory, FALSE);
-					if(thisbox->items[z].type == TYPEBOX)
-					{
-						Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-						if(boxinfo && boxinfo->grouphwnd)
-							MoveWindow(boxinfo->grouphwnd, 0, 0,
-									   width + vectorx, height + vectory, FALSE);
-
-					}
-				}
-
-				/* Notebook dialog requires additional processing */
-				if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0)
-				{
-					RECT rect;
-					NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-					int pageid = TabCtrl_GetCurSel(handle);
-
-					if(pageid > -1 && array && array[pageid])
-					{
-						GetClientRect(handle,&rect);
-						TabCtrl_AdjustRect(handle,FALSE,&rect);
-						MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
-								   rect.right - rect.left, rect.bottom-rect.top, FALSE);
-					}
-				}
-
-				if(thisbox->type == DW_HORZ)
-					currentx += width + vectorx + (pad * 2);
-				if(thisbox->type == DW_VERT)
-					currenty += height + vectory + (pad * 2);
-			}
-		}
-	}
-	return 0;
-}
-
-void _do_resize(Box *thisbox, int x, int y)
-{
-	if(x != 0 && y != 0)
-	{
-		if(thisbox)
-		{
-			int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
-
-			if(usedx-usedpadx == 0 || usedy-usedpady == 0)
-				return;
-
-			thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
-			thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
-
-			usedpadx = usedpady = usedx = usedy = depth = 0;
-
-			_resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
-		}
-	}
-}
-
-int _HandleScroller(HWND handle, int pos, int which)
-{
-	SCROLLINFO si;
-
-	si.cbSize = sizeof(SCROLLINFO);
-	si.fMask = SIF_ALL;
-
-	SendMessage(handle, SBM_GETSCROLLINFO, 0, (LPARAM)&si);
-
-	switch(which)
-	{
-	case SB_THUMBTRACK:
-		return pos;
-	/*case SB_PAGEDOWN:*/
-	case SB_PAGELEFT:
-		pos = si.nPos - si.nPage;
-		if(pos < si.nMin)
-			pos = si.nMin;
-		return pos;
-	/*case SB_PAGEUP:*/
-	case SB_PAGERIGHT:
-		pos = si.nPos + si.nPage;
-		if(pos > (si.nMax - si.nPage) + 1)
-			pos = (si.nMax - si.nPage) + 1;
-		return pos;
-	/*case SB_LINEDOWN:*/
-	case SB_LINELEFT:
-		pos = si.nPos - 1;
-		if(pos < si.nMin)
-			pos = si.nMin;
-		return pos;
-	/*case SB_LINEUP:*/
-	case SB_LINERIGHT:
-		pos = si.nPos + 1;
-		if(pos > (si.nMax - si.nPage) + 1)
-			pos = (si.nMax - si.nPage) + 1;
-		return pos;
-	}
-	return -1;
-}
-
-#ifndef WINNT_COMPAT
-HMENU _get_owner(HMENU menu)
-{
-	MENUINFO mi;
-
-	mi.cbSize = sizeof(MENUINFO);
-	mi.fMask = MIM_MENUDATA;
-
-	if(GetMenuInfo(menu, &mi))
-		return (HMENU)mi.dwMenuData;
-	return (HMENU)0;
-}
-
-/* Find the desktop window handle */
-HMENU _menu_owner(HMENU handle)
-{
-	HMENU menuowner = 0, lastowner = _get_owner(handle);
-
-	/* Find the toplevel menu */
-	while((menuowner = _get_owner(lastowner)) != 0)
-	{
-		if(menuowner == (HMENU)1)
-			return lastowner;
-		lastowner = menuowner;
-	}
-	return (HMENU)0;
-}
-#endif
-
-/* The main window procedure for Dynamic Windows, all the resizing code is done here. */
-BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	int result = -1, taskbar = FALSE;
-	static int command_active = 0;
-	SignalHandler *tmp = Root;
-	void (*windowfunc)(PVOID);
-	ULONG origmsg = msg;
-
-	/* Deal with translating some messages */
-	if(msg == WM_USER+2)
-	{
-		taskbar = TRUE;
-		origmsg = msg = (UINT)mp2; /* no else here */
-	}
-	if(msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN)
-		msg = WM_LBUTTONDOWN;
-	else if(msg == WM_RBUTTONUP || msg == WM_MBUTTONUP)
-		msg = WM_LBUTTONUP;
-	else if(msg == WM_HSCROLL)
-		msg = WM_VSCROLL;
-	else if(msg == WM_KEYDOWN) /* && mp1 >= VK_F1 && mp1 <= VK_F24) allow ALL special keys */
-		msg = WM_CHAR;
-
-	if(result == -1)
-	{
-		/* Avoid infinite recursion */
-		command_active = 1;
-
-		/* Find any callbacks for this function */
-		while(tmp)
-		{
-			if(tmp->message == msg || msg == WM_COMMAND || msg == WM_NOTIFY || tmp->message == WM_USER+1)
-			{
-				switch(msg)
-				{
-				case WM_TIMER:
-				{
-					int (*timerfunc)(void *) = tmp->signalfunction;
-					if(tmp->id == (int)mp1)
-					{
-						if(!timerfunc(tmp->data))
-							dw_timer_disconnect(tmp->id);
-						tmp = NULL;
-					}
-					result = 0;
-				}
-				break;
-				case WM_SETFOCUS:
-					{
-						int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							result = setfocusfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_SIZE:
-					{
-						int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_LBUTTONDOWN:
-					{
-						int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							int button;
-
-							switch(origmsg)
-							{
-							case WM_LBUTTONDOWN:
-								button = 1;
-								break;
-							case WM_RBUTTONDOWN:
-								button = 2;
-								break;
-							case WM_MBUTTONDOWN:
-								button = 3;
-								break;
-							}
-							if(taskbar)
-							{
-								POINT ptl;
-								GetCursorPos(&ptl);
-								result = buttonfunc(tmp->window, ptl.x, ptl.y, button, tmp->data);
-							}
-							else
-							{
-								POINTS pts = MAKEPOINTS(mp2);
-								result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data);
-							}
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_LBUTTONUP:
-					{
-						int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							int button;
-
-							switch(origmsg)
-							{
-							case WM_LBUTTONUP:
-								button = 1;
-								break;
-							case WM_RBUTTONUP:
-								button = 2;
-								break;
-							case WM_MBUTTONUP:
-								button = 3;
-								break;
-							}
-							if(taskbar)
-							{
-								POINT ptl;
-								GetCursorPos(&ptl);
-								result = buttonfunc(tmp->window, ptl.x, ptl.y, button, tmp->data);
-							}
-							else
-							{
-								POINTS pts = MAKEPOINTS(mp2);
-								result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data);
-							}
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_MOUSEMOVE:
-					{
-						POINTS pts = MAKEPOINTS(mp2);
-						int (*motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							int keys = 0;
-
-							if (mp1 & MK_LBUTTON)
-								keys = DW_BUTTON1_MASK;
-							if (mp1 & MK_RBUTTON)
-								keys |= DW_BUTTON2_MASK;
-							if (mp1 & MK_MBUTTON)
-								keys |= DW_BUTTON3_MASK;
-
-							result = motionfunc(tmp->window, pts.x, pts.y, keys, tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_CHAR:
-					{
-						int (*keypressfunc)(HWND, char, int, int, void *) = tmp->signalfunction;
-
-						if(hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window)
-						{
-							int special = 0;
-							char ch = 0;
-
-							if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-								special |= KC_SHIFT;
-							if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
-								special |= KC_CTRL;
-                            if(mp2 & (1 << 29))
-								special |= KC_ALT;
-
-							if(origmsg == WM_CHAR && mp1 < 128)
-								ch = (char)mp1;
-
-							result = keypressfunc(tmp->window, ch, mp1, special, tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_CLOSE:
-					{
-						int (*closefunc)(HWND, void *) = tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							result = closefunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_PAINT:
-					{
-						PAINTSTRUCT ps;
-						DWExpose exp;
-						int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction;
-
-						if(hWnd == tmp->window)
-						{
-							BeginPaint(hWnd, &ps);
-							exp.x = ps.rcPaint.left;
-							exp.y = ps.rcPaint.top;
-							exp.width = ps.rcPaint.right - ps.rcPaint.left;
-							exp.height = ps.rcPaint.bottom - ps.rcPaint.top;
-							result = exposefunc(hWnd, &exp, tmp->data);
-							EndPaint(hWnd, &ps);
-						}
-					}
-					break;
-				case WM_NOTIFY:
-					{
-						if(tmp->message == TVN_SELCHANGED ||
-						   tmp->message == NM_RCLICK ||
-						   tmp->message == TVN_ITEMEXPANDED)
-						{
-							NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2;
-							char tmpbuf[100];
-
-							GetClassName(tem->hdr.hwndFrom, tmpbuf, 99);
-
-							if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0)
-							{
-								if(tem->hdr.code == TVN_SELCHANGED && tmp->message == TVN_SELCHANGED)
-								{
-									if(tmp->window == tem->hdr.hwndFrom && !dw_window_get_data(tmp->window, "_dw_select_item"))
-									{
-										int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = tmp->signalfunction;
-										TVITEM tvi;
-										void **ptrs;
-
-										tvi.mask = TVIF_HANDLE;
-										tvi.hItem = tem->itemNew.hItem;
-
-										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]);
-
-										tmp = NULL;
-									}
-								}
-								else if(tem->hdr.code == TVN_ITEMEXPANDED && tmp->message == TVN_ITEMEXPANDED)
-								{
-									if(tmp->window == tem->hdr.hwndFrom && tem->action == TVE_EXPAND)
-									{
-										int (*treeexpandfunc)(HWND, HTREEITEM, void *) = tmp->signalfunction;
-
-										result = treeexpandfunc(tmp->window, tem->itemNew.hItem, tmp->data);
-										tmp = NULL;
-									}
-								}
-								else if(tem->hdr.code == NM_RCLICK && tmp->message == NM_RCLICK)
-								{
-									if(tmp->window == tem->hdr.hwndFrom)
-									{
-										int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
-										HTREEITEM hti, last;
-										TVITEM tvi;
-										TVHITTESTINFO thi;
-										void **ptrs = NULL;
-										LONG x, y;
-
-										dw_pointer_query_pos(&x, &y);
-
-										thi.pt.x = x;
-										thi.pt.y = y;
-
-										MapWindowPoints(HWND_DESKTOP, tmp->window, &thi.pt, 1);
-
-										last = TreeView_GetSelection(tmp->window);
-										hti = TreeView_HitTest(tmp->window, &thi);
-
-										if(hti)
-										{
-											tvi.mask = TVIF_HANDLE;
-											tvi.hItem = hti;
-
-											TreeView_GetItem(tmp->window, &tvi);
-											TreeView_SelectItem(tmp->window, hti);
-
-											ptrs = (void **)tvi.lParam;
-										}
-										containercontextfunc(tmp->window, ptrs ? (char *)ptrs[0] : NULL, x, y, tmp->data, ptrs ? ptrs[1] : NULL);
-										tmp = NULL;
-									}
-								}
-							}
-							else if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0)
-							{
-								if(tem->hdr.code == LVN_ITEMCHANGED && tmp->message == TVN_SELCHANGED)
-								{
-									if(tmp->window == tem->hdr.hwndFrom)
-									{
-										LV_ITEM lvi;
-										int iItem;
-
-										iItem = ListView_GetNextItem(tmp->window, -1, LVNI_SELECTED);
-
-										memset(&lvi, 0, sizeof(LV_ITEM));
-
-										if(iItem > -1)
-										{
-											int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction;
-
-											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);
-											tmp = NULL;
-										}
-									}
-								}
-							}
-						}
-						else if(tmp->message == TCN_SELCHANGE)
-						{
-							NMHDR FAR *tem=(NMHDR FAR *)mp2;
-							if(tmp->window == tem->hwndFrom && tem->code == tmp->message)
-							{
-								int (*switchpagefunc)(HWND, unsigned long, void *) = tmp->signalfunction;
-								unsigned long num=dw_notebook_page_query(tem->hwndFrom);
-								result = switchpagefunc(tem->hwndFrom, num, tmp->data);
-								tmp = NULL;
-							}
-						}
-						else if(tmp->message == LVN_COLUMNCLICK)
-						{
-							NMLISTVIEW FAR *tem=(NMLISTVIEW FAR *)mp2;
-							if(tmp->window == tem->hdr.hwndFrom && tem->hdr.code == tmp->message)
-							{
-								int (*columnclickfunc)(HWND, int, void *) = tmp->signalfunction;
-								result = columnclickfunc(tem->hdr.hwndFrom, tem->iSubItem, tmp->data);
-								tmp = NULL;
-							}
-						}
-					}
-					break;
-				case WM_COMMAND:
-					{
-						int (*clickfunc)(HWND, void *) = tmp->signalfunction;
-						HWND command;
-						ULONG passthru = (ULONG)LOWORD(mp1);
-						ULONG message = HIWORD(mp1);
-
-						command = (HWND)passthru;
-
-						if(message == LBN_SELCHANGE || message == CBN_SELCHANGE)
-						{
-							int (*listboxselectfunc)(HWND, int, void *) = tmp->signalfunction;
-
-							if(tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2)
-							{
-								result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data);
-								tmp = NULL;
-							}
-						}
-#ifndef WINNT_COMPAT
-						else if(tmp->id && passthru == tmp->id)
-						{
-							HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window);
-
-							if(menuowner == hwndmenu || !menuowner)
-							{
-								result = clickfunc(tmp->window, tmp->data);
-								tmp = NULL;
-							}
-						} /* Make sure it's the right window, and the right ID */
-#endif
-						else if(tmp->window < (HWND)65536 && command == tmp->window)
-						{
-							result = clickfunc(popup ? popup : tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					break;
-				case WM_HSCROLL:
-				case WM_VSCROLL:
-					{
-						char tmpbuf[100];
-                        HWND handle = (HWND)mp2;
-						int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
-
-						GetClassName(handle, tmpbuf, 99);
-
-						if(strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
-						{
-
-							if(handle == tmp->window)
-							{
-								int value = (int)SendMessage(handle, TBM_GETPOS, 0, 0);
-								int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
-								ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
-
-								if(currentstyle & TBS_VERT)
-									result = valuechangefunc(tmp->window, max - value, tmp->data);
-								else
-									result = valuechangefunc(tmp->window, value, tmp->data);
-								tmp = NULL;
-							}
-						}
-						else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0)
-						{
-							if(handle == tmp->window)
-							{
-								int value = _HandleScroller(handle, (int)HIWORD(mp1), (int)LOWORD(mp1));
-
-								if(value > -1)
-								{
-									dw_scrollbar_set_pos(tmp->window, value);
-									result = valuechangefunc(tmp->window, value, tmp->data);
-								}
-								tmp = NULL;
-								msg = 0;
-							}
-						}
-					}
-					break;
-				}
-			}
-			if(tmp)
-				tmp = tmp->next;
-		}
-		command_active = 0;
-	}
-
-	/* Now that any handlers are done... do normal processing */
-	switch( msg )
-	{
-	case WM_PAINT:
-		{
-			PAINTSTRUCT ps;
-
-			BeginPaint(hWnd, &ps);
-			EndPaint(hWnd, &ps);
-		}
-		break;
-	case WM_SIZE:
-		{
-			static int lastx = -1, lasty = -1;
-			static HWND lasthwnd = 0;
-
-			if(lastx != LOWORD(mp2) || lasty != HIWORD(mp2) || lasthwnd != hWnd)
-			{
-				Box *mybox = (Box *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-				if(mybox && mybox->count)
-				{
-					lastx = LOWORD(mp2);
-					lasty = HIWORD(mp2);
-					lasthwnd = hWnd;
-
-					ShowWindow(mybox->items[0].hwnd, SW_HIDE);
-					_do_resize(mybox,LOWORD(mp2),HIWORD(mp2));
-					ShowWindow(mybox->items[0].hwnd, SW_SHOW);
-					return 0;
-				}
-			}
-		}
-		break;
-	case WM_CHAR:
-		if(LOWORD(mp1) == '\t')
-		{
-			if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return TRUE;
-		}
-		break;
-	case WM_USER:
-		windowfunc = (void *)mp1;
-
-		if(windowfunc)
-			windowfunc((void *)mp2);
-		break;
-	case WM_USER+5:
-		_free_menu_data((HMENU)mp1);
-		DestroyMenu((HMENU)mp1);
-		break;
-	case WM_NOTIFY:
-		{
-			NMHDR FAR *tem=(NMHDR FAR *)mp2;
-
-			if(tem->code == TCN_SELCHANGING)
-			{
-				int num=TabCtrl_GetCurSel(tem->hwndFrom);
-				NotebookPage **array = (NotebookPage **)dw_window_get_data(tem->hwndFrom, "_dw_array");
-
-				if(num > -1 && array && array[num])
-					SetParent(array[num]->hwnd, DW_HWND_OBJECT);
-
-			}
-			else if(tem->code == TCN_SELCHANGE)
-			{
-				int num=TabCtrl_GetCurSel(tem->hwndFrom);
-				NotebookPage **array = (NotebookPage **)dw_window_get_data(tem->hwndFrom, "_dw_array");
-
-				if(num > -1 && array && array[num])
-					SetParent(array[num]->hwnd, tem->hwndFrom);
-
-				_resize_notebook_page(tem->hwndFrom, num);
-			}
-		}
-		break;
-	case WM_HSCROLL:
-	case WM_VSCROLL:
-		{
-			HWND handle = (HWND)mp2;
-
-			if(dw_window_get_data(handle, "_dw_scrollbar"))
-			{
-				int value = _HandleScroller(handle, (int)HIWORD(mp1), (int)LOWORD(mp1));
-
-				if(value > -1)
-					dw_scrollbar_set_pos(handle, value);
-			}
-		}
-		break;
-	case WM_GETMINMAXINFO:
-		{
-			MINMAXINFO *info = (MINMAXINFO *)mp2;
-			info->ptMinTrackSize.x = 8;
-			info->ptMinTrackSize.y = 8;
-			return 0;
-		}
-		break;
-	case WM_DESTROY:
-		{
-			HMENU menu = GetMenu(hWnd);
-
-			if(menu)
-				_free_menu_data(menu);
-
-			/* Free memory before destroying */
-			_free_window_memory(hWnd, 0);
-			EnumChildWindows(hWnd, _free_window_memory, 0);
-		}
-		break;
-	case WM_CTLCOLORSTATIC:
-	case WM_CTLCOLORLISTBOX:
-	case WM_CTLCOLORBTN:
-	case WM_CTLCOLOREDIT:
-	case WM_CTLCOLORMSGBOX:
-	case WM_CTLCOLORSCROLLBAR:
-	case WM_CTLCOLORDLG:
-		{
-			ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
-			if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-			{
-				/* Handle foreground */
-				if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
-				{
-					if(thiscinfo->fore != DW_CLR_DEFAULT)
-					{
-						SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
-												   _green[thiscinfo->fore],
-												   _blue[thiscinfo->fore]));
-					}
-				}
-				else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-				{
-					SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
-											   DW_GREEN_VALUE(thiscinfo->fore),
-											   DW_BLUE_VALUE(thiscinfo->fore)));
-				}
-				/* Handle background */
-				if(thiscinfo->back > -1 && thiscinfo->back < 18)
-				{
-					if(thiscinfo->back == DW_CLR_DEFAULT)
-					{
-						HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
-
-						SelectObject((HDC)mp1, hbr);
-						return (LONG)hbr;
-					}
-					else
-					{
-						SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
-												 _green[thiscinfo->back],
-												 _blue[thiscinfo->back]));
-						if(thiscinfo->hbrush)
-							DeleteObject(thiscinfo->hbrush);
-						thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
-																 _green[thiscinfo->back],
-																 _blue[thiscinfo->back]));
-						SelectObject((HDC)mp1, thiscinfo->hbrush);
-					}
-					return (LONG)thiscinfo->hbrush;
-				}
-				else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
-				{
-					SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
-												 DW_GREEN_VALUE(thiscinfo->back),
-												 DW_BLUE_VALUE(thiscinfo->back)));
-					if(thiscinfo->hbrush)
-						DeleteObject(thiscinfo->hbrush);
-					thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
-															 DW_GREEN_VALUE(thiscinfo->back),
-															 DW_BLUE_VALUE(thiscinfo->back)));
-					SelectObject((HDC)mp1, thiscinfo->hbrush);
-					return (LONG)thiscinfo->hbrush;
-				}
-			}
-
-		}
-		break;
-	}
-	if(result != -1)
-		return result;
-	else
-		return DefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
-{
-	_wndproc(hwnd, msg, (WPARAM)idEvent, 0);
-}
-
-BOOL CALLBACK _framewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	switch( msg )
-	{
-	case WM_LBUTTONDOWN:
-	case WM_MBUTTONDOWN:
-	case WM_RBUTTONDOWN:
-		SetActiveWindow(hWnd);
-		SetFocus(hWnd);
-		break;
-	case WM_COMMAND:
-	case WM_NOTIFY:
-		_wndproc(hWnd, msg, mp1, mp2);
-		break;
-#if 0
-	case WM_ERASEBKGND:
-		{
-			ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-			if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-				return FALSE;
-		}
-		break;
-#endif
-	case WM_PAINT:
-		{
-			ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-			if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-			{
-				PAINTSTRUCT ps;
-				HDC hdcPaint = BeginPaint(hWnd, &ps);
-				int success = FALSE;
-
-				if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-				{
-					/* Handle foreground */
-					if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
-					{
-						if(thiscinfo->fore != DW_CLR_DEFAULT)
-						{
-							SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
-													   _green[thiscinfo->fore],
-													   _blue[thiscinfo->fore]));
-						}
-					}
-					else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-					{
-						SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
-												   DW_GREEN_VALUE(thiscinfo->fore),
-												   DW_BLUE_VALUE(thiscinfo->fore)));
-					}
-					/* Handle background */
-					if(thiscinfo->back > -1 && thiscinfo->back < 18)
-					{
-						if(thiscinfo->back != DW_CLR_DEFAULT)
-						{
-							SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
-													 _green[thiscinfo->back],
-													 _blue[thiscinfo->back]));
-							if(thiscinfo->hbrush)
-								DeleteObject(thiscinfo->hbrush);
-							thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
-																	 _green[thiscinfo->back],
-																	 _blue[thiscinfo->back]));
-							SelectObject(hdcPaint, thiscinfo->hbrush);
-							Rectangle(hdcPaint, ps.rcPaint.left - 1, ps.rcPaint.top - 1, ps.rcPaint.right + 1, ps.rcPaint.bottom + 1);
-							success = TRUE;
-						}
-					}
-					else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
-					{
-						SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
-												 DW_GREEN_VALUE(thiscinfo->back),
-												 DW_BLUE_VALUE(thiscinfo->back)));
-						if(thiscinfo->hbrush)
-							DeleteObject(thiscinfo->hbrush);
-						thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
-																 DW_GREEN_VALUE(thiscinfo->back),
-																 DW_BLUE_VALUE(thiscinfo->back)));
-						SelectObject(hdcPaint, thiscinfo->hbrush);
-						Rectangle(hdcPaint, ps.rcPaint.left - 1, ps.rcPaint.top - 1, ps.rcPaint.right + 1, ps.rcPaint.bottom + 1);
-						success = TRUE;
-					}
-				}
-
-				EndPaint(hWnd, &ps);
-				if(success)
-					return FALSE;
-			}
-
-		}
-		break;
-	}
-	return DefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	switch( msg )
-	{
-	case WM_LBUTTONDOWN:
-	case WM_MBUTTONDOWN:
-	case WM_RBUTTONDOWN:
-		SetFocus(hWnd);
-		_wndproc(hWnd, msg, mp1, mp2);
-		break;
-	case WM_LBUTTONUP:
-	case WM_MBUTTONUP:
-	case WM_RBUTTONUP:
-	case WM_MOUSEMOVE:
-	case WM_PAINT:
-	case WM_SIZE:
-	case WM_COMMAND:
-	case WM_CHAR:
-	case WM_KEYDOWN:
-		_wndproc(hWnd, msg, mp1, mp2);
-		break;
-	}
-	return DefWindowProc(hWnd, msg, mp1, mp2);
-}
-
-BOOL CALLBACK _spinnerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	ColorInfo *cinfo;
-
-	cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-	if(cinfo)
-	{
-		switch( msg )
-		{
-		case WM_LBUTTONDOWN:
-		case WM_MBUTTONDOWN:
-		case WM_RBUTTONDOWN:
-		case WM_KEYDOWN:
-			{
-				BOOL ret;
-
-				if(!cinfo || !cinfo->pOldProc)
-					ret = DefWindowProc(hWnd, msg, mp1, mp2);
-				ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-
-				/* Tell the edit control that a buttonpress has
-				 * occured and to update it's window title.
-				 */
-				if(cinfo && cinfo->buddy)
-					SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
-
-				SetTimer(hWnd, 100, 100, (TIMERPROC)NULL);
-
-				return ret;
-			}
-			break;
-		case WM_LBUTTONUP:
-		case WM_MBUTTONUP:
-		case WM_RBUTTONUP:
-		case WM_KEYUP:
-			{
-				BOOL ret;
-
-				if(!cinfo || !cinfo->pOldProc)
-					ret = DefWindowProc(hWnd, msg, mp1, mp2);
-				ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-
-				/* Tell the edit control that a buttonpress has
-				 * occured and to update it's window title.
-				 */
-				if(cinfo && cinfo->buddy)
-					SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
-
-				KillTimer(hWnd, 100);
-
-				return ret;
-			}
-			break;
-		case WM_TIMER:
-			{
-				if(mp1 == 100)
-				{
-					BOOL ret;
-
-					if(cinfo && cinfo->buddy)
-						SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
-
-					if(!cinfo || !cinfo->pOldProc)
-						ret = DefWindowProc(hWnd, msg, mp1, mp2);
-					ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-
-					/* Tell the edit control that a buttonpress has
-					 * occured and to update it's window title.
-					 */
-					if(cinfo && cinfo->buddy)
-						SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
-
-					return ret;
-				}
-			}
-			break;
-		case WM_USER+10:
-			{
-				if(cinfo->buddy)
-				{
-					char tempbuf[100] = "";
-					long position;
-
-					GetWindowText(cinfo->buddy, tempbuf, 99);
-
-					position = atol(tempbuf);
-
-					if(IS_IE5PLUS)
-						SendMessage(hWnd, UDM_SETPOS32, 0, (LPARAM)position);
-					else
-						SendMessage(hWnd, UDM_SETPOS, 0, (LPARAM)MAKELONG((short)position, 0));
-				}
-			}
-			break;
-		}
-	}
-
-	if(!cinfo || !cinfo->pOldProc)
-		return DefWindowProc(hWnd, msg, mp1, mp2);
-	return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-}
-
-void _click_default(HWND handle)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	/* These are the window classes which can
-	 * obtain input focus.
-	 */
-	if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0)
-	{
-		/* Generate click on default item */
-		SignalHandler *tmp = Root;
-
-		/* Find any callbacks for this function */
-		while(tmp)
-		{
-			if(tmp->message == WM_COMMAND)
-			{
-				int (*clickfunc)(HWND, void *) = tmp->signalfunction;
-
-				/* Make sure it's the right window, and the right ID */
-				if(tmp->window == handle)
-				{
-					clickfunc(tmp->window, tmp->data);
-					tmp = NULL;
-				}
-			}
-			if(tmp)
-				tmp= tmp->next;
-		}
-	}
-	else
-		SetFocus(handle);
-}
-
-BOOL CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	ColorInfo *cinfo;
-	char tmpbuf[100];
-	WNDPROC pOldProc = 0;
-
-	cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-	GetClassName(hWnd, tmpbuf, 99);
-	if(strcmp(tmpbuf, FRAMECLASSNAME) == 0)
-		cinfo = &(((Box *)cinfo)->cinfo);
-
-	if(cinfo)
-	{
-		pOldProc = cinfo->pOldProc;
-
-		switch( msg )
-		{
-		case WM_SETFOCUS:
-            if(cinfo->combo)
-				_wndproc(cinfo->combo, msg, mp1, mp2);
-			else
-				_wndproc(hWnd, msg, mp1, mp2);
-			break;
-		case WM_VSCROLL:
-		case WM_HSCROLL:
-			_wndproc(hWnd, msg, mp1, mp2);
-			break;
-		case WM_KEYDOWN:
-		case WM_KEYUP:
-			{
-				if(mp1 == VK_UP || mp1 == VK_DOWN)
-				{
-					BOOL ret;
-
-					if(!cinfo || !cinfo->pOldProc)
-						ret = DefWindowProc(hWnd, msg, mp1, mp2);
-					ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-
-					/* Tell the spinner control that a keypress has
-					 * occured and to update it's internal value.
-					 */
-					if(cinfo && cinfo->buddy && !cinfo->combo)
-						PostMessage(hWnd, WM_USER+10, 0, 0);
-
-                    if(msg == WM_KEYDOWN)
-						SetTimer(hWnd, 101, 100, (TIMERPROC)NULL);
-                    else
-						KillTimer(hWnd, 101);
-
-					return ret;
-				}
-			}
-			break;
-		case WM_TIMER:
-			{
-				if(mp1 == 101)
-				{
-					BOOL ret;
-
-					if(!cinfo || !cinfo->pOldProc)
-						ret = DefWindowProc(hWnd, msg, mp1, mp2);
-					ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-
-					/* Tell the spinner control that a keypress has
-					 * occured and to update it's internal value.
-					 */
-					if(cinfo && cinfo->buddy && !cinfo->combo)
-						PostMessage(hWnd, WM_USER+10, 0, 0);
-
-					return ret;
-				}
-			}
-			break;
-		case WM_CHAR:
-			_wndproc(hWnd, msg, mp1, mp2);
-			if(LOWORD(mp1) == '\t')
-			{
-				if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-				{
-					if(cinfo->combo)
-						_shift_focus_back(cinfo->combo);
-					else if(cinfo->buddy)
-						_shift_focus_back(cinfo->buddy);
-					else
-						_shift_focus_back(hWnd);
-				}
-				else
-				{
-					if(cinfo->combo)
-						_shift_focus(cinfo->combo);
-					else if(cinfo->buddy)
-						_shift_focus(cinfo->buddy);
-					else
-						_shift_focus(hWnd);
-				}
-				return FALSE;
-			}
-			else if(LOWORD(mp1) == '\r')
-			{
-				if(cinfo->clickdefault)
-					_click_default(cinfo->clickdefault);
-
-			}
-
-			/* Tell the spinner control that a keypress has
-			 * occured and to update it's internal value.
-			 */
-			if(cinfo->buddy && !cinfo->combo)
-			{
-				if(IsWinNT())
-					PostMessage(cinfo->buddy, WM_USER+10, 0, 0);
-				else
-					SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
-			}
-			break;
-		case WM_USER+10:
-			{
-				if(cinfo->buddy)
-				{
-					long val;
-
-					if(IS_IE5PLUS)
-						val = (long)SendMessage(cinfo->buddy, UDM_GETPOS32, 0, 0);
-					else
-						val = (long)SendMessage(cinfo->buddy, UDM_GETPOS, 0, 0);
-
-					sprintf(tmpbuf, "%d", val);
-					SetWindowText(hWnd, tmpbuf);
-				}
-			}
-			break;
-		case WM_CTLCOLORSTATIC:
-		case WM_CTLCOLORLISTBOX:
-		case WM_CTLCOLORBTN:
-		case WM_CTLCOLOREDIT:
-		case WM_CTLCOLORMSGBOX:
-		case WM_CTLCOLORSCROLLBAR:
-		case WM_CTLCOLORDLG:
-			{
-				ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
-				if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
-				{
-					/* Handle foreground */
-					if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
-					{
-						if(thiscinfo->fore != DW_CLR_DEFAULT)
-						{
-							SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
-													   _green[thiscinfo->fore],
-													   _blue[thiscinfo->fore]));
-						}
-					}
-					else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
-					{
-						SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
-												   DW_GREEN_VALUE(thiscinfo->fore),
-												   DW_BLUE_VALUE(thiscinfo->fore)));
-					}
-					/* Handle background */
-					if(thiscinfo->back > -1 && thiscinfo->back < 18)
-					{
-						if(thiscinfo->back == DW_CLR_DEFAULT)
-						{
-							HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
-
-							SetBkColor((HDC)mp1, GetSysColor(COLOR_3DFACE));
-
-
-							SelectObject((HDC)mp1, hbr);
-							return (LONG)hbr;
-						}
-						else
-						{
-							SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
-													 _green[thiscinfo->back],
-													 _blue[thiscinfo->back]));
-							if(thiscinfo->hbrush)
-								DeleteObject(thiscinfo->hbrush);
-							thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
-																	 _green[thiscinfo->back],
-																	 _blue[thiscinfo->back]));
-							SelectObject((HDC)mp1, thiscinfo->hbrush);
-						}
-						return (LONG)thiscinfo->hbrush;
-					}
-					else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
-					{
-						SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
-												 DW_GREEN_VALUE(thiscinfo->back),
-												 DW_BLUE_VALUE(thiscinfo->back)));
-						if(thiscinfo->hbrush)
-							DeleteObject(thiscinfo->hbrush);
-						thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
-																 DW_GREEN_VALUE(thiscinfo->back),
-																 DW_BLUE_VALUE(thiscinfo->back)));
-						SelectObject((HDC)mp1, thiscinfo->hbrush);
-						return (LONG)thiscinfo->hbrush;
-					}
-				}
-
-			}
-			break;
-		}
-	}
-
-	if(!pOldProc)
-		return DefWindowProc(hWnd, msg, mp1, mp2);
-	return CallWindowProc(pOldProc, hWnd, msg, mp1, mp2);
-}
-
-BOOL CALLBACK _containerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	ContainerInfo *cinfo;
-
-	cinfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-	switch( msg )
-	{
-	case WM_COMMAND:
-	case WM_NOTIFY:
-		_wndproc(hWnd, msg, mp1, mp2);
-		break;
-	case WM_LBUTTONDBLCLK:
-	case WM_CHAR:
-		{
-			LV_ITEM lvi;
-			int iItem;
-
-			if(LOWORD(mp1) == '\t')
-			{
-				if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-					_shift_focus_back(hWnd);
-				else
-					_shift_focus(hWnd);
-				return FALSE;
-			}
-
-			if(msg == WM_CHAR && (char)mp1 != '\r')
-				break;
-
-			iItem = ListView_GetNextItem(hWnd, -1, LVNI_FOCUSED);
-
-			memset(&lvi, 0, sizeof(LV_ITEM));
-
-			if(iItem > -1)
-			{
-				lvi.iItem = iItem;
-				lvi.mask = LVIF_PARAM;
-
-				ListView_GetItem(hWnd, &lvi);
-			}
-
-			{
-				SignalHandler *tmp = Root;
-
-				while(tmp)
-				{
-					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);
-						tmp = NULL;
-					}
-					if(tmp)
-						tmp = tmp->next;
-				}
-			}
-		}
-		break;
-	case WM_CONTEXTMENU:
-		{
-			SignalHandler *tmp = Root;
-
-			while(tmp)
-			{
-				if(tmp->message == NM_RCLICK && tmp->window == hWnd)
-				{
-					int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
-					LONG x,y;
-					LV_ITEM lvi;
-					int iItem;
-					LVHITTESTINFO lhi;
-
-					dw_pointer_query_pos(&x, &y);
-
-					lhi.pt.x = x;
-					lhi.pt.y = y;
-
-					MapWindowPoints(HWND_DESKTOP, tmp->window, &lhi.pt, 1);
-
-					iItem = ListView_HitTest(tmp->window, &lhi);
-
-					memset(&lvi, 0, sizeof(LV_ITEM));
-
-					if(iItem > -1)
-					{
-						lvi.iItem = iItem;
-						lvi.mask = LVIF_PARAM;
-
-						ListView_GetItem(tmp->window, &lvi);
-						ListView_SetSelectionMark(tmp->window, iItem);
-					}
-
-					/* 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);
-					tmp = NULL;
-				}
-				if(tmp)
-					tmp = tmp->next;
-			}
-		}
-		break;
-	}
-
-	if(!cinfo || !cinfo->pOldProc)
-		return DefWindowProc(hWnd, msg, mp1, mp2);
-	return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-}
-
-BOOL CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	ContainerInfo *cinfo;
-
-	cinfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
-
-	switch( msg )
-	{
-	case WM_CHAR:
-		if(LOWORD(mp1) == '\t')
-		{
-			if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-				_shift_focus_back(hWnd);
-			else
-				_shift_focus(hWnd);
-			return FALSE;
-		}
-		break;
-	}
-
-	if(!cinfo || !cinfo->pOldProc)
-		return DefWindowProc(hWnd, msg, mp1, mp2);
-	return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
-}
-
-void _changebox(Box *thisbox, int percent, int type)
-{
-	int z;
-
-	for(z=0;z<thisbox->count;z++)
-	{
-		if(thisbox->items[z].type == TYPEBOX)
-		{
-			Box *tmp = (Box*)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
-			_changebox(tmp, percent, type);
-		}
-		else
-		{
-			if(type == DW_HORZ)
-			{
-				if(thisbox->items[z].hsize == SIZEEXPAND)
-					thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
-			}
-			else
-			{
-				if(thisbox->items[z].vsize == SIZEEXPAND)
-					thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
-			}
-		}
-	}
-}
-
-void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
-{
-	if(type == DW_HORZ)
-	{
-		int newx = x;
-		float ratio = (float)percent/(float)100.0;
-		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		Box *tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
-
-		newx = (int)((float)newx * ratio) - (SPLITBAR_WIDTH/2);
-
-		ShowWindow(handle1, SW_HIDE);
-		ShowWindow(handle2, SW_HIDE);
-
-		MoveWindow(handle1, 0, 0, newx, y, FALSE);
-		_do_resize(tmp, newx - 1, y - 1);
-
-		tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
-
-		newx = x - newx - SPLITBAR_WIDTH;
-
-		MoveWindow(handle2, x - newx, 0, newx, y, FALSE);
-		_do_resize(tmp, newx - 1, y - 1);
-
-		ShowWindow(handle1, SW_SHOW);
-		ShowWindow(handle2, SW_SHOW);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newx);
-	}
-	else
-	{
-		int newy = y;
-		float ratio = (float)(100.0-percent)/(float)100.0;
-		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		Box *tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
-
-		newy = (int)((float)newy * ratio) - (SPLITBAR_WIDTH/2);
-
-		ShowWindow(handle1, SW_HIDE);
-		ShowWindow(handle2, SW_HIDE);
-
-		MoveWindow(handle1, 0, y - newy, x, newy, FALSE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
-
-		newy = y - newy - SPLITBAR_WIDTH;
-
-		MoveWindow(handle2, 0, 0, x, newy, FALSE);
-		_do_resize(tmp, x - 1, newy - 1);
-
-		ShowWindow(handle1, SW_SHOW);
-		ShowWindow(handle2, SW_SHOW);
-
-		dw_window_set_data(hwnd, "_dw_start", (void *)newy);
-	}
-}
-
-/* This handles any activity on the splitbars (sizers) */
-BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
-	int type = (int)dw_window_get_data(hwnd, "_dw_type");
-	int start = (int)dw_window_get_data(hwnd, "_dw_start");
-
-	switch (msg)
-	{
-	case WM_ACTIVATE:
-	case WM_SETFOCUS:
-		return FALSE;
-
-	case WM_PAINT:
-		{
-			PAINTSTRUCT ps;
-			HDC hdcPaint;
-
-			BeginPaint(hwnd, &ps);
-
-			if((hdcPaint = GetDC(hwnd)) != NULL)
-			{
-				int cx, cy;
-				HBRUSH oldBrush = SelectObject(hdcPaint, GetSysColorBrush(COLOR_3DFACE));
-				HPEN oldPen = SelectObject(hdcPaint, CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DFACE)));
-
-				dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
-
-				if(type == DW_HORZ)
-					Rectangle(hdcPaint, cx - start - SPLITBAR_WIDTH, 0, cx - start, cy);
-				else
-					Rectangle(hdcPaint, 0, start, cx, start + SPLITBAR_WIDTH);
-
-				SelectObject(hdcPaint, oldBrush);
-				DeleteObject(SelectObject(hdcPaint, oldPen));
-				ReleaseDC(hwnd, hdcPaint);
-			}
-			EndPaint(hwnd, &ps);
-		}
-		break;
-	case WM_LBUTTONDOWN:
-		{
-			SetCapture(hwnd);
-			break;
-		}
-	case WM_LBUTTONUP:
-		{
-            if(GetCapture() == hwnd)
-				ReleaseCapture();
-		}
-		break;
-	case WM_MOUSEMOVE:
-		{
-			if(type == DW_HORZ)
-				SetCursor(LoadCursor(NULL, IDC_SIZEWE));
-			else
-				SetCursor(LoadCursor(NULL, IDC_SIZENS));
-
-			if(GetCapture() == hwnd && percent)
-			{
-				POINT point;
-				RECT rect;
-				static POINT lastpoint;
-
-				GetCursorPos(&point);
-				GetWindowRect(hwnd, &rect);
-
-				if(memcmp(&point, &lastpoint, sizeof(POINT)))
-				{
-					if(PtInRect(&rect, point))
-					{
-						int width = (rect.right - rect.left);
-						int height = (rect.bottom - rect.top);
-
-						if(type == DW_HORZ)
-						{
-							start = point.x - rect.left;
-							if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
-								*percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
-						}
-						else
-						{
-							start = point.y - rect.top;
-							if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
-								*percent = ((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0;
-						}
-						_handle_splitbar_resize(hwnd, *percent, type, width, height);
-					}
-					memcpy(&lastpoint, &point, sizeof(POINT));
-				}
-			}
-			break;
-		}
-	}
-	return DefWindowProc(hwnd, msg, mp1, mp2);
-}
-
-/* This handles drawing the status text areas */
-BOOL CALLBACK _statuswndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
-{
-	switch (msg)
-	{
-	case WM_SETTEXT:
-		{
-			/* Make sure the control redraws when there is a text change */
-			int ret = (int)DefWindowProc(hwnd, msg, mp1, mp2);
-
-			InvalidateRgn(hwnd, NULL, TRUE);
-			return ret;
-		}
-	case WM_PAINT:
-		{
-			HDC hdcPaint;
-			PAINTSTRUCT ps;
-			RECT rc;
-			unsigned long cx, cy;
-			int threadid = dw_thread_id();
-			char tempbuf[1024] = "";
-			ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-			HFONT hfont = _acquire_font(hwnd, cinfo ? cinfo->fontname : NULL);
-			HFONT oldfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
-
-			dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
-			GetWindowText(hwnd, tempbuf, 1024);
-
-			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);
-			if(hfont && oldfont)
-				SelectObject(hdcPaint, oldfont);
-			if(hfont)
-				DeleteObject(hfont);
-			EndPaint(hwnd, &ps);
-		}
-		return FALSE;
-	}
-	return DefWindowProc(hwnd, msg, mp1, mp2);
-}
-
-/* Function: _BtProc
- * Abstract: Subclass procedure for buttons
- */
-
-BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
-{
-	BubbleButton *bubble;
-	static int bMouseOver = 0;
-	POINT point;
-	RECT rect;
-	WNDPROC pOldProc;
-
-	bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-
-	if(!bubble)
-		return DefWindowProc(hwnd, msg, mp1, mp2);
-
-	/* We must save a pointer to the old
-	 * window procedure because if a signal
-	 * handler attached here destroys this
-	 * window it will then be invalid.
-	 */
-	pOldProc = bubble->pOldProc;
-
-	switch(msg)
-	{
-	case WM_CTLCOLORSTATIC:
-	case WM_CTLCOLORLISTBOX:
-	case WM_CTLCOLORBTN:
-	case WM_CTLCOLOREDIT:
-	case WM_CTLCOLORMSGBOX:
-	case WM_CTLCOLORSCROLLBAR:
-	case WM_CTLCOLORDLG:
-		_wndproc(hwnd, msg, mp1, mp2);
-		break;
-	case WM_SETFOCUS:
-		_wndproc(hwnd, msg, mp1, mp2);
-		break;
-	case WM_LBUTTONUP:
-		{
-			SignalHandler *tmp = Root;
-
-			/* Find any callbacks for this function */
-			while(tmp)
-			{
-				if(tmp->message == WM_COMMAND)
-				{
-					int (*clickfunc)(HWND, void *) = tmp->signalfunction;
-
-					/* Make sure it's the right window, and the right ID */
-					if(tmp->window == hwnd)
-					{
-						if(bubble->checkbox)
-							in_checkbox_handler = 1;
-
-						clickfunc(tmp->window, tmp->data);
-
-						if(bubble->checkbox)
-							in_checkbox_handler = 0;
-						tmp = NULL;
-					}
-				}
-				if(tmp)
-					tmp= tmp->next;
-			}
-		}
-		break;
-	case WM_CHAR:
-		{
-			/* A button press should also occur for an ENTER or SPACE press
-			 * while the button has the active input focus.
-			 */
-			if(LOWORD(mp1) == '\r' || LOWORD(mp1) == ' ')
-			{
-				SignalHandler *tmp = Root;
-
-				/* Find any callbacks for this function */
-				while(tmp)
-				{
-					if(tmp->message == WM_COMMAND)
-					{
-						int (*clickfunc)(HWND, void *) = tmp->signalfunction;
-
-						/* Make sure it's the right window, and the right ID */
-						if(tmp->window == hwnd)
-						{
-							clickfunc(tmp->window, tmp->data);
-							tmp = NULL;
-						}
-					}
-					if(tmp)
-						tmp= tmp->next;
-				}
-			}
-			if(LOWORD(mp1) == '\t')
-			{
-				if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
-					_shift_focus_back(hwnd);
-				else
-					_shift_focus(hwnd);
-				return FALSE;
-			}
-		}
-		break;
-	case WM_KEYDOWN:
-		if(mp1 == VK_LEFT || mp1 == VK_UP)
-			_shift_focus_back(hwnd);
-		if(mp1 == VK_RIGHT || mp1 == VK_DOWN)
-			_shift_focus(hwnd);
-		break;
-	case WM_TIMER:
-		if (hwndBubble)
-		{
-			_free_window_memory(hwndBubble, 0);
-			DestroyWindow(hwndBubble);
-			hwndBubble = 0;
-			KillTimer(hwnd, 1);
-		}
-		break;
-
-	case WM_MOUSEMOVE:
-		GetCursorPos(&point);
-		GetWindowRect(hwnd, &rect);
-
-		if(PtInRect(&rect, point))
-		{
-			if(hwnd != GetCapture())
-			{
-				SetCapture(hwnd);
-			}
-			if(!bMouseOver)
-			{
-				bMouseOver = 1;
-				if(!*bubble->bubbletext)
-					break;
-
-				if(hwndBubble)
-				{
-					_free_window_memory(hwndBubble, 0);
-					DestroyWindow(hwndBubble);
-					hwndBubble = 0;
-					KillTimer(hwndBubbleLast, 1);
-				}
-
-				if(!hwndBubble)
-				{
-					POINTL ptlWork = {0,0};
-					ULONG ulColor = DW_CLR_YELLOW;
-					SIZE size;
-					HFONT hFont, oldFont = (HFONT)0;
-					HDC hdc;
-					RECT rect;
-					void *oldproc;
-
-					/* Use the WS_EX_TOOLWINDOW extended style
-					 * so the window doesn't get listed in the
-					 * taskbar.
-					 */
-					hwndBubble = CreateWindowEx(WS_EX_TOOLWINDOW,
-												STATICCLASSNAME,
-												bubble->bubbletext,
-												BS_TEXT | WS_POPUP |
-												WS_BORDER |
-												SS_CENTER,
-												0,0,50,20,
-												HWND_DESKTOP,
-												NULL,
-												DWInstance,
-												NULL);
-
-					dw_window_set_font(hwndBubble, DefaultFont);
-					dw_window_set_color(hwndBubble, DW_CLR_BLACK, DW_CLR_YELLOW);
-
-					hwndBubbleLast = hwnd;
-
-					SetTimer(hwnd, 1, 3000, NULL);
-
-					hFont = (HFONT)SendMessage(hwndBubble, WM_GETFONT, 0, 0);
-
-					hdc = GetDC(hwndBubble);
-
-					if(hFont)
-						oldFont = (HFONT)SelectObject(hdc, hFont);
-
-					GetTextExtentPoint32(hdc, bubble->bubbletext, strlen(bubble->bubbletext), &size);
-
-					if(hFont)
-						SelectObject(hdc, oldFont);
-
-					MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)&ptlWork, 1);
-
-					GetWindowRect(hwnd, &rect);
-
-					SetWindowPos(hwndBubble,
-								 HWND_TOP,
-								 ptlWork.x,
-								 ptlWork.y + (rect.bottom-rect.top) + 1,
-								 size.cx + 8,
-								 size.cy + 2,
-								 SWP_NOACTIVATE | SWP_SHOWWINDOW);
-
-					ReleaseDC(hwndBubble, hdc);
-				}
-			}
-		}
-		else{
-			/* Calling ReleaseCapture in Win95 also causes WM_CAPTURECHANGED
-			 * to be sent.  Be sure to account for that.
-			 */
-			ReleaseCapture();
-
-			if(bMouseOver)
-			{
-				bMouseOver = 0;
-				_free_window_memory(hwndBubble, 0);
-				DestroyWindow(hwndBubble);
-				hwndBubble = 0;
-				KillTimer(hwndBubbleLast, 1);
-			}
-		}
-		break;
-	case WM_CAPTURECHANGED:
-		/* This message means we are losing the capture for some reason
-		 * Either because we intentionally lost it or another window
-		 * stole it
-		 */
-		if(bMouseOver)
-		{
-			bMouseOver = 0;
-			_free_window_memory(hwndBubble, 0);
-			DestroyWindow(hwndBubble);
-			hwndBubble = 0;
-			KillTimer(hwndBubbleLast, 1);
-		}
-		break;
-	}
-
-	if(!pOldProc)
-		return DefWindowProc(hwnd, msg, mp1, mp2);
-	return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
-}
-
-/* This function recalculates a notebook page for example
- * during switching of notebook pages.
- */
-void _resize_notebook_page(HWND handle, int pageid)
-{
-	RECT rect;
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-
-	if(array && array[pageid])
-	{
-		Box *box = (Box *)GetWindowLongPtr(array[pageid]->hwnd, GWLP_USERDATA);
-
-		GetClientRect(handle,&rect);
-		TabCtrl_AdjustRect(handle,FALSE,&rect);
-		MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
-				   rect.right - rect.left, rect.bottom-rect.top, TRUE);
-		if(box && box->count)
-		{
-			ShowWindow(box->items[0].hwnd, SW_HIDE);
-			_do_resize(box, rect.right - rect.left, rect.bottom - rect.top);
-			ShowWindow(box->items[0].hwnd, SW_SHOW);
-		}
-
-		ShowWindow(array[pageid]->hwnd, SW_SHOWNORMAL);
-	}
-}
-
-/*
- * Initializes the Dynamic Windows engine.
- * Parameters:
- *           newthread: True if this is the only thread.
- *                      False if there is already a message loop running.
- */
-int API dw_init(int newthread, int argc, char *argv[])
-{
-	WNDCLASS wc;
-	int z;
-	INITCOMMONCONTROLSEX icc;
-
-	icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
-	icc.dwICC = ICC_WIN95_CLASSES;
-
-	InitCommonControlsEx(&icc);
-
-	memset(lookup, 0, sizeof(HICON) * ICON_INDEX_LIMIT);
-
-	/* Register the generic Dynamic Windows class */
-	memset(&wc, 0, sizeof(WNDCLASS));
-	wc.style = CS_DBLCLKS;
-	wc.lpfnWndProc = (WNDPROC)_wndproc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 32;
-	wc.hbrBackground = NULL;
-	wc.lpszMenuName = NULL;
-	wc.lpszClassName = ClassName;
-
-	RegisterClass(&wc);
-
-	/* Register the splitbar control */
-	memset(&wc, 0, sizeof(WNDCLASS));
-	wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
-	wc.lpfnWndProc = (WNDPROC)_splitwndproc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 0;
-	wc.hbrBackground = NULL;
-	wc.lpszMenuName = NULL;
-	wc.lpszClassName = SplitbarClassName;
-
-	RegisterClass(&wc);
-
-	/* Register a frame control like on OS/2 */
-	memset(&wc, 0, sizeof(WNDCLASS));
-	wc.style = CS_DBLCLKS;
-	wc.lpfnWndProc = (WNDPROC)_framewndproc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 32;
-	wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wc.lpszMenuName = NULL;
-	wc.lpszClassName = FRAMECLASSNAME;
-
-	RegisterClass(&wc);
-
-	/* Create a set of brushes using the default OS/2 and DOS colors */
-	for(z=0;z<18;z++)
-		_colors[z] = CreateSolidBrush(RGB(_red[z],_green[z],_blue[z]));
-
-	/* Register an Object Windows class like OS/2 and Win2k+
-	 * so similar functionality can be used on earlier releases
-	 * of Windows.
-	 */
-	memset(&wc, 0, sizeof(WNDCLASS));
-	wc.style = 0;
-	wc.lpfnWndProc = (WNDPROC)_wndproc;
-	wc.cbClsExtra = 0;
-	wc.cbWndExtra = 0;
-	wc.hbrBackground = NULL;
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wc.lpszMenuName = NULL;
-	wc.lpszClassName = ObjectClassName;
-
-	RegisterClass(&wc);
-
-	/* Since Windows 95/98/NT don't have a HWND_OBJECT class
-	 * also known as a input only window, I will create a
-	 * temporary window that isn't visible and really does nothing
-	 * except temporarily hold the child windows before they are
-	 * packed into their correct parent.
-	 */
-
-	DW_HWND_OBJECT = CreateWindow(ObjectClassName, "", 0, 0, 0,
-								  0, 0, HWND_DESKTOP, NULL, DWInstance, NULL);
-
-	if(!DW_HWND_OBJECT)
-	{
-		dw_messagebox("Dynamic Windows", DW_MB_OK|DW_MB_ERROR, "Could not initialize the object window. error code %d", GetLastError());
-		exit(1);
-	}
-
-	/* We need the version to check capability like up-down controls */
-	dwVersion = GetVersion();
-	dwComctlVer = GetDllVersion(TEXT("comctl32.dll"));
-
-	for(z=0;z<THREAD_LIMIT;z++)
-	{
-		_foreground[z] = RGB(128,128,128);
-		_background[z] = DW_RGB_TRANSPARENT;
-		_hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]);
-		_hBrush[z] = CreateSolidBrush(_foreground[z]);
-	}
-
-	return 0;
-}
-
-/*
- * Runs a message loop for Dynamic Windows.
- */
-void API dw_main(void)
-{
-	MSG msg;
-
-	_dwtid = dw_thread_id();
-
-	while(GetMessage(&msg, NULL, 0, 0))
-	{
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-	}
-}
-
-/*
- * Runs a message loop for Dynamic Windows, for a period of milliseconds.
- * Parameters:
- *           milliseconds: Number of milliseconds to run the loop for.
- */
-void API dw_main_sleep(int milliseconds)
-{
-	MSG msg;
-	double start = (double)clock();
-
-	while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
-	{
-		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
-		{
-			GetMessage(&msg, NULL, 0, 0);
-			TranslateMessage(&msg);
-			DispatchMessage(&msg);
-		}
-		else
-			Sleep(1);
-	}
-}
-
-/*
- * Processes a single message iteration and returns.
- */
-void API dw_main_iteration(void)
-{
-	MSG msg;
-
-	_dwtid = dw_thread_id();
-
-	if(GetMessage(&msg, NULL, 0, 0))
-	{
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-	}
-}
-
-/*
- * Free's memory allocated by dynamic windows.
- * Parameters:
- *           ptr: Pointer to dynamic windows allocated
- *                memory to be free()'d.
- */
-void API dw_free(void *ptr)
-{
-	free(ptr);
-}
-
-/*
- * Allocates and initializes a dialog struct.
- * Parameters:
- *           data: User defined data to be passed to functions.
- */
-DWDialog * API dw_dialog_new(void *data)
-{
-	DWDialog *tmp = malloc(sizeof(DWDialog));
-
-	tmp->eve = dw_event_new();
-	dw_event_reset(tmp->eve);
-	tmp->data = data;
-	tmp->done = FALSE;
-	tmp->result = NULL;
-
-    return tmp;
-}
-
-/*
- * Accepts a dialog struct and returns the given data to the
- * initial called of dw_dialog_wait().
- * Parameters:
- *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
- *           result: Data to be returned by dw_dialog_wait().
- */
-int API dw_dialog_dismiss(DWDialog *dialog, void *result)
-{
-	dialog->result = result;
-	dw_event_post(dialog->eve);
-	dialog->done = TRUE;
-	return 0;
-}
-
-/*
- * Accepts a dialog struct waits for dw_dialog_dismiss() to be
- * called by a signal handler with the given dialog struct.
- * Parameters:
- *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
- */
-void * API dw_dialog_wait(DWDialog *dialog)
-{
-	MSG msg;
-	void *tmp;
-
-	while (GetMessage(&msg,NULL,0,0))
-	{
-		if(msg.hwnd == NULL && msg.message == WM_TIMER)
-			_wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-		if(dialog->done)
-			break;
-	}
-	dw_event_close(&dialog->eve);
-	tmp = dialog->result;
-	free(dialog);
-	return tmp;
-}
-
-/*
- * Displays a Message Box with given text and title..
- * Parameters:
- *           title: The title of the message box.
- *           format: printf style format string.
- *           ...: Additional variables for use in the format.
- */
-int API dw_messagebox(char *title, int flags, char *format, ...)
-{
-	va_list args;
-	char outbuf[256];
-	int rc;
-
-	va_start(args, format);
-	vsprintf(outbuf, format, args);
-	va_end(args);
-
-	rc = MessageBox(HWND_DESKTOP, outbuf, title, flags);
-	if(rc == IDOK)
-		return DW_MB_RETURN_OK;
-	else if(rc == IDYES)
-		return DW_MB_RETURN_YES;
-	else if(rc == IDNO)
-		return DW_MB_RETURN_NO;
-	else if(rc == IDCANCEL)
-		return DW_MB_RETURN_CANCEL;
-	else return 0;
-}
-
-/*
- * Minimizes or Iconifies a top-level window.
- * Parameters:
- *           handle: The window handle to minimize.
- */
-int API dw_window_minimize(HWND handle)
-{
-	return ShowWindow(handle, SW_MINIMIZE);
-}
-
-/*
- * Makes the window topmost.
- * Parameters:
- *           handle: The window handle to make topmost.
- */
-int API dw_window_raise(HWND handle)
-{
-	return SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-}
-
-/*
- * Makes the window bottommost.
- * Parameters:
- *           handle: The window handle to make bottommost.
- */
-int API dw_window_lower(HWND handle)
-{
-	return SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-}
-
-/*
- * Makes the window visible.
- * Parameters:
- *           handle: The window handle to make visible.
- */
-int API dw_window_show(HWND handle)
-{
-	int rc = ShowWindow(handle, SW_SHOW);
-	SetFocus(handle);
-	_initial_focus(handle);
-	return rc;
-}
-
-/*
- * Makes the window invisible.
- * Parameters:
- *           handle: The window handle to make visible.
- */
-int API dw_window_hide(HWND handle)
-{
-	return ShowWindow(handle, SW_HIDE);
-}
-
-/*
- * Destroys a window and all of it's children.
- * Parameters:
- *           handle: The window handle to destroy.
- */
-int API dw_window_destroy(HWND handle)
-{
-	HWND parent = GetParent(handle);
-	Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);
-#ifndef WINNT_COMPAT
-	HMENU menu = GetMenu(handle);
-
-	if(menu)
-		_free_menu_data(menu);
-#endif
-
-	if(parent != HWND_DESKTOP && thisbox && thisbox->count)
-	{
-		int z, index = -1;
-		Item *tmpitem, *thisitem = thisbox->items;
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			if(thisitem[z].hwnd == handle)
-				index = z;
-		}
-
-		if(index == -1)
-			return 0;
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
-
-		/* Copy all but the current entry to the new list */
-		for(z=0;z<index;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-		for(z=index+1;z<thisbox->count;z++)
-		{
-			tmpitem[z-1] = thisitem[z];
-		}
-
-		thisbox->items = tmpitem;
-		free(thisitem);
-		thisbox->count--;
-		_free_window_memory(handle, 0);
-		EnumChildWindows(handle, _free_window_memory, 0);
-	}
-	return DestroyWindow(handle);
-}
-
-/* Causes entire window to be invalidated and redrawn.
- * Parameters:
- *           handle: Toplevel window handle to be redrawn.
- */
-void API dw_window_redraw(HWND handle)
-{
-	Box *mybox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	if(mybox)
-	{
-		RECT rect;
-		int istoplevel = (GetParent(handle) == HWND_DESKTOP);
-
-		GetClientRect(handle, &rect);
-
-		ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_HIDE);
-		_do_resize(mybox, rect.right - rect.left, rect.bottom - rect.top);
-		ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_SHOW);
-	}
-}
-
-int instring(char *text, char *buffer)
-{
-	int z, len = strlen(text), buflen = strlen(buffer);
-
-	if(buflen > len)
-	{
-		for(z=0;z<=(buflen-len);z++)
-		{
-			if(memcmp(text, &buffer[z], len) == 0)
-				return z;
-		}
-	}
-	return 0;
-}
-
-/*
- * Changes a window's parent to newparent.
- * Parameters:
- *           handle: The window handle to destroy.
- *           newparent: The window's new parent window.
- */
-void API dw_window_reparent(HWND handle, HWND newparent)
-{
-	SetParent(handle, newparent);
-}
-
-HFONT _acquire_font(HWND handle, char *fontname)
-{
-	HFONT hfont = 0;
-
-	if(fontname != DefaultFont && fontname[0])
-	{
-        int Italic, Bold;
-		char *myFontName;
-		int z, size = 9;
-		LOGFONT lf;
-#if 0
-		HDC hDC = GetDC(handle);
-#endif
-		for(z=0;z<strlen(fontname);z++)
-		{
-			if(fontname[z]=='.')
-				break;
-		}
-		size = atoi(fontname) + 5;
-		Italic = instring(" Italic", &fontname[z+1]);
-		Bold = instring(" Bold", &fontname[z+1]);
-#if 0
-		lf.lfHeight = -MulDiv(size, GetDeviceCaps(hDC, LOGPIXELSY), 72);
-#endif
-		lf.lfHeight = size;
-		lf.lfWidth = 0;
-		lf.lfEscapement = 0;
-		lf.lfOrientation = 0;
-		lf.lfItalic = Italic ? TRUE : FALSE;
-		lf.lfUnderline = 0;
-		lf.lfStrikeOut = 0;
-		lf.lfWeight = Bold ? FW_BOLD : FW_NORMAL;
-		lf.lfCharSet = DEFAULT_CHARSET;
-		lf.lfOutPrecision = 0;
-		lf.lfClipPrecision = 0;
-		lf.lfQuality = DEFAULT_QUALITY;
-		lf.lfPitchAndFamily = DEFAULT_PITCH | FW_DONTCARE;
-		/* 
-		 * remove any font modifiers
-		 */
-		myFontName = strdup(&fontname[z+1]);
-		if(Italic)
-			myFontName[Italic] = 0;
-		if(Bold)
-			myFontName[Bold] = 0;
-		strcpy(lf.lfFaceName, myFontName);
-		free(myFontName);
-
-		hfont = CreateFontIndirect(&lf);
-#if 0
-		ReleaseDC(handle, hDC);
-#endif
-	}
-	if(!hfont)
-		hfont = GetStockObject(DEFAULT_GUI_FONT);
-	return hfont;
-}
-
-/*
- * Sets the font used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          fontname: Name and size of the font in the form "size.fontname"
- */
-int API dw_window_set_font(HWND handle, char *fontname)
-{
-	HFONT oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
-	HFONT hfont = _acquire_font(handle, fontname);
-	ColorInfo *cinfo;
-
-	cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	if(fontname)
-	{
-		if(cinfo)
-		{
-			strcpy(cinfo->fontname, fontname);
-			if(!oldfont)
-				oldfont = cinfo->hfont;
-			cinfo->hfont = hfont;
-		}
-		else
-		{
-			cinfo = calloc(1, sizeof(ColorInfo));
-			cinfo->fore = cinfo->back = -1;
-
-			strcpy(cinfo->fontname, fontname);
-
-			cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
-			SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
-		}
-	}
-	SendMessage(handle, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
-	if(oldfont)
-		DeleteObject(oldfont);
-	return 0;
-}
-
-/*
- * Sets the colors used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          fore: Foreground color in RGB format.
- *          back: Background color in RGB format.
- */
-int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
-{
-	ColorInfo *cinfo;
-	char tmpbuf[100];
-
-	cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0)
-	{
-		fore = _internal_color(fore);
-		back = _internal_color(back);
-
-		ListView_SetTextColor(handle, RGB(DW_RED_VALUE(fore),
-										  DW_GREEN_VALUE(fore),
-										  DW_BLUE_VALUE(fore)));
-		ListView_SetTextBkColor(handle, RGB(DW_RED_VALUE(back),
-											DW_GREEN_VALUE(back),
-											DW_BLUE_VALUE(back)));
-		ListView_SetBkColor(handle, RGB(DW_RED_VALUE(back),
-										DW_GREEN_VALUE(back),
-										DW_BLUE_VALUE(back)));
-		InvalidateRgn(handle, NULL, TRUE);
-		return TRUE;
-	}
-
-	if(cinfo)
-	{
-		cinfo->fore = fore;
-		cinfo->back = back;
-	}
-	else
-	{
-		cinfo = calloc(1, sizeof(ColorInfo));
-
-		cinfo->fore = fore;
-		cinfo->back = back;
-
-		cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
-		SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
-	}
-	InvalidateRgn(handle, NULL, TRUE);
-	return TRUE;
-}
-
-/*
- * Sets the font used by a specified window (widget) handle.
- * Parameters:
- *          handle: The window (widget) handle.
- *          border: Size of the window border in pixels.
- */
-int API dw_window_set_border(HWND handle, int border)
-{
-	return 0;
-}
-
-/*
- * Captures the mouse input to this window.
- * Parameters:
- *       handle: Handle to receive mouse input.
- */
-void API dw_window_capture(HWND handle)
-{
-	SetCapture(handle);
-}
-
-/*
- * Releases previous mouse capture.
- */
-void API dw_window_release(void)
-{
-	ReleaseCapture();
-}
-
-/*
- * Changes the appearance of the mouse pointer.
- * Parameters:
- *       handle: Handle to widget for which to change.
- *       cursortype: ID of the pointer you want.
- */
-void API dw_window_pointer(HWND handle, int pointertype)
-{
-/*
-	if(pointertype == DW_POINTER_ARROW)
-		SetClassLong( handle, GCL_HCURSOR, LoadCursor( NULL, IDC_ARROW));
-	else if(pointertype == DW_POINTER_CLOCK)
-		SetClassLong( handle, GCL_HCURSOR, LoadCursor( NULL, IDC_WAIT));
-	else
-*/
-	SetCursor(pointertype < 65536 ? LoadCursor(NULL, MAKEINTRESOURCE(pointertype)) : (HCURSOR)pointertype);
-}
-
-/*
- * Create a new Window Frame.
- * Parameters:
- *       owner: The Owner's window handle or HWND_DESKTOP.
- *       title: The Window title.
- *       flStyle: Style flags, see the DW reference.
- */
-HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle)
-{
-	HWND hwndframe;
-	Box *newbox = calloc(sizeof(Box), 1);
-	ULONG flStyleEx = 0;
-
-	newbox->pad = 0;
-	newbox->type = DW_VERT;
-	newbox->count = 0;
-	newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-	if(hwndOwner)
-		flStyleEx |= WS_EX_MDICHILD;
-
-	if(!(flStyle & WS_CAPTION))
-		flStyle |= WS_POPUPWINDOW;
-
-	if(flStyle & DW_FCF_TASKLIST)
-	{
-		ULONG newflags = (flStyle | WS_CLIPCHILDREN) & ~DW_FCF_TASKLIST;
-
-		hwndframe = CreateWindowEx(flStyleEx, ClassName, title, newflags, CW_USEDEFAULT, CW_USEDEFAULT,
-								   CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
-	}
-	else
-	{
-		flStyleEx |= WS_EX_TOOLWINDOW;
-
-		hwndframe = CreateWindowEx(flStyleEx, ClassName, title, flStyle | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT,
-								   CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
-	}
-	SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
-
-#if 0
-	if(hwndOwner)
-		SetParent(hwndframe, hwndOwner);
-#endif
-
-	return hwndframe;
-}
-
-/*
- * Create a new Box to be packed.
- * Parameters:
- *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
- *       pad: Number of pixels to pad around the box.
- */
-HWND API dw_box_new(int type, int pad)
-{
-	Box *newbox = calloc(sizeof(Box), 1);
-	HWND hwndframe;
-
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-	newbox->grouphwnd = (HWND)NULL;
-	newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-	hwndframe = CreateWindow(FRAMECLASSNAME,
-							 "",
-							 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-							 0,0,2000,1000,
-							 DW_HWND_OBJECT,
-							 NULL,
-							 DWInstance,
-							 NULL);
-
-	newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc);
-	newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-	SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
-	return hwndframe;
-}
-
-/*
- * Create a new Group Box to be packed.
- * Parameters:
- *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
- *       pad: Number of pixels to pad around the box.
- *       title: Text to be displayined in the group outline.
- */
-HWND API dw_groupbox_new(int type, int pad, char *title)
-{
-	Box *newbox = calloc(sizeof(Box), 1);
-	HWND hwndframe;
-
-	newbox->pad = pad;
-	newbox->type = type;
-	newbox->count = 0;
-	newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-	hwndframe = CreateWindow(FRAMECLASSNAME,
-							 "",
-							 WS_VISIBLE | WS_CHILD,
-							 0,0,2000,1000,
-							 DW_HWND_OBJECT,
-							 NULL,
-							 DWInstance,
-							 NULL);
-
-	newbox->grouphwnd = CreateWindow(BUTTONCLASSNAME,
-									 title,
-									 WS_CHILD | BS_GROUPBOX |
-									 WS_VISIBLE | WS_CLIPCHILDREN,
-									 0,0,2000,1000,
-									 hwndframe,
-									 NULL,
-									 DWInstance,
-									 NULL);
-
-	SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
-	dw_window_set_font(newbox->grouphwnd, DefaultFont);
-	return hwndframe;
-}
-
-/*
- * Create a new MDI Frame to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id or 0L.
- */
-HWND API dw_mdi_new(unsigned long id)
-{
-	CLIENTCREATESTRUCT ccs;
-	HWND hwndframe;
-
-	ccs.hWindowMenu = NULL;
-	ccs.idFirstChild = 0;
-
-	hwndframe = CreateWindow("MDICLIENT",
-							 "",
-							 WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
-							 0,0,2000,1000,
-							 DW_HWND_OBJECT,
-							 (HMENU)id,
-							 DWInstance,
-							 &ccs);
-	return hwndframe;
-}
-
-/*
- * Create a bitmap object to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id or 0L.
- */
-HWND API dw_bitmap_new(ULONG id)
-{
-	return CreateWindow(STATICCLASSNAME,
-						"",
-						SS_BITMAP | WS_VISIBLE |
-						WS_CHILD | WS_CLIPCHILDREN,
-						0,0,2000,1000,
-						DW_HWND_OBJECT,
-						(HMENU)id,
-						DWInstance,
-						NULL);
-}
-
-/*
- * Create a notebook object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_notebook_new(ULONG id, int top)
-{
-	ULONG flags = 0;
-	HWND tmp;
-	NotebookPage **array = calloc(256, sizeof(NotebookPage *));
-
-	if(!top)
-		flags = TCS_BOTTOM;
-
-	tmp = CreateWindow(WC_TABCONTROL,
-					   "",
-					   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-					   0,0,2000,1000,
-					   DW_HWND_OBJECT,
-					   (HMENU)id,
-					   DWInstance,
-					   NULL);
-	dw_window_set_data(tmp, "_dw_array", (void *)array);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a menu object to be popped up.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HMENUI API dw_menu_new(ULONG id)
-{
-	return (HMENUI)CreatePopupMenu();
-}
-
-/*
- * Create a menubar on a window.
- * Parameters:
- *       location: Handle of a window frame to be attached to.
- */
-HMENUI API dw_menubar_new(HWND location)
-{
-	HMENUI tmp;
-
-	tmp = (HMENUI)CreateMenu();
-
-#ifndef WINNT_COMPAT
-	{
-		MENUINFO mi;
-
-		mi.cbSize = sizeof(MENUINFO);
-		mi.fMask = MIM_MENUDATA;
-		mi.dwMenuData = (ULONG_PTR)1;
-
-		SetMenuInfo((HMENU)tmp, &mi);
-	}
-#endif
-
-	dw_window_set_data(location, "_dw_menu", (void *)tmp);
-
-	SetMenu(location, (HMENU)tmp);
-	return location;
-}
-
-/*
- * Destroys a menu created with dw_menubar_new or dw_menu_new.
- * Parameters:
- *       menu: Handle of a menu.
- */
-void API dw_menu_destroy(HMENUI *menu)
-{
-	if(menu)
-	{
-		HMENU mymenu = (HMENU)*menu;
-
-		if(IsWindow((HWND)mymenu) && !IsMenu(mymenu))
-			mymenu = (HMENU)dw_window_get_data((HWND)mymenu, "_dw_menu");
-        if(IsMenu(mymenu))
-			DestroyMenu(mymenu);
-	}
-}
-
-/*
- * Adds a menuitem or submenu to an existing menu.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       title: The title text on the menu item to be added.
- *       id: An ID to be used for message passing.
- *       end: If TRUE memu is positioned at the end of the menu.
- *       check: If TRUE menu is "check"able.
- *       flags: Extended attributes to set on the menu.
- *       submenu: Handle to an existing menu to be a submenu or NULL.
- */
-HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
-{
-	MENUITEMINFO mii;
-	HMENU mymenu = (HMENU)menux;
-#ifndef WINNT_COMPAT
-	char buffer[15];
-#endif
-
-	if(IsWindow(menux) && !IsMenu(mymenu))
-		mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
-
-	mii.cbSize = sizeof(MENUITEMINFO);
-	mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE;
-
-	/* Convert from OS/2 style accellerators to Win32 style */
-	if(title)
-	{
-		char *tmp = title;
-
-		while(*tmp)
-		{
-			if(*tmp == '~')
-				*tmp = '&';
-			tmp++;
-		}
-	}
-
-	if(title && *title)
-		mii.fType = MFT_STRING;
-	else
-		mii.fType = MFT_SEPARATOR;
-
-	mii.wID = id;
-    if(IsMenu((HMENU)submenu))
-		mii.hSubMenu = (HMENU)submenu;
-	else
-		mii.hSubMenu = 0;
-	mii.dwTypeData = title;
-	mii.cch = strlen(title);
-
-	InsertMenuItem(mymenu, 65535, TRUE, &mii);
-
-#ifndef WINNT_COMPAT
-	sprintf(buffer, "_dw_id%d", id);
-	dw_window_set_data(DW_HWND_OBJECT, buffer, (void *)mymenu);
-
-	/* According to the docs this will only work on Win2k/98 and above */
-	if(submenu)
-	{
-		MENUINFO mi;
-
-		mi.cbSize = sizeof(MENUINFO);
-		mi.fMask = MIM_MENUDATA;
-		mi.dwMenuData = (ULONG_PTR)mymenu;
-
-		SetMenuInfo((HMENU)submenu, &mi);
-	}
-#endif
-
-	if(IsWindow(menux) && !IsMenu((HMENU)menux))
-		DrawMenuBar(menux);
-	return (HWND)id;
-}
-
-/*
- * Sets the state of a menu item check.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       id: Menuitem id.
- *       check: TRUE for checked FALSE for not checked.
- */
-void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check)
-{
-	MENUITEMINFO mii;
-	HMENU mymenu = (HMENU)menux;
-
-	if(IsWindow(menux) && !IsMenu(mymenu))
-		mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
-
-	mii.cbSize = sizeof(MENUITEMINFO);
-	mii.fMask = MIIM_STATE;
-	if(check)
-		mii.fState = MFS_CHECKED;
-	else
-		mii.fState = MFS_UNCHECKED;
-	SetMenuItemInfo(mymenu, id, FALSE, &mii);
-}
-
-/*
- * Pops up a context menu at given x and y coordinates.
- * Parameters:
- *       menu: The handle the the existing menu.
- *       parent: Handle to the window initiating the popup.
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
-{
-	if(menu)
-	{
-		HMENU mymenu = (HMENU)*menu;
-
-		if(IsWindow(*menu) && !IsMenu(mymenu))
-			mymenu = (HMENU)dw_window_get_data(*menu, "_dw_menu");
-
-		popup = parent;
-		TrackPopupMenu(mymenu, 0, x, y, 0, parent, NULL);
-		PostMessage(DW_HWND_OBJECT, WM_USER+5, (LPARAM)mymenu, 0);
-	}
-}
-
-
-/*
- * Create a container object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_container_new(ULONG id, int multi)
-{
-	HWND tmp = CreateWindow(WC_LISTVIEW,
-							"",
-							WS_VISIBLE | WS_CHILD |
-							(multi ? 0 : LVS_SINGLESEL) |
-							LVS_REPORT | LVS_SHOWSELALWAYS |
-							LVS_SHAREIMAGELISTS | WS_BORDER |
-							WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
-
-	if(!cinfo)
-	{
-		DestroyWindow(tmp);
-		return NULL;
-	}
-
-	cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
-	cinfo->cinfo.fore = cinfo->cinfo.back = -1;
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a tree object to be packed.
- * Parameters:
- *       id: An ID to be used for getting the resource from the
- *           resource file.
- */
-HWND API dw_tree_new(ULONG id)
-{
-	HWND tmp = CreateWindow(WC_TREEVIEW,
-							"",
-							WS_VISIBLE | WS_CHILD |
-							TVS_HASLINES | TVS_SHOWSELALWAYS |
-							TVS_HASBUTTONS | TVS_LINESATROOT |
-							WS_BORDER | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
-	TreeView_SetItemHeight(tmp, 16);
-
-	if(!cinfo)
-	{
-		DestroyWindow(tmp);
-		return NULL;
-	}
-
-	cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
-	cinfo->cinfo.fore = cinfo->cinfo.back = -1;
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Returns the current X and Y coordinates of the mouse pointer.
- * Parameters:
- *       x: Pointer to variable to store X coordinate.
- *       y: Pointer to variable to store Y coordinate.
- */
-void API dw_pointer_query_pos(long *x, long *y)
-{
-	POINT ptl;
-
-	GetCursorPos(&ptl);
-	if(x && y)
-	{
-		*x = ptl.x;
-		*y = ptl.y;
-	}
-}
-
-/*
- * Sets the X and Y coordinates of the mouse pointer.
- * Parameters:
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_pointer_set_pos(long x, long y)
-{
-	SetCursorPos(x, y);
-}
-
-/*
- * Create a new static text window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_text_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindow(STATICCLASSNAME,
-							text,
-							BS_TEXT | WS_VISIBLE |
-							WS_CHILD | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new status text window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_status_text_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindow(ObjectClassName,
-							text,
-							BS_TEXT | WS_VISIBLE |
-							WS_CHILD | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	dw_window_set_font(tmp, DefaultFont);
-	SubclassWindow(tmp, _statuswndproc);
-	return tmp;
-}
-
-/*
- * Create a new Multiline Editbox window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_mle_new(ULONG id)
-{
-    
-	HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-							  EDITCLASSNAME,
-							  "",
-							  WS_VISIBLE | WS_BORDER |
-							  WS_VSCROLL | ES_MULTILINE |
-							  ES_WANTRETURN | WS_CHILD |
-							  WS_CLIPCHILDREN,
-							  0,0,2000,1000,
-							  DW_HWND_OBJECT,
-							  (HMENU)id,
-							  DWInstance,
-							  NULL);
-	ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
-
-	if(!cinfo)
-	{
-		DestroyWindow(tmp);
-		return NULL;
-	}
-
-	cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
-	cinfo->cinfo.fore = cinfo->cinfo.back = -1;
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new Entryfield window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_entryfield_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-							  EDITCLASSNAME,
-							  text,
-							  ES_WANTRETURN | WS_CHILD |
-							  WS_BORDER | ES_AUTOHSCROLL |
-							  WS_VISIBLE | WS_CLIPCHILDREN,
-							  0,0,2000,1000,
-							  DW_HWND_OBJECT,
-							  (HMENU)id,
-							  DWInstance,
-							  NULL);
-	ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
-
-	cinfo->back = cinfo->fore = -1;
-
-	cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new Entryfield passwird window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the entryfield widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_entryfield_password_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-							  EDITCLASSNAME,
-							  text,
-							  ES_WANTRETURN | WS_CHILD |
-							  ES_PASSWORD | WS_BORDER | WS_VISIBLE |
-							  ES_AUTOHSCROLL | WS_CLIPCHILDREN,
-							  0,0,2000,1000,
-							  DW_HWND_OBJECT,
-							  (HMENU)id,
-							  DWInstance,
-							  NULL);
-	ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
-
-	cinfo->back = cinfo->fore = -1;
-
-	cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-BOOL CALLBACK _subclass_child(HWND handle, LPARAM lp)
-{
-	ColorInfo *cinfo = (ColorInfo *)lp;
-
-	if(cinfo)
-	{
-		cinfo->buddy = handle;
-		cinfo->pOldProc = (WNDPROC)SubclassWindow(handle, _colorwndproc);
-		SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
-	}
-	return FALSE;
-}
-
-/*
- * Create a new Combobox window (widget) to be packed.
- * Parameters:
- *       text: The default text to be in the combpbox widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_combobox_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindow(COMBOBOXCLASSNAME,
-							text,
-							WS_CHILD | CBS_DROPDOWN | WS_VSCROLL |
-							WS_CLIPCHILDREN | CBS_AUTOHSCROLL | WS_VISIBLE,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo));
-	ColorInfo *cinfo2 = (ColorInfo *)calloc(1, sizeof(ColorInfo));
-
-	if(!cinfo || !cinfo2)
-	{
-		if(cinfo)
-			free(cinfo);
-		if(cinfo2)
-			free(cinfo2);
-		DestroyWindow(tmp);
-		return NULL;
-	}
-
-	cinfo2->fore = cinfo->fore = -1;
-	cinfo2->back = cinfo->back = -1;
-	cinfo2->combo = cinfo->combo = tmp;
-	EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo2);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	SetWindowText(tmp, text);
-	return tmp;
-}
-
-/*
- * Create a new button window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_button_new(char *text, ULONG id)
-{
-	BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-
-	HWND tmp = CreateWindow(BUTTONCLASSNAME,
-							text,
-							WS_CHILD | BS_PUSHBUTTON |
-							WS_VISIBLE | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-
-	bubble->id = id;
-	bubble->bubbletext[0] = '\0';
-	bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new bitmap button window (widget) to be packed.
- * Parameters:
- *       text: Bubble help text to be displayed.
- *       id: An ID of a bitmap in the resource file.
- */
-HWND API dw_bitmapbutton_new(char *text, ULONG id)
-{
-	HWND tmp;
-	BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-	HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
-
-	tmp = CreateWindow(BUTTONCLASSNAME,
-					   "",
-					   WS_CHILD | BS_PUSHBUTTON |
-					   BS_BITMAP | WS_CLIPCHILDREN |
-					   WS_VISIBLE,
-					   0,0,2000,1000,
-					   DW_HWND_OBJECT,
-					   (HMENU)id,
-					   DWInstance,
-					   NULL);
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
-
-	SendMessage(tmp, BM_SETIMAGE,
-				(WPARAM) IMAGE_BITMAP,
-				(LPARAM) hbitmap);
-	return tmp;
-}
-
-/*
- * Create a new bitmap button window (widget) to be packed from a file.
- * Parameters:
- *       text: Bubble help text to be displayed.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (BMP on OS/2 or Windows, XPM on Unix)
- */
-HWND dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
-{
-	HWND tmp;
-	BubbleButton *bubble;
-	HBITMAP hbitmap = 0;
-	char *file = malloc(strlen(filename) + 5);
-
-	if(!file || !(bubble = calloc(1, sizeof(BubbleButton))))
-	{
-		if(file)
-			free(file);
-		return 0;
-	}
-
-	tmp = CreateWindow(BUTTONCLASSNAME,
-					   "",
-					   WS_CHILD | BS_PUSHBUTTON |
-					   BS_BITMAP | WS_CLIPCHILDREN |
-					   WS_VISIBLE,
-					   0,0,2000,1000,
-					   DW_HWND_OBJECT,
-					   (HMENU)id,
-					   DWInstance,
-					   NULL);
-
-	bubble->id = id;
-	strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1);
-	bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0';
-	bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) == 0)
-		hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
-	else
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".bmp");
-		if(access(file, 04) == 0)
-			hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
-	}
-
-
-	if(hbitmap)
-		SendMessage(tmp, BM_SETIMAGE,
-					(WPARAM) IMAGE_BITMAP,
-					(LPARAM) hbitmap);
-	free(file);
-	return tmp;
-}
-
-/*
- * Create a new spinbutton window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_spinbutton_new(char *text, ULONG id)
-{
-	ULONG *data = malloc(sizeof(ULONG));
-	HWND buddy = CreateWindowEx(WS_EX_CLIENTEDGE,
-								EDITCLASSNAME,
-								text,
-								WS_CHILD | WS_BORDER | WS_VISIBLE |
-								ES_NUMBER | WS_CLIPCHILDREN,
-								0,0,2000,1000,
-								DW_HWND_OBJECT,
-								NULL,
-								DWInstance,
-								NULL);
-	HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-							  UPDOWN_CLASS,
-							  NULL,
-							  WS_CHILD | UDS_ALIGNRIGHT | WS_BORDER |
-							  UDS_ARROWKEYS | UDS_SETBUDDYINT |
-							  UDS_WRAP | UDS_NOTHOUSANDS | WS_VISIBLE,
-							  0,0,2000,1000,
-							  DW_HWND_OBJECT,
-							  (HMENU)id,
-							  DWInstance,
-							  NULL);
-	ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
-
-	SendMessage(tmp, UDM_SETBUDDY, (WPARAM)buddy, 0);
-	cinfo->back = cinfo->fore = -1;
-	cinfo->buddy = tmp;
-
-	cinfo->pOldProc = SubclassWindow(buddy, _colorwndproc);
-	SetWindowLongPtr(buddy, GWLP_USERDATA, (LONG_PTR)cinfo);
-
-	cinfo = calloc(1, sizeof(ColorInfo));
-	cinfo->buddy = buddy;
-	cinfo->pOldProc = SubclassWindow(tmp, _spinnerwndproc);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(buddy, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new radiobutton window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_radiobutton_new(char *text, ULONG id)
-{
-	HWND tmp = CreateWindow(BUTTONCLASSNAME,
-							text,
-							WS_CHILD | BS_AUTORADIOBUTTON |
-							WS_CLIPCHILDREN | WS_VISIBLE,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-	bubble->id = id;
-	bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-	bubble->cinfo.fore = -1;
-	bubble->cinfo.back = -1;
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-
-/*
- * Create a new slider window (widget) to be packed.
- * Parameters:
- *       vertical: TRUE or FALSE if slider is vertical.
- *       increments: Number of increments available.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_slider_new(int vertical, int increments, ULONG id)
-{
-	HWND tmp = CreateWindow(TRACKBAR_CLASS,
-							"",
-							WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
-							(vertical ? TBS_VERT : TBS_HORZ),
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
-
-	cinfo->back = cinfo->fore = -1;
-
-	cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(0, increments-1));
-	return tmp;
-}
-
-/*
- * Create a new scrollbar window (widget) to be packed.
- * Parameters:
- *       vertical: TRUE or FALSE if scrollbar is vertical.
- *       increments: Number of increments available.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_scrollbar_new(int vertical, int increments, ULONG id)
-{
-	HWND tmp = CreateWindow(SCROLLBARCLASSNAME,
-							"",
-							WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
-							(vertical ? SBS_VERT : SBS_HORZ),
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
-
-	cinfo->back = cinfo->fore = -1;
-
-	cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_data(tmp, "_dw_scrollbar", (void *)1);
-	return tmp;
-}
-
-/*
- * Create a new percent bar window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_percent_new(ULONG id)
-{
-	return CreateWindow(PROGRESS_CLASS,
-						"",
-						WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-						0,0,2000,1000,
-						DW_HWND_OBJECT,
-						(HMENU)id,
-						DWInstance,
-						NULL);
-}
-
-/*
- * Create a new checkbox window (widget) to be packed.
- * Parameters:
- *       text: The text to be display by the static text widget.
- *       id: An ID to be used with dw_window_from_id() or 0L.
- */
-HWND API dw_checkbox_new(char *text, ULONG id)
-{
-	BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
-	HWND tmp = CreateWindow(BUTTONCLASSNAME,
-							text,
-							WS_CHILD | BS_AUTOCHECKBOX |
-							BS_TEXT | WS_CLIPCHILDREN | WS_VISIBLE,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	bubble->id = id;
-	bubble->checkbox = 1;
-	bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
-	bubble->cinfo.fore = -1;
-	bubble->cinfo.back = -1;
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Create a new listbox window (widget) to be packed.
- * Parameters:
- *       id: An ID to be used with dw_window_from_id() or 0L.
- *       multi: Multiple select TRUE or FALSE.
- */
-HWND API dw_listbox_new(ULONG id, int multi)
-{
-	HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
-							  LISTBOXCLASSNAME,
-							  "",
-							  WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
-							  WS_CHILD | LBS_HASSTRINGS |
-							  LBS_NOTIFY | WS_BORDER  | WS_CLIPCHILDREN |
-							  WS_VSCROLL | (multi ? LBS_MULTIPLESEL : 0) ,
-							  0,0,2000,1000,
-							  DW_HWND_OBJECT,
-							  (HMENU)id,
-							  DWInstance,
-							  NULL);
-	ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
-
-	if(!cinfo)
-	{
-		DestroyWindow(tmp);
-		return NULL;
-	}
-
-	cinfo->cinfo.fore = -1;
-	cinfo->cinfo.back = -1;
-	cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
-	dw_window_set_font(tmp, DefaultFont);
-	return tmp;
-}
-
-/*
- * Sets the icon used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- *       id: An ID to be used to specify the icon.
- */
-void API dw_window_set_icon(HWND handle, ULONG id)
-{
-	HICON hicon = id < 65536 ? LoadIcon(DWInstance, MAKEINTRESOURCE(id)) : (HICON)id;
-
-	SendMessage(handle, WM_SETICON,
-				(WPARAM) IMAGE_ICON,
-				(LPARAM) hicon);
-}
-
-/*
- * Sets the bitmap used for a given static window.
- * Parameters:
- *       handle: Handle to the window.
- *       id: An ID to be used to specify the icon,
- *           (pass 0 if you use the filename param)
- *       filename: a path to a file (Bitmap on OS/2 or
- *                 Windows and a pixmap on Unix, pass
- *                 NULL if you use the id param)
- */
-void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
-{
-	HBITMAP hbitmap;
-	HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
-
-	if(id)
-		hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
-	else if(filename)
-	{
-		char *file = malloc(strlen(filename) + 5);
-
-		if (!file)
-			return;
-
-		strcpy(file, filename);
-
-		/* check if we can read from this file (it exists and read permission) */
-		if(access(file, 04) != 0)
-		{
-			/* Try with .bmp extention */
-			strcat(file, ".bmp");
-			if(access(file, 04) != 0)
-			{
-				free(file);
-				return;
-			}
-		}
-
-		hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
-		free(file);
-	}
-	else
-		return;
-
-	SendMessage(handle, STM_SETIMAGE,
-				(WPARAM) IMAGE_BITMAP,
-				(LPARAM) hbitmap);
-
-	if(oldbitmap)
-		DeleteObject(oldbitmap);
-}
-
-/*
- * Sets the text used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- *       text: The text associsated with a given window.
- */
-void API dw_window_set_text(HWND handle, char *text)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	SetWindowText(handle, text);
-
-	/* Combobox */
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0));
-}
-
-/*
- * Gets the text used for a given window.
- * Parameters:
- *       handle: Handle to the window.
- * Returns:
- *       text: The text associsated with a given window.
- */
-char * API dw_window_get_text(HWND handle)
-{
-	int len = GetWindowTextLength(handle);
-	char *tempbuf = calloc(1, len + 2);
-
-	GetWindowText(handle, tempbuf, len + 1);
-
-	return tempbuf;
-}
-
-/*
- * Disables given window (widget).
- * Parameters:
- *       handle: Handle to the window.
- */
-void API dw_window_disable(HWND handle)
-{
-	EnableWindow(handle, FALSE);
-}
-
-/*
- * Enables given window (widget).
- * Parameters:
- *       handle: Handle to the window.
- */
-void API dw_window_enable(HWND handle)
-{
-	EnableWindow(handle, TRUE);
-}
-
-static HWND _dw_wfid_hwnd = NULL;
-
-BOOL CALLBACK _wfid(HWND handle, LPARAM lParam)
-{
-	if(GetWindowLong(handle, GWL_ID) == lParam)
-	{
-		_dw_wfid_hwnd = handle;
-		return FALSE;
-	}
-	return TRUE;
-}
-
-/*
- * Gets the child window handle with specified ID.
- * Parameters:
- *       handle: Handle to the parent window.
- *       id: Integer ID of the child.
- */
-HWND API dw_window_from_id(HWND handle, int id)
-{
-	_dw_wfid_hwnd = NULL;
-	EnumChildWindows(handle, _wfid, (LPARAM)id);
-    return _dw_wfid_hwnd;
-}
-
-/*
- * Pack windows (widgets) into a box from the start (or top).
- * Parameters:
- *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
- *       width: Width in pixels of the item or -1 to be self determined.
- *       height: Height in pixels of the item or -1 to be self determined.
- *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
- *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
- *       pad: Number of pixels of padding around the item.
- */
-void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
-{
-	Box *thisbox;
-
-		/*
-		 * If you try and pack an item into itself VERY bad things can happen; like at least an
-		 * infinite loop on GTK! Lets be safe!
-		 */
-	if(box == item)
-	{
-		dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!",box,item);
-		return;
-	}
-
-	thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z] = thisitem[z];
-		}
-
-		GetClassName(item, tmpbuf, 99);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
-			tmpitem[thisbox->count].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox("dw_box_pack_start()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[thisbox->count].type = TYPEITEM;
-		}
-
-		tmpitem[thisbox->count].hwnd = item;
-		tmpitem[thisbox->count].origwidth = tmpitem[thisbox->count].width = width;
-		tmpitem[thisbox->count].origheight = tmpitem[thisbox->count].height = height;
-		tmpitem[thisbox->count].pad = pad;
-		if(hsize)
-			tmpitem[thisbox->count].hsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[thisbox->count].vsize = SIZEEXPAND;
-		else
-			tmpitem[thisbox->count].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-		SetParent(item, box);
-		if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
-		{
-			ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(item, GWLP_USERDATA);
-
-			if(cinfo)
-			{
-				SetParent(cinfo->buddy, box);
-				ShowWindow(cinfo->buddy, SW_SHOW);
-				SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0);
-			}
-		}
-	}
-}
-
-/*
- * Sets the size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          width: New width in pixels.
- *          height: New height in pixels.
- */
-void API dw_window_set_usize(HWND handle, ULONG width, ULONG height)
-{
-	SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
-}
-
-/*
- * Returns the width of the screen.
- */
-int API dw_screen_width(void)
-{
-	return GetSystemMetrics(SM_CXSCREEN);
-}
-
-/*
- * Returns the height of the screen.
- */
-int API dw_screen_height(void)
-{
-	return GetSystemMetrics(SM_CYSCREEN);
-}
-
-/* This should return the current color depth */
-unsigned long API dw_color_depth(void)
-{
-	int bpp;
-	HDC hdc = GetDC(HWND_DESKTOP);
-    
-	bpp = GetDeviceCaps(hdc, BITSPIXEL);
-
-	ReleaseDC(HWND_DESKTOP, hdc);
-
-	return bpp;
-}
-
-
-/*
- * Sets the position of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- */
-void API dw_window_set_pos(HWND handle, ULONG x, ULONG y)
-{
-	SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
-}
-
-/*
- * Sets the position and size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- *          width: Width of the widget.
- *          height: Height of the widget.
- */
-void API dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height)
-{
-	SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
-}
-
-/*
- * Gets the position and size of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          x: X location from the bottom left.
- *          y: Y location from the bottom left.
- *          width: Width of the widget.
- *          height: Height of the widget.
- */
-void API dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height)
-{
-	WINDOWPLACEMENT wp;
-
-	wp.length = sizeof(WINDOWPLACEMENT);
-
-	GetWindowPlacement(handle, &wp);
-	if( wp.showCmd == SW_SHOWMAXIMIZED)
-	{
-		if(x)
-			*x=0;
-		if(y)
-			*y=0;
-		if(width)
-			*width=dw_screen_width();
-		if(height)
-			*height=dw_screen_height();
-	}
-else
-	{
-		if(x)
-			*x = wp.rcNormalPosition.left;
-		if(y)
-			*y = wp.rcNormalPosition.top;
-		if(width)
-			*width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
-		if(height)
-			*height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
-	}
-}
-
-/*
- * Sets the style of a given window (widget).
- * Parameters:
- *          handle: Window (widget) handle.
- *          width: New width in pixels.
- *          height: New height in pixels.
- */
-void API dw_window_set_style(HWND handle, ULONG style, ULONG mask)
-{
-	ULONG tmp, currentstyle = GetWindowLong(handle, GWL_STYLE);
-	ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	tmp = currentstyle | mask;
-	tmp ^= mask;
-	tmp |= style;
-
-
-	/* We are using SS_NOPREFIX as a VCENTER flag */
-	if(tmp & SS_NOPREFIX)
-	{
-
-		if(cinfo)
-			cinfo->vcenter = 1;
-		else
-		{
-			cinfo = calloc(1, sizeof(ColorInfo));
-			cinfo->fore = cinfo->back = -1;
-			cinfo->vcenter = 1;
-
-			cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
-			SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
-		}
-	}
-	else if(cinfo)
-		cinfo->vcenter = 0;
-
-	SetWindowLong(handle, GWL_STYLE, tmp);
-}
-
-/* Finds the physical ID from the reference ID */
-int _findnotebookid(NotebookPage **array, int pageid)
-{
-	int z;
-
-	for(z=0;z<256;z++)
-	{
-		if(array[z] && array[z]->realid == pageid)
-			return z;
-	}
-	return -1;
-}
-
-/*
- * Adds a new page to specified notebook.
- * Parameters:
- *          handle: Window (widget) handle.
- *          flags: Any additional page creation flags.
- *          front: If TRUE page is added at the beginning.
- */
-unsigned long API dw_notebook_page_new(HWND handle, ULONG flags, int front)
-{
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-
-	if(array)
-	{
-		int z, refid = -1;
-
-		for(z=0;z<256;z++)
-		{
-			if(_findnotebookid(array, z) == -1)
-			{
-				refid = z;
-				break;
-			}
-		}
-
-		if(refid == -1)
-			return -1;
-
-		for(z=0;z<256;z++)
-		{
-			if(!array[z])
-			{
-				int oldpage = TabCtrl_GetCurSel(handle);
-
-				array[z] = calloc(1, sizeof(NotebookPage));
-				array[z]->realid = refid;
-				array[z]->item.mask = TCIF_TEXT;
-				array[z]->item.iImage = -1;
-				array[z]->item.pszText = "";
-				TabCtrl_InsertItem(handle, z, &(array[z]->item));
-
-				if(oldpage > -1 && array[oldpage])
-					SetParent(array[oldpage]->hwnd, DW_HWND_OBJECT);
-
-				TabCtrl_SetCurSel(handle, z);
-				return refid;
-			}
-		}
-	}
-	return -1;
-}
-
-/*
- * Sets the text on the specified notebook tab.
- * Parameters:
- *          handle: Notebook handle.
- *          pageid: Page ID of the tab to set.
- *          text: Pointer to the text to set.
- */
-void API dw_notebook_page_set_text(HWND handle, ULONG pageidx, char *text)
-{
-
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-	int pageid;
-
-	if(!array)
-		return;
-
-	pageid = _findnotebookid(array, pageidx);
-
-	if(pageid > -1 && array[pageid])
-	{
-		array[pageid]->item.mask = TCIF_TEXT;
-		array[pageid]->item.pszText = text;
-		TabCtrl_SetItem(handle, pageid, &(array[pageid]->item));
-		_resize_notebook_page(handle, pageid);
-	}
-}
-
-/*
- * Sets the text on the specified notebook tab status area.
- * Parameters:
- *          handle: Notebook handle.
- *          pageid: Page ID of the tab to set.
- *          text: Pointer to the text to set.
- */
-void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text)
-{
-}
-
-/*
- * Packs the specified box into the notebook page.
- * Parameters:
- *          handle: Handle to the notebook to be packed.
- *          pageid: Page ID in the notebook which is being packed.
- *          page: Box handle to be packed.
- */
-void API dw_notebook_pack(HWND handle, ULONG pageidx, HWND page)
-{
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-	int pageid;
-
-	if(!array)
-		return;
-
-	pageid = _findnotebookid(array, pageidx);
-
-	if(pageid > -1 && array[pageid])
-	{
-		HWND tmpbox = dw_box_new(DW_VERT, 0);
-
-		dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
-		SubclassWindow(tmpbox, _wndproc);
-		if(array[pageid]->hwnd)
-			dw_window_destroy(array[pageid]->hwnd);
-		array[pageid]->hwnd = tmpbox;
-		if(pageidx == dw_notebook_page_query(handle))
-		{
-			SetParent(tmpbox, handle);
-			_resize_notebook_page(handle, pageid);
-		}
-	}
-}
-
-/*
- * Remove a page from a notebook.
- * Parameters:
- *          handle: Handle to the notebook widget.
- *          pageid: ID of the page to be destroyed.
- */
-void API dw_notebook_page_destroy(HWND handle, unsigned int pageidx)
-{
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-	int newid = -1, z, pageid;
-
-	if(!array)
-		return;
-
-	pageid = _findnotebookid(array, pageidx);
-
-	if(pageid < 0)
-		return;
-
-	if(array[pageid])
-	{
-		SetParent(array[pageid]->hwnd, DW_HWND_OBJECT);
-		free(array[pageid]);
-		array[pageid] = NULL;
-	}
-
-	TabCtrl_DeleteItem(handle, pageid);
-
-	/* Shift the pages over 1 */
-	for(z=pageid;z<255;z++)
-		array[z] = array[z+1];
-	array[255] = NULL;
-
-	for(z=0;z<256;z++)
-	{
-		if(array[z])
-		{
-			newid = z;
-			break;
-		}
-	}
-	if(newid > -1)
-	{
-		SetParent(array[newid]->hwnd, handle);
-		_resize_notebook_page(handle, newid);
-		dw_notebook_page_set(handle, array[newid]->realid);
-	}
-}
-
-/*
- * Queries the currently visible page ID.
- * Parameters:
- *          handle: Handle to the notebook widget.
- */
-unsigned long API dw_notebook_page_query(HWND handle)
-{
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-	int physid = TabCtrl_GetCurSel(handle);
-
-	if(physid > -1 && physid < 256 && array && array[physid])
-		return array[physid]->realid;
-	return -1;
-}
-
-/*
- * Sets the currently visible page ID.
- * Parameters:
- *          handle: Handle to the notebook widget.
- *          pageid: ID of the page to be made visible.
- */
-void API dw_notebook_page_set(HWND handle, unsigned int pageidx)
-{
-	NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
-	int pageid;
-
-	if(!array)
-		return;
-
-	pageid = _findnotebookid(array, pageidx);
-
-	if(pageid > -1 && pageid < 256)
-	{
-		int oldpage = TabCtrl_GetCurSel(handle);
-
-		if(oldpage > -1 && array && array[oldpage])
-			SetParent(array[oldpage]->hwnd, DW_HWND_OBJECT);
-
-		TabCtrl_SetCurSel(handle, pageid);
-
-		SetParent(array[pageid]->hwnd, handle);
-		_resize_notebook_page(handle, pageid);
-	}
-}
-
-/*
- * Appends the specified text to the listbox's (or combobox) entry list.
- * Parameters:
- *          handle: Handle to the listbox to be appended to.
- *          text: Text to append into listbox.
- */
-void API dw_listbox_append(HWND handle, char *text)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		SendMessage(handle,
-					CB_ADDSTRING,
-					0, (LPARAM)text);
-	else
-		SendMessage(handle,
-					LB_ADDSTRING,
-					0, (LPARAM)text);
-}
-
-/*
- * Clears the listbox's (or combobox) list of all entries.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- */
-void API dw_listbox_clear(HWND handle)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-	{
-		char *buf = dw_window_get_text(handle);
-
-		SendMessage(handle,
-					CB_RESETCONTENT, 0L, 0L);
-
-		if(buf)
-		{
-			dw_window_set_text(handle, buf);
-			free(buf);
-		}
-	}
-	else
-		SendMessage(handle,
-					LB_RESETCONTENT, 0L, 0L);
-}
-
-/*
- * Sets the text of a given listbox entry.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          index: Index into the list to be queried.
- *          buffer: Buffer where text will be copied.
- */
-void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-	{
-		SendMessage(handle,	CB_DELETESTRING, (WPARAM)index, 0);
-		SendMessage(handle, CB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer);
-	}
-	else
-	{
-		unsigned int sel = (unsigned int)SendMessage(handle, LB_GETCURSEL, 0, 0);
-		SendMessage(handle,	LB_DELETESTRING, (WPARAM)index, 0);
-		SendMessage(handle, LB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer);
-		SendMessage(handle, LB_SETCURSEL, (WPARAM)sel, 0);
-		SendMessage(handle, LB_SETSEL, (WPARAM)TRUE, (LPARAM)sel);
-	}
-}
-
-/*
- * Copies the given index item's text into buffer.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          index: Index into the list to be queried.
- *          buffer: Buffer where text will be copied.
- *          length: Length of the buffer (including NULL).
- */
-void API dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
-{
-	char tmpbuf[100];
-	int len;
-
-	if(!buffer || !length)
-		return;
-
-	buffer[0] = 0;
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-	{
-		len = (int)SendMessage(handle, CB_GETLBTEXTLEN, (WPARAM)index, 0);
-
-		if(len < length && len != CB_ERR)
-			SendMessage(handle,
-						CB_GETLBTEXT, (WPARAM)index, (LPARAM)buffer);
-	}
-	else
-	{
-		len = (int)SendMessage(handle, LB_GETTEXTLEN, (WPARAM)index, 0);
-
-		if(len < length && len != LB_ERR)
-			SendMessage(handle,
-						LB_GETTEXT, (WPARAM)index, (LPARAM)buffer);
-	}
-}
-
-/*
- * Returns the index to the item in the list currently selected.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- */
-unsigned int API dw_listbox_selected(HWND handle)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		return (unsigned int)SendMessage(handle,
-										 CB_GETCURSEL,
-										 0, 0);
-
-	return (unsigned int)SendMessage(handle,
-									 LB_GETCURSEL,
-									 0, 0);
-}
-
-/*
- * Returns the index to the current selected item or -1 when done.
- * Parameters:
- *          handle: Handle to the listbox to be queried.
- *          where: Either the previous return or -1 to restart.
- */
-int API dw_listbox_selected_multi(HWND handle, int where)
-{
-	int *array, count, z;
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	/* This doesn't work on comboboxes */
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		return -1;
-
-	count = (int)SendMessage(handle, LB_GETSELCOUNT, 0, 0);
-	if(count > 0)
-	{
-		array = malloc(sizeof(int)*count);
-		SendMessage(handle, LB_GETSELITEMS, (WPARAM)count, (LPARAM)array);
-
-		if(where == -1)
-		{
-			int ret = array[0];
-			free(array);
-			return ret;
-		}
-		for(z=0;z<count;z++)
-		{
-			if(array[z] == where && (z+1) < count)
-			{
-				int ret = array[z+1];
-				free(array);
-				return ret;
-			}
-		}
-		free(array);
-	}
-	return -1;
-}
-
-/*
- * Sets the selection state of a given index.
- * Parameters:
- *          handle: Handle to the listbox to be set.
- *          index: Item index.
- *          state: TRUE if selected FALSE if unselected.
- */
-void API dw_listbox_select(HWND handle, int index, int state)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		SendMessage(handle, CB_SETCURSEL, (WPARAM)index, 0);
-	else
-	{
-		SendMessage(handle, LB_SETCURSEL, (WPARAM)index, 0);
-		SendMessage(handle, LB_SETSEL, (WPARAM)state, (LPARAM)index);
-	}
-	_wndproc(handle, WM_COMMAND, (WPARAM)(LBN_SELCHANGE << 16), (LPARAM)handle);
-}
-
-/*
- * Deletes the item with given index from the list.
- * Parameters:
- *          handle: Handle to the listbox to be set.
- *          index: Item index.
- */
-void API dw_listbox_delete(HWND handle, int index)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		SendMessage(handle, CB_DELETESTRING, (WPARAM)index, 0);
-	else
-		SendMessage(handle, LB_DELETESTRING, (WPARAM)index, 0);
-}
-
-/*
- * Returns the listbox's item count.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- */
-int API dw_listbox_count(HWND handle)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		return (int)SendMessage(handle,
-								CB_GETCOUNT,0L, 0L);
-
-	return (int)SendMessage(handle,
-							LB_GETCOUNT,0L, 0L);
-}
-
-/*
- * Sets the topmost item in the viewport.
- * Parameters:
- *          handle: Handle to the listbox to be cleared.
- *          top: Index to the top item.
- */
-void API dw_listbox_set_top(HWND handle, int top)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	/* This doesn't work on comboboxes */
-	if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
-		return;
-
-	SendMessage(handle, LB_SETTOPINDEX, (WPARAM)top, 0);
-}
-
-/*
- * Adds text to an MLE box and returns the current point.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          buffer: Text buffer to be imported.
- *          startpoint: Point to start entering text.
- */
-unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
-{
-	int textlen, len = GetWindowTextLength(handle);
-	char *tmpbuf;
-
-	if((textlen = strlen(buffer)) < 1)
-		return startpoint;
-
-	startpoint++;
-	tmpbuf = calloc(1, len + textlen + startpoint + 2);
-
-	if(startpoint < 0)
-		startpoint = 0;
-
-	if(len)
-	{
-		char *dest, *start;
-		int copylen = len - startpoint;
-
-		GetWindowText(handle, tmpbuf, len+1);
-
-		dest = &tmpbuf[startpoint+textlen-1];
-		start = &tmpbuf[startpoint];
-
-		if(copylen > 0)
-			memcpy(dest, start, copylen);
-	}
-	memcpy(&tmpbuf[startpoint], buffer, textlen);
-
-	SetWindowText(handle, tmpbuf);
-
-	free(tmpbuf);
-	return (startpoint + textlen - 1);
-}
-
-/*
- * Grabs text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          buffer: Text buffer to be exported.
- *          startpoint: Point to start grabbing text.
- *          length: Amount of text to be grabbed.
- */
-void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
-{
-	int max, len = GetWindowTextLength(handle);
-	char *tmpbuf = calloc(1, len+2);
-
-	if(len)
-		GetWindowText(handle, tmpbuf, len+1);
-
-	buffer[0] = 0;
-
-	if(startpoint < len)
-	{
-		max = MIN(length, len - startpoint);
-
-		memcpy(buffer, &tmpbuf[startpoint], max);
-	}
-
-	free(tmpbuf);
-}
-
-/*
- * Obtains information about an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be queried.
- *          bytes: A pointer to a variable to return the total bytes.
- *          lines: A pointer to a variable to return the number of lines.
- */
-void API dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines)
-{
-	if(bytes)
-		*bytes = GetWindowTextLength(handle);
-	if(lines)
-		*lines = (unsigned long)SendMessage(handle, EM_GETLINECOUNT, 0, 0);
-}
-
-/*
- * Deletes text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be deleted from.
- *          startpoint: Point to start deleting text.
- *          length: Amount of text to be deleted.
- */
-void API dw_mle_delete(HWND handle, int startpoint, int length)
-{
-	int len = GetWindowTextLength(handle);
-	char *tmpbuf = calloc(1, len+2);
-
-	GetWindowText(handle, tmpbuf, len+1);
-
-	if(startpoint + length < len)
-	{
-		strcpy(&tmpbuf[startpoint], &tmpbuf[startpoint+length]);
-
-		SetWindowText(handle, tmpbuf);
-	}
-
-	free(tmpbuf);
-}
-
-/*
- * Clears all text from an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be cleared.
- */
-void API dw_mle_clear(HWND handle)
-{
-	SetWindowText(handle, "");
-}
-
-/*
- * Sets the visible line of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE.
- *          line: Line to be visible.
- */
-void API dw_mle_set_visible(HWND handle, int line)
-{
-	int point = (int)SendMessage(handle, EM_LINEINDEX, (WPARAM)line, 0);
-	dw_mle_set(handle, point);
-}
-
-/*
- * Sets the editablity of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE.
- *          state: TRUE if it can be edited, FALSE for readonly.
- */
-void API dw_mle_set_editable(HWND handle, int state)
-{
-	SendMessage(handle, EM_SETREADONLY, (WPARAM)(state ? FALSE : TRUE), 0);
-}
-
-/*
- * Sets the word wrap state of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE.
- *          state: TRUE if it wraps, FALSE if it doesn't.
- */
-void API dw_mle_set_word_wrap(HWND handle, int state)
-{
-	/* If ES_AUTOHSCROLL is not set and there is not
-	 * horizontal scrollbar it word wraps.
-	 */
-	if(state)
-		dw_window_set_style(handle, 0, ES_AUTOHSCROLL);
-	else
-		dw_window_set_style(handle, ES_AUTOHSCROLL, ES_AUTOHSCROLL);
-}
-
-/*
- * Sets the current cursor position of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be positioned.
- *          point: Point to position cursor.
- */
-void API dw_mle_set(HWND handle, int point)
-{
-	SendMessage(handle, EM_SETSEL, 0, MAKELONG(point,point));
-	SendMessage(handle, EM_SCROLLCARET, 0, 0);
-}
-
-/*
- * Finds text in an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to be cleared.
- *          text: Text to search for.
- *          point: Start point of search.
- *          flags: Search specific flags.
- */
-int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
-{
-	int len = GetWindowTextLength(handle);
-	char *tmpbuf = calloc(1, len+2);
-	int z, textlen, retval = 0;
-
-	GetWindowText(handle, tmpbuf, len+1);
-
-	textlen = strlen(text);
-
-	if(flags & DW_MLE_CASESENSITIVE)
-	{
-		for(z=point;z<(len-textlen) && !retval;z++)
-		{
-			if(strncmp(&tmpbuf[z], text, textlen) == 0)
-				retval = z + textlen;
-		}
-	}
-	else
-	{
-		for(z=point;z<(len-textlen) && !retval;z++)
-		{
-			if(strnicmp(&tmpbuf[z], text, textlen) == 0)
-				retval = z + textlen;
-		}
-	}
-
-	if(retval)
-	{
-		SendMessage(handle, EM_SETSEL, (WPARAM)retval - textlen, (LPARAM)retval);
-		SendMessage(handle, EM_SCROLLCARET, 0, 0);
-	}
-
-	free(tmpbuf);
-
-	return retval;
-}
-
-/*
- * Stops redrawing of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to freeze.
- */
-void API dw_mle_freeze(HWND handle)
-{
-}
-
-/*
- * Resumes redrawing of an MLE box.
- * Parameters:
- *          handle: Handle to the MLE to thaw.
- */
-void API dw_mle_thaw(HWND handle)
-{
-}
-
-/*
- * Returns the range of the percent bar.
- * Parameters:
- *          handle: Handle to the percent bar to be queried.
- */
-unsigned int API dw_percent_query_range(HWND handle)
-{
-	return (unsigned int)SendMessage(handle, PBM_GETRANGE, (WPARAM)FALSE, 0);
-}
-
-/*
- * Sets the percent bar position.
- * Parameters:
- *          handle: Handle to the percent bar to be set.
- *          position: Position of the percent bar withing the range.
- */
-void API dw_percent_set_pos(HWND handle, unsigned int position)
-{
-	SendMessage(handle, PBM_SETPOS, (WPARAM)position, 0);
-}
-
-/*
- * Returns the position of the slider.
- * Parameters:
- *          handle: Handle to the slider to be queried.
- */
-unsigned int API dw_slider_query_pos(HWND handle)
-{
-	int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
-	ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
-
-	if(currentstyle & TBS_VERT)
-		return max - (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
-	return (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
-}
-
-/*
- * Sets the slider position.
- * Parameters:
- *          handle: Handle to the slider to be set.
- *          position: Position of the slider withing the range.
- */
-void API dw_slider_set_pos(HWND handle, unsigned int position)
-{
-	int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
-	ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
-
-	if(currentstyle & TBS_VERT)
-		SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)max - position);
-	else
-		SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)position);
-}
-
-/*
- * Returns the position of the scrollbar.
- * Parameters:
- *          handle: Handle to the scrollbar to be queried.
- */
-unsigned int API dw_scrollbar_query_pos(HWND handle)
-{
-	return (unsigned int)SendMessage(handle, SBM_GETPOS, 0, 0);
-}
-
-/*
- * Sets the scrollbar position.
- * Parameters:
- *          handle: Handle to the scrollbar to be set.
- *          position: Position of the scrollbar withing the range.
- */
-void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
-{
-	dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
-	SendMessage(handle, SBM_SETPOS, (WPARAM)position, (LPARAM)TRUE);
-}
-
-/*
- * Sets the scrollbar range.
- * Parameters:
- *          handle: Handle to the scrollbar to be set.
- *          range: Maximum range value.
- *          visible: Visible area relative to the range.
- */
-void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
-{
-	SCROLLINFO si;
-
-	si.cbSize = sizeof(SCROLLINFO);
-	si.fMask = SIF_RANGE | SIF_PAGE;
-	si.nMin = 0;
-	si.nMax = range - 1;
-	si.nPage = visible;
-	SendMessage(handle, SBM_SETSCROLLINFO, (WPARAM)TRUE, (LPARAM)&si);
-}
-
-/*
- * Sets the spinbutton value.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          position: Current value of the spinbutton.
- */
-void API dw_spinbutton_set_pos(HWND handle, long position)
-{
-	char tmpbuf[100];
-	ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	sprintf(tmpbuf, "%d", position);
-
-	if(cinfo && cinfo->buddy)
-		SetWindowText(cinfo->buddy, tmpbuf);
-
-	if(IS_IE5PLUS)
-		SendMessage(handle, UDM_SETPOS32, 0, (LPARAM)position);
-	else
-		SendMessage(handle, UDM_SETPOS, 0, (LPARAM)MAKELONG((short)position, 0));
-}
-
-/*
- * Sets the spinbutton limits.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          position: Current value of the spinbutton.
- *          position: Current value of the spinbutton.
- */
-void API dw_spinbutton_set_limits(HWND handle, long upper, long lower)
-{
-	if(IS_IE5PLUS)
-		SendMessage(handle, UDM_SETRANGE32, (WPARAM)lower,(LPARAM)upper);
-	else
-		SendMessage(handle, UDM_SETRANGE32, (WPARAM)((short)lower),
-					(LPARAM)((short)upper));
-}
-
-/*
- * Sets the entryfield character limit.
- * Parameters:
- *          handle: Handle to the spinbutton to be set.
- *          limit: Number of characters the entryfield will take.
- */
-void API dw_entryfield_set_limit(HWND handle, ULONG limit)
-{
-	SendMessage(handle, EM_SETLIMITTEXT, (WPARAM)limit, 0);
-}
-
-/*
- * Returns the current value of the spinbutton.
- * Parameters:
- *          handle: Handle to the spinbutton to be queried.
- */
-long API dw_spinbutton_query(HWND handle)
-{
-	if(IS_IE5PLUS)
-		return (long)SendMessage(handle, UDM_GETPOS32, 0, 0);
-	else
-		return (long)SendMessage(handle, UDM_GETPOS, 0, 0);
-}
-
-/*
- * Returns the state of the checkbox.
- * Parameters:
- *          handle: Handle to the checkbox to be queried.
- */
-int API dw_checkbox_query(HWND handle)
-{
-	if(SendMessage(handle, BM_GETCHECK, 0, 0) == BST_CHECKED)
-		return (in_checkbox_handler ? FALSE : TRUE);
-	return (in_checkbox_handler ? TRUE : FALSE);
-}
-
-/* This function unchecks all radiobuttons on a box */
-BOOL CALLBACK _uncheck_radios(HWND handle, LPARAM lParam)
-{
-	char tmpbuf[100];
-
-	GetClassName(handle, tmpbuf, 99);
-
-	if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
-	{
-		BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-		if(bubble && !bubble->checkbox)
-			SendMessage(handle, BM_SETCHECK, 0, 0);
-	}
-	return TRUE;
-}
-/*
- * Sets the state of the checkbox.
- * Parameters:
- *          handle: Handle to the checkbox to be queried.
- *          value: TRUE for checked, FALSE for unchecked.
- */
-void API dw_checkbox_set(HWND handle, int value)
-{
-	BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
-
-	if(bubble && !bubble->checkbox)
-	{
-		HWND parent = GetParent(handle);
-
-		if(parent)
-			EnumChildWindows(parent, _uncheck_radios, 0);
-	}
-	SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0);
-}
-
-/*
- * Inserts an item into a tree window (widget) after another item.
- * Parameters:
- *          handle: Handle to the tree to be inserted.
- *          item: Handle to the item to be positioned after.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- *          parent: Parent handle or 0 if root.
- *          itemdata: Item specific data.
- */
-HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	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 = title;
-	tvi.lParam = (LONG)ptrs;
-	tvi.cchTextMax = strlen(title);
-	tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
-
-	tvins.item = tvi;
-	tvins.hParent = parent;
-	tvins.hInsertAfter = item ? item : TVI_FIRST;
-
-	hti = TreeView_InsertItem(handle, &tvins);
-
-	return hti;
-}
-
-/*
- * Inserts an item into a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree to be inserted.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- *          parent: Parent handle or 0 if root.
- *          itemdata: Item specific data.
- */
-HTREEITEM API dw_tree_insert(HWND handle, char *title, unsigned long icon, HTREEITEM parent, void *itemdata)
-{
-	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 = title;
-	tvi.lParam = (LONG)ptrs;
-	tvi.cchTextMax = strlen(title);
-	tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
-
-	tvins.item = tvi;
-	tvins.hParent = parent;
-	tvins.hInsertAfter = TVI_LAST;
-
-	hti = TreeView_InsertItem(handle, &tvins);
-
-	return hti;
-}
-
-/*
- * Sets the text and icon of an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- *          title: The text title of the entry.
- *          icon: Handle to coresponding icon.
- */
-void API dw_tree_set(HWND handle, HTREEITEM item, char *title, unsigned long 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 = title;
-		tvi.cchTextMax = strlen(title);
-		tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
-		tvi.hItem = (HTREEITEM)item;
-
-		TreeView_SetItem(handle, &tvi);
-	}
-}
-
-/*
- * Sets the item data of a tree item.
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- *          itemdata: User defined data to be associated with item.
- */
-void API dw_tree_set_data(HWND handle, HTREEITEM item, void *itemdata)
-{
-	TVITEM tvi;
-	void **ptrs;
-
-	tvi.mask = TVIF_HANDLE;
-	tvi.hItem = item;
-
-	if(TreeView_GetItem(handle, &tvi))
-	{
-		ptrs = (void **)tvi.lParam;
-		ptrs[1] = itemdata;
-	}
-}
-
-/*
- * Gets the item data of a tree item.
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-void * API dw_tree_get_data(HWND handle, HTREEITEM item)
-{
-	TVITEM tvi;
-	void **ptrs;
-
-	tvi.mask = TVIF_HANDLE;
-	tvi.hItem = item;
-
-	if(TreeView_GetItem(handle, &tvi))
-	{
-		ptrs = (void **)tvi.lParam;
-		return ptrs[1];
-	}
-	return NULL;
-}
-
-/*
- * Gets the text an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-char * API dw_tree_get_title(HWND handle, HTREEITEM item)
-{
-	TVITEM tvi;
-
-	tvi.mask = TVIF_HANDLE;
-	tvi.hItem = item;
-
-	if(TreeView_GetItem(handle, &tvi))
-		return tvi.pszText;
-    return NULL;
-}
-
-/*
- * Gets the text an item in a tree window (widget).
- * Parameters:
- *          handle: Handle to the tree containing the item.
- *          item: Handle of the item to be modified.
- */
-HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
-{
-	return TreeView_GetParent(handle, item);
-}
-
-/*
- * Sets this item as the active selection.
- * Parameters:
- *       handle: Handle to the tree window (widget) to be selected.
- *       item: Handle to the item to be selected.
- */
-void API dw_tree_item_select(HWND handle, HTREEITEM item)
-{
-	dw_window_set_data(handle, "_dw_select_item", (void *)1);
-	TreeView_SelectItem(handle, item);
-	dw_window_set_data(handle, "_dw_select_item", (void *)0);
-}
-
-/* Delete all tree subitems */
-void _dw_tree_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_delete(handle, lastitem);
-	}
-}
-
-/*
- * Removes all nodes from a tree.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- */
-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_delete_recursive(handle, hti);
-		hti = TreeView_GetNextSibling(handle, hti);
-		dw_tree_delete(handle, lastitem);
-	}
-	dw_window_set_data(handle, "_dw_select_item", (void *)0);
-}
-
-/*
- * Expands a node on a tree.
- * Parameters:
- *       handle: Handle to the tree window (widget).
- *       item: Handle to node to be expanded.
- */
-void API dw_tree_expand(HWND handle, HTREEITEM item)
-{
-	TreeView_Expand(handle, item, TVE_EXPAND);
-}
-
-/*
- * Collapses a node on a tree.
- * Parameters:
- *       handle: Handle to the tree window (widget).
- *       item: Handle to node to be collapsed.
- */
-void API dw_tree_collapse(HWND handle, HTREEITEM item)
-{
-	TreeView_Expand(handle, item, TVE_COLLAPSE);
-}
-
-/*
- * Removes a node from a tree.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- *       item: Handle to node to be deleted.
- */
-void API dw_tree_delete(HWND handle, HTREEITEM item)
-{
-	TVITEM tvi;
-	void **ptrs;
-
-	if(item == TVI_ROOT || !item)
-		return;
-
-	tvi.mask = TVIF_HANDLE;
-	tvi.hItem = item;
-
-	if(TreeView_GetItem(handle, &tvi))
-		ptrs = (void **)tvi.lParam;
-
-	_dw_tree_delete_recursive(handle, item);
-	TreeView_DeleteItem(handle, item);
-	if(ptrs)
-		free(ptrs);
-}
-
-/*
- * Sets up the container columns.
- * Parameters:
- *          handle: Handle to the container to be configured.
- *          flags: An array of unsigned longs with column flags.
- *          titles: An array of strings with column text titles.
- *          count: The number of columns (this should match the arrays).
- *          separator: The column number that contains the main separator.
- *                     (only used on OS/2 but must be >= 0 on all)
- */
-int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
-{
-	ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-	int z, l = 0;
-	unsigned long *tempflags = calloc(sizeof(unsigned long), count + 2);
-	LVCOLUMN lvc;
-
-	if(separator == -1)
-	{
-		tempflags[0] = DW_CFA_RESERVED;
-		l = 1;
-	}
-
-	memcpy(&tempflags[l], flags, sizeof(unsigned long) * count);
-	tempflags[count + l] = 0;
-	cinfo->flags = tempflags;
-	cinfo->columns = count + l;
-
-
-	for(z=0;z<count;z++)
-	{
-		if(titles[z])
-		{
-			lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
-			lvc.pszText = titles[z];
-			lvc.cchTextMax = strlen(titles[z]);
-			if(flags[z] & DW_CFA_RIGHT)
-				lvc.fmt = LVCFMT_RIGHT;
-			else if(flags[z] & DW_CFA_CENTER)
-				lvc.fmt = LVCFMT_CENTER;
-			else
-				lvc.fmt = LVCFMT_LEFT;
-			lvc.cx = 75;
-			lvc.iSubItem = count;
-			SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)z + l, (LPARAM)&lvc);
-		}
-	}
-	ListView_SetExtendedListViewStyle(handle, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
-	return TRUE;
-}
-
-/*
- * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
- * Parameters:
- *          handle: Handle to the container to be configured.
- *          flags: An array of unsigned longs with column flags.
- *          titles: An array of strings with column text titles.
- *          count: The number of columns (this should match the arrays).
- */
-int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
-{
-	LV_COLUMN lvc;
-
-	lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
-	lvc.pszText = "Filename";
-	lvc.cchTextMax = 8;
-	lvc.fmt = 0;
-	if(!count)
-		lvc.cx = 300;
-	else
-		lvc.cx = 150;
-	lvc.iSubItem = count;
-	SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)0, (LPARAM)&lvc);
-	dw_container_setup(handle, flags, titles, count, -1);
-	return TRUE;
-}
-
-/*
- * Obtains an icon from a module (or header in GTK).
- * Parameters:
- *          module: Handle to module (DLL) in OS/2 and Windows.
- *          id: A unsigned long id int the resources on OS/2 and
- *              Windows, on GTK this is converted to a pointer
- *              to an embedded XPM.
- */
-unsigned long API dw_icon_load(unsigned long module, unsigned long id)
-{
-	return (unsigned long)LoadIcon(DWInstance, MAKEINTRESOURCE(id));
-}
-
-/*
- * Obtains an icon from a file.
- * Parameters:
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (ICO on OS/2 or Windows, XPM on Unix)
- */
-unsigned long API dw_icon_load_from_file(char *filename)
-{
-	char *file = malloc(strlen(filename) + 5);
-	HANDLE icon;
-
-	if(!file)
-		return 0;
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".ico");
-		if(access(file, 04) != 0)
-		{
-			free(file);
-			return 0;
-		}
-	}
-	icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
-	free(file);
-	return (unsigned long)icon;
-}
-
-/*
- * Frees a loaded resource in OS/2 and Windows.
- * Parameters:
- *          handle: Handle to icon returned by dw_icon_load().
- */
-void API dw_icon_free(unsigned long handle)
-{
-	DestroyIcon((HICON)handle);
-}
-
-/*
- * Allocates memory used to populate a container.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          rowcount: The number of items to be populated.
- */
-void * API dw_container_alloc(HWND handle, int rowcount)
-{
-	LV_ITEM lvi;
-	int z;
-
-	lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT | LVIF_IMAGE;
-	lvi.iSubItem = 0;
-	/* Insert at the end */
-	lvi.iItem = 1000000;
-	lvi.pszText = "";
-	lvi.cchTextMax = 1;
-	lvi.iImage = -1;
-
-	ShowWindow(handle, SW_HIDE);
-	for(z=0;z<rowcount;z++)
-		ListView_InsertItem(handle, &lvi);
-	return (void *)handle;
-}
-
-/* Finds a icon in the table, otherwise it adds it to the table
- * and returns the index in the table.
- */
-int _lookup_icon(HWND handle, HICON hicon, int type)
-{
-	int z;
-	static HWND lasthwnd = NULL;
-
-	if(!hSmall || !hLarge)
-	{
-		hSmall = ImageList_Create(16, 16, ILC_COLOR16 | ILC_MASK, ICON_INDEX_LIMIT, 0);
-		hLarge = ImageList_Create(32, 32, ILC_COLOR16 | ILC_MASK, ICON_INDEX_LIMIT, 0);
-	}
-	for(z=0;z<ICON_INDEX_LIMIT;z++)
-	{
-		if(!lookup[z])
-		{
-			lookup[z] = hicon;
-			ImageList_AddIcon(hSmall, hicon);
-			ImageList_AddIcon(hLarge, hicon);
-			if(type)
-			{
-				TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
-			}
-			else
-			{
-				ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-				ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
-			}
-			lasthwnd = handle;
-			return z;
-		}
-
-		if(hicon == lookup[z])
-		{
-			if(lasthwnd != handle)
-			{
-				if(type)
-				{
-					TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
-				}
-				else
-				{
-					ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-					ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
-				}
-                lasthwnd = handle;
-			}
-			return z;
-		}
-	}
-	return -1;
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon)
-{
-	LV_ITEM lvi;
-
-	lvi.iItem = row;
-	lvi.iSubItem = 0;
-	lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE | LVIF_TEXT;
-	lvi.pszText = filename;
-	lvi.cchTextMax = strlen(filename);
-	lvi.iImage = _lookup_icon(handle, (HICON)icon, 0);
-
-	ListView_SetItem(handle, &lvi);
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
-{
-	dw_container_set_item(handle, pointer, column + 1, row, data);
-}
-
-/*
- * Sets an item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
-{
-	ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-	ULONG *flags;
-	LV_ITEM lvi;
-	char textbuffer[100], *destptr = textbuffer;
-
-	if(!cinfo || !cinfo->flags || !data)
-		return;
-
-	flags = cinfo->flags;
-
-	lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT;
-	lvi.iItem = row;
-	lvi.iSubItem = column;
-
-	if(flags[column] & DW_CFA_BITMAPORICON)
-	{
-		HICON hicon = *((HICON *)data);
-
-		lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE;
-		lvi.pszText = NULL;
-		lvi.cchTextMax = 0;
-
-		lvi.iImage = _lookup_icon(handle, hicon, 0);
-	}
-	else if(flags[column] & DW_CFA_STRING)
-	{
-		char *tmp = *((char **)data);
-
-		if(!tmp)
-			tmp = "";
-
-		lvi.pszText = tmp;
-		lvi.cchTextMax = strlen(tmp);
-		destptr = tmp;
-	}
-	else if(flags[column] & DW_CFA_ULONG)
-	{
-		ULONG tmp = *((ULONG *)data);
-
-		sprintf(textbuffer, "%lu", tmp);
-
-		lvi.pszText = textbuffer;
-		lvi.cchTextMax = strlen(textbuffer);
-	}
-	else if(flags[column] & DW_CFA_DATE)
-	{
-		struct tm curtm;
-		CDATE cdate = *((CDATE *)data);
-
-		curtm.tm_mday = cdate.day;
-		curtm.tm_mon = cdate.month - 1;
-		curtm.tm_year = cdate.year - 1900;
-
-		strftime(textbuffer, 100, "%x", &curtm);
-
-		lvi.pszText = textbuffer;
-		lvi.cchTextMax = strlen(textbuffer);
-	}
-	else if(flags[column] & DW_CFA_TIME)
-	{
-		struct tm curtm;
-		CTIME ctime = *((CTIME *)data);
-
-		curtm.tm_hour = ctime.hours;
-		curtm.tm_min = ctime.minutes;
-		curtm.tm_sec = ctime.seconds;
-
-		strftime(textbuffer, 100, "%X", &curtm);
-
-		lvi.pszText = textbuffer;
-		lvi.cchTextMax = strlen(textbuffer);
-	}
-
-	ListView_SetItem(handle, &lvi);
-}
-
-/*
- * Changes an existing item in specified row and column to the given data.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          column: Zero based column of data being set.
- *          row: Zero based row of data being set.
- *          data: Pointer to the data to be added.
- */
-void API dw_container_change_item(HWND handle, int column, int row, void *data)
-{
-	dw_container_set_item(handle, NULL, column, row, data);
-}
-
-/*
- * Sets the width of a column in the container.
- * Parameters:
- *          handle: Handle to window (widget) of container.
- *          column: Zero based column of width being set.
- *          width: Width of column in pixels.
- */
-void API dw_container_set_column_width(HWND handle, int column, int width)
-{
-	ListView_SetColumnWidth(handle, column, width);
-}
-
-/*
- * Sets the title 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.
- *          title: String title of the item.
- */
-void API dw_container_set_row_title(void *pointer, int row, char *title)
-{
-	LV_ITEM lvi;
-	HWND container = (HWND)pointer;
-
-	lvi.iItem = row;
-	lvi.iSubItem = 0;
-	lvi.mask = LVIF_PARAM;
-	lvi.lParam = (LPARAM)title;
-
-	if(!ListView_SetItem(container, &lvi) && lvi.lParam)
-		lvi.lParam = 0;
-
-}
-
-/*
- * Sets the title of a row in the container.
- * Parameters:
- *          handle: Handle to the container window (widget).
- *          pointer: Pointer to the allocated memory in dw_container_alloc().
- *          rowcount: The number of rows to be inserted.
- */
-void API dw_container_insert(HWND handle, void *pointer, int rowcount)
-{
-	ShowWindow(handle, SW_SHOW);
-}
-
-/*
- * Removes all rows from a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be cleared.
- *       redraw: TRUE to cause the container to redraw immediately.
- */
-void API dw_container_clear(HWND handle, int redraw)
-{
-	ListView_DeleteAllItems(handle);
-}
-
-/*
- * Removes the first x rows from a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be deleted from.
- *       rowcount: The number of rows to be deleted.
- */
-void API dw_container_delete(HWND handle, int rowcount)
-{
-	int z;
-
-	for(z=0;z<rowcount;z++)
-	{
-		ListView_DeleteItem(handle, 0);
-	}
-}
-
-/*
- * Scrolls container up or down.
- * Parameters:
- *       handle: Handle to the window (widget) to be scrolled.
- *       direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or
- *                  DW_SCROLL_BOTTOM. (rows is ignored for last two)
- *       rows: The number of rows to be scrolled.
- */
-void API dw_container_scroll(HWND handle, int direction, long rows)
-{
-	switch(direction)
-	{
-	case DW_SCROLL_TOP:
-		ListView_Scroll(handle, 0, -10000000);
-        break;
-	case DW_SCROLL_BOTTOM:
-		ListView_Scroll(handle, 0, 10000000);
-		break;
-	}
-}
-
-/*
- * Starts a new query of a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be queried.
- *       flags: If this parameter is DW_CRA_SELECTED it will only
- *              return items that are currently selected.  Otherwise
- *              it will return all records in the container.
- */
-char * API dw_container_query_start(HWND handle, unsigned long flags)
-{
-	LV_ITEM lvi;
-
-	_index = ListView_GetNextItem(handle, -1, flags);
-
-	if(_index == -1)
-		return NULL;
-
-	memset(&lvi, 0, sizeof(LV_ITEM));
-
-	lvi.iItem = _index;
-	lvi.mask = LVIF_PARAM;
-
-	ListView_GetItem(handle, &lvi);
-
-	return (char *)lvi.lParam;
-}
-
-/*
- * Continues an existing query of a container.
- * Parameters:
- *       handle: Handle to the window (widget) to be queried.
- *       flags: If this parameter is DW_CRA_SELECTED it will only
- *              return items that are currently selected.  Otherwise
- *              it will return all records in the container.
- */
-char * API dw_container_query_next(HWND handle, unsigned long flags)
-{
-	LV_ITEM lvi;
-
-	_index = ListView_GetNextItem(handle, _index, flags);
-
-	if(_index == -1)
-		return NULL;
-
-	memset(&lvi, 0, sizeof(LV_ITEM));
-
-	lvi.iItem = _index;
-	lvi.mask = LVIF_PARAM;
-
-	ListView_GetItem(handle, &lvi);
-
-	return (char *)lvi.lParam;
-}
-
-/*
- * 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(HWND handle, char *text)
-{
-	int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
-
-	while(index != -1)
-	{
-		LV_ITEM lvi;
-
-		memset(&lvi, 0, sizeof(LV_ITEM));
-
-		lvi.iItem = index;
-		lvi.mask = LVIF_PARAM;
-
-		ListView_GetItem(handle, &lvi);
-
-		if((char *)lvi.lParam == text)
-		{
-			RECT viewport, item;
-
-			ListView_SetItemState(handle, index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
-			ListView_EnsureVisible(handle, index, TRUE);
-			return;
-		}
-
-        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(HWND handle, char *text)
-{
-	int index = ListView_GetNextItem(handle, -1, LVNI_ALL);
-
-	while(index != -1)
-	{
-		LV_ITEM lvi;
-
-		memset(&lvi, 0, sizeof(LV_ITEM));
-
-		lvi.iItem = index;
-		lvi.mask = LVIF_PARAM;
-
-		ListView_GetItem(handle, &lvi);
-
-		if((char *)lvi.lParam == text)
-		{
-			ListView_DeleteItem(handle, index);
-			return;
-		}
-
-        index = ListView_GetNextItem(handle, index, LVNI_ALL);
-	}
-}
-
-/*
- * Optimizes the column widths so that all data is visible.
- * Parameters:
- *       handle: Handle to the window (widget) to be optimized.
- */
-void API dw_container_optimize(HWND handle)
-{
-	ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-	ULONG *flags;
-	LV_ITEM lvi;
-
-	if(cinfo && cinfo->columns == 1)
-	{
-		ListView_SetColumnWidth(handle, 0, LVSCW_AUTOSIZE);
-	}
-	else if(cinfo && cinfo->columns > 1)
-	{
-		int z, index;
-		ULONG *flags = cinfo->flags, *columns = calloc(sizeof(ULONG), cinfo->columns);
-		char *text = malloc(1024);
-
-		/* Initialize with sizes of column labels */
-		for(z=0;z<cinfo->columns;z++)
-		{
-			if(flags[z] & DW_CFA_BITMAPORICON)
-				columns[z] = 5;
-			else
-			{
-				LVCOLUMN lvc;
-
-				lvc.mask = LVCF_TEXT;
-				lvc.cchTextMax = 1023;
-				lvc.pszText = text;
-
-				if(ListView_GetColumn(handle, z, &lvc))
-					columns[z] = ListView_GetStringWidth(handle, lvc.pszText);
-
-				if(flags[z] & DW_CFA_RESERVED)
-					columns[z] += 20;
-			}
-		}
-
-		index = ListView_GetNextItem(handle, -1, LVNI_ALL);
-
-		/* Query all the item texts */
-		while(index != -1)
-		{
-			for(z=0;z<cinfo->columns;z++)
-			{
-				LV_ITEM lvi;
-
-				memset(&lvi, 0, sizeof(LV_ITEM));
-
-				lvi.iItem = index;
-				lvi.iSubItem = z;
-				lvi.mask = LVIF_TEXT;
-				lvi.cchTextMax = 1023;
-				lvi.pszText = text;
-
-				if(ListView_GetItem(handle, &lvi))
-				{
-					int width = ListView_GetStringWidth(handle, lvi.pszText);
-					if(width > columns[z])
-					{
-						if(z == 0)
-							columns[z] = width + 20;
-						else
-							columns[z] = width;
-					}
-				}
-			}
-
-			index = ListView_GetNextItem(handle, index, LVNI_ALL);
-		}
-
-		/* Set the new sizes */
-		for(z=0;z<cinfo->columns;z++)
-			ListView_SetColumnWidth(handle, z, columns[z] + 16);
-
-		free(columns);
-		free(text);
-	}
-}
-
-/*
- * Inserts an icon into the taskbar.
- * Parameters:
- *       handle: Window handle that will handle taskbar icon messages.
- *       icon: Icon handle to display in the taskbar.
- *       bubbletext: Text to show when the mouse is above the icon.
- */
-void dw_taskbar_insert(HWND handle, unsigned long icon, char *bubbletext)
-{
-	NOTIFYICONDATA tnid;
- 
-	tnid.cbSize = sizeof(NOTIFYICONDATA);
-	tnid.hWnd = handle;
-	tnid.uID = icon;
-	tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
-	tnid.uCallbackMessage = WM_USER+2;
-	tnid.hIcon = (HICON)icon;
-	if(bubbletext)
-		strncpy(tnid.szTip, bubbletext, sizeof(tnid.szTip));
-	else
-		tnid.szTip[0] = 0;
-
-	Shell_NotifyIcon(NIM_ADD, &tnid);
-}
-
-/*
- * Deletes an icon from the taskbar.
- * Parameters:
- *       handle: Window handle that was used with dw_taskbar_insert().
- *       icon: Icon handle that was used with dw_taskbar_insert().
- */
-void dw_taskbar_delete(HWND handle, unsigned long icon)
-{
-	NOTIFYICONDATA tnid;
-
-	tnid.cbSize = sizeof(NOTIFYICONDATA);
-	tnid.hWnd = handle;
-	tnid.uID = icon;
-
-	Shell_NotifyIcon(NIM_DELETE, &tnid);
-}
-
-/*
- * Creates a rendering context widget (window) to be packed.
- * Parameters:
- *       id: An id to be used with dw_window_from_id.
- * Returns:
- *       A handle to the widget or NULL on failure.
- */
-HWND API dw_render_new(unsigned long id)
-{
-	Box *newbox = calloc(sizeof(Box), 1);
-	HWND tmp = CreateWindow(ObjectClassName,
-							"",
-							WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-	newbox->pad = 0;
-	newbox->type = 0;
-	newbox->count = 0;
-	newbox->grouphwnd = (HWND)NULL;
-	newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc);
-	newbox->cinfo.fore = newbox->cinfo.back = -1;
-
-	SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)newbox);
-	return tmp;
-}
-
-/* Sets the current foreground drawing color.
- * Parameters:
- *       red: red value.
- *       green: green value.
- *       blue: blue value.
- */
-void API dw_color_foreground_set(unsigned long value)
-{
-	int threadid = dw_thread_id();
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	value = _internal_color(value);
-
-	DeleteObject(_hPen[threadid]);
-	DeleteObject(_hBrush[threadid]);
-	_foreground[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
-	_hPen[threadid] = CreatePen(PS_SOLID, 1, _foreground[threadid]);
-	_hBrush[threadid] = CreateSolidBrush(_foreground[threadid]);
-}
-
-/* Sets the current background drawing color.
- * Parameters:
- *       red: red value.
- *       green: green value.
- *       blue: blue value.
- */
-void API dw_color_background_set(unsigned long value)
-{
-	int threadid = dw_thread_id();
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	value = _internal_color(value);
-
-	if(value == DW_RGB_TRANSPARENT)
-		_background[threadid] = DW_RGB_TRANSPARENT;
-	else
-		_background[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
-}
-
-/* Draw a point on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x: X coordinate.
- *       y: Y coordinate.
- */
-void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
-{
-	HDC hdcPaint;
-	int threadid = dw_thread_id();
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	if(handle)
-		hdcPaint = GetDC(handle);
-	else if(pixmap)
-		hdcPaint = pixmap->hdc;
-	else
-		return;
-
-	SetPixel(hdcPaint, x, y, _foreground[threadid]);
-	if(!pixmap)
-		ReleaseDC(handle, hdcPaint);
-}
-
-/* Draw a line on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x1: First X coordinate.
- *       y1: First Y coordinate.
- *       x2: Second X coordinate.
- *       y2: Second Y coordinate.
- */
-void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
-{
-	HDC hdcPaint;
-	HPEN oldPen;
-	int threadid = dw_thread_id();
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	if(handle)
-		hdcPaint = GetDC(handle);
-	else if(pixmap)
-		hdcPaint = pixmap->hdc;
-	else
-		return;
-
-	oldPen = SelectObject(hdcPaint, _hPen[threadid]);
-	MoveToEx(hdcPaint, x1, y1, NULL);
-	LineTo(hdcPaint, x2, y2);
-	SelectObject(hdcPaint, oldPen);
-	/* For some reason Win98 (at least) fails
-	 * to draw the last pixel.  So I do it myself.
-	 */
-	SetPixel(hdcPaint, x2, y2, _foreground[threadid]);
-	if(!pixmap)
-		ReleaseDC(handle, hdcPaint);
-}
-
-/* Draw a rectangle on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x: X coordinate.
- *       y: Y coordinate.
- *       width: Width of rectangle.
- *       height: Height of rectangle.
- */
-void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height)
-{
-	HDC hdcPaint;
-	HPEN oldPen;
-	HBRUSH oldBrush;
-	RECT Rect;
-	int threadid = dw_thread_id();
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	if(handle)
-		hdcPaint = GetDC(handle);
-	else if(pixmap)
-		hdcPaint = pixmap->hdc;
-	else
-		return;
-
-	SetRect(&Rect, x, y, x + width , y + height );
-	if(fill)
-		FillRect(hdcPaint, &Rect, _hBrush[threadid]);
-	else
-		FrameRect(hdcPaint, &Rect, _hBrush[threadid]);
-	if(!pixmap)
-		ReleaseDC(handle, hdcPaint);
-}
-
-/* Draw text on a window (preferably a render window).
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       x: X coordinate.
- *       y: Y coordinate.
- *       text: Text to be displayed.
- */
-void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
-{
-	HDC hdc;
-	int size = 9, z, mustdelete = 0;
-	HFONT hFont = 0, oldFont = 0;
-	int threadid = dw_thread_id();
-	ColorInfo *cinfo;
-
-	if(threadid < 0 || threadid >= THREAD_LIMIT)
-		threadid = 0;
-
-	if(handle)
-		hdc = GetDC(handle);
-	else if(pixmap)
-		hdc = pixmap->hdc;
-	else
-		return;
-
-	if(handle)
-		cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-	else
-		cinfo = (ColorInfo *)GetWindowLongPtr(pixmap->handle, GWLP_USERDATA);
-
-	if(cinfo)
-	{
-		hFont = _acquire_font(handle, cinfo->fontname);
-		mustdelete = 1;
-	}
-
-	if(hFont)
-		oldFont = SelectObject(hdc, hFont);
-	SetTextColor(hdc, _foreground[threadid]);
-	if(_background[threadid] == DW_RGB_TRANSPARENT)
-		SetBkMode(hdc, TRANSPARENT);
-	else
-	{
-		SetBkMode(hdc, OPAQUE);
-		SetBkColor(hdc, _background[threadid]);
-	}
-	TextOut(hdc, x, y, text, strlen(text));
-	if(oldFont)
-		SelectObject(hdc, oldFont);
-	if(mustdelete)
-		DeleteObject(hFont);
-	if(!pixmap)
-		ReleaseDC(handle, hdc);
-}
-
-/* Query the width and height of a text string.
- * Parameters:
- *       handle: Handle to the window.
- *       pixmap: Handle to the pixmap. (choose only one of these)
- *       text: Text to be queried.
- *       width: Pointer to a variable to be filled in with the width.
- *       height Pointer to a variable to be filled in with the height.
- */
-void API dw_font_text_extents(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
-{
-	HDC hdc;
-	int mustdelete = 0;
-	HFONT hFont = NULL, oldFont;
-	SIZE sz;
-
-	if(handle)
-		hdc = GetDC(handle);
-	else if(pixmap)
-		hdc = pixmap->hdc;
-	else
-		return;
-
-	{
-		ColorInfo *cinfo;
-
-		if(handle)
-			cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
-		else
-			cinfo = (ColorInfo *)GetWindowLongPtr(pixmap->handle, GWLP_USERDATA);
-
-		if(cinfo)
-		{
-			hFont = _acquire_font(handle, cinfo->fontname);
-			mustdelete = 1;
-		}
-	}
-	oldFont = SelectObject(hdc, hFont);
-
-	GetTextExtentPoint32(hdc, text, strlen(text), &sz);
-
-	if(width)
-		*width = sz.cx;
-
-	if(height)
-		*height = sz.cy;
-
-	SelectObject(hdc, oldFont);
-	if(mustdelete)
-		DeleteObject(hFont);
-	if(!pixmap)
-		ReleaseDC(handle, hdc);
-}
-
-/* Call this after drawing to the screen to make sure
- * anything you have drawn is visible.
- */
-void API dw_flush(void)
-{
-}
-
-/*
- * Creates a pixmap with given parameters.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       width: Width of the pixmap in pixels.
- *       height: Height of the pixmap in pixels.
- *       depth: Color depth of the pixmap.
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
-{
-	HPIXMAP pixmap;
-	BITMAP bm;
-	HDC hdc;
-
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hdc = GetDC(handle);
-
-	pixmap->width = width; pixmap->height = height;
-
-	pixmap->handle = handle;
-	pixmap->hbm = CreateCompatibleBitmap(hdc, width, height);
-	pixmap->hdc = CreateCompatibleDC(hdc);
-
-	SelectObject(pixmap->hdc, pixmap->hbm);
-
-	ReleaseDC(handle, hdc);
-
-	return pixmap;
-}
-
-/*
- * Creates a pixmap from a file.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       filename: Name of the file, omit extention to have
- *                 DW pick the appropriate file extension.
- *                 (BMP on OS/2 or Windows, XPM on Unix)
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
-{
-	HPIXMAP pixmap;
-	BITMAP bm;
-	HDC hdc;
-	char *file = malloc(strlen(filename) + 5);
-
-	if (!file || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
-	{
-		if(file)
-			free(file);
-		return NULL;
-	}
-
-	strcpy(file, filename);
-
-	/* check if we can read from this file (it exists and read permission) */
-	if(access(file, 04) != 0)
-	{
-		/* Try with .bmp extention */
-		strcat(file, ".bmp");
-		if(access(file, 04) != 0)
-		{
-			free(pixmap);
-			free(file);
-			return NULL;
-		}
-	}
-
-	hdc = GetDC(handle);
-
-	pixmap->handle = handle;
-	pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
-
-	if(!pixmap->hbm)
-	{
-		free(file);
-		free(pixmap);
-		ReleaseDC(handle, hdc);
-		return NULL;
-	}
-
-	pixmap->hdc = CreateCompatibleDC(hdc);
-
-    GetObject(pixmap->hbm, sizeof(bm), &bm);
-
-	pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
-
-	SelectObject(pixmap->hdc, pixmap->hbm);
-
-	ReleaseDC(handle, hdc);
-
-	free(file);
-
-	return pixmap;
-}
-
-/*
- * Creates a pixmap from internal resource graphic specified by id.
- * Parameters:
- *       handle: Window handle the pixmap is associated with.
- *       id: Resource ID associated with requested pixmap.
- * Returns:
- *       A handle to a pixmap or NULL on failure.
- */
-HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id)
-{
-	HPIXMAP pixmap;
-	BITMAP bm;
-	HDC hdc;
-
-	if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
-		return NULL;
-
-	hdc = GetDC(handle);
-
-
-	pixmap->hbm = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
-	pixmap->hdc = CreateCompatibleDC(hdc);
-
-	GetObject(pixmap->hbm, sizeof(BITMAP), (void *)&bm);
-
-	pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
-
-	SelectObject(pixmap->hdc, pixmap->hbm);
-
-	ReleaseDC(handle, hdc);
-
-	return pixmap;
-}
-
-/*
- * Destroys an allocated pixmap.
- * Parameters:
- *       pixmap: Handle to a pixmap returned by
- *               dw_pixmap_new..
- */
-void API dw_pixmap_destroy(HPIXMAP pixmap)
-{
-	if(pixmap)
-	{
-		DeleteDC(pixmap->hdc);
-		DeleteObject(pixmap->hbm);
-		free(pixmap);
-	}
-}
-
-/*
- * Copies from one item to another.
- * Parameters:
- *       dest: Destination window handle.
- *       destp: Destination pixmap. (choose only one).
- *       xdest: X coordinate of destination.
- *       ydest: Y coordinate of destination.
- *       width: Width of area to copy.
- *       height: Height of area to copy.
- *       src: Source window handle.
- *       srcp: Source pixmap. (choose only one).
- *       xsrc: X coordinate of source.
- *       ysrc: Y coordinate of source.
- */
-void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
-{
-	HDC hdcdest;
-	HDC hdcsrc;
-
-	if(dest)
-		hdcdest = GetDC(dest);
-	else if(destp)
-		hdcdest = destp->hdc;
-	else
-		return;
-
-	if(src)
-		hdcsrc = GetDC(src);
-	else if(srcp)
-		hdcsrc = srcp->hdc;
-	else
-		return;
-
-	BitBlt(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY);
-
-	if(!destp)
-		ReleaseDC(dest, hdcdest);
-	if(!srcp)
-		ReleaseDC(src, hdcsrc);
-}
-
-/*
- * Emits a beep.
- * Parameters:
- *       freq: Frequency.
- *       dur: Duration.
- */
-void API dw_beep(int freq, int dur)
-{
-	Beep(freq, dur);
-}
-
-/* Open a shared library and return a handle.
- * Parameters:
- *         name: Base name of the shared library.
- *         handle: Pointer to a module handle,
- *                 will be filled in with the handle.
- */
-int API dw_module_load(char *name, HMOD *handle)
-{
-	if(!handle)
-		return	-1;
-
-	*handle = LoadLibrary(name);
-	return (NULL == *handle);
-}
-
-/* Queries the address of a symbol within open handle.
- * Parameters:
- *         handle: Module handle returned by dw_module_load()
- *         name: Name of the symbol you want the address of.
- *         func: A pointer to a function pointer, to obtain
- *               the address.
- */
-int API dw_module_symbol(HMOD handle, char *name, void**func)
-{
-	if(!func || !name)
-		return	-1;
-
-	if(0 == strlen(name))
-		return	-1;
-
-	*func = (void*)GetProcAddress(handle, name);
-	return	(NULL == *func);
-}
-
-/* Frees the shared library previously opened.
- * Parameters:
- *         handle: Module handle returned by dw_module_load()
- */
-int API dw_module_close(HMOD handle)
-{
-	return FreeLibrary(handle);
-}
-
-/*
- * Returns the handle to an unnamed mutex semaphore.
- */
-HMTX API dw_mutex_new(void)
-{
-	return (HMTX)CreateMutex(NULL, FALSE, NULL);
-}
-
-/*
- * Closes a semaphore created by dw_mutex_new().
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_close(HMTX mutex)
-{
-	CloseHandle((HANDLE)mutex);
-}
-
-/*
- * Tries to gain access to the semaphore, if it can't it blocks.
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_lock(HMTX mutex)
-{
-	if(_dwtid == dw_thread_id())
-	{
-		int rc = WaitForSingleObject((HANDLE)mutex, 0);
-
-		while(rc == WAIT_TIMEOUT)
-		{
-			dw_main_sleep(1);
-			rc = WaitForSingleObject((HANDLE)mutex, 0);
-		}
-	}
-    else
-		WaitForSingleObject((HANDLE)mutex, INFINITE);
-}
-
-/*
- * Reliquishes the access to the semaphore.
- * Parameters:
- *       mutex: The handle to the mutex returned by dw_mutex_new().
- */
-void API dw_mutex_unlock(HMTX mutex)
-{
-	ReleaseMutex((HANDLE)mutex);
-}
-
-/*
- * Returns the handle to an unnamed event semaphore.
- */
-HEV API dw_event_new(void)
-{
-    return CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-/*
- * Resets a semaphore created by dw_event_new().
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_reset(HEV eve)
-{
-	return ResetEvent(eve);
-}
-
-/*
- * Posts a semaphore created by dw_event_new(). Causing all threads
- * waiting on this event in dw_event_wait to continue.
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_post(HEV eve)
-{
-	return SetEvent(eve);
-}
-
-/*
- * Waits on a semaphore created by dw_event_new(), until the
- * event gets posted or until the timeout expires.
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_wait(HEV eve, unsigned long timeout)
-{
-	int rc;
-
-	rc = WaitForSingleObject(eve, timeout);
-	if(rc == WAIT_OBJECT_0)
-		return 1;
-	if(rc == WAIT_ABANDONED)
-		return -1;
-	return 0;
-}
-
-/*
- * Closes a semaphore created by dw_event_new().
- * Parameters:
- *       eve: The handle to the event returned by dw_event_new().
- */
-int API dw_event_close(HEV *eve)
-{
-	if(eve)
-		return CloseHandle(*eve);
-	return FALSE;
-}
-
-/*
- * Creates a new thread with a starting point of func.
- * Parameters:
- *       func: Function which will be run in the new thread.
- *       data: Parameter(s) passed to the function.
- *       stack: Stack size of new thread (OS/2 and Windows only).
- */
-DWTID API dw_thread_new(void *func, void *data, int stack)
-{
-#if defined(__CYGWIN__)
-	return 0;
-#else
-	return (DWTID)_beginthread((void(*)(void *))func, stack, data);
-#endif
-}
-
-/*
- * Ends execution of current thread immediately.
- */
-void API dw_thread_end(void)
-{
-#if !defined(__CYGWIN__)
-	_endthread();
-#endif
-}
-
-/*
- * Returns the current thread's ID.
- */
-DWTID API dw_thread_id(void)
-{
-#if defined(__CYGWIN__)
-	return 0;
-#else
-	return (DWTID)GetCurrentThreadId();
-#endif
-}
-
-/*
- * 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)
-{
-	exit(exitcode);
-}
-
-/*
- * Creates a splitbar window (widget) with given parameters.
- * Parameters:
- *       type: Value can be DW_VERT or DW_HORZ.
- *       topleft: Handle to the window to be top or left.
- *       bottomright:  Handle to the window to be bottom or right.
- * Returns:
- *       A handle to a splitbar window or NULL on failure.
- */
-HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
-{
-	HWND tmp = CreateWindow(SplitbarClassName,
-							"",
-							WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
-							0,0,2000,1000,
-							DW_HWND_OBJECT,
-							(HMENU)id,
-							DWInstance,
-							NULL);
-
-	if(tmp)
-	{
-		HWND tmpbox = dw_box_new(DW_VERT, 0);
-        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);
-
-		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);
-		*percent = 50.0;
-		dw_window_set_data(tmp, "_dw_percent", (void *)percent);
-		dw_window_set_data(tmp, "_dw_type", (void *)type);
-	}
-	return tmp;
-}
-
-/*
- * Sets the position of a splitbar (pecentage).
- * Parameters:
- *       handle: The handle to the splitbar returned by dw_splitbar_new().
- */
-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;
-
-	if(mypercent)
-		*mypercent = percent;
-
-	dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
-
-	_handle_splitbar_resize(handle, percent, type, width, height);
-}
-
-/*
- * Gets the position of a splitbar (pecentage).
- * Parameters:
- *       handle: The handle to the splitbar returned by dw_splitbar_new().
- */
-float API dw_splitbar_get(HWND handle)
-{
-	float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
-
-	if(percent)
-		return *percent;
-	return 0.0;
-}
-
-/*
- * Pack windows (widgets) into a box from the end (or bottom).
- * Parameters:
- *       box: Window handle of the box to be packed into.
- *       item: Window handle of the item to be back.
- *       width: Width in pixels of the item or -1 to be self determined.
- *       height: Height in pixels of the item or -1 to be self determined.
- *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
- *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
- *       pad: Number of pixels of padding around the item.
- */
-void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
-{
-	Box *thisbox;
-
-		/*
-		 * If you try and pack an item into itself VERY bad things can happen; like at least an
-		 * infinite loop on GTK! Lets be safe!
-		 */
-	if(box == item)
-	{
-		dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!",box,item);
-		return;
-	}
-
-	thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
-	if(thisbox)
-	{
-		int z;
-		Item *tmpitem, *thisitem = thisbox->items;
-		char tmpbuf[100];
-
-		tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
-
-		for(z=0;z<thisbox->count;z++)
-		{
-			tmpitem[z+1] = thisitem[z];
-		}
-
-		GetClassName(item, tmpbuf, 99);
-
-		if(vsize && !height)
-			height = 1;
-		if(hsize && !width)
-			width = 1;
-
-		if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
-			tmpitem[0].type = TYPEBOX;
-		else
-		{
-			if ( width == 0 && hsize == FALSE )
-				dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
-			if ( height == 0 && vsize == FALSE )
-				dw_messagebox("dw_box_pack_end()", DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
-
-			tmpitem[0].type = TYPEITEM;
-		}
-
-		tmpitem[0].hwnd = item;
-		tmpitem[0].origwidth = tmpitem[0].width = width;
-		tmpitem[0].origheight = tmpitem[0].height = height;
-		tmpitem[0].pad = pad;
-		if(hsize)
-			tmpitem[0].hsize = SIZEEXPAND;
-		else
-			tmpitem[0].hsize = SIZESTATIC;
-
-		if(vsize)
-			tmpitem[0].vsize = SIZEEXPAND;
-		else
-			tmpitem[0].vsize = SIZESTATIC;
-
-		thisbox->items = tmpitem;
-
-		if(thisbox->count)
-			free(thisitem);
-
-		thisbox->count++;
-
-		SetParent(item, box);
-		if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
-		{
-			ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(item, GWLP_USERDATA);
-
-			if(cinfo)
-			{
-				SetParent(cinfo->buddy, box);
-				ShowWindow(cinfo->buddy, SW_SHOW);
-				SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0);
-			}
-		}
-	}
-}
-
-/*
- * Sets the default focus item for a window/dialog.
- * Parameters:
- *         window: Toplevel window or dialog.
- *         defaultitem: Handle to the dialog item to be default.
- */
-void API dw_window_default(HWND window, HWND defaultitem)
-{
-	Box *thisbox = (Box *)GetWindowLongPtr(window, GWLP_USERDATA);
-
-	if(thisbox)
-		thisbox->defaultitem = defaultitem;
-}
-
-/*
- * Sets window to click the default dialog item when an ENTER is pressed.
- * Parameters:
- *         window: Window (widget) to look for the ENTER press.
- *         next: Window (widget) to move to next (or click)
- */
-void API dw_window_click_default(HWND window, HWND next)
-{
-	ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
-
-	if(cinfo)
-		cinfo->clickdefault = next;
-}
-
-/*
- * Returns some information about the current operating environment.
- * Parameters:
- *       env: Pointer to a DWEnv struct.
- */
-void API dw_environment_query(DWEnv *env)
-{
-	if(!env)
-		return;
-
-	/* Get the Windows version. */
-
-	env->MajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
-	env->MinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
-
-	/* Get the build number for Windows NT/Windows 2000. */
-
-	env->MinorBuild =  0;
-
-	if (dwVersion < 0x80000000)
-	{
-		if(env->MajorVersion == 5 && env->MinorVersion == 1)
-			strcpy(env->osName, "Windows XP");
-		else if(env->MajorVersion == 5 && env->MinorVersion == 0)
-			strcpy(env->osName, "Windows 2000");
-		else
-			strcpy(env->osName, "Windows NT");
-
-		env->MajorBuild = (DWORD)(HIWORD(dwVersion));
-	}
-	else
-	{
-		strcpy(env->osName, "Windows 95/98/ME");
-		env->MajorBuild =  0;
-	}
-
-	strcpy(env->buildDate, __DATE__);
-	strcpy(env->buildTime, __TIME__);
-	env->DWMajorVersion = DW_MAJOR_VERSION;
-	env->DWMinorVersion = DW_MINOR_VERSION;
-	env->DWSubVersion = DW_SUB_VERSION;
-}
-
-/*
- * Opens a file dialog and queries user selection.
- * Parameters:
- *       title: Title bar text for dialog.
- *       defpath: The default path of the open dialog.
- *       ext: Default file extention.
- *       flags: DW_FILE_OPEN or DW_FILE_SAVE or DW_DIRECTORY_OPEN.
- * Returns:
- *       NULL on error. A malloced buffer containing
- *       the file path on success.
- *       
- */
-char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
-{
-	OPENFILENAME of;
-	char filenamebuf[1001] = "";
-	int rc;
-
-	BROWSEINFO bi;
-	TCHAR szDir[MAX_PATH];
-	LPITEMIDLIST pidl;
-	LPMALLOC pMalloc;
-
-	if(flags==DW_DIRECTORY_OPEN)
-	{
-		if (SUCCEEDED(SHGetMalloc(&pMalloc)))
-		{
-			ZeroMemory(&bi,sizeof(bi));
-			bi.hwndOwner = NULL;
-			bi.pszDisplayName = 0;
-			bi.pidlRoot = 0;
-			bi.lpszTitle = title;
-			bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
-			bi.lpfn = NULL; /*BrowseCallbackProc*/
-
-			pidl = SHBrowseForFolder(&bi);
-			if (pidl)
-			{
-				if (SHGetPathFromIDList(pidl,szDir))
-				{
-					strcpy(filenamebuf,szDir);
-				}
-
-				// In C++: pMalloc->Free(pidl); pMalloc->Release();
-				pMalloc->lpVtbl->Free(pMalloc,pidl);
-				pMalloc->lpVtbl->Release(pMalloc);
-				return strdup(filenamebuf);
-			}
-		}
-	}
-	else
-	{
-		if(ext)
-		{
-			strcpy(filenamebuf, "*.");
-			strcat(filenamebuf, ext);
-		}
-
-		memset(&of, 0, sizeof(OPENFILENAME));
-
-		of.lStructSize = sizeof(OPENFILENAME);
-		of.hwndOwner = HWND_DESKTOP;
-		of.hInstance = DWInstance;
-		of.lpstrInitialDir = defpath;
-		of.lpstrTitle = title;
-		of.lpstrFile = filenamebuf;
-		of.nMaxFile = 1000;
-		of.lpstrDefExt = ext;
-		of.Flags = 0;
-
-		if(flags & DW_FILE_SAVE)
-			rc = GetSaveFileName(&of);
-		else
-			rc = GetOpenFileName(&of);
-
-		if(rc)
-			return strdup(of.lpstrFile);
-	}
-	return NULL;
-}
-
-/*
- * Execute and external program in a seperate session.
- * Parameters:
- *       program: Program name with optional path.
- *       type: Either DW_EXEC_CON or DW_EXEC_GUI.
- *       params: An array of pointers to string arguements.
- * Returns:
- *       -1 on error.
- */
-int API dw_exec(char *program, int type, char **params)
-{
-	char **newparams;
-	int retcode, count = 0, z;
-
-	while(params[count])
-	{
-		count++;
-	}
-
-	newparams = (char **)malloc(sizeof(char *) * (count+1));
-
-	for(z=0;z<count;z++)
-	{
-		newparams[z] = malloc(strlen(params[z])+3);
-		strcpy(newparams[z], "\"");
-		strcat(newparams[z], params[z]);
-		strcat(newparams[z], "\"");
-	}
-	newparams[count] = NULL;
-
-	retcode = spawnvp(P_NOWAIT, program, newparams);
-
-	for(z=0;z<count;z++)
-	{
-		free(newparams[z]);
-	}
-	free(newparams);
-
-	return retcode;
-}
-
-/*
- * Loads a web browser pointed at the given URL.
- * Parameters:
- *       url: Uniform resource locator.
- */
-int API dw_browse(char *url)
-{
-	char *browseurl = url;
-	int retcode;
-
-	if(strlen(url) > 7 && strncmp(url, "file://", 7) == 0)
-	{
-		int len, z;
-
-		browseurl = &url[7];
-		len = strlen(browseurl);
-
-		for(z=0;z<len;z++)
-		{
-			if(browseurl[z] == '|')
-				browseurl[z] = ':';
-			if(browseurl[z] == '/')
-				browseurl[z] = '\\';
-		}
-	}
-
-	retcode = (int)ShellExecute(NULL, "open", browseurl, NULL, NULL, SW_SHOWNORMAL);
-	if(retcode<33 && retcode != 2)
-		return -1;
-	return 1;
-}
-
-/*
- * Returns a pointer to a static buffer which containes the
- * current user directory.  Or the root directory (C:\ on
- * OS/2 and Windows).
- */
-char * API dw_user_dir(void)
-{
-	static char _user_dir[1024] = "";
-
-	if(!_user_dir[0])
-	{
-		/* Figure out how to do this the "Windows way" */
-		char *home = getenv("HOME");
-
-		if(home)
-			strcpy(_user_dir, home);
-		else
-			strcpy(_user_dir, "C:\\");
-	}
-	return _user_dir;
-}
-
-/*
- * Call a function from the window (widget)'s context.
- * Parameters:
- *       handle: Window handle of the widget.
- *       function: Function pointer to be called.
- *       data: Pointer to the data to be passed to the function.
- */
-void API dw_window_function(HWND handle, void *function, void *data)
-{
-	SendMessage(handle, WM_USER, (WPARAM)function, (LPARAM)data);
-}
-
-/* Functions for managing the user data lists that are associated with
- * a given window handle.  Used in dw_window_set_data() and
- * dw_window_get_data().
- */
-UserData *_find_userdata(UserData **root, char *varname)
-{
-	UserData *tmp = *root;
-
-	while(tmp)
-	{
-		if(stricmp(tmp->varname, varname) == 0)
-			return tmp;
-		tmp = tmp->next;
-	}
-	return NULL;
-}
-
-int _new_userdata(UserData **root, char *varname, void *data)
-{
-	UserData *new = _find_userdata(root, varname);
-
-	if(new)
-	{
-		new->data = data;
-		return TRUE;
-	}
-	else
-	{
-		new = malloc(sizeof(UserData));
-		if(new)
-		{
-			new->varname = strdup(varname);
-			new->data = data;
-
-			new->next = NULL;
-
-			if (!*root)
-				*root = new;
-			else
-			{
-				UserData *prev = NULL, *tmp = *root;
-				while(tmp)
-				{
-					prev = tmp;
-					tmp = tmp->next;
-				}
-				if(prev)
-					prev->next = new;
-				else
-					*root = new;
-			}
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-int _remove_userdata(UserData **root, char *varname, int all)
-{
-	UserData *prev = NULL, *tmp = *root;
-
-	while(tmp)
-	{
-		if(all || stricmp(tmp->varname, varname) == 0)
-		{
-			if(!prev)
-			{
-				*root = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				if(!all)
-					return 0;
-				tmp = *root;
-			}
-			else
-			{
-				/* If all is true we should
-				 * never get here.
-				 */
-				prev->next = tmp->next;
-				free(tmp->varname);
-				free(tmp);
-				return 0;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-	return 0;
-}
-
-/*
- * Add a named user data item to a window handle.
- * Parameters:
- *       window: Window handle of signal to be called back.
- *       dataname: A string pointer identifying which signal to be hooked.
- *       data: User data to be passed to the handler function.
- */
-void API dw_window_set_data(HWND window, char *dataname, void *data)
-{
-	ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
-
-	if(!cinfo)
-	{
-		if(!dataname)
-			return;
-
-		cinfo = calloc(1, sizeof(ColorInfo));
-		cinfo->fore = cinfo->back = -1;
-		SetWindowLongPtr(window, GWLP_USERDATA, (LONG_PTR)cinfo);
-	}
-
-	if(cinfo)
-	{
-		if(data)
-			_new_userdata(&(cinfo->root), dataname, data);
-		else
-		{
-			if(dataname)
-				_remove_userdata(&(cinfo->root), dataname, FALSE);
-			else
-				_remove_userdata(&(cinfo->root), NULL, TRUE);
-		}
-	}
-}
-
-/*
- * Gets a named user data item to a window handle.
- * Parameters:
- *       window: Window handle of signal to be called back.
- *       dataname: A string pointer identifying which signal to be hooked.
- *       data: User data to be passed to the handler function.
- */
-void * API dw_window_get_data(HWND window, char *dataname)
-{
-	ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
-
-	if(cinfo && cinfo->root && dataname)
-	{
-		UserData *ud = _find_userdata(&(cinfo->root), dataname);
-		if(ud)
-			return ud->data;
-	}
-	return NULL;
-}
-
-/*
- * Add a callback to a timer event.
- * Parameters:
- *       interval: Milliseconds to delay between calls.
- *       sigfunc: The pointer to the function to be used as the callback.
- *       data: User data to be passed to the handler function.
- * Returns:
- *       Timer ID for use with dw_timer_disconnect(), 0 on error.
- */
-int API dw_timer_connect(int interval, void *sigfunc, void *data)
-{
-	if(sigfunc)
-	{
-		int timerid = SetTimer(NULL, 0, interval, _TimerProc);
-
-		if(timerid)
-		{
-			_new_signal(WM_TIMER, NULL, timerid, sigfunc, data);
-			return timerid;
-		}
-	}
-	return 0;
-}
-
-/*
- * Removes timer callback.
- * Parameters:
- *       id: Timer ID returned by dw_timer_connect().
- */
-void API dw_timer_disconnect(int id)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	/* 0 is an invalid timer ID */
-	if(!id)
-		return;
-
-	KillTimer(NULL, id);
-
-	while(tmp)
-	{
-		if(tmp->id == id)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Add a callback to a window event.
- * 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.
- *       data: User data to be passed to the handler function.
- */
-void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
-{
-	ULONG message = 0, id = 0;
-
-	if(window && signame && sigfunc)
-	{
-		if(stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
-			window = _normalize_handle(window);
-
-		if((message = _findsigmessage(signame)) != 0)
-		{
-			/* Handle special case of the menu item */
-			if(message == WM_COMMAND && window < (HWND)65536)
-			{
-				char buffer[15];
-				HWND owner;
-
-				sprintf(buffer, "_dw_id%d", (int)window);
-				owner = (HWND)dw_window_get_data(DW_HWND_OBJECT, buffer);
-
-				if(owner)
-				{
-					id = (ULONG)window;
-					window = owner;
-					dw_window_set_data(DW_HWND_OBJECT, buffer, 0);
-				}
-				else
-				{
-					/* If it is a popup menu clear all entries */
-					dw_signal_disconnect_by_window(window);
-				}
-			}
-			_new_signal(message, window, id, sigfunc, data);
-		}
-	}
-}
-
-/*
- * Removes callbacks for a given window with given name.
- * Parameters:
- *       window: Window handle of callback to be removed.
- */
-void API dw_signal_disconnect_by_name(HWND window, char *signame)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-	ULONG message;
-
-	if(!window || !signame || (message = _findsigmessage(signame)) == 0)
-		return;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->message == message)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Removes all callbacks for a given window.
- * Parameters:
- *       window: Window handle of callback to be removed.
- */
-void API dw_signal_disconnect_by_window(HWND window)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
-/*
- * Removes all callbacks for a given window with specified data.
- * Parameters:
- *       window: Window handle of callback to be removed.
- *       data: Pointer to the data to be compared against.
- */
-void API dw_signal_disconnect_by_data(HWND window, void *data)
-{
-	SignalHandler *prev = NULL, *tmp = Root;
-
-	while(tmp)
-	{
-		if(tmp->window == window && tmp->data == data)
-		{
-			if(prev)
-			{
-				prev->next = tmp->next;
-				free(tmp);
-				tmp = prev->next;
-			}
-			else
-			{
-				Root = tmp->next;
-				free(tmp);
-				tmp = Root;
-			}
-		}
-		else
-		{
-			prev = tmp;
-			tmp = tmp->next;
-		}
-	}
-}
-
+/*
+ * Dynamic Windows:
+ *          A GTK like implementation of the Win32 GUI
+ *
+ * (C) 2000-2011 Brian Smith <brian@dbsoft.org>
+ * (C) 2003-2005 Mark Hessling <m.hessling@qut.edu.au>
+ *
+ */
+#define _WIN32_IE 0x0500
+#define WINVER 0x500
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <shlwapi.h>
+#include <shlobj.h>
+#include <userenv.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <process.h>
+#include <time.h>
+#include <math.h>
+#include "dw.h"
+#include "XBrowseForFolder.h"
+
+#ifdef GDIPLUS
+/* GDI+ Headers are not C compatible... so define what we need here instead */
+struct GdiplusStartupInput
+{
+    UINT32 GdiplusVersion;
+    void *DebugEventCallback;
+    BOOL SuppressBackgroundThread;
+    BOOL SuppressExternalCodecs;       
+};
+
+typedef enum  {
+  Ok                          = 0,
+  GenericError                = 1,
+  InvalidParameter            = 2,
+  OutOfMemory                 = 3,
+  ObjectBusy                  = 4,
+  InsufficientBuffer          = 5,
+  NotImplemented              = 6,
+  Win32Error                  = 7,
+  WrongState                  = 8,
+  Aborted                     = 9,
+  FileNotFound                = 10,
+  ValueOverflow               = 11,
+  AccessDenied                = 12,
+  UnknownImageFormat          = 13,
+  FontFamilyNotFound          = 14,
+  FontStyleNotFound           = 15,
+  NotTrueTypeFont             = 16,
+  UnsupportedGdiplusVersion   = 17,
+  GdiplusNotInitialized       = 18,
+  PropertyNotFound            = 19,
+  PropertyNotSupported        = 20,
+  ProfileNotFound             = 21 
+} Status;
+
+Status WINAPI GdipCreateBitmapFromFile(const WCHAR* filename, void **bitmap);
+Status WINAPI GdipCreateHBITMAPFromBitmap(void *bitmap, HBITMAP* hbmReturn, DWORD background);
+Status WINAPI GdipCreateHICONFromBitmap(void *bitmap, HICON *hbmReturn);
+Status WINAPI GdipDisposeImage(void *image);
+Status WINAPI GdipGetImagePixelFormat(void *image, INT *format);
+Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, void *output);
+VOID WINAPI GdiplusShutdown(ULONG_PTR token);
+
+/* Pixel format information */
+#define    PixelFormatIndexed      0x00010000 
+#define    PixelFormatGDI          0x00020000
+#define    PixelFormatAlpha        0x00040000
+#define    PixelFormatPAlpha       0x00080000
+#define    PixelFormatExtended     0x00100000
+#define    PixelFormatCanonical    0x00200000 
+
+#define    PixelFormatUndefined       0
+#define    PixelFormatDontCare        0
+
+#define    PixelFormat1bppIndexed     (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat4bppIndexed     (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat8bppIndexed     (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define    PixelFormat16bppGrayScale  (4 | (16 << 8) | PixelFormatExtended)
+#define    PixelFormat16bppRGB555     (5 | (16 << 8) | PixelFormatGDI)
+#define    PixelFormat16bppRGB565     (6 | (16 << 8) | PixelFormatGDI)
+#define    PixelFormat16bppARGB1555   (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
+#define    PixelFormat24bppRGB        (8 | (24 << 8) | PixelFormatGDI)
+#define    PixelFormat32bppRGB        (9 | (32 << 8) | PixelFormatGDI)
+#define    PixelFormat32bppARGB       (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
+#define    PixelFormat32bppPARGB      (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
+#define    PixelFormat48bppRGB        (12 | (48 << 8) | PixelFormatExtended)
+#define    PixelFormat64bppARGB       (13 | (64 << 8) | PixelFormatAlpha  | PixelFormatCanonical | PixelFormatExtended)
+#define    PixelFormat64bppPARGB      (14 | (64 << 8) | PixelFormatAlpha  | PixelFormatPAlpha | PixelFormatExtended)
+#define    PixelFormat32bppCMYK       (15 | (32 << 8))
+
+/* Token to the GDI+ Instance */
+ULONG_PTR gdiplusToken; 
+#endif
+
+/*
+ * MinGW (as at 3.2.3) doesn't have MIM_MENUDATA
+ * so #define it here
+ */
+
+#if !defined( MIM_MENUDATA )
+# define MIM_MENUDATA 0x00000008
+#endif
+
+HWND popup = (HWND)NULL, DW_HWND_OBJECT = (HWND)NULL;
+
+HINSTANCE DWInstance = NULL;
+
+DWORD dwVersion = 0, dwComctlVer = 0;
+DWTID _dwtid = -1;
+SECURITY_DESCRIPTOR _dwsd;
+
+#define PACKVERSION(major,minor) MAKELONG(minor,major)
+
+#define IS_XPPLUS (dwComctlVer >= PACKVERSION(5,82))
+#define IS_VISTAPLUS (dwComctlVer >= PACKVERSION(6,10))
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/*
+ * 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
+ * We use _tempnam() which uses TMP env variable by default. It can be passed
+ * an alternate temporary directory if TMP is not set, so we get the value
+ * of TEMP and store it here.
+ */
+static char _dw_alternate_temp_dir[MAX_PATH+1];
+
+int main(int argc, char *argv[]);
+
+#define ICON_INDEX_LIMIT 200
+HICON lookup[200];
+HIMAGELIST hSmall  = 0, hLarge = 0;
+
+/* Special flag used for internal tracking */
+#define DW_CFA_RESERVED (1 << 30)
+
+DWORD _foreground;
+DWORD _background;
+DWORD _hPen;
+DWORD _hBrush;
+
+BYTE _red[] = {   0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77,
+           0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 };
+BYTE _green[] = { 0x00, 0x00, 0xbb, 0xaa, 0x00, 0x00, 0xbb, 0xaa, 0x77,
+           0x00, 0xff, 0xee, 0x00, 0x00, 0xee, 0xff, 0xaa, 0x00 };
+BYTE _blue[] = {  0x00, 0x00, 0x00, 0x00, 0xcc, 0xbb, 0xbb, 0xaa, 0x77,
+            0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0xff, 0xaa, 0x00};
+
+HBRUSH _colors[18];
+
+static int screenx, screeny;
+HFONT _DefaultFont = NULL;
+
+LRESULT CALLBACK _browserWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+void _resize_notebook_page(HWND handle, int pageid);
+void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y);
+int _lookup_icon(HWND handle, HICON hicon, int type);
+HFONT _acquire_font(HWND handle, char *fontname);
+void _click_default(HWND handle);
+void _do_resize(Box *thisbox, int x, int y);
+
+typedef struct _sighandler
+{
+   struct _sighandler   *next;
+   ULONG message;
+   HWND window;
+   int id;
+   void *signalfunction;
+   void *data;
+
+} SignalHandler;
+
+SignalHandler *Root = NULL;
+
+typedef struct
+{
+   ULONG message;
+   char name[30];
+
+} SignalList;
+
+static int in_checkbox_handler = 0;
+
+/* List of signals and their equivilent Win32 message */
+#define SIGNALMAX 17
+
+SignalList SignalTranslate[SIGNALMAX] = {
+   { WM_SIZE,         DW_SIGNAL_CONFIGURE },
+   { WM_CHAR,         DW_SIGNAL_KEY_PRESS },
+   { WM_LBUTTONDOWN,  DW_SIGNAL_BUTTON_PRESS },
+   { WM_LBUTTONUP,    DW_SIGNAL_BUTTON_RELEASE },
+   { WM_MOUSEMOVE,    DW_SIGNAL_MOTION_NOTIFY },
+   { WM_CLOSE,        DW_SIGNAL_DELETE },
+   { WM_PAINT,        DW_SIGNAL_EXPOSE },
+   { WM_COMMAND,      DW_SIGNAL_CLICKED },
+   { NM_DBLCLK,       DW_SIGNAL_ITEM_ENTER },
+   { NM_RCLICK,       DW_SIGNAL_ITEM_CONTEXT },
+   { LBN_SELCHANGE,   DW_SIGNAL_LIST_SELECT },
+   { TVN_SELCHANGED,  DW_SIGNAL_ITEM_SELECT },
+   { WM_SETFOCUS,     DW_SIGNAL_SET_FOCUS },
+   { WM_VSCROLL,      DW_SIGNAL_VALUE_CHANGED },
+   { TCN_SELCHANGE,   DW_SIGNAL_SWITCH_PAGE },
+   { LVN_COLUMNCLICK, DW_SIGNAL_COLUMN_CLICK },
+   { TVN_ITEMEXPANDED,DW_SIGNAL_TREE_EXPAND }
+};
+
+#ifdef BUILD_DLL
+void Win32_Set_Instance(HINSTANCE hInstance)
+{
+   DWInstance = hInstance;
+}
+#else
+char **_convertargs(int *count, char *start)
+{
+   char *tmp, *argstart, **argv;
+   int loc = 0, inquotes = 0;
+
+   (*count) = 1;
+
+   tmp = start;
+
+   /* Count the number of entries */
+   if(*start)
+   {
+      (*count)++;
+
+      while(*tmp)
+      {
+         if(*tmp == '"' && inquotes)
+            inquotes = 0;
+         else if(*tmp == '"' && !inquotes)
+            inquotes = 1;
+         else if(*tmp == ' ' && !inquotes)
+         {
+            /* Push past any white space */
+            while(*(tmp+1) == ' ')
+               tmp++;
+            /* If we aren't at the end of the command
+             * line increment the count.
+             */
+            if(*(tmp+1))
+               (*count)++;
+         }
+         tmp++;
+      }
+   }
+
+   argv = (char **)malloc(sizeof(char *) * ((*count)+1));
+   argv[0] = malloc(260);
+   GetModuleFileName(DWInstance, argv[0], 260);
+
+   argstart = tmp = start;
+
+   if(*start)
+   {
+      loc = 1;
+
+      while(*tmp)
+      {
+         if(*tmp == '"' && inquotes)
+         {
+            *tmp = 0;
+            inquotes = 0;
+         }
+         else if(*tmp == '"' && !inquotes)
+         {
+            argstart = tmp+1;
+            inquotes = 1;
+         }
+         else if(*tmp == ' ' && !inquotes)
+         {
+            *tmp = 0;
+            argv[loc] = strdup(argstart);
+
+            /* Push past any white space */
+            while(*(tmp+1) == ' ')
+               tmp++;
+
+            /* Move the start pointer */
+            argstart = tmp+1;
+
+            /* If we aren't at the end of the command
+             * line increment the count.
+             */
+            if(*(tmp+1))
+               loc++;
+         }
+         tmp++;
+      }
+      if(*argstart)
+         argv[loc] = strdup(argstart);
+   }
+   argv[loc+1] = NULL;
+   return argv;
+}
+
+/* Ok this is a really big hack but what the hell ;) */
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+   char **argv;
+   int argc;
+
+   DWInstance = hInstance;
+
+   argv = _convertargs(&argc, lpCmdLine);
+
+   return main(argc, argv);
+}
+#endif
+
+DWORD GetDllVersion(LPCTSTR lpszDllName)
+{
+
+   HINSTANCE hinstDll;
+   DWORD dwVersion = 0;
+
+   hinstDll = LoadLibrary(lpszDllName);
+
+   if(hinstDll)
+   {
+      DLLGETVERSIONPROC pDllGetVersion;
+
+      pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hinstDll, "DllGetVersion");
+
+      /* Because some DLLs might not implement this function, you
+       * must test for it explicitly. Depending on the particular
+       * DLL, the lack of a DllGetVersion function can be a useful
+       * indicator of the version.
+       */
+      if(pDllGetVersion)
+      {
+         DLLVERSIONINFO dvi;
+         HRESULT hr;
+
+         ZeroMemory(&dvi, sizeof(dvi));
+         dvi.cbSize = sizeof(dvi);
+
+            hr = (*pDllGetVersion)(&dvi);
+
+         if(SUCCEEDED(hr))
+         {
+            dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion);
+         }
+      }
+
+      FreeLibrary(hinstDll);
+   }
+    return dwVersion;
+}
+
+#ifdef GDIPLUS
+/*
+ * List those icons that have transparency first
+ * GDI+ List of supported formats: BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF.
+ * Not sure if we should include all these or not... maybe we should add TIFF and GIF?
+ */
+#define NUM_EXTS 8
+char *image_exts[NUM_EXTS] =
+{
+   "",
+   ".png",
+   ".ico",
+   ".gif",
+   ".jpg",
+   ".jpeg",
+   ".tiff",
+   ".bmp"
+};
+
+/* Section for loading files of types besides BMP and ICO and return HBITMAP or HICON */
+void *_dw_load_gpbitmap( char *filename )
+{
+   int found_ext = 0,i, wclen = (strlen(filename) + 6) * sizeof(wchar_t);
+   char *file = _alloca(strlen(filename) + 6);
+   wchar_t *wfile = _alloca(wclen);
+   void *image;
+
+   /* Try various extentions */
+   for ( i = 0; i < NUM_EXTS; i++ )
+   {
+      strcpy( file, filename );
+      strcat( file, image_exts[i] );
+      if ( access( file, 04 ) == 0 )
+      {
+         /* Convert to wide format */
+         MultiByteToWideChar(CP_ACP, 0, file, strlen(file)+1, wfile, wclen);
+         if(!GdipCreateBitmapFromFile(wfile, &image))
+             return image;
+      }
+   }
+   return NULL;
+}
+
+/* Try to load the appropriate image and return the HBITMAP handle */
+HBITMAP _dw_load_bitmap(char *filename, unsigned long *depth)
+{
+    void *bitmap = _dw_load_gpbitmap(filename);
+    if(bitmap)
+    {
+        HBITMAP hbm = NULL;
+
+        if(!GdipCreateHBITMAPFromBitmap(bitmap, &hbm, 0))
+        {
+            if(depth)
+            {
+                INT pf;
+
+                /* Default to 0 */
+                *depth = 0;
+
+                /* Query the pixel format so we can determine the depth */
+                if(!GdipGetImagePixelFormat(bitmap, &pf))
+                {
+                    switch(pf)
+                    {
+                    case PixelFormat1bppIndexed:
+                        *depth = 1;
+                        break;
+                    case PixelFormat4bppIndexed:
+                        *depth = 4;
+                        break;
+                    case PixelFormat8bppIndexed:
+                        *depth = 8;
+                        break;
+                    case PixelFormat16bppGrayScale:
+                    case PixelFormat16bppRGB555:
+                    case PixelFormat16bppRGB565:
+                    case PixelFormat16bppARGB1555:
+                        *depth = 16;
+                        break;
+                    case PixelFormat24bppRGB:
+                        *depth = 24;
+                        break;
+                    case PixelFormat32bppRGB:
+                    case PixelFormat32bppARGB:
+                    case PixelFormat32bppPARGB:
+                    case PixelFormat32bppCMYK:
+                        *depth = 32;
+                        break;
+                    case PixelFormat48bppRGB:
+                        *depth = 48;
+                        break;
+                    case PixelFormat64bppARGB:
+                    case PixelFormat64bppPARGB:
+                        *depth = 64;
+                        break;
+                    }
+                }
+            }
+        }
+        GdipDisposeImage(bitmap);
+        return hbm;
+    }
+    return NULL;
+}
+
+/* Try to load the appropriate image and return the HICON handle */
+HICON _dw_load_icon(char *filename)
+{
+    void *bitmap = _dw_load_gpbitmap(filename);
+    if(bitmap)
+    {
+        HICON hicon = NULL;
+
+        GdipCreateHICONFromBitmap(bitmap, &hicon);
+        GdipDisposeImage(bitmap);
+        return hicon;
+    }
+    return NULL;
+}
+#endif
+
+/* This function adds a signal handler callback into the linked list.
+ */
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
+{
+   SignalHandler *new = malloc(sizeof(SignalHandler));
+
+   new->message = message;
+   new->window = window;
+   new->id = id;
+   new->signalfunction = signalfunction;
+   new->data = data;
+   new->next = NULL;
+
+   if (!Root)
+   {
+      Root = new;
+   }
+   else
+   {
+      SignalHandler *prev = NULL, *tmp = Root;
+      while(tmp)
+      {
+         if(tmp->message == message &&
+            tmp->window == window &&
+            tmp->id == id &&
+            tmp->signalfunction == signalfunction)
+         {
+            tmp->data = data;
+            free(new);
+            return;
+         }
+         prev = tmp;
+         tmp = tmp->next;
+      }
+      if(prev)
+         prev->next = new;
+      else
+         Root = new;
+   }
+}
+
+/* Finds the message number for a given signal name */
+ULONG _findsigmessage(char *signame)
+{
+   int z;
+
+   for(z=0;z<SIGNALMAX;z++)
+   {
+      if(stricmp(signame, SignalTranslate[z].name) == 0)
+         return SignalTranslate[z].message;
+   }
+   return 0L;
+}
+
+/* This function removes and handlers on windows and frees
+ * the user memory allocated to it.
+ */
+BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam)
+{
+   ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   HFONT oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
+   HICON oldicon = (HICON)SendMessage(handle, WM_GETICON, 0, 0);
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* Don't try to free memory from an OLE embedded IE */
+   if(strncmp(tmpbuf, "Internet Explorer_Server", 25) == 0)
+      return TRUE;
+
+   /* Delete font, icon and bitmap GDI objects in use */
+   if(oldfont)
+      DeleteObject(oldfont);
+   if(oldicon)
+      DeleteObject(oldicon);
+
+   if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
+   {
+      HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
+
+      if(oldbitmap)
+         DeleteObject(oldbitmap);
+   }
+   if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
+   {
+      HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, BM_GETIMAGE, IMAGE_BITMAP, 0);
+
+      if(oldbitmap)
+         DeleteObject(oldbitmap);
+   }
+   else if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+   {
+      Box *box = (Box *)thiscinfo;
+
+      if(box && box->count && box->items)
+         free(box->items);
+   }
+   else if(strnicmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+   {
+      void *data = dw_window_get_data(handle, "_dw_percent");
+
+      if(data)
+         free(data);
+   }
+   else if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)==0)
+   {
+      dw_tree_clear(handle);
+   }
+   else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL)+1)==0) /* Notebook */
+   {
+      NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+
+      if(array)
+      {
+         int z;
+
+         for(z=0;z<256;z++)
+         {
+            if(array[z])
+            {
+               _free_window_memory(array[z]->hwnd, 0);
+               EnumChildWindows(array[z]->hwnd, _free_window_memory, 0);
+               DestroyWindow(array[z]->hwnd);
+               free(array[z]);
+            }
+         }
+         free(array);
+      }
+   }
+   else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
+   {
+      /* for spinbuttons, we need to get the spinbutton's "buddy", the text window associated and destroy it */
+      ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+      if(cinfo && cinfo->buddy)
+         DestroyWindow( cinfo->buddy );
+   }
+
+   dw_signal_disconnect_by_window(handle);
+
+   if(thiscinfo)
+   {
+      SubclassWindow(handle, thiscinfo->pOldProc);
+
+      /* Delete the brush so as not to leak GDI objects */
+      if(thiscinfo->hbrush)
+         DeleteObject(thiscinfo->hbrush);
+
+      /* Free user data linked list memory */
+      if(thiscinfo->root)
+         dw_window_set_data(handle, NULL, NULL);
+
+      SetWindowLongPtr(handle, GWLP_USERDATA, 0);
+      free(thiscinfo);
+   }
+   return TRUE;
+}
+
+void _free_menu_data(HMENU menu)
+{
+    int i, count = GetMenuItemCount(menu);
+
+    for(i=0;i<count;i++)
+    {
+        MENUITEMINFO mii;
+
+        mii.cbSize = sizeof(MENUITEMINFO);
+        mii.fMask = MIIM_SUBMENU | MIIM_ID;
+
+        if ( GetMenuItemInfo( menu, i, TRUE, &mii ) )
+        {  
+           /* Free the data associated with the ID */
+           if(mii.wID >= 30000)
+           {
+              char buffer[31] = {0};
+           
+              _snprintf(buffer, 30, "_dw_id%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_checkable%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_ischecked%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+              _snprintf(buffer, 30, "_dw_isdisabled%ld", mii.wID);
+              dw_window_set_data( DW_HWND_OBJECT, buffer, NULL );
+           }
+           
+           /* Check any submenus */
+           if( mii.hSubMenu )
+              _free_menu_data(mii.hSubMenu);
+        }
+    }
+    dw_signal_disconnect_by_name((HWND)menu, DW_SIGNAL_CLICKED);
+}
+
+/* Convert to our internal color scheme */
+ULONG _internal_color(ULONG color)
+{
+   if(color == DW_CLR_DEFAULT)
+      return DW_RGB_TRANSPARENT;
+   if(color < 18)
+      return DW_RGB(_red[color], _green[color], _blue[color]);
+   return color;
+}
+
+/* This function returns 1 if the window (widget) handle
+ * passed to it is a valid window that can gain input focus.
+ */
+int _validate_focus(HWND handle)
+{
+   char tmpbuf[100];
+
+   if(!handle)
+      return 0;
+
+   if(!IsWindowEnabled(handle))
+      return 0;
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1)==0 ||          /* Entryfield */
+      strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0 ||      /* Button */
+      strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0 ||  /* Combobox */
+      strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME)+1)==0 ||    /* List box */
+      strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0 ||            /* Spinbutton */
+      strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0 ||        /* Slider */
+      strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)== 0 ||             /* Container */
+      strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW)+1)== 0)               /* Tree */
+      return 1;
+   return 0;
+}
+
+HWND _normalize_handle(HWND handle)
+{
+   char tmpbuf[100] = "";
+
+   GetClassName(handle, tmpbuf, 99);
+   if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) /* Spinner */
+   {
+      ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+      if(cinfo && cinfo->buddy)
+         return cinfo->buddy;
+   }
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) /* Combobox */
+   {
+      ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+      if(cinfo && cinfo->buddy)
+         return cinfo->buddy;
+   }
+   return handle;
+}
+
+int _focus_check_box(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=box->count-1;z>-1;z--)
+   {
+      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))
+            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
+         {
+            char tmpbuf[100] = "";
+
+            GetClassName(box->items[z].hwnd, tmpbuf, 99);
+
+            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 *)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");
+
+               if(mybox)
+               {
+                  Box *splitbox = (Box *)GetWindowLongPtr(mybox, GWLP_USERDATA);
+
+                  if(splitbox && _focus_check_box(splitbox, handle, start == 3 ? 3 : 0, defaultitem))
+                     return 1;
+               }
+            }
+            else if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(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(notebox, handle, start == 3 ? 3 : 0, defaultitem))
+                        return 1;
+                  }
+               }
+            }
+            else if(strnicmp(tmpbuf, ScrollClassName, strlen(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(scrollbox, handle, start == 3 ? 3 : 0, 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))
+            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
+         {
+            char tmpbuf[100] = "";
+
+            GetClassName(box->items[z].hwnd, tmpbuf, 99);
+
+            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 *)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(strnicmp(tmpbuf, WC_TABCONTROL, strlen(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(strnicmp(tmpbuf, ScrollClassName, strlen(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;
+}
+
+/* This function finds the first widget in the
+ * layout and moves the current focus to it.
+ */
+void _initial_focus(HWND handle)
+{
+   Box *thisbox;
+   char tmpbuf[100];
+
+   if(!handle)
+      return;
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, ClassName, strlen(ClassName))!=0)
+      return;
+
+
+   if(handle)
+      thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   if(thisbox)
+   {
+      _focus_check_box(thisbox, handle, 3, thisbox->defaultitem);
+   }
+}
+
+HWND _toplevel_window(HWND handle)
+{
+   HWND box, lastbox = GetParent(handle);
+
+   /* Find the toplevel window */
+   while((box = GetParent(lastbox)))
+   {
+      lastbox = box;
+   }
+   if(lastbox)
+      return lastbox;
+   return handle;
+}
+
+/* This function finds the current widget in the
+ * layout and moves the current focus to the next item.
+ */
+void _shift_focus(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(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);
+   }
+}
+
+/* This function calculates how much space the widgets and boxes require
+ * and does expansion as necessary.
+ */
+int _resize_box(Box *thisbox, int *depth, int x, int y, int *usedx, int *usedy,
+            int pass, int *usedpadx, int *usedpady)
+{
+   int z, currentx = 0, currenty = 0;
+   int uymax = 0, uxmax = 0;
+   int upymax = 0, upxmax = 0;
+   /* Used for the SIZEEXPAND */
+   int nux = *usedx, nuy = *usedy;
+   int nupx = *usedpadx, nupy = *usedpady;
+
+   (*usedx) += (thisbox->pad * 2);
+   (*usedy) += (thisbox->pad * 2);
+
+   if(thisbox->grouphwnd)
+   {
+      char *text = dw_window_get_text(thisbox->grouphwnd);
+
+      thisbox->grouppady = 0;
+
+      if(text)
+      {
+         dw_font_text_extents_get(thisbox->grouphwnd, 0, text, NULL, &thisbox->grouppady);
+         dw_free(text);
+      }
+
+      if(thisbox->grouppady)
+         thisbox->grouppady += 3;
+      else
+         thisbox->grouppady = 6;
+
+      thisbox->grouppadx = 6;
+
+      (*usedx) += thisbox->grouppadx;
+      (*usedpadx) += thisbox->grouppadx;
+      (*usedy) += thisbox->grouppady;
+      (*usedpady) += thisbox->grouppady;
+   }
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         int initialx, initialy;
+         Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
+
+         initialx = x - (*usedx);
+         initialy = y - (*usedy);
+
+         if(tmp)
+         {
+            int newx, newy;
+            int nux = *usedx, nuy = *usedy;
+            int upx = *usedpadx + (tmp->pad*2), upy = *usedpady + (tmp->pad*2);
+
+            /* On the second pass we know how big the box needs to be and how
+             * much space we have, so we can calculate a ratio for the new box.
+             */
+            if(pass == 2)
+            {
+               int deep = *depth + 1;
+
+               _resize_box(tmp, &deep, x, y, &nux, &nuy, 1, &upx, &upy);
+
+               tmp->upx = upx - *usedpadx;
+               tmp->upy = upy - *usedpady;
+
+               newx = x - nux;
+               newy = y - nuy;
+
+               tmp->width = thisbox->items[z].width = initialx - newx;
+               tmp->height = thisbox->items[z].height = initialy - newy;
+
+               tmp->parentxratio = thisbox->xratio;
+               tmp->parentyratio = thisbox->yratio;
+
+               tmp->parentpad = tmp->pad;
+
+               /* Just in case */
+               tmp->xratio = thisbox->xratio;
+               tmp->yratio = thisbox->yratio;
+
+               if(thisbox->type == DW_VERT)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppady;
+
+                  if((thisbox->items[z].width - tmppad)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmppad))/((float)(thisbox->items[z].width-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].width-tmp->upx)!=0)
+                     tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-tmp->upx))/((float)(thisbox->items[z].width-tmp->upx));
+               }
+               if(thisbox->type == DW_HORZ)
+               {
+                  int tmppad = (thisbox->items[z].pad*2)+(tmp->pad*2)+tmp->grouppadx;
+
+                  if((thisbox->items[z].height-tmppad)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmppad))/((float)(thisbox->items[z].height-tmppad));
+               }
+               else
+               {
+                  if((thisbox->items[z].height-tmp->upy)!=0)
+                     tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-tmp->upy))/((float)(thisbox->items[z].height-tmp->upy));
+               }
+
+               nux = *usedx; nuy = *usedy;
+               upx = *usedpadx + (tmp->pad*2); upy = *usedpady + (tmp->pad*2);
+            }
+
+            (*depth)++;
+
+            _resize_box(tmp, depth, x, y, &nux, &nuy, pass, &upx, &upy);
+
+            (*depth)--;
+
+            newx = x - nux;
+            newy = y - nuy;
+
+            tmp->minwidth = thisbox->items[z].width = initialx - newx;
+            tmp->minheight = thisbox->items[z].height = initialy - newy;
+         }
+      }
+
+      if(pass > 1 && *depth > 0)
+      {
+         if(thisbox->type == DW_VERT)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppadx;
+
+            if((thisbox->minwidth-tmppad) == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-tmppad))/((float)(thisbox->minwidth-tmppad));
+         }
+         else
+         {
+            if(thisbox->minwidth-thisbox->upx == 0)
+               thisbox->items[z].xratio = 1.0;
+            else
+               thisbox->items[z].xratio = ((float)((thisbox->width * thisbox->parentxratio)-thisbox->upx))/((float)(thisbox->minwidth-thisbox->upx));
+         }
+
+         if(thisbox->type == DW_HORZ)
+         {
+            int tmppad = (thisbox->items[z].pad*2)+(thisbox->parentpad*2)+thisbox->grouppady;
+
+            if((thisbox->minheight-tmppad) == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-tmppad))/((float)(thisbox->minheight-tmppad));
+         }
+         else
+         {
+            if(thisbox->minheight-thisbox->upy == 0)
+               thisbox->items[z].yratio = 1.0;
+            else
+               thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy));
+         }
+
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
+
+            if(tmp)
+            {
+               tmp->parentxratio = thisbox->items[z].xratio;
+               tmp->parentyratio = thisbox->items[z].yratio;
+            }
+         }
+      }
+      else
+      {
+         thisbox->items[z].xratio = thisbox->xratio;
+         thisbox->items[z].yratio = thisbox->yratio;
+      }
+
+      if(thisbox->type == DW_VERT)
+      {
+         int itemwidth = (thisbox->items[z].pad*2) + thisbox->items[z].width;
+
+         if(itemwidth > uxmax)
+            uxmax = itemwidth;
+         if(thisbox->items[z].hsize != SIZEEXPAND)
+         {
+            if(itemwidth > upxmax)
+               upxmax = itemwidth;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upxmax)
+               upxmax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].width == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].width = */
+         }
+         else
+         {
+            (*usedx) += thisbox->items[z].width + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               (*usedpadx) += (thisbox->items[z].pad*2) + thisbox->items[z].width;
+            else
+               (*usedpadx) += thisbox->items[z].pad*2;
+         }
+      }
+      if(thisbox->type == DW_HORZ)
+      {
+         int itemheight = (thisbox->items[z].pad*2) + thisbox->items[z].height;
+
+         if(itemheight > uymax)
+            uymax = itemheight;
+         if(thisbox->items[z].vsize != SIZEEXPAND)
+         {
+            if(itemheight > upymax)
+               upymax = itemheight;
+         }
+         else
+         {
+            if(thisbox->items[z].pad*2 > upymax)
+               upymax = thisbox->items[z].pad*2;
+         }
+      }
+      else
+      {
+         if(thisbox->items[z].height == -1)
+         {
+            /* figure out how much space this item requires */
+            /* thisbox->items[z].height = */
+         }
+         else
+         {
+            (*usedy) += thisbox->items[z].height + (thisbox->items[z].pad*2);
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               (*usedpady) += (thisbox->items[z].pad*2) + thisbox->items[z].height;
+            else
+               (*usedpady) += thisbox->items[z].pad*2;
+         }
+      }
+   }
+
+   (*usedx) += uxmax;
+   (*usedy) += uymax;
+   (*usedpadx) += upxmax;
+   (*usedpady) += upymax;
+
+   currentx += thisbox->pad;
+   currenty += thisbox->pad;
+
+   if(thisbox->grouphwnd)
+   {
+      currentx += 3;
+      currenty += thisbox->grouppady - 3;
+   }
+
+   /* The second pass is for expansion and actual placement. */
+   if(pass > 1)
+   {
+      /* Any SIZEEXPAND items should be set to uxmax/uymax */
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(thisbox->items[z].hsize == SIZEEXPAND && thisbox->type == DW_VERT)
+            thisbox->items[z].width = uxmax-(thisbox->items[z].pad*2);
+         if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == DW_HORZ)
+            thisbox->items[z].height = uymax-(thisbox->items[z].pad*2);
+         /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */
+         if(thisbox->items[z].type == TYPEBOX)
+         {
+            Box *tmp = (Box *)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
+
+            if(tmp)
+            {
+               if(*depth > 0)
+               {
+                  float calcval;
+
+                  if(thisbox->type == DW_VERT)
+                  {
+                     calcval = (float)(tmp->minwidth-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->xratio = thisbox->xratio;
+                     else
+                        tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->width = thisbox->items[z].width;
+                  }
+                  if(thisbox->type == DW_HORZ)
+                  {
+                     calcval = (float)(tmp->minheight-((thisbox->items[z].pad*2)+(thisbox->pad*2)));
+                     if(calcval == 0.0)
+                        tmp->yratio = thisbox->yratio;
+                     else
+                        tmp->yratio = ((float)((thisbox->items[z].height * thisbox->yratio)-((thisbox->items[z].pad*2)+(thisbox->pad*2))))/calcval;
+                     tmp->height = thisbox->items[z].height;
+                  }
+               }
+
+               (*depth)++;
+
+               _resize_box(tmp, depth, x, y, &nux, &nuy, 3, &nupx, &nupy);
+
+               (*depth)--;
+
+            }
+         }
+      }
+
+      for(z=0;z<(thisbox->count);z++)
+      {
+         int height = thisbox->items[z].height;
+         int width = thisbox->items[z].width;
+         int pad = thisbox->items[z].pad;
+         HWND handle = thisbox->items[z].hwnd;
+         int vectorx, vectory;
+
+         /* When upxmax != pad*2 then ratios are incorrect. */
+         vectorx = (int)((width*thisbox->items[z].xratio)-width);
+         vectory = (int)((height*thisbox->items[z].yratio)-height);
+
+         if(width > 0 && height > 0)
+         {
+            char tmpbuf[100];
+            /* This is a hack to fix rounding of the sizing */
+            if(*depth == 0)
+            {
+               vectorx++;
+               vectory++;
+            }
+
+            /* If this item isn't going to expand... reset the vectors to 0 */
+            if(thisbox->items[z].vsize != SIZEEXPAND)
+               vectory = 0;
+            if(thisbox->items[z].hsize != SIZEEXPAND)
+               vectorx = 0;
+
+            GetClassName(handle, tmpbuf, 99);
+
+            if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+            {
+               /* Handle special case Combobox */
+               MoveWindow(handle, currentx + pad, currenty + pad,
+                        width + vectorx, (height + vectory) + 400, FALSE);
+            }
+            else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
+            {
+               /* Handle special case Spinbutton */
+               ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+               MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad,
+                        20, height + vectory, FALSE);
+
+               if(cinfo)
+               {
+                  MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
+                           (width + vectorx) - 20, height + vectory, FALSE);
+               }
+            }
+            else if(strncmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+            {
+                /* Handle special case of scrollbox */
+                ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+                int cx = width + vectorx;
+                int cy = height + vectory;
+                int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0;
+                Box *thisbox = (Box *)GetWindowLongPtr(cinfo->combo, GWLP_USERDATA);
+                SCROLLINFO hsi, vsi;
+                RECT rect;
+
+                vsi.cbSize = hsi.cbSize = sizeof(SCROLLINFO);
+                vsi.fMask = hsi.fMask = SIF_POS;
+
+                /* Save the current scroll positions */
+                GetScrollInfo(handle, SB_HORZ, &hsi);
+                GetScrollInfo(handle, SB_VERT, &vsi);
+
+                /* Position the scrollbox */
+                MoveWindow(handle, currentx + pad, currenty + pad, cx, cy, FALSE);
+
+                GetClientRect(handle, &rect);
+                cx = rect.right;
+                cy = rect.bottom;
+
+
+                /* Get the required space for the box */
+                _resize_box(thisbox, &depth, cx, cy, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+                if(cx < usedx)
+                {
+                    cx = usedx;
+                }
+                if(cy < usedy)
+                {
+                    cy = usedy;
+                }
+
+                /* Position the scrolled box */
+                vsi.fMask = hsi.fMask = SIF_POS | SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL;
+                vsi.nMin = hsi.nMin = vsi.nMax = hsi.nMax = 0;
+                if(rect.bottom < usedy)
+                {
+                    vsi.nMax = usedy;
+                    vsi.nPage = rect.bottom;
+                    if(vsi.nPos > vsi.nMax)
+                    {
+                        vsi.nPos = vsi.nMax;
+                    }
+                }
+                if(rect.right < usedx)
+                {
+                    hsi.nMax = usedx;
+                    hsi.nPage = rect.right;
+                    if(hsi.nPos > hsi.nMax)
+                    {
+                        hsi.nPos = hsi.nMax;
+                    }
+                }
+                MoveWindow(cinfo->combo, -hsi.nPos, -vsi.nPos, cx, cy, FALSE);
+                SetScrollInfo(handle, SB_HORZ, &hsi, TRUE);
+                SetScrollInfo(handle, SB_VERT, &vsi, TRUE);
+
+                /* Layout the content of the scrollbox */
+                _do_resize(thisbox, cx, cy);
+            }
+            else if(strncmp(tmpbuf, SplitbarClassName, strlen(SplitbarClassName)+1)==0)
+            {
+               /* Then try the bottom or right box */
+               float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+               int type = (int)dw_window_get_data(handle, "_dw_type");
+               int cx = width + vectorx;
+               int cy = height + vectory;
+
+               MoveWindow(handle, currentx + pad, currenty + pad,
+                        cx, cy, FALSE);
+
+               if(cx > 0 && cy > 0 && percent)
+                  _handle_splitbar_resize(handle, *percent, type, cx, cy);
+            }
+            else if(strnicmp(tmpbuf, STATICCLASSNAME, strlen(STATICCLASSNAME)+1)==0)
+            {
+               /* Handle special case Vertically Center static text */
+               ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+               if(cinfo && cinfo->vcenter)
+               {
+                  /* We are centered so calculate a new position */
+                  char tmpbuf[1024];
+                  int textheight, diff, total = height + vectory;
+
+                  GetWindowText(handle, tmpbuf, 1023);
+
+                  /* Figure out how big the text is */
+                  dw_font_text_extents_get(handle, 0, tmpbuf, 0, &textheight);
+
+                  diff = (total - textheight) / 2;
+
+                  MoveWindow(handle, currentx + pad, currenty + pad + diff,
+                           width + vectorx, height + vectory - diff, FALSE);
+               }
+               else
+               {
+                  MoveWindow(handle, currentx + pad, currenty + pad,
+                           width + vectorx, height + vectory, FALSE);
+               }
+            }
+            else
+            {
+               /* Everything else */
+               MoveWindow(handle, currentx + pad, currenty + pad,
+                        width + vectorx, height + vectory, FALSE);
+               if(thisbox->items[z].type == TYPEBOX)
+               {
+                  Box *boxinfo = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+                  if(boxinfo && boxinfo->grouphwnd)
+                  {
+                     MoveWindow(boxinfo->grouphwnd, 0, 0,
+                              width + vectorx, height + vectory, FALSE);
+                  }
+
+               }
+            }
+
+            /* Notebook dialog requires additional processing */
+            if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0)
+            {
+               RECT rect;
+               NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+               int pageid = TabCtrl_GetCurSel(handle);
+
+               if(pageid > -1 && array && array[pageid])
+               {
+                  GetClientRect(handle,&rect);
+                  TabCtrl_AdjustRect(handle,FALSE,&rect);
+                  MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
+                           rect.right - rect.left, rect.bottom-rect.top, FALSE);
+               }
+            }
+
+            if(thisbox->type == DW_HORZ)
+               currentx += width + vectorx + (pad * 2);
+            if(thisbox->type == DW_VERT)
+               currenty += height + vectory + (pad * 2);
+         }
+      }
+   }
+   return 0;
+}
+
+void _do_resize(Box *thisbox, int x, int y)
+{
+   if(x != 0 && y != 0)
+   {
+      if(thisbox)
+      {
+         int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady);
+
+         if(usedx-usedpadx == 0 || usedy-usedpady == 0)
+            return;
+
+         thisbox->xratio = ((float)(x-usedpadx))/((float)(usedx-usedpadx));
+         thisbox->yratio = ((float)(y-usedpady))/((float)(usedy-usedpady));
+
+         usedpadx = usedpady = usedx = usedy = depth = 0;
+
+         _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady);
+      }
+   }
+}
+
+int _HandleScroller(HWND handle, int bar, int pos, int which)
+{
+   SCROLLINFO si;
+
+   ZeroMemory( &si, sizeof(si) );
+   si.cbSize = sizeof(SCROLLINFO);
+   si.fMask = SIF_ALL;
+
+   SendMessage(handle, SBM_GETSCROLLINFO, 0, (LPARAM)&si);
+
+   switch(which)
+   {
+   case SB_THUMBTRACK:
+      return pos;
+   /*case SB_PAGEUP:*/
+   case SB_PAGELEFT:
+      pos = si.nPos - si.nPage;
+      if(pos < si.nMin)
+         pos = si.nMin;
+      return pos;
+   /*case SB_PAGEDOWN:*/
+   case SB_PAGERIGHT:
+      pos = si.nPos + si.nPage;
+      if(pos > (si.nMax - si.nPage) + 1)
+         pos = (si.nMax - si.nPage) + 1;
+      return pos;
+   /*case SB_LINEUP:*/
+   case SB_LINELEFT:
+      pos = si.nPos - 1;
+      if(pos < si.nMin)
+         pos = si.nMin;
+      return pos;
+   /*case SB_LINEDOWN:*/
+   case SB_LINERIGHT:
+      pos = si.nPos + 1;
+      if(pos > (si.nMax - si.nPage) + 1)
+         pos = (si.nMax - si.nPage) + 1;
+      return pos;
+   }
+   return -1;
+}
+
+HMENU _get_owner(HMENU menu)
+{
+   MENUINFO mi;
+
+   mi.cbSize = sizeof(MENUINFO);
+   mi.fMask = MIM_MENUDATA;
+
+   if ( GetMenuInfo( menu, &mi ) )
+      return (HMENU)mi.dwMenuData;
+   return (HMENU)0;
+}
+
+/* Find the desktop window handle */
+HMENU _menu_owner(HMENU handle)
+{
+   HMENU menuowner = 0, lastowner = _get_owner(handle);
+
+   /* Find the toplevel menu */
+   while((menuowner = _get_owner(lastowner)) != 0)
+   {
+      if(menuowner == (HMENU)1)
+         return lastowner;
+      lastowner = menuowner;
+   }
+   return (HMENU)0;
+}
+
+/*
+ * Determine if this is a checkable menu. If it is get the current state
+ * and toggle it. Windows doesn't do this automatically :-(
+ */
+static void _dw_toggle_checkable_menu_item( HWND window, int id )
+{
+   char buffer[40];
+   int checkable;
+   sprintf( buffer, "_dw_checkable%ld", id );
+   checkable = (int)dw_window_get_data(DW_HWND_OBJECT, buffer);
+   if ( checkable )
+   {
+      int is_checked;
+      sprintf( buffer, "_dw_ischecked%ld", id );
+      is_checked = (int)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      is_checked = (is_checked) ? 0 : 1;
+      dw_menu_item_set_check( window, id, is_checked );
+   }
+}
+
+/* The main window procedure for Dynamic Windows, all the resizing code is done here. */
+BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   int result = -1, taskbar = FALSE;
+   static int command_active = 0;
+   SignalHandler *tmp = Root;
+   void (*windowfunc)(PVOID);
+   ULONG origmsg = msg;
+
+   /* Deal with translating some messages */
+   if (msg == WM_USER+2)
+   {
+      taskbar = TRUE;
+      origmsg = msg = (UINT)mp2; /* no else here */
+   }
+   if (msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN)
+      msg = WM_LBUTTONDOWN;
+   else if (msg == WM_RBUTTONUP || msg == WM_MBUTTONUP)
+      msg = WM_LBUTTONUP;
+   else if (msg == WM_HSCROLL)
+      msg = WM_VSCROLL;
+   else if (msg == WM_KEYDOWN) /* && mp1 >= VK_F1 && mp1 <= VK_F24) allow ALL special keys */
+      msg = WM_CHAR;
+
+   if (result == -1)
+   {
+      /* Avoid infinite recursion */
+      command_active = 1;
+
+      /* Find any callbacks for this function */
+      while (tmp)
+      {
+         if (tmp->message == msg || msg == WM_COMMAND || msg == WM_NOTIFY || tmp->message == WM_USER+1)
+         {
+            switch (msg)
+            {
+               case WM_TIMER:
+                  {
+                     if (!hWnd)
+                     {
+                        int (*timerfunc)(void *) = tmp->signalfunction;
+                        if (tmp->id == (int)mp1)
+                        {
+                           if (!timerfunc(tmp->data))
+                           {
+                              dw_timer_disconnect(tmp->id);
+                           }
+                           tmp = NULL;
+                        }
+                     }
+                     result = 0;
+                  }
+                  break;
+               case WM_SETFOCUS:
+                  {
+                     int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction;
+
+                     if(hWnd == tmp->window)
+                     {
+                        result = setfocusfunc(tmp->window, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_SIZE:
+                  {
+                     int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction;
+                     if(hWnd == tmp->window)
+                     {
+                        result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_LBUTTONDOWN:
+                  {
+                     int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+
+                     if(hWnd == tmp->window)
+                     {
+                        int button=0;
+
+                        switch(origmsg)
+                        {
+                        case WM_LBUTTONDOWN:
+                           button = 1;
+                           break;
+                        case WM_RBUTTONDOWN:
+                           button = 2;
+                           break;
+                        case WM_MBUTTONDOWN:
+                           button = 3;
+                           break;
+                        }
+                        if(taskbar)
+                        {
+                           POINT ptl;
+                           GetCursorPos(&ptl);
+                           result = buttonfunc(tmp->window, ptl.x, ptl.y, button, tmp->data);
+                        }
+                        else
+                        {
+                           POINTS pts = MAKEPOINTS(mp2);
+                           result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data);
+                        }
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_LBUTTONUP:
+                  {
+                     int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+
+                     if(hWnd == tmp->window)
+                     {
+                        int button=0;
+
+                        switch(origmsg)
+                        {
+                        case WM_LBUTTONUP:
+                           button = 1;
+                           break;
+                        case WM_RBUTTONUP:
+                           button = 2;
+                           break;
+                        case WM_MBUTTONUP:
+                           button = 3;
+                           break;
+                        }
+                        if(taskbar)
+                        {
+                           POINT ptl;
+                           GetCursorPos(&ptl);
+                           result = buttonfunc(tmp->window, ptl.x, ptl.y, button, tmp->data);
+                        }
+                        else
+                        {
+                           POINTS pts = MAKEPOINTS(mp2);
+                           result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data);
+                        }
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_MOUSEMOVE:
+                  {
+                     POINTS pts = MAKEPOINTS(mp2);
+                     int (*motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction;
+
+                     if(hWnd == tmp->window)
+                     {
+                        int keys = 0;
+
+                        if (mp1 & MK_LBUTTON)
+                           keys = DW_BUTTON1_MASK;
+                        if (mp1 & MK_RBUTTON)
+                           keys |= DW_BUTTON2_MASK;
+                        if (mp1 & MK_MBUTTON)
+                           keys |= DW_BUTTON3_MASK;
+
+                        result = motionfunc(tmp->window, pts.x, pts.y, keys, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_CHAR:
+                  {
+                     int (*keypressfunc)(HWND, char, int, int, void *) = tmp->signalfunction;
+
+                     if(hWnd == tmp->window || _toplevel_window(hWnd) == tmp->window)
+                     {
+                        int special = 0;
+                        char ch = 0;
+
+                        if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
+                           special |= KC_SHIFT;
+                        if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
+                           special |= KC_CTRL;
+                               if(mp2 & (1 << 29))
+                           special |= KC_ALT;
+
+                        if(origmsg == WM_CHAR && mp1 < 128)
+                           ch = (char)mp1;
+
+                        result = keypressfunc(tmp->window, ch, mp1, special, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_CLOSE:
+                  {
+                     int (*closefunc)(HWND, void *) = tmp->signalfunction;
+
+                     if(hWnd == tmp->window)
+                     {
+                        result = closefunc(tmp->window, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_PAINT:
+                  {
+                     PAINTSTRUCT ps;
+                     DWExpose exp;
+                     int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction;
+
+                     if ( hWnd == tmp->window )
+                     {
+                        BeginPaint(hWnd, &ps);
+                        exp.x = ps.rcPaint.left;
+                        exp.y = ps.rcPaint.top;
+                        exp.width = ps.rcPaint.right - ps.rcPaint.left;
+                        exp.height = ps.rcPaint.bottom - ps.rcPaint.top;
+                        result = exposefunc(hWnd, &exp, tmp->data);
+                        EndPaint(hWnd, &ps);
+                     }
+                  }
+                  break;
+               case WM_NOTIFY:
+                  {
+                     if(tmp->message == TVN_SELCHANGED ||
+                        tmp->message == NM_RCLICK ||
+                        tmp->message == TVN_ITEMEXPANDED)
+                     {
+                        NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2;
+                        NMLISTVIEW FAR *lem=(NMLISTVIEW FAR *)mp2;
+                        char tmpbuf[100];
+
+                        GetClassName(tem->hdr.hwndFrom, tmpbuf, 99);
+
+                        if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0)
+                        {
+                           if(tem->hdr.code == TVN_SELCHANGED && tmp->message == TVN_SELCHANGED)
+                           {
+                              if(tmp->window == tem->hdr.hwndFrom && !dw_window_get_data(tmp->window, "_dw_select_item"))
+                              {
+                                 int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = tmp->signalfunction;
+                                 TVITEM tvi;
+                                 void **ptrs;
+
+                                 tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+                                 tvi.hItem = tem->itemNew.hItem;
+
+                                 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]);
+
+                                 tmp = NULL;
+                              }
+                           }
+                           else if(tem->hdr.code == TVN_ITEMEXPANDED && tmp->message == TVN_ITEMEXPANDED)
+                           {
+                              if(tmp->window == tem->hdr.hwndFrom && tem->action == TVE_EXPAND)
+                              {
+                                 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = tmp->signalfunction;
+
+                                 result = treeexpandfunc(tmp->window, tem->itemNew.hItem, tmp->data);
+                                 tmp = NULL;
+                              }
+                           }
+                           else if(tem->hdr.code == NM_RCLICK && tmp->message == NM_RCLICK)
+                           {
+                              if(tmp->window == tem->hdr.hwndFrom)
+                              {
+                                 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
+                                 HTREEITEM hti, last;
+                                 TVITEM tvi;
+                                 TVHITTESTINFO thi;
+                                 void **ptrs = NULL;
+                                 LONG x, y;
+
+                                 dw_pointer_query_pos(&x, &y);
+
+                                 thi.pt.x = x;
+                                 thi.pt.y = y;
+
+                                 MapWindowPoints(HWND_DESKTOP, tmp->window, &thi.pt, 1);
+
+                                 last = TreeView_GetSelection(tmp->window);
+                                 hti = TreeView_HitTest(tmp->window, &thi);
+
+                                 if(hti)
+                                 {
+                                    tvi.mask = TVIF_HANDLE | TVIF_PARAM;
+                                    tvi.hItem = hti;
+
+                                    TreeView_GetItem(tmp->window, &tvi);
+                                    TreeView_SelectItem(tmp->window, hti);
+
+                                    ptrs = (void **)tvi.lParam;
+                                 }
+                                 containercontextfunc(tmp->window, ptrs ? (char *)ptrs[0] : NULL, x, y, tmp->data, ptrs ? ptrs[1] : NULL);
+                                 tmp = NULL;
+                              }
+                           }
+                        }
+                        else if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)==0)
+                        {
+                           if((lem->hdr.code == LVN_ITEMCHANGED && (lem->uChanged & LVIF_STATE)) && tmp->message == TVN_SELCHANGED)
+                           {
+                              if(tmp->window == tem->hdr.hwndFrom)
+                              {
+                                 LV_ITEM lvi;
+                                 int iItem;
+
+                                 iItem = ListView_GetNextItem(tmp->window, -1, LVNI_SELECTED);
+
+                                 memset(&lvi, 0, sizeof(LV_ITEM));
+
+                                 if(iItem > -1)
+                                 {
+                                    int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction;
+
+                                    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);
+                                    tmp = NULL;
+                                 }
+                              }
+                           }
+                        }
+                     }
+                     else if(tmp->message == TCN_SELCHANGE)
+                     {
+                        NMHDR FAR *tem=(NMHDR FAR *)mp2;
+                        if(tmp->window == tem->hwndFrom && tem->code == tmp->message)
+                        {
+                           int (*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;
+                        }
+                     }
+                     else if(tmp->message == LVN_COLUMNCLICK)
+                     {
+                        NMLISTVIEW FAR *tem=(NMLISTVIEW FAR *)mp2;
+                        if(tmp->window == tem->hdr.hwndFrom && tem->hdr.code == tmp->message)
+                        {
+                           int (*columnclickfunc)(HWND, int, void *) = tmp->signalfunction;
+                           result = columnclickfunc(tem->hdr.hwndFrom, tem->iSubItem, tmp->data);
+                           tmp = NULL;
+                        }
+                     }
+                  }
+                  break;
+               case WM_COMMAND:
+                  {
+                     int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+                     HWND command;
+                     ULONG passthru = (ULONG)LOWORD(mp1);
+                     ULONG message = HIWORD(mp1);
+
+                     command = (HWND)passthru;
+
+                     if (message == LBN_SELCHANGE || message == CBN_SELCHANGE)
+                     {
+                        int (*listboxselectfunc)(HWND, int, void *) = tmp->signalfunction;
+
+                        if (tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2)
+                        {
+                           result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data);
+                           tmp = NULL;
+                        }
+                     }
+                     else if (tmp->id && passthru == tmp->id)
+                     {
+                        HMENU hwndmenu = GetMenu(hWnd), menuowner = _menu_owner((HMENU)tmp->window);
+
+                        if (menuowner == hwndmenu || !menuowner)
+                        {
+                           _dw_toggle_checkable_menu_item( tmp->window, tmp->id );
+                           /*
+                            * Call the user supplied callback
+                            */
+                           result = clickfunc(tmp->window, 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 );
+                        result = clickfunc(popup ? popup : tmp->window, tmp->data);
+                        tmp = NULL;
+                     }
+                  }
+                  break;
+               case WM_HSCROLL:
+               case WM_VSCROLL:
+                  {
+                     char tmpbuf[100] = "";
+                     HWND handle = (HWND)mp2;
+                     int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
+
+                     if(!GetClassName(handle, tmpbuf, 99))
+                     {
+                         GetClassName(hWnd, tmpbuf, 99);
+                     }
+
+                     if (strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
+                     {
+
+                        if (handle == tmp->window)
+                        {
+                           int value = (int)SendMessage(handle, TBM_GETPOS, 0, 0);
+                           int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
+                           ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
+
+                           if(currentstyle & TBS_VERT)
+                              result = valuechangefunc(tmp->window, max - value, tmp->data);
+                           else
+                              result = valuechangefunc(tmp->window, value, tmp->data);
+                           tmp = NULL;
+                        }
+                     }
+                     else if(strnicmp(tmpbuf, SCROLLBARCLASSNAME, strlen(SCROLLBARCLASSNAME)+1)==0)
+                     {
+                        if(handle == tmp->window)
+                        {
+                           int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT;
+                           int value = _HandleScroller(handle, bar, (int)HIWORD(mp1), (int)LOWORD(mp1));
+
+                           if(value > -1)
+                           {
+                              dw_scrollbar_set_pos(tmp->window, value);
+                              result = valuechangefunc(tmp->window, value, tmp->data);
+                           }
+                           tmp = NULL;
+                           msg = 0;
+                        }
+                     }
+                  }
+                  break;
+            }
+         }
+         if(tmp)
+            tmp = tmp->next;
+      }
+      command_active = 0;
+   }
+
+   /* Now that any handlers are done... do normal processing */
+   switch( msg )
+   {
+   case WM_PAINT:
+      {
+         PAINTSTRUCT ps;
+
+         BeginPaint(hWnd, &ps);
+         EndPaint(hWnd, &ps);
+      }
+      break;
+   case WM_SIZE:
+      {
+         static int lastx = -1, lasty = -1;
+         static HWND lasthwnd = 0;
+
+         if(lastx != LOWORD(mp2) || lasty != HIWORD(mp2) || lasthwnd != hWnd)
+         {
+            Box *mybox = (Box *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+            if(mybox && mybox->count)
+            {
+               lastx = LOWORD(mp2);
+               lasty = HIWORD(mp2);
+               lasthwnd = hWnd;
+
+               ShowWindow(mybox->items[0].hwnd, SW_HIDE);
+               _do_resize(mybox,LOWORD(mp2),HIWORD(mp2));
+               ShowWindow(mybox->items[0].hwnd, SW_SHOW);
+               return 0;
+            }
+         }
+      }
+      break;
+   case WM_USER:
+      windowfunc = (void *)mp1;
+
+      if(windowfunc)
+         windowfunc((void *)mp2);
+      break;
+   case WM_USER+5:
+      _free_menu_data((HMENU)mp1);
+      DestroyMenu((HMENU)mp1);
+      break;
+   case WM_NOTIFY:
+      {
+         NMHDR FAR *tem=(NMHDR FAR *)mp2;
+
+         if(tem->code == TCN_SELCHANGING)
+         {
+            int num=TabCtrl_GetCurSel(tem->hwndFrom);
+            NotebookPage **array = (NotebookPage **)dw_window_get_data(tem->hwndFrom, "_dw_array");
+
+            if(num > -1 && array && array[num])
+               SetParent(array[num]->hwnd, DW_HWND_OBJECT);
+
+         }
+         else if(tem->code == TCN_SELCHANGE)
+         {
+            int num=TabCtrl_GetCurSel(tem->hwndFrom);
+            NotebookPage **array = (NotebookPage **)dw_window_get_data(tem->hwndFrom, "_dw_array");
+
+            if(num > -1 && array && array[num])
+               SetParent(array[num]->hwnd, tem->hwndFrom);
+
+            _resize_notebook_page(tem->hwndFrom, num);
+         }
+      }
+      break;
+   case WM_HSCROLL:
+   case WM_VSCROLL:
+      {
+         HWND handle = (HWND)mp2;
+         char tmpbuf[100];
+         int bar = (origmsg == WM_HSCROLL) ? SB_HORZ : SB_VERT;
+
+         if(dw_window_get_data(handle, "_dw_scrollbar"))
+         {
+            int value = _HandleScroller(handle, bar, (int)HIWORD(mp1), (int)LOWORD(mp1));
+
+            if(value > -1)
+               dw_scrollbar_set_pos(handle, value);
+         }
+         else
+         {
+            GetClassName( hWnd, tmpbuf, 99 );
+            if ( strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1 ) == 0 )
+            {
+               int value = _HandleScroller(hWnd, bar, (int)HIWORD(mp1), (int)LOWORD(mp1));
+            }
+         }
+      }
+      break;
+   case WM_GETMINMAXINFO:
+      {
+         MINMAXINFO *info = (MINMAXINFO *)mp2;
+         info->ptMinTrackSize.x = 8;
+         info->ptMinTrackSize.y = 8;
+         return 0;
+      }
+      break;
+   case WM_DESTROY:
+      {
+         HMENU menu = GetMenu(hWnd);
+
+         if(menu)
+            _free_menu_data(menu);
+
+         /* Free memory before destroying */
+         _free_window_memory(hWnd, 0);
+         EnumChildWindows(hWnd, _free_window_memory, 0);
+      }
+      break;
+   case WM_MOUSEMOVE:
+      {
+         HCURSOR cursor;
+
+         if((cursor = (HCURSOR)dw_window_get_data(hWnd, "_dw_cursor")) ||
+            (cursor = (HCURSOR)dw_window_get_data(_toplevel_window(hWnd), "_dw_cursor")))
+         {
+            SetCursor(cursor);
+         }
+      }
+      break;
+   case WM_CTLCOLORSTATIC:
+   case WM_CTLCOLORLISTBOX:
+   case WM_CTLCOLORBTN:
+   case WM_CTLCOLOREDIT:
+   case WM_CTLCOLORMSGBOX:
+   case WM_CTLCOLORSCROLLBAR:
+   case WM_CTLCOLORDLG:
+      {
+         ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
+         if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+         {
+            /* Handle foreground */
+            if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
+            {
+               if(thiscinfo->fore != DW_CLR_DEFAULT)
+               {
+                  SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
+                                       _green[thiscinfo->fore],
+                                       _blue[thiscinfo->fore]));
+               }
+            }
+            else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
+            {
+               SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
+                                    DW_GREEN_VALUE(thiscinfo->fore),
+                                    DW_BLUE_VALUE(thiscinfo->fore)));
+            }
+            /* Handle background */
+            if(thiscinfo->back > -1 && thiscinfo->back < 18)
+            {
+               if(thiscinfo->back == DW_CLR_DEFAULT)
+               {
+                  HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
+
+                  SelectObject((HDC)mp1, hbr);
+                  return (LONG)hbr;
+               }
+               else
+               {
+                  SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
+                                     _green[thiscinfo->back],
+                                     _blue[thiscinfo->back]));
+                  if(thiscinfo->hbrush)
+                     DeleteObject(thiscinfo->hbrush);
+                  thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
+                                                 _green[thiscinfo->back],
+                                                 _blue[thiscinfo->back]));
+                  SelectObject((HDC)mp1, thiscinfo->hbrush);
+               }
+               return (LONG)thiscinfo->hbrush;
+            }
+            else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
+            {
+               SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
+                                     DW_GREEN_VALUE(thiscinfo->back),
+                                     DW_BLUE_VALUE(thiscinfo->back)));
+               if(thiscinfo->hbrush)
+                  DeleteObject(thiscinfo->hbrush);
+               thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
+                                              DW_GREEN_VALUE(thiscinfo->back),
+                                              DW_BLUE_VALUE(thiscinfo->back)));
+               SelectObject((HDC)mp1, thiscinfo->hbrush);
+               return (LONG)thiscinfo->hbrush;
+            }
+         }
+
+      }
+      break;
+   }
+   if(result != -1)
+      return result;
+   else
+   {
+      return DefWindowProc(hWnd, msg, mp1, mp2);
+   }
+}
+
+VOID CALLBACK _TimerProc(HWND hwnd, UINT msg, UINT_PTR idEvent, DWORD dwTime)
+{
+   _wndproc(hwnd, msg, (WPARAM)idEvent, 0);
+}
+
+BOOL CALLBACK _framewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   switch( msg )
+   {
+   case WM_LBUTTONDOWN:
+   case WM_MBUTTONDOWN:
+   case WM_RBUTTONDOWN:
+      SetActiveWindow(hWnd);
+      SetFocus(hWnd);
+      break;
+   case WM_COMMAND:
+   case WM_NOTIFY:
+   case WM_MOUSEMOVE:
+      _wndproc(hWnd, msg, mp1, mp2);
+      break;
+#if 0
+   case WM_ERASEBKGND:
+      {
+         ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+         if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+            return FALSE;
+      }
+      break;
+#endif
+   case WM_PAINT:
+      {
+         ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+         if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+         {
+            PAINTSTRUCT ps;
+            HDC hdcPaint = BeginPaint(hWnd, &ps);
+            int success = FALSE;
+
+            if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+            {
+               /* Handle foreground */
+               if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
+               {
+                  if(thiscinfo->fore != DW_CLR_DEFAULT)
+                  {
+                     SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
+                                          _green[thiscinfo->fore],
+                                          _blue[thiscinfo->fore]));
+                  }
+               }
+               else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
+               {
+                  SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
+                                       DW_GREEN_VALUE(thiscinfo->fore),
+                                       DW_BLUE_VALUE(thiscinfo->fore)));
+               }
+               /* Handle background */
+               if(thiscinfo->back > -1 && thiscinfo->back < 18)
+               {
+                  if(thiscinfo->back != DW_CLR_DEFAULT)
+                  {
+                     SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
+                                        _green[thiscinfo->back],
+                                        _blue[thiscinfo->back]));
+                     if(thiscinfo->hbrush)
+                        DeleteObject(thiscinfo->hbrush);
+                     thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
+                                                    _green[thiscinfo->back],
+                                                    _blue[thiscinfo->back]));
+                     SelectObject(hdcPaint, thiscinfo->hbrush);
+                     Rectangle(hdcPaint, ps.rcPaint.left - 1, ps.rcPaint.top - 1, ps.rcPaint.right + 1, ps.rcPaint.bottom + 1);
+                     success = TRUE;
+                  }
+               }
+               else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
+               {
+                  SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
+                                     DW_GREEN_VALUE(thiscinfo->back),
+                                     DW_BLUE_VALUE(thiscinfo->back)));
+                  if(thiscinfo->hbrush)
+                     DeleteObject(thiscinfo->hbrush);
+                  thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
+                                                 DW_GREEN_VALUE(thiscinfo->back),
+                                                 DW_BLUE_VALUE(thiscinfo->back)));
+                  SelectObject(hdcPaint, thiscinfo->hbrush);
+                  Rectangle(hdcPaint, ps.rcPaint.left - 1, ps.rcPaint.top - 1, ps.rcPaint.right + 1, ps.rcPaint.bottom + 1);
+                  success = TRUE;
+               }
+            }
+
+            EndPaint(hWnd, &ps);
+            if(success)
+               return FALSE;
+         }
+
+      }
+      break;
+   }
+   return DefWindowProc(hWnd, msg, mp1, mp2);
+}
+
+BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   BOOL rcode = TRUE;
+
+   switch( msg )
+   {
+   case WM_LBUTTONDOWN:
+   case WM_MBUTTONDOWN:
+   case WM_RBUTTONDOWN:
+      SetFocus(hWnd);
+      rcode = _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   case WM_MOUSEMOVE:
+      /* call our standard Windows procedure */
+      rcode = _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   case WM_USER+2:
+   case WM_LBUTTONUP:
+   case WM_MBUTTONUP:
+   case WM_RBUTTONUP:
+      rcode = _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   case WM_PAINT:
+   case WM_SIZE:
+   case WM_COMMAND:
+   case WM_CHAR:
+   case WM_KEYDOWN:
+      rcode = _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   default:
+      break;
+   }
+   /* only call the default Windows process if the user hasn't handled the message themselves */
+   if ( rcode != 0 )
+      rcode = DefWindowProc(hWnd, msg, mp1, mp2);
+   return rcode;
+}
+
+BOOL CALLBACK _spinnerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   ColorInfo *cinfo;
+
+   cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+   if(msg == WM_MOUSEMOVE)
+      _wndproc(hWnd, msg, mp1, mp2);
+
+   if(cinfo)
+   {
+      switch( msg )
+      {
+      case WM_LBUTTONDOWN:
+      case WM_MBUTTONDOWN:
+      case WM_RBUTTONDOWN:
+      case WM_KEYDOWN:
+         {
+            BOOL ret;
+
+            if(!cinfo || !cinfo->pOldProc)
+               ret = DefWindowProc(hWnd, msg, mp1, mp2);
+            ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+
+            /* Tell the edit control that a buttonpress has
+             * occured and to update it's window title.
+             */
+            if(cinfo && cinfo->buddy)
+               SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
+
+            SetTimer(hWnd, 100, 100, (TIMERPROC)NULL);
+
+            return ret;
+         }
+         break;
+      case WM_LBUTTONUP:
+      case WM_MBUTTONUP:
+      case WM_RBUTTONUP:
+      case WM_KEYUP:
+         {
+            BOOL ret;
+
+            if(!cinfo || !cinfo->pOldProc)
+               ret = DefWindowProc(hWnd, msg, mp1, mp2);
+            ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+
+            /* Tell the edit control that a buttonpress has
+             * occured and to update it's window title.
+             */
+            if(cinfo && cinfo->buddy)
+               SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
+
+            if(hWnd)
+               KillTimer(hWnd, 100);
+
+            return ret;
+         }
+         break;
+      case WM_TIMER:
+         {
+            if(mp1 == 100)
+            {
+               BOOL ret;
+
+               if(cinfo && cinfo->buddy)
+                  SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
+
+               if(!cinfo || !cinfo->pOldProc)
+                  ret = DefWindowProc(hWnd, msg, mp1, mp2);
+               ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+
+               /* Tell the edit control that a buttonpress has
+                * occured and to update it's window title.
+                */
+               if(cinfo && cinfo->buddy)
+                  SendMessage(cinfo->buddy, WM_USER+10, 0, 0);
+
+               return ret;
+            }
+         }
+         break;
+      case WM_USER+10:
+         {
+            if(cinfo->buddy)
+            {
+               char tempbuf[100] = "";
+               long position;
+
+               GetWindowText(cinfo->buddy, tempbuf, 99);
+
+               position = atol(tempbuf);
+
+               SendMessage(hWnd, UDM_SETPOS32, 0, (LPARAM)position);
+            }
+         }
+         break;
+      }
+   }
+
+   if(!cinfo || !cinfo->pOldProc)
+      return DefWindowProc(hWnd, msg, mp1, mp2);
+   return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+}
+
+void _click_default(HWND handle)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* These are the window classes which can
+    * obtain input focus.
+    */
+   if (strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0)
+   {
+      /* Generate click on default item */
+      SignalHandler *tmp = Root;
+
+      /* Find any callbacks for this function */
+      while (tmp)
+      {
+         if (tmp->message == WM_COMMAND)
+         {
+            /* Make sure it's the right window, and the right ID */
+            if (tmp->window == handle)
+            {
+               int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+               clickfunc(tmp->window, tmp->data);
+               tmp = NULL;
+            }
+         }
+         if (tmp)
+            tmp= tmp->next;
+      }
+   }
+   else
+      SetFocus(handle);
+}
+
+BOOL CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   ColorInfo *cinfo;
+   char tmpbuf[100];
+   WNDPROC pOldProc = 0;
+   int ret = -1;
+
+   cinfo = (ColorInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+   GetClassName(hWnd, tmpbuf, 99);
+   if(strcmp(tmpbuf, FRAMECLASSNAME) == 0)
+      cinfo = &(((Box *)cinfo)->cinfo);
+
+   if ( msg == WM_MOUSEMOVE || msg == WM_USER+2 )
+      ret = _wndproc(hWnd, msg, mp1, mp2);
+
+   if (cinfo)
+   {
+      pOldProc = cinfo->pOldProc;
+
+      switch( msg )
+      {
+      case WM_SETFOCUS:
+         if(cinfo->combo)
+            ret = _wndproc(cinfo->combo, msg, mp1, mp2);
+         else
+            ret = _wndproc(hWnd, msg, mp1, mp2);
+         break;
+      case WM_VSCROLL:
+      case WM_HSCROLL:
+            ret = _wndproc(hWnd, msg, mp1, mp2);
+         break;
+      case WM_KEYDOWN:
+      case WM_KEYUP:
+         {
+            if (hWnd && (mp1 == VK_UP || mp1 == VK_DOWN))
+            {
+               if (!cinfo || !cinfo->pOldProc)
+                  ret = DefWindowProc(hWnd, msg, mp1, mp2);
+               ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+
+               /* Tell the spinner control that a keypress has
+                * occured and to update it's internal value.
+                */
+               if (cinfo && cinfo->buddy && !cinfo->combo)
+                  PostMessage(hWnd, WM_USER+10, 0, 0);
+
+               if(msg == WM_KEYDOWN)
+                  SetTimer(hWnd, 101, 100, (TIMERPROC)NULL);
+               else
+                  KillTimer(hWnd, 101);
+
+               return ret;
+            }
+         }
+         break;
+      case WM_TIMER:
+         {
+            if(mp1 == 101)
+            {
+               if(!cinfo || !cinfo->pOldProc)
+                  ret = DefWindowProc(hWnd, msg, mp1, mp2);
+               ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2);
+
+               /* Tell the spinner control that a keypress has
+                * occured and to update it's internal value.
+                */
+               if(cinfo && cinfo->buddy && !cinfo->combo)
+                  PostMessage(hWnd, WM_USER+10, 0, 0);
+
+               return ret;
+            }
+         }
+         break;
+      case WM_CHAR:
+         ret = _wndproc(hWnd, msg, mp1, mp2);
+         if (ret != TRUE && LOWORD(mp1) == '\t')
+         {
+            if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
+            {
+               if (cinfo->combo)
+                  _shift_focus_back(cinfo->combo);
+               else if(cinfo->buddy)
+                  _shift_focus_back(cinfo->buddy);
+               else
+                  _shift_focus_back(hWnd);
+            }
+            else
+            {
+               if (cinfo->combo)
+                  _shift_focus(cinfo->combo);
+               else if(cinfo->buddy)
+                  _shift_focus(cinfo->buddy);
+               else
+                  _shift_focus(hWnd);
+            }
+            return FALSE;
+         }
+         else if(LOWORD(mp1) == '\r')
+         {
+
+            if ( cinfo->clickdefault )
+            {
+               _click_default(cinfo->clickdefault);
+            }
+            else
+            {
+               /*
+                * Find the toplevel window for the current window and check if it
+                * has a default click set
+                */
+               HWND tl = _toplevel_window( hWnd );
+               ColorInfo *mycinfo = (ColorInfo *)GetWindowLongPtr( tl, GWLP_USERDATA );
+               if ( mycinfo && mycinfo->clickdefault )
+               {
+                  _click_default( mycinfo->clickdefault );
+               }
+            }
+         }
+
+         /* Tell the spinner control that a keypress has
+          * occured and to update it's internal value.
+          */
+         if (cinfo->buddy && !cinfo->combo)
+         {
+            PostMessage(cinfo->buddy, WM_USER+10, 0, 0);
+         }
+         break;
+      case WM_USER+10:
+         {
+            if(cinfo->buddy)
+            {
+               long val;
+
+               val = (long)SendMessage(cinfo->buddy, UDM_GETPOS32, 0, 0);
+
+               sprintf(tmpbuf, "%ld", val);
+               SetWindowText(hWnd, tmpbuf);
+            }
+         }
+         break;
+      case WM_CTLCOLORSTATIC:
+      case WM_CTLCOLORLISTBOX:
+      case WM_CTLCOLORBTN:
+      case WM_CTLCOLOREDIT:
+      case WM_CTLCOLORMSGBOX:
+      case WM_CTLCOLORSCROLLBAR:
+      case WM_CTLCOLORDLG:
+         {
+            ColorInfo *thiscinfo = (ColorInfo *)GetWindowLongPtr((HWND)mp2, GWLP_USERDATA);
+            if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+            {
+               /* Handle foreground */
+               if(thiscinfo->fore > -1 && thiscinfo->fore < 18)
+               {
+                  if(thiscinfo->fore != DW_CLR_DEFAULT)
+                  {
+                     SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
+                                          _green[thiscinfo->fore],
+                                          _blue[thiscinfo->fore]));
+                  }
+               }
+               else if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR)
+               {
+                  SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
+                                       DW_GREEN_VALUE(thiscinfo->fore),
+                                       DW_BLUE_VALUE(thiscinfo->fore)));
+               }
+               /* Handle background */
+               if(thiscinfo->back > -1 && thiscinfo->back < 18)
+               {
+                  if(thiscinfo->back == DW_CLR_DEFAULT)
+                  {
+                     HBRUSH hbr = GetSysColorBrush(COLOR_3DFACE);
+
+                     SetBkColor((HDC)mp1, GetSysColor(COLOR_3DFACE));
+
+
+                     SelectObject((HDC)mp1, hbr);
+                     return (LONG)hbr;
+                  }
+                  else
+                  {
+                     SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
+                                        _green[thiscinfo->back],
+                                        _blue[thiscinfo->back]));
+                     if(thiscinfo->hbrush)
+                        DeleteObject(thiscinfo->hbrush);
+                     thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
+                                                    _green[thiscinfo->back],
+                                                    _blue[thiscinfo->back]));
+                     SelectObject((HDC)mp1, thiscinfo->hbrush);
+                  }
+                  return (LONG)thiscinfo->hbrush;
+               }
+               else if((thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
+               {
+                  SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
+                                     DW_GREEN_VALUE(thiscinfo->back),
+                                     DW_BLUE_VALUE(thiscinfo->back)));
+                  if(thiscinfo->hbrush)
+                     DeleteObject(thiscinfo->hbrush);
+                  thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
+                                                 DW_GREEN_VALUE(thiscinfo->back),
+                                                 DW_BLUE_VALUE(thiscinfo->back)));
+                  SelectObject((HDC)mp1, thiscinfo->hbrush);
+                  return (LONG)thiscinfo->hbrush;
+               }
+            }
+
+         }
+         break;
+      }
+   }
+
+   if(ret != TRUE)
+   {
+       if(!pOldProc)
+          return DefWindowProc(hWnd, msg, mp1, mp2);
+       return CallWindowProc(pOldProc, hWnd, msg, mp1, mp2);
+   }
+   return ret;
+}
+
+/* Window procedure for container/listview */
+BOOL CALLBACK _containerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   ContainerInfo *cinfo;
+
+   cinfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+   switch( msg )
+   {
+   case WM_COMMAND:
+   case WM_NOTIFY:
+   case WM_MOUSEMOVE:
+      _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   case WM_PAINT:
+       if(cinfo->cinfo.pOldProc && (cinfo->even != DW_RGB_TRANSPARENT || cinfo->odd != DW_RGB_TRANSPARENT))
+       {
+            RECT rectUpd, rectDestin, rect;
+            int iItems, iTop, i;
+            COLORREF c;
+
+            /* Load the default background color for the first pass */
+            ListView_SetTextBkColor(hWnd, cinfo->cinfo.back != -1 ? cinfo->cinfo.back : ListView_GetBkColor(hWnd));
+            /* get the rectangle to be updated */
+            GetUpdateRect(hWnd, &rectUpd, FALSE);
+            /* allow default processing first */
+            CallWindowProc(cinfo->cinfo.pOldProc, hWnd, msg, 0, 0);
+            /* number of displayed rows */
+            iItems = ListView_GetCountPerPage(hWnd);
+            /* first visible row */
+            iTop = ListView_GetTopIndex(hWnd);
+
+            for(i=iTop; i<=(iTop+iItems+1); i++) 
+            {
+                /* if row rectangle intersects update rectangle then it requires re-drawing */
+                if(ListView_GetItemRect(hWnd, i, &rect, LVIR_BOUNDS) && IntersectRect(&rectDestin, &rectUpd, &rect)) 
+                {
+                    /* change text background colour accordingly */
+                    c = (i % 2) ? cinfo->odd : cinfo->even;
+
+                    if(c != DW_RGB_TRANSPARENT)
+                    {
+                        ListView_SetTextBkColor(hWnd, c);
+                        /* invalidate the row rectangle then... */
+                        InvalidateRect(hWnd, &rectDestin, FALSE);
+                        /* ...force default processing */
+                        CallWindowProc(cinfo->cinfo.pOldProc, hWnd, msg, 0, 0);
+                    }
+                }
+            }            
+       }
+       break;
+   case WM_LBUTTONDBLCLK:
+   case WM_CHAR:
+      {
+         LV_ITEM lvi;
+         int iItem;
+
+         if(LOWORD(mp1) == '\t')
+         {
+            if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
+               _shift_focus_back(hWnd);
+            else
+               _shift_focus(hWnd);
+            return FALSE;
+         }
+
+         if(msg == WM_CHAR && (char)mp1 != '\r')
+            break;
+
+         iItem = ListView_GetNextItem(hWnd, -1, LVNI_FOCUSED);
+
+         memset(&lvi, 0, sizeof(LV_ITEM));
+
+         if(iItem > -1)
+         {
+            lvi.iItem = iItem;
+            lvi.mask = LVIF_PARAM;
+
+            ListView_GetItem(hWnd, &lvi);
+         }
+
+         {
+            SignalHandler *tmp = Root;
+
+            while(tmp)
+            {
+               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);
+                  tmp = NULL;
+               }
+               if(tmp)
+                  tmp = tmp->next;
+            }
+         }
+      }
+      break;
+   case WM_CONTEXTMENU:
+      {
+         SignalHandler *tmp = Root;
+
+         while(tmp)
+         {
+            if(tmp->message == NM_RCLICK && tmp->window == hWnd)
+            {
+               int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
+               LONG x,y;
+               LV_ITEM lvi;
+               int iItem;
+               LVHITTESTINFO lhi;
+
+               dw_pointer_query_pos(&x, &y);
+
+               lhi.pt.x = x;
+               lhi.pt.y = y;
+
+               MapWindowPoints(HWND_DESKTOP, tmp->window, &lhi.pt, 1);
+
+               iItem = ListView_HitTest(tmp->window, &lhi);
+
+               memset(&lvi, 0, sizeof(LV_ITEM));
+
+               if(iItem > -1)
+               {
+                  lvi.iItem = iItem;
+                  lvi.mask = LVIF_PARAM;
+
+                  ListView_GetItem(tmp->window, &lvi);
+                  ListView_SetSelectionMark(tmp->window, iItem);
+               }
+
+               /* 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);
+               tmp = NULL;
+            }
+            if(tmp)
+               tmp = tmp->next;
+         }
+      }
+      break;
+   }
+
+   if(!cinfo || !cinfo->cinfo.pOldProc)
+      return DefWindowProc(hWnd, msg, mp1, mp2);
+   return CallWindowProc(cinfo->cinfo.pOldProc, hWnd, msg, mp1, mp2);
+}
+
+BOOL CALLBACK _treewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   ContainerInfo *cinfo;
+   int ret = -1;
+
+   cinfo = (ContainerInfo *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+   switch( msg )
+   {
+   case WM_MOUSEMOVE:
+      ret = _wndproc(hWnd, msg, mp1, mp2);
+      break;
+   case WM_CHAR:
+      ret = _wndproc(hWnd, msg, mp1, mp2);
+      if(ret != TRUE && LOWORD(mp1) == '\t')
+      {
+         if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
+            _shift_focus_back(hWnd);
+         else
+            _shift_focus(hWnd);
+         return FALSE;
+      }
+      break;
+   }
+
+   if(ret != TRUE)
+   {
+       if(!cinfo || !cinfo->cinfo.pOldProc)
+          return DefWindowProc(hWnd, msg, mp1, mp2);
+       return CallWindowProc(cinfo->cinfo.pOldProc, hWnd, msg, mp1, mp2);
+   }
+   return ret;
+}
+
+void _changebox(Box *thisbox, int percent, int type)
+{
+   int z;
+
+   for(z=0;z<thisbox->count;z++)
+   {
+      if(thisbox->items[z].type == TYPEBOX)
+      {
+         Box *tmp = (Box*)GetWindowLongPtr(thisbox->items[z].hwnd, GWLP_USERDATA);
+         _changebox(tmp, percent, type);
+      }
+      else
+      {
+         if(type == DW_HORZ)
+         {
+            if(thisbox->items[z].hsize == SIZEEXPAND)
+               thisbox->items[z].width = (int)(((float)thisbox->items[z].origwidth) * (((float)percent)/((float)100.0)));
+         }
+         else
+         {
+            if(thisbox->items[z].vsize == SIZEEXPAND)
+               thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0)));
+         }
+      }
+   }
+}
+
+void _handle_splitbar_resize(HWND hwnd, float percent, int type, int x, int y)
+{
+   HWND handle1, handle2;
+   Box *tmp;
+
+   if(type == DW_HORZ)
+   {
+      int newx = x;
+      float ratio = (float)percent/(float)100.0;
+
+      handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+      handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+      tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
+
+      newx = (int)((float)newx * ratio) - (SPLITBAR_WIDTH/2);
+
+      ShowWindow(handle1, SW_HIDE);
+      ShowWindow(handle2, SW_HIDE);
+
+      MoveWindow(handle1, 0, 0, newx, y, FALSE);
+      _do_resize(tmp, newx - 1, y - 1);
+
+      tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
+
+      newx = x - newx - SPLITBAR_WIDTH;
+
+      MoveWindow(handle2, x - newx, 0, newx, y, FALSE);
+      _do_resize(tmp, newx - 1, y - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newx);
+   }
+   else
+   {
+      int newy = y;
+      float ratio = (float)(100.0-percent)/(float)100.0;
+
+      handle1 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+      handle2 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+      tmp = (Box *)GetWindowLongPtr(handle1, GWLP_USERDATA);
+
+      newy = (int)((float)newy * ratio) - (SPLITBAR_WIDTH/2);
+
+      ShowWindow(handle1, SW_HIDE);
+      ShowWindow(handle2, SW_HIDE);
+
+      MoveWindow(handle1, 0, y - newy, x, newy, FALSE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      tmp = (Box *)GetWindowLongPtr(handle2, GWLP_USERDATA);
+
+      newy = y - newy - SPLITBAR_WIDTH;
+
+      MoveWindow(handle2, 0, 0, x, newy, FALSE);
+      _do_resize(tmp, x - 1, newy - 1);
+
+      dw_window_set_data(hwnd, "_dw_start", (void *)newy);
+   }
+
+   ShowWindow(handle1, SW_SHOW);
+   ShowWindow(handle2, SW_SHOW);
+}
+
+/* This handles any activity on the scrollbox */
+BOOL CALLBACK _scrollwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   switch (msg)
+   {
+       case WM_HSCROLL:
+       case WM_VSCROLL:
+       {
+            ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+            SCROLLINFO hsi, vsi, *si = &hsi;
+            int bar = SB_HORZ;
+            int which = LOWORD(mp1);
+
+            /* Initialize the scroll info structs */
+            vsi.cbSize = hsi.cbSize = sizeof(SCROLLINFO);
+            vsi.fMask = hsi.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
+
+            /* Save the current scroll positions */
+            GetScrollInfo(hwnd, SB_HORZ, &hsi);
+            GetScrollInfo(hwnd, SB_VERT, &vsi);
+
+            if(msg == WM_VSCROLL)
+            {
+                bar = SB_VERT;
+                si = &vsi;
+            }
+
+            switch(which)
+            {
+            case SB_THUMBTRACK:
+                si->nPos = HIWORD(mp1);
+                break;
+            /*case SB_PAGEDOWN:*/
+            case SB_PAGELEFT:
+                si->nPos = si->nPos - si->nPage;
+                if(si->nPos < 0)
+                    si->nPos = 0;
+                break;
+            /*case SB_PAGEUP:*/
+            case SB_PAGERIGHT:
+                si->nPos = si->nPos + si->nPage;
+                if(si->nPos > (si->nMax - si->nPage) + 1)
+                    si->nPos = (si->nMax - si->nPage) + 1;
+                break;
+            /*case SB_LINEDOWN:*/
+            case SB_LINELEFT:
+                si->nPos = si->nPos - 1;
+                if(si->nPos < si->nMin)
+                    si->nPos = si->nMin;
+                break;
+            /*case SB_LINEUP:*/
+            case SB_LINERIGHT:
+                si->nPos = si->nPos + 1;
+                if(si->nPos > (si->nMax - si->nPage) + 1)
+                    si->nPos = (si->nMax - si->nPage) + 1;
+                break;
+            }
+
+            /* Position the scrolled box */
+            vsi.fMask = hsi.fMask = SIF_POS | SIF_DISABLENOSCROLL;
+            SetWindowPos(cinfo->combo, 0, -hsi.nPos, -vsi.nPos, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+            SetScrollInfo(hwnd, bar, si, TRUE);
+       }
+       break;
+   }
+   return DefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* This handles any activity on the splitbars (sizers) */
+BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   switch (msg)
+   {
+   case WM_ACTIVATE:
+   case WM_SETFOCUS:
+      return FALSE;
+
+   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");
+
+         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)));
+
+            dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
+
+            if(type == DW_HORZ)
+               Rectangle(hdcPaint, cx - start - SPLITBAR_WIDTH, 0, cx - start, cy);
+            else
+               Rectangle(hdcPaint, 0, start, cx, start + SPLITBAR_WIDTH);
+
+            SelectObject(hdcPaint, oldBrush);
+            DeleteObject(SelectObject(hdcPaint, oldPen));
+            ReleaseDC(hwnd, hdcPaint);
+         }
+         EndPaint(hwnd, &ps);
+      }
+      break;
+   case WM_LBUTTONDOWN:
+      {
+         SetCapture(hwnd);
+         break;
+      }
+   case WM_LBUTTONUP:
+      {
+            if(GetCapture() == hwnd)
+            ReleaseCapture();
+      }
+      break;
+   case WM_MOUSEMOVE:
+      {
+         float *percent = (float *)dw_window_get_data(hwnd, "_dw_percent");
+         int type = (int)dw_window_get_data(hwnd, "_dw_type");
+         int start;
+
+         if(type == DW_HORZ)
+            SetCursor(LoadCursor(NULL, IDC_SIZEWE));
+         else
+            SetCursor(LoadCursor(NULL, IDC_SIZENS));
+
+         if(GetCapture() == hwnd && percent)
+         {
+            POINT point;
+            RECT rect;
+            static POINT lastpoint;
+
+            GetCursorPos(&point);
+            GetWindowRect(hwnd, &rect);
+
+            if(memcmp(&point, &lastpoint, sizeof(POINT)))
+            {
+               if(PtInRect(&rect, point))
+               {
+                  int width = (rect.right - rect.left);
+                  int height = (rect.bottom - rect.top);
+
+                  if(type == DW_HORZ)
+                  {
+                     start = point.x - rect.left;
+                     if(width - SPLITBAR_WIDTH > 1 && start < width - SPLITBAR_WIDTH)
+                        *percent = ((float)start / (float)(width - SPLITBAR_WIDTH)) * 100.0;
+                  }
+                  else
+                  {
+                     start = point.y - rect.top;
+                     if(height - SPLITBAR_WIDTH > 1 && start < height - SPLITBAR_WIDTH)
+                        *percent = ((float)start / (float)(height - SPLITBAR_WIDTH)) * 100.0;
+                  }
+                  _handle_splitbar_resize(hwnd, *percent, type, width, height);
+               }
+               memcpy(&lastpoint, &point, sizeof(POINT));
+            }
+         }
+         break;
+      }
+   }
+   return DefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* This handles drawing the status text areas */
+BOOL CALLBACK _statuswndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2)
+{
+   switch (msg)
+   {
+   case WM_MOUSEMOVE:
+      _wndproc(hwnd, msg, mp1, mp2);
+      break;
+   case WM_SETTEXT:
+      {
+         /* Make sure the control redraws when there is a text change */
+         int ret = (int)DefWindowProc(hwnd, msg, mp1, mp2);
+
+         InvalidateRgn(hwnd, NULL, TRUE);
+         return ret;
+      }
+   case WM_PAINT:
+      {
+         HDC hdcPaint;
+         PAINTSTRUCT ps;
+         RECT rc;
+         unsigned long cx, cy;
+         char tempbuf[1024] = "";
+         ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+         HFONT hfont = _acquire_font(hwnd, cinfo ? cinfo->fontname : NULL);
+         HFONT oldfont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
+
+         dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
+         GetWindowText(hwnd, tempbuf, 1024);
+
+         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);
+         if(hfont && oldfont)
+            SelectObject(hdcPaint, oldfont);
+         if(hfont)
+            DeleteObject(hfont);
+         EndPaint(hwnd, &ps);
+      }
+      return FALSE;
+   }
+   return DefWindowProc(hwnd, msg, mp1, mp2);
+}
+
+/* Function: _BtProc
+ * Abstract: Subclass procedure for buttons
+ */
+
+BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2)
+{
+   BubbleButton *bubble;
+   POINT point;
+   RECT rect;
+   WNDPROC pOldProc;
+
+   bubble = (BubbleButton *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+
+   if ( !bubble )
+      return DefWindowProc(hwnd, msg, mp1, mp2);
+
+   /* We must save a pointer to the old
+    * window procedure because if a signal
+    * handler attached here destroys this
+    * window it will then be invalid.
+    */
+   pOldProc = bubble->pOldProc;
+
+   switch(msg)
+   {
+   case WM_CTLCOLORSTATIC:
+   case WM_CTLCOLORLISTBOX:
+   case WM_CTLCOLORBTN:
+   case WM_CTLCOLOREDIT:
+   case WM_CTLCOLORMSGBOX:
+   case WM_CTLCOLORSCROLLBAR:
+   case WM_CTLCOLORDLG:
+      _wndproc(hwnd, msg, mp1, mp2);
+      break;
+   case WM_SETFOCUS:
+      _wndproc(hwnd, msg, mp1, mp2);
+      break;
+   case WM_LBUTTONUP:
+      {
+         SignalHandler *tmp = Root;
+
+         /* Find any callbacks for this function */
+         while(tmp)
+         {
+            if(tmp->message == WM_COMMAND)
+            {
+               int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+
+               /* Make sure it's the right window, and the right ID */
+               if(tmp->window == hwnd)
+               {
+                  if(bubble->checkbox)
+                     in_checkbox_handler = 1;
+
+                  clickfunc(tmp->window, tmp->data);
+
+                  if(bubble->checkbox)
+                     in_checkbox_handler = 0;
+                  tmp = NULL;
+               }
+            }
+            if(tmp)
+               tmp= tmp->next;
+         }
+      }
+      break;
+   case WM_CHAR:
+      {
+         /* A button press should also occur for an ENTER or SPACE press
+          * while the button has the active input focus.
+          */
+         if(LOWORD(mp1) == '\r' || LOWORD(mp1) == ' ')
+         {
+            SignalHandler *tmp = Root;
+
+            /* Find any callbacks for this function */
+            while(tmp)
+            {
+               if(tmp->message == WM_COMMAND)
+               {
+                  int (*clickfunc)(HWND, void *) = tmp->signalfunction;
+
+                  /* Make sure it's the right window, and the right ID */
+                  if(tmp->window == hwnd)
+                  {
+                     clickfunc(tmp->window, tmp->data);
+                     tmp = NULL;
+                  }
+               }
+               if(tmp)
+                  tmp= tmp->next;
+            }
+         }
+         if(LOWORD(mp1) == '\t')
+         {
+            if(GetAsyncKeyState(VK_SHIFT) & 0x8000)
+               _shift_focus_back(hwnd);
+            else
+               _shift_focus(hwnd);
+            return FALSE;
+         }
+      }
+      break;
+   case WM_KEYDOWN:
+      if(mp1 == VK_LEFT || mp1 == VK_UP)
+         _shift_focus_back(hwnd);
+      if(mp1 == VK_RIGHT || mp1 == VK_DOWN)
+         _shift_focus(hwnd);
+      break;
+   }
+
+   if ( !pOldProc )
+      return DefWindowProc(hwnd, msg, mp1, mp2);
+   return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
+}
+
+/* This function recalculates a notebook page for example
+ * during switching of notebook pages.
+ */
+void _resize_notebook_page(HWND handle, int pageid)
+{
+   RECT rect;
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+
+   if(array && array[pageid])
+   {
+      Box *box = (Box *)GetWindowLongPtr(array[pageid]->hwnd, GWLP_USERDATA);
+
+      GetClientRect(handle,&rect);
+      TabCtrl_AdjustRect(handle,FALSE,&rect);
+      MoveWindow(array[pageid]->hwnd, rect.left, rect.top,
+               rect.right - rect.left, rect.bottom-rect.top, TRUE);
+      if(box && box->count)
+      {
+         ShowWindow(box->items[0].hwnd, SW_HIDE);
+         _do_resize(box, rect.right - rect.left, rect.bottom - rect.top);
+         ShowWindow(box->items[0].hwnd, SW_SHOW);
+      }
+
+      ShowWindow(array[pageid]->hwnd, SW_SHOWNORMAL);
+   }
+}
+
+void _create_tooltip(HWND handle, char *text)
+{
+    /* Create a tooltip. */
+    HWND hwndTT = CreateWindowEx(WS_EX_TOPMOST,
+        TOOLTIPS_CLASS, NULL,
+        WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+        CW_USEDEFAULT, CW_USEDEFAULT,
+        CW_USEDEFAULT, CW_USEDEFAULT,
+        handle, NULL, DWInstance,NULL);
+    TOOLINFO ti = { 0 };
+
+    SetWindowPos(hwndTT, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+    /* Set up "tool" information.
+     * In this case, the "tool" is the entire parent window.
+     */
+    ti.cbSize = sizeof(TOOLINFO);
+    ti.uFlags = TTF_SUBCLASS;
+    ti.hwnd = handle;
+    ti.hinst = DWInstance;
+    ti.lpszText = text;
+    GetClientRect(handle, &ti.rect);
+
+    /* Associate the tooltip with the "tool" window. */
+    SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+}
+
+#ifndef GDIPLUS
+/* This function determines the handle for a supplied image filename
+ */
+int _dw_get_image_handle(char *filename, HANDLE *icon, HBITMAP *hbitmap)
+{
+   int len, windowtype = 0;
+   char *file = malloc(strlen(filename) + 5);
+
+   *hbitmap = 0;
+   *icon = 0;
+
+   if (!file)
+   {
+      return 0;
+   }
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if (access(file, 04) == 0)
+   {
+      len = strlen( file );
+      if ( len < 4 )
+      {
+         free(file);
+         return 0;
+      }
+      if ( stricmp( file + len - 4, ".ico" ) == 0 )
+      {
+         *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+         windowtype = BS_ICON;
+      }
+      else if ( stricmp( file + len - 4, ".bmp" ) == 0 )
+      {
+         *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+         windowtype = BS_BITMAP;
+      }
+      else if ( stricmp( file + len - 4, ".png" ) == 0 )
+      {
+         *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+         windowtype = BS_BITMAP;
+      }
+      free(file);
+   }
+   else
+   {
+      /* Try with .ico extension first...*/
+      strcat(file, ".ico");
+      if (access(file, 04) == 0)
+      {
+         *icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+         windowtype = BS_ICON;
+      }
+      else
+      {
+         strcpy(file, filename);
+         strcat(file, ".bmp");
+         if (access(file, 04) == 0)
+         {
+            *hbitmap = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+            windowtype = BS_BITMAP;
+         }
+      }
+      free(file);
+   }
+   return windowtype;
+}
+#endif
+
+/* Initialize thread local values to the defaults */
+void _init_thread(void)
+{
+    COLORREF foreground = RGB(128,128,128);
+    COLORREF background = DW_RGB_TRANSPARENT;
+    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:
+ *           newthread: True if this is the only thread.
+ *                      False if there is already a message loop running.
+ */
+int API dw_init(int newthread, int argc, char *argv[])
+{
+   WNDCLASS wc;
+   int z;
+   INITCOMMONCONTROLSEX icc;
+   char *fname, *alttmpdir;
+   HFONT oldfont;
+   struct GdiplusStartupInput si; 
+
+   /* Initialize our thread local storage */
+   _foreground = TlsAlloc();
+   _background = TlsAlloc();
+   _hPen = TlsAlloc();
+   _hBrush = TlsAlloc();
+   _init_thread();
+
+   icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
+   icc.dwICC = ICC_WIN95_CLASSES|ICC_DATE_CLASSES;
+
+   InitCommonControlsEx(&icc);
+
+   memset(lookup, 0, sizeof(HICON) * ICON_INDEX_LIMIT);
+
+   /* Register the generic Dynamic Windows class */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS;
+   wc.lpfnWndProc = (WNDPROC)_wndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 32;
+   wc.hbrBackground = NULL;
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = ClassName;
+
+   RegisterClass(&wc);
+
+   /* Register the splitbar control */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+   wc.lpfnWndProc = (WNDPROC)_splitwndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 0;
+   wc.hbrBackground = NULL;
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = SplitbarClassName;
+
+   RegisterClass(&wc);
+
+   /* Register the scroller control */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS;
+   wc.lpfnWndProc = (WNDPROC)_scrollwndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 32;
+   wc.hbrBackground = NULL;
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = ScrollClassName;
+
+   RegisterClass(&wc);
+
+   /* Register a frame control like on OS/2 */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = CS_DBLCLKS;
+   wc.lpfnWndProc = (WNDPROC)_framewndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 32;
+   wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
+   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = FRAMECLASSNAME;
+
+   RegisterClass(&wc);
+
+   /* Register HTML renderer class */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.lpfnWndProc = (WNDPROC)_browserWindowProc;
+   wc.lpszClassName = BrowserClassName;
+   wc.style = CS_HREDRAW|CS_VREDRAW;
+   RegisterClass(&wc);
+
+   /* Create a set of brushes using the default OS/2 and DOS colors */
+   for(z=0;z<18;z++)
+      _colors[z] = CreateSolidBrush(RGB(_red[z],_green[z],_blue[z]));
+
+   /* Register an Object Windows class like OS/2 and Win2k+
+    * so similar functionality can be used on earlier releases
+    * of Windows.
+    */
+   memset(&wc, 0, sizeof(WNDCLASS));
+   wc.style = 0;
+   wc.lpfnWndProc = (WNDPROC)_wndproc;
+   wc.cbClsExtra = 0;
+   wc.cbWndExtra = 0;
+   wc.hbrBackground = NULL;
+   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+   wc.lpszMenuName = NULL;
+   wc.lpszClassName = ObjectClassName;
+
+   RegisterClass(&wc);
+
+   /* Since Windows 95/98/NT don't have a HWND_OBJECT class
+    * also known as a input only window, I will create a
+    * temporary window that isn't visible and really does nothing
+    * except temporarily hold the child windows before they are
+    * packed into their correct parent.
+    */
+
+   DW_HWND_OBJECT = CreateWindow(ObjectClassName, "", 0, 0, 0,
+                          0, 0, HWND_DESKTOP, NULL, DWInstance, NULL);
+
+   if(!DW_HWND_OBJECT)
+   {
+      dw_messagebox("Dynamic Windows", DW_MB_OK|DW_MB_ERROR, "Could not initialize the object window. error code %d", GetLastError());
+      exit(1);
+   }
+   
+   /* 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);
+
+   OleInitialize(NULL);
+   
+   /*
+    * Get an alternate temporary directory in case TMP doesn't exist
+    */
+   if ( (alttmpdir = getenv( "TEMP" ) ) == NULL )
+   {
+      strcpy( _dw_alternate_temp_dir, "c:\\tmp" );
+   }
+   else
+   {
+      strncpy( _dw_alternate_temp_dir, alttmpdir, MAX_PATH );
+   }
+   /*
+    * Get screen size. Used to make calls to dw_screen_width()
+    * and dw_screen-height() quicker, but to alos limit the
+    * default size of windows.
+    */
+   screenx = GetSystemMetrics(SM_CXSCREEN);
+   screeny = GetSystemMetrics(SM_CYSCREEN);
+
+#ifdef GDIPLUS
+   /* Setup GDI+ */
+   si.GdiplusVersion = 1;
+   si.DebugEventCallback = NULL;
+   si.SuppressBackgroundThread = FALSE;
+   si.SuppressExternalCodecs = FALSE;
+   GdiplusStartup(&gdiplusToken, &si, NULL);
+#endif
+   return 0;
+}
+
+/*
+ * Runs a message loop for Dynamic Windows.
+ */
+void API dw_main(void)
+{
+   MSG msg;
+
+   _dwtid = dw_thread_id();
+
+   while(GetMessage(&msg, NULL, 0, 0))
+   {
+      if(msg.hwnd == NULL && msg.message == WM_TIMER)
+         _wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+      else
+      {
+         TranslateMessage(&msg);
+         DispatchMessage(&msg);
+      }
+   }
+}
+
+/*
+ * Runs a message loop for Dynamic Windows, for a period of milliseconds.
+ * Parameters:
+ *           milliseconds: Number of milliseconds to run the loop for.
+ */
+void API dw_main_sleep(int milliseconds)
+{
+   MSG msg;
+   double start = (double)clock();
+
+   while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
+   {
+      if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
+      {
+         GetMessage(&msg, NULL, 0, 0);
+         if(msg.hwnd == NULL && msg.message == WM_TIMER)
+            _wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+         else
+         {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+         }
+      }
+      else
+         Sleep(1);
+   }
+}
+
+/*
+ * Processes a single message iteration and returns.
+ */
+void API dw_main_iteration(void)
+{
+   MSG msg;
+
+   _dwtid = dw_thread_id();
+
+   if(GetMessage(&msg, NULL, 0, 0))
+   {
+      if(msg.hwnd == NULL && msg.message == WM_TIMER)
+         _wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+      else
+      {
+         TranslateMessage(&msg);
+         DispatchMessage(&msg);
+      }
+   }
+}
+
+/*
+ * Free's memory allocated by dynamic windows.
+ * Parameters:
+ *           ptr: Pointer to dynamic windows allocated
+ *                memory to be free()'d.
+ */
+void API dw_free(void *ptr)
+{
+   free(ptr);
+}
+
+/*
+ * Allocates and initializes a dialog struct.
+ * Parameters:
+ *           data: User defined data to be passed to functions.
+ */
+DWDialog * API dw_dialog_new(void *data)
+{
+   DWDialog *tmp = malloc(sizeof(DWDialog));
+
+   tmp->eve = dw_event_new();
+   dw_event_reset(tmp->eve);
+   tmp->data = data;
+   tmp->done = FALSE;
+   tmp->result = NULL;
+
+    return tmp;
+}
+
+/*
+ * Accepts a dialog struct and returns the given data to the
+ * initial called of dw_dialog_wait().
+ * Parameters:
+ *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
+ *           result: Data to be returned by dw_dialog_wait().
+ */
+int API dw_dialog_dismiss(DWDialog *dialog, void *result)
+{
+   dialog->result = result;
+   dw_event_post(dialog->eve);
+   dialog->done = TRUE;
+   return 0;
+}
+
+/*
+ * Accepts a dialog struct waits for dw_dialog_dismiss() to be
+ * called by a signal handler with the given dialog struct.
+ * Parameters:
+ *           dialog: Pointer to a dialog struct aquired by dw_dialog_new).
+ */
+void * API dw_dialog_wait(DWDialog *dialog)
+{
+   MSG msg;
+   void *tmp;
+
+   while (GetMessage(&msg,NULL,0,0))
+   {
+      if(msg.hwnd == NULL && msg.message == WM_TIMER)
+         _wndproc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+      else
+      {
+         TranslateMessage(&msg);
+         DispatchMessage(&msg);
+      }
+      if(dialog->done)
+         break;
+   }
+   dw_event_close(&dialog->eve);
+   tmp = dialog->result;
+   free(dialog);
+   return tmp;
+}
+
+/*
+ * Displays a debug message on the console...
+ * Parameters:
+ *           format: printf style format string.
+ *           ...: Additional variables for use in the format.
+ */
+void API dw_debug(char *format, ...)
+{
+   va_list args;
+   char outbuf[1025] = {0};
+
+   va_start(args, format);
+   vsnprintf(outbuf, 1024, format, args);
+   va_end(args);
+   
+   OutputDebugString(outbuf);
+}
+
+/*
+ * Displays a Message Box with given text and title..
+ * Parameters:
+ *           title: The title of the message box.
+ *           format: printf style format string.
+ *           ...: Additional variables for use in the format.
+ */
+int API dw_messagebox(char *title, int flags, char *format, ...)
+{
+   va_list args;
+   char outbuf[1024];
+   int rc;
+
+   va_start(args, format);
+   vsnprintf(outbuf, 1024, format, args);
+   va_end(args);
+
+   rc = MessageBox(HWND_DESKTOP, outbuf, title, flags);
+   if(rc == IDOK)
+      return DW_MB_RETURN_OK;
+   else if(rc == IDYES)
+      return DW_MB_RETURN_YES;
+   else if(rc == IDNO)
+      return DW_MB_RETURN_NO;
+   else if(rc == IDCANCEL)
+      return DW_MB_RETURN_CANCEL;
+   else return 0;
+}
+
+/*
+ * Minimizes or Iconifies a top-level window.
+ * Parameters:
+ *           handle: The window handle to minimize.
+ */
+int API dw_window_minimize(HWND handle)
+{
+   return ShowWindow(handle, SW_MINIMIZE);
+}
+
+/*
+ * Makes the window topmost.
+ * Parameters:
+ *           handle: The window handle to make topmost.
+ */
+int API dw_window_raise(HWND handle)
+{
+   return SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+/*
+ * Makes the window bottommost.
+ * Parameters:
+ *           handle: The window handle to make bottommost.
+ */
+int API dw_window_lower(HWND handle)
+{
+   return SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
+}
+
+/*
+ * Makes the window visible.
+ * Parameters:
+ *           handle: The window handle to make visible.
+ */
+int API dw_window_show(HWND handle)
+{
+   int rc = ShowWindow(handle, SW_SHOW);
+   SetFocus(handle);
+   _initial_focus(handle);
+   return rc;
+}
+
+/*
+ * Makes the window invisible.
+ * Parameters:
+ *           handle: The window handle to make visible.
+ */
+int API dw_window_hide(HWND handle)
+{
+   return ShowWindow(handle, SW_HIDE);
+}
+
+/*
+ * Destroys a window and all of it's children.
+ * Parameters:
+ *           handle: The window handle to destroy.
+ */
+int API dw_window_destroy(HWND handle)
+{
+   HWND parent = GetParent(handle);
+   Box *thisbox = (Box *)GetWindowLongPtr(parent, GWLP_USERDATA);
+   HMENU menu = GetMenu(handle);
+
+   if(menu)
+      _free_menu_data(menu);
+
+   /* If it is a desktop window let WM_DESTROY handle it */
+   if(parent != HWND_DESKTOP)
+   {
+      /* If the parent box has items... 
+       * try to remove it from the layout 
+       */
+      if(thisbox && thisbox->count)
+      {
+         int z, index = -1;
+         Item *tmpitem, *thisitem = thisbox->items;
+
+         for(z=0;z<thisbox->count;z++)
+         {
+            if(thisitem[z].hwnd == handle)
+               index = z;
+         }
+
+         if(index == -1)
+            return 0;
+
+         tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
+
+         /* Copy all but the current entry to the new list */
+         for(z=0;z<index;z++)
+         {
+            tmpitem[z] = thisitem[z];
+         }
+         for(z=index+1;z<thisbox->count;z++)
+         {
+            tmpitem[z-1] = thisitem[z];
+         }
+
+         thisbox->items = tmpitem;
+         free(thisitem);
+         thisbox->count--;
+      }
+      _free_window_memory(handle, 0);
+      EnumChildWindows(handle, _free_window_memory, 0);
+   }
+   return DestroyWindow(handle);
+}
+
+/* Causes entire window to be invalidated and redrawn.
+ * Parameters:
+ *           handle: Toplevel window handle to be redrawn.
+ */
+void API dw_window_redraw(HWND handle)
+{
+   Box *mybox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   if(mybox)
+   {
+      RECT rect;
+      int istoplevel = (GetParent(handle) == HWND_DESKTOP);
+
+      GetClientRect(handle, &rect);
+
+      ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_HIDE);
+      _do_resize(mybox, rect.right - rect.left, rect.bottom - rect.top);
+      ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_SHOW);
+   }
+}
+
+int instring(char *text, char *buffer)
+{
+   int z, len = strlen(text), buflen = strlen(buffer);
+
+   if(buflen > len)
+   {
+      for(z=0;z<=(buflen-len);z++)
+      {
+         if(memcmp(text, &buffer[z], len) == 0)
+            return z;
+      }
+   }
+   return 0;
+}
+
+/*
+ * Changes a window's parent to newparent.
+ * Parameters:
+ *           handle: The window handle to destroy.
+ *           newparent: The window's new parent window.
+ */
+void API dw_window_reparent(HWND handle, HWND newparent)
+{
+   SetParent(handle, newparent);
+}
+
+LOGFONT _get_logfont(HDC hdc, char *fontname)
+{
+   int Italic, Bold;
+   char *myFontName;
+   int z, size = 9;
+   LOGFONT lf = {0};
+
+   for(z=0;z<strlen(fontname);z++)
+   {
+      if(fontname[z]=='.')
+         break;
+   }
+   size = atoi(fontname);
+   lf.lfHeight = -MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+   Italic = instring(" Italic", &fontname[z+1]);
+   Bold = instring(" Bold", &fontname[z+1]);
+   lf.lfWidth = 0;
+   lf.lfEscapement = 0;
+   lf.lfOrientation = 0;
+   lf.lfItalic = Italic ? TRUE : FALSE;
+   lf.lfUnderline = 0;
+   lf.lfStrikeOut = 0;
+   lf.lfWeight = Bold ? FW_BOLD : FW_NORMAL;
+   lf.lfCharSet = DEFAULT_CHARSET;
+   lf.lfOutPrecision = 0;
+   lf.lfClipPrecision = 0;
+   lf.lfQuality = DEFAULT_QUALITY;
+   lf.lfPitchAndFamily = DEFAULT_PITCH | FW_DONTCARE;
+   /*
+    * remove any font modifiers
+    */
+   myFontName = strdup(&fontname[z+1]);
+   if(Italic)
+      myFontName[Italic] = 0;
+   if(Bold)
+      myFontName[Bold] = 0;
+   strncpy(lf.lfFaceName, myFontName, sizeof(lf.lfFaceName)-1);
+   free(myFontName);
+   return lf;
+}
+
+/* Create a duplicate of an existing font handle
+ * that is safe to call DeleteObject() on.
+ */
+HFONT _DupFontHandle(HFONT hfont)
+{
+    LOGFONT lf = {0};
+    return GetObject(hfont, sizeof(lf), &lf) ? CreateFontIndirect(&lf) : NULL;
+}
+
+/* Create a font handle from specified font name..
+ * or return a handle to the default font.
+ */
+HFONT _acquire_font2(HDC hdc, char *fontname)
+{
+   HFONT hfont = 0;
+
+   if(fontname != DefaultFont && fontname[0])
+   {
+      LOGFONT lf = _get_logfont(hdc, fontname);
+      hfont = CreateFontIndirect(&lf);
+   }
+   if(!hfont && _DefaultFont)
+      hfont = _DupFontHandle(_DefaultFont);
+   if(!hfont)
+      hfont = GetStockObject(DEFAULT_GUI_FONT);
+   return hfont;
+}
+
+/* Create a font handle from specified font name..
+ * or return a handle to the default font.
+ */
+HFONT _acquire_font(HWND handle, char *fontname)
+{
+   HDC hdc = GetDC(handle);
+   HFONT hfont = _acquire_font2(hdc, fontname);
+   ReleaseDC(handle, hdc);
+   return hfont;
+}
+
+/*
+ * Sets the default font used on text based widgets.
+ * Parameters:
+ *           fontname: Font name in Dynamic Windows format.
+ */
+void API dw_font_set_default(char *fontname)
+{
+    HFONT oldfont = _DefaultFont;
+
+    _DefaultFont = _acquire_font(HWND_DESKTOP, fontname);
+    if(oldfont)
+    {
+        DeleteObject(oldfont);
+    }
+}
+
+/*
+ * Sets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ */
+int API dw_window_set_font(HWND handle, char *fontname)
+{
+    HFONT hfont, oldfont;
+    ColorInfo *cinfo;
+    char tmpbuf[100];
+
+    cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+    GetClassName(handle, tmpbuf, 99);
+    if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+    {
+        /* groupbox */
+        Box *thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
+        if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
+        {
+            handle = thisbox->grouphwnd;
+        }
+    }
+
+    /* This needs to be after we get the correct handle */
+    oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
+    hfont = _acquire_font(handle, fontname);
+
+    if (fontname)
+    {
+        if(cinfo)
+        {
+            strcpy(cinfo->fontname, fontname);
+            if(!oldfont)
+                oldfont = cinfo->hfont;
+            cinfo->hfont = hfont;
+        }
+        else
+        {
+            cinfo = calloc(1, sizeof(ColorInfo));
+            cinfo->fore = cinfo->back = -1;
+
+            strncpy(cinfo->fontname, fontname, 127);
+
+            cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
+            SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
+        }
+    }
+    SendMessage(handle, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
+    if(oldfont)
+        DeleteObject(oldfont);
+   return 0;
+}
+
+/* Allows the user to choose a font using the system's font chooser dialog.
+ * Parameters:
+ *       currfont: current font
+ * Returns:
+ *       A malloced buffer with the selected font or NULL on error.
+ */
+char * API dw_font_choose(char *currfont)
+{
+   CHOOSEFONT cf = { 0 };
+   LOGFONT lf = { 0 };
+   char *str = NULL;
+   char *bold = "";
+   char *italic = "";
+
+   if(currfont && *currfont)
+      lf = _get_logfont(NULL, currfont);
+
+   cf.lStructSize = sizeof(cf);
+   cf.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT;
+   cf.lpLogFont = &lf;
+
+   if(ChooseFont(&cf))
+   {
+      str = (char *)calloc( 101, 1 );
+      if ( str )
+      {
+         int height;
+         HDC hdc = GetDC(NULL);
+
+         if ( lf.lfWeight > FW_MEDIUM )
+            bold = " Bold";
+         if ( lf.lfItalic )
+            italic = " Italic";
+         height = MulDiv(abs(lf.lfHeight), 72,  GetDeviceCaps (hdc, LOGPIXELSY));
+         ReleaseDC(NULL, hdc);
+         _snprintf( str, 100, "%d.%s%s%s", height, lf.lfFaceName, bold, italic );
+      }
+   }
+   return str;
+}
+
+/*
+ * Gets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ */
+char * API dw_window_get_font(HWND handle)
+{
+   HFONT oldfont = NULL;
+   char *str = NULL;
+   char *bold = "";
+   char *italic = "";
+   LOGFONT lf = { 0 };
+   Box *thisbox;
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+   if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+   {
+      /* groupbox */
+      thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
+      if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
+      {
+         handle = thisbox->grouphwnd;
+      }
+   }
+   oldfont = (HFONT)SendMessage(handle, WM_GETFONT, 0, 0);
+   if ( GetObject( oldfont, sizeof(lf), &lf ) )
+   {
+      str = (char *)calloc( 100, 1 );
+      if ( str )
+      {
+         int height;
+         HDC hdc = GetDC(handle);
+
+         if ( lf.lfWeight > FW_MEDIUM )
+            bold = " Bold";
+         if ( lf.lfItalic )
+            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 );
+      }
+   }
+   if ( oldfont )
+      DeleteObject( oldfont );
+   return str;
+}
+
+/*
+ * Sets the colors used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          fore: Foreground color in RGB format.
+ *          back: Background color in RGB format.
+ */
+int API dw_window_set_color(HWND handle, ULONG fore, ULONG back)
+{
+   ColorInfo *cinfo;
+   Box *thisbox;
+   char tmpbuf[100];
+
+   cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0)
+   {
+      cinfo->fore = fore = _internal_color(fore);
+      cinfo->back = back = _internal_color(back);
+
+      ListView_SetTextColor(handle, RGB(DW_RED_VALUE(fore),
+                                DW_GREEN_VALUE(fore),
+                                DW_BLUE_VALUE(fore)));
+      ListView_SetTextBkColor(handle, RGB(DW_RED_VALUE(back),
+                                 DW_GREEN_VALUE(back),
+                                 DW_BLUE_VALUE(back)));
+      ListView_SetBkColor(handle, RGB(DW_RED_VALUE(back),
+                              DW_GREEN_VALUE(back),
+                              DW_BLUE_VALUE(back)));
+      InvalidateRgn(handle, NULL, TRUE);
+      return TRUE;
+   }
+   else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)) == 0 )
+   {
+      /* groupbox */
+      thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
+      if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
+      {
+         thisbox->cinfo.fore = fore;
+         thisbox->cinfo.back = back;
+      }
+   }
+
+   if(cinfo)
+   {
+      cinfo->fore = fore;
+      cinfo->back = back;
+   }
+   else
+   {
+      cinfo = calloc(1, sizeof(ColorInfo));
+
+      cinfo->fore = fore;
+      cinfo->back = back;
+
+      cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
+      SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
+   }
+   InvalidateRgn(handle, NULL, TRUE);
+   return TRUE;
+}
+
+/*
+ * Sets the font used by a specified window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          border: Size of the window border in pixels.
+ */
+int API dw_window_set_border(HWND handle, int border)
+{
+   return 0;
+}
+
+/*
+ * Captures the mouse input to this window.
+ * Parameters:
+ *       handle: Handle to receive mouse input.
+ */
+void API dw_window_capture(HWND handle)
+{
+   SetCapture(handle);
+}
+
+/*
+ * Releases previous mouse capture.
+ */
+void API dw_window_release(void)
+{
+   ReleaseCapture();
+}
+
+/*
+ * Changes the appearance of the mouse pointer.
+ * Parameters:
+ *       handle: Handle to widget for which to change.
+ *       cursortype: ID of the pointer you want.
+ */
+void API dw_window_set_pointer(HWND handle, int pointertype)
+{
+   HCURSOR cursor = pointertype < 65536 ? LoadCursor(NULL, MAKEINTRESOURCE(pointertype)) : (HCURSOR)pointertype;
+
+   if(!pointertype)
+      dw_window_set_data(handle, "_dw_cursor", 0);
+    else
+   {
+      dw_window_set_data(handle, "_dw_cursor", (void *)cursor);
+      SetCursor(cursor);
+   }
+}
+
+/*
+ * Create a new Window Frame.
+ * Parameters:
+ *       owner: The Owner's window handle or HWND_DESKTOP.
+ *       title: The Window title.
+ *       flStyle: Style flags, see the DW reference.
+ */
+HWND API dw_window_new(HWND hwndOwner, char *title, ULONG flStyle)
+{
+   HWND hwndframe;
+   Box *newbox = calloc(sizeof(Box), 1);
+   ULONG flStyleEx = 0;
+
+   newbox->pad = 0;
+   newbox->type = DW_VERT;
+   newbox->count = 0;
+   newbox->cinfo.fore = newbox->cinfo.back = -1;
+
+   /* Hmm, the "correct" way doesn't seem to be
+    * working, but the old hackish SetParent()
+    * at the bottom seems to work, so I'll leave
+    * it like this for now.
+    */
+#if 0
+   if(hwndOwner)
+      flStyleEx |= WS_EX_MDICHILD;
+#endif
+
+   if(!(flStyle & WS_CAPTION))
+      flStyle |= WS_POPUPWINDOW;
+
+   if(flStyle & DW_FCF_TASKLIST)
+   {
+      ULONG newflags = (flStyle | WS_CLIPCHILDREN) & ~DW_FCF_TASKLIST;
+
+      hwndframe = CreateWindowEx(flStyleEx, ClassName, title, newflags, CW_USEDEFAULT, CW_USEDEFAULT,
+                           CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
+   }
+   else
+   {
+      flStyleEx |= WS_EX_TOOLWINDOW;
+
+      hwndframe = CreateWindowEx(flStyleEx, ClassName, title, flStyle | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT,
+                           CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, DWInstance, NULL);
+   }
+   SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
+
+   if(hwndOwner)
+      SetParent(hwndframe, hwndOwner);
+
+   return hwndframe;
+}
+
+/*
+ * Create a new Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ */
+HWND API dw_box_new(int type, int pad)
+{
+   Box *newbox = calloc(sizeof(Box), 1);
+   HWND hwndframe;
+
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+   newbox->grouphwnd = (HWND)NULL;
+   newbox->cinfo.fore = newbox->cinfo.back = -1;
+
+   hwndframe = CreateWindow(FRAMECLASSNAME,
+                      "",
+                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
+                      0,0,2000,1000,
+                      DW_HWND_OBJECT,
+                      NULL,
+                      DWInstance,
+                      NULL);
+
+   newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc);
+   newbox->cinfo.fore = newbox->cinfo.back = -1;
+
+   SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
+   return hwndframe;
+}
+
+/*
+ * Create a new scroll Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ */
+HWND API dw_scrollbox_new(int type, int pad)
+{
+    ColorInfo *cinfo = calloc(sizeof(ColorInfo), 1);
+    HWND hwndframe, box = dw_box_new(type, pad);
+    HWND tmpbox = dw_box_new(DW_VERT, 0);
+    dw_box_pack_start(tmpbox, box, 1, 1, TRUE, TRUE, 0);
+
+    cinfo->fore = cinfo->back = -1;
+
+    hwndframe = CreateWindow(ScrollClassName,
+                      "",
+                      WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
+                      0,0,2000,1000,
+                      DW_HWND_OBJECT,
+                      NULL,
+                      DWInstance,
+                      NULL);
+
+    cinfo->buddy = box;
+    cinfo->combo = tmpbox;
+    SetParent(tmpbox, hwndframe);
+    SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)cinfo);
+    return hwndframe;
+}
+
+/*
+ * Returns the position of the scrollbar in the scrollbox
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_pos( HWND handle, int orient )
+{
+    SCROLLINFO si;
+    int bar = SB_HORZ;
+
+    if(orient == DW_VERT)
+    {
+        bar = SB_VERT;
+    }
+
+    si.cbSize = sizeof(SCROLLINFO);
+    si.fMask = SIF_POS;
+
+    /* Get the current scroll positions */
+    if(!GetScrollInfo(handle, bar, &si))
+    {
+        return -1;
+    }
+    return si.nPos;
+}
+
+/*
+ * Gets the range for the scrollbar in the scrollbox.
+ * Parameters:
+ *          handle: Handle to the scrollbox to be queried.
+ *          orient: The vertical or horizontal scrollbar.
+ */
+int API dw_scrollbox_get_range( HWND handle, int orient )
+{
+    SCROLLINFO si;
+    int bar = SB_HORZ;
+
+    if(orient == DW_VERT)
+    {
+        bar = SB_VERT;
+    }
+
+    si.cbSize = sizeof(SCROLLINFO);
+    si.fMask = SIF_RANGE;
+
+    /* Get the current scroll positions */
+    if(!GetScrollInfo(handle, bar, &si))
+    {
+        return -1;
+    }
+    return si.nMax;
+}
+/*
+ * Create a new Group Box to be packed.
+ * Parameters:
+ *       type: Either DW_VERT (vertical) or DW_HORZ (horizontal).
+ *       pad: Number of pixels to pad around the box.
+ *       title: Text to be displayined in the group outline.
+ */
+HWND API dw_groupbox_new(int type, int pad, char *title)
+{
+   Box *newbox = calloc(sizeof(Box), 1);
+   HWND hwndframe;
+
+   newbox->pad = pad;
+   newbox->type = type;
+   newbox->count = 0;
+   newbox->cinfo.fore = newbox->cinfo.back = -1;
+
+   hwndframe = CreateWindow(FRAMECLASSNAME,
+                      "",
+                      WS_VISIBLE | WS_CHILD,
+                      0,0,2000,1000,
+                      DW_HWND_OBJECT,
+                      NULL,
+                      DWInstance,
+                      NULL);
+
+   newbox->grouphwnd = CreateWindow(BUTTONCLASSNAME,
+                            title,
+                            WS_CHILD | BS_GROUPBOX |
+                            WS_VISIBLE | WS_CLIPCHILDREN,
+                            0,0,2000,1000,
+                            hwndframe,
+                            NULL,
+                            DWInstance,
+                            NULL);
+
+   SetWindowLongPtr(hwndframe, GWLP_USERDATA, (LONG_PTR)newbox);
+   dw_window_set_font(hwndframe, DefaultFont);
+   return hwndframe;
+}
+
+/*
+ * Create a new MDI Frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND API dw_mdi_new(unsigned long id)
+{
+   CLIENTCREATESTRUCT ccs;
+   HWND hwndframe;
+
+   ccs.hWindowMenu = NULL;
+   ccs.idFirstChild = 0;
+
+   hwndframe = CreateWindow("MDICLIENT",
+                      "",
+                      WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
+                      0,0,2000,1000,
+                      DW_HWND_OBJECT,
+                      (HMENU)id,
+                      DWInstance,
+                      &ccs);
+   return hwndframe;
+}
+
+/*
+ * Create a new HTML browser frame to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND API dw_html_new(unsigned long id)
+{
+#if defined(BUILD_DLL) || defined(BUILD_HTML)
+   return CreateWindow(BrowserClassName,
+                  "",
+                  WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS,
+                  0,0,2000,1000,
+                  DW_HWND_OBJECT,
+                  (HMENU)id,
+                  DWInstance,
+                  NULL);
+#else
+   return 0;
+#endif
+}
+
+/*
+ * Create a bitmap object to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id or 0L.
+ */
+HWND API dw_bitmap_new(ULONG id)
+{
+   return CreateWindow(STATICCLASSNAME,
+                  "",
+                  SS_BITMAP | SS_CENTERIMAGE | WS_VISIBLE |
+                  WS_CHILD | WS_CLIPCHILDREN,
+                  0,0,2000,1000,
+                  DW_HWND_OBJECT,
+                  (HMENU)id,
+                  DWInstance,
+                  NULL);
+}
+
+/*
+ * Create a notebook object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_notebook_new(ULONG id, int top)
+{
+   ULONG flags = 0;
+   HWND tmp;
+   NotebookPage **array = calloc(256, sizeof(NotebookPage *));
+
+   if(!top)
+      flags = TCS_BOTTOM;
+
+   tmp = CreateWindow(WC_TABCONTROL,
+                  "",
+                  WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | flags,
+                  0,0,2000,1000,
+                  DW_HWND_OBJECT,
+                  (HMENU)id,
+                  DWInstance,
+                  NULL);
+   dw_window_set_data(tmp, "_dw_array", (void *)array);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a menu object to be popped up.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HMENUI API dw_menu_new(ULONG id)
+{
+   return (HMENUI)CreatePopupMenu();
+}
+
+/*
+ * Create a menubar on a window.
+ * Parameters:
+ *       location: Handle of a window frame to be attached to.
+ */
+HMENUI API dw_menubar_new(HWND location)
+{
+   HMENUI tmp;
+   MENUINFO mi;
+
+   tmp = (HMENUI)CreateMenu();
+
+   mi.cbSize = sizeof(MENUINFO);
+   mi.fMask = MIM_MENUDATA;
+   mi.dwMenuData = (ULONG_PTR)1;
+
+   SetMenuInfo( (HMENU)tmp, &mi );
+
+   dw_window_set_data(location, "_dw_menu", (void *)tmp);
+
+   SetMenu(location, (HMENU)tmp);
+   return location;
+}
+
+/*
+ * Destroys a menu created with dw_menubar_new or dw_menu_new.
+ * Parameters:
+ *       menu: Handle of a menu.
+ */
+void API dw_menu_destroy(HMENUI *menu)
+{
+   if(menu)
+   {
+      HMENU mymenu = (HMENU)*menu;
+
+      if(IsWindow((HWND)mymenu) && !IsMenu(mymenu))
+         mymenu = (HMENU)dw_window_get_data((HWND)mymenu, "_dw_menu");
+        if(IsMenu(mymenu))
+         DestroyMenu(mymenu);
+   }
+}
+
+/* Internal function to make sure menu ID isn't in use */
+int _menuid_allocated(int id)
+{
+   SignalHandler *tmp = Root;
+
+   while(tmp)
+   {
+     if(tmp->id == id)
+        return TRUE;   
+     tmp = tmp->next;
+   }
+   return FALSE;
+}
+
+/*
+ * Adds a menuitem or submenu to an existing menu.
+ * Parameters:
+ *       menu: The handle to the existing menu.
+ *       title: The title text on the menu item to be added.
+ *       id: An ID to be used for message passing.
+ *       end: If TRUE memu is positioned at the end of the menu.
+ *       check: If TRUE menu is "check"able.
+ *       flags: Extended attributes to set on the menu.
+ *       submenu: Handle to an existing menu to be a submenu or NULL.
+ */
+HWND API dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu)
+{
+   MENUITEMINFO mii;
+   HMENU mymenu = (HMENU)menux;
+   char buffer[31] = {0};
+   int is_checked, is_disabled;
+
+   /*
+    * Check if this is a menubar; if so get the menu object
+    * for the menubar
+    */
+   if (IsWindow(menux) && !IsMenu(mymenu))
+      mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
+
+   memset( &mii, 0, sizeof(mii) );
+   mii.cbSize = sizeof(MENUITEMINFO);
+   mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE | MIIM_STATE;
+
+   /* Convert from OS/2 style accellerators to Win32 style */
+   if (title)
+   {
+      char *tmp = title;
+
+      while(*tmp)
+      {
+         if(*tmp == '~')
+            *tmp = '&';
+         tmp++;
+      }
+   }
+
+   if (title && *title)
+   {
+      /* Code to autogenerate a menu ID if not specified or invalid
+       * First pool is smaller for transient popup menus 
+       */
+      if(id == (ULONG)-1)
+      {
+         static ULONG tempid = 61000;
+         
+         tempid++;
+         id = tempid;
+         
+         if(tempid > 65500)
+            tempid = 61000;
+      }
+      /* Second pool is larger for more static windows */
+      else if(!id || id >= 30000)
+      {
+         static ULONG menuid = 30000;
+
+         do
+         {
+            menuid++;
+            if(menuid > 60000)
+               menuid = 30000;
+         }
+         while(_menuid_allocated(menuid));
+         id = menuid;
+      }
+      mii.fType = MFT_STRING;
+   }
+   else
+      mii.fType = MFT_SEPARATOR;
+
+   /*
+    * Handle flags
+    */
+   is_checked = (flags & DW_MIS_CHECKED) ? 1 : 0;
+   if ( is_checked )
+      mii.fState |= MFS_CHECKED;
+   else
+      mii.fState |= MFS_UNCHECKED;
+   is_disabled = (flags & DW_MIS_DISABLED) ? 1 : 0;
+   if ( is_disabled )
+      mii.fState |= MFS_DISABLED;
+   else
+      mii.fState |= MFS_ENABLED;
+
+   mii.wID = id;
+   if (IsMenu((HMENU)submenu))
+      mii.hSubMenu = (HMENU)submenu;
+   else
+      mii.hSubMenu = 0;
+   mii.dwTypeData = title;
+   mii.cch = strlen(title);
+
+   InsertMenuItem(mymenu, 65535, TRUE, &mii);
+
+   _snprintf(buffer, 30, "_dw_id%ld", id);
+   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)mymenu );
+   _snprintf(buffer, 30, "_dw_checkable%ld", id);
+   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)check );
+   _snprintf(buffer, 30, "_dw_ischecked%ld", id);
+   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)is_checked );
+   _snprintf(buffer, 30, "_dw_isdisabled%ld", id);
+   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)is_disabled );
+
+   if (submenu)
+   {
+      MENUINFO mi;
+
+      mi.cbSize = sizeof(MENUINFO);
+      mi.fMask = MIM_MENUDATA;
+      mi.dwMenuData = (ULONG_PTR)mymenu;
+
+      SetMenuInfo( (HMENU)submenu, &mi );
+   }
+
+   if (IsWindow(menux) && !IsMenu((HMENU)menux))
+      DrawMenuBar(menux);
+   return (HWND)id;
+}
+
+/*
+ * Sets the state of a menu item check.
+ * Deprecated: use dw_menu_item_set_state()
+ * Parameters:
+ *       menu: The handle to the existing menu.
+ *       id: Menuitem id.
+ *       check: TRUE for checked FALSE for not checked.
+ */
+void API dw_menu_item_set_check(HMENUI menux, unsigned long id, int check)
+{
+   MENUITEMINFO mii;
+   HMENU mymenu = (HMENU)menux;
+   char buffer[30];
+
+   if (IsWindow(menux) && !IsMenu(mymenu))
+      mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
+
+   /*
+    * Get the current state of the menu item in case it already has some other state set on it
+    */
+   memset( &mii, 0, sizeof(mii) );
+   GetMenuItemInfo( mymenu, id, FALSE, &mii);
+
+   mii.cbSize = sizeof(MENUITEMINFO);
+   mii.fMask = MIIM_STATE | MIIM_CHECKMARKS;
+   if (check)
+      mii.fState |= MFS_CHECKED;
+   else
+      mii.fState |= MFS_UNCHECKED;
+   SetMenuItemInfo( mymenu, id, FALSE, &mii );
+   /*
+    * Keep our internal state consistent
+    */
+   _snprintf( buffer, 30, "_dw_ischecked%ld", id );
+   dw_window_set_data( DW_HWND_OBJECT, buffer, (void *)check );
+}
+
+/*
+ * Sets the state of a menu item.
+ * Parameters:
+ *       menu: The handle to the existing menu.
+ *       id: Menuitem id.
+ *       flags: DW_MIS_ENABLED/DW_MIS_DISABLED
+ *              DW_MIS_CHECKED/DW_MIS_UNCHECKED
+ */
+void API dw_menu_item_set_state( HMENUI menux, unsigned long id, unsigned long state)
+{
+   MENUITEMINFO mii;
+   HMENU mymenu = (HMENU)menux;
+   char buffer1[31] = {0},buffer2[31] = {0};
+   int check;
+   int disabled;
+
+   if (IsWindow(menux) && !IsMenu(mymenu))
+      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 );
+   _snprintf( buffer2, 30, "_dw_isdisabled%ld", id );
+   disabled = (int)dw_window_get_data( DW_HWND_OBJECT, buffer2 );
+
+   memset( &mii, 0, sizeof(mii) );
+
+   mii.cbSize = sizeof(MENUITEMINFO);
+   mii.fMask = MIIM_STATE | MIIM_CHECKMARKS;
+   if ( (state & DW_MIS_CHECKED) || (state & DW_MIS_UNCHECKED) )
+   {
+      /*
+       * If we are changing state of "checked" base our setting on the passed flag...
+       */
+      if ( state & DW_MIS_CHECKED )
+      {
+         mii.fState |= MFS_CHECKED;
+         check = 1;
+      }
+      else
+      {
+         mii.fState |= MFS_UNCHECKED;
+         check = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "checked" state.
+       */
+      if ( check )
+      {
+         mii.fState |= MFS_CHECKED;
+      }
+      else
+      {
+         mii.fState |= MFS_UNCHECKED;
+      }
+   }
+   if ( (state & DW_MIS_ENABLED) || (state & DW_MIS_DISABLED) )
+   {
+      if ( state & DW_MIS_DISABLED )
+      {
+         mii.fState |= MFS_DISABLED;
+         disabled = 1;
+      }
+      else
+      {
+         mii.fState |= MFS_ENABLED;
+         disabled = 0;
+      }
+   }
+   else
+   {
+      /*
+       * ...otherwise base our setting on the current "checked" state.
+       */
+      if ( disabled )
+      {
+         mii.fState |= MFS_DISABLED;
+      }
+      else
+      {
+         mii.fState |= MFS_ENABLED;
+      }
+   }
+   SetMenuItemInfo( mymenu, id, FALSE, &mii );
+   /*
+    * 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 );
+}
+
+/*
+ * INCOMPLETE
+ * Deletes the menu item specified
+ * Parameters:
+ *       menu: The handle to the  menu in which the item was appended.
+ *       id: Menuitem id.
+ */
+void API dw_menu_delete_item(HMENUI menux, unsigned long id)
+{
+   HMENU mymenu = (HMENU)menux;
+
+   if ( IsWindow(menux) && !IsMenu(mymenu) )
+      mymenu = (HMENU)dw_window_get_data(menux, "_dw_menu");
+
+   if ( DeleteMenu(mymenu, id, MF_BYCOMMAND) == 0 )
+   {
+      char lasterror[257];
+      FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), lasterror, 256, NULL);
+      fprintf(stderr, "Error deleting menu: %s", lasterror);
+   }
+   DrawMenuBar(menux);
+}
+
+/*
+ * Pops up a context menu at given x and y coordinates.
+ * Parameters:
+ *       menu: The handle the the existing menu.
+ *       parent: Handle to the window initiating the popup.
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_menu_popup(HMENUI *menu, HWND parent, int x, int y)
+{
+   if(menu)
+   {
+      HMENU mymenu = (HMENU)*menu;
+
+      if(IsWindow(*menu) && !IsMenu(mymenu))
+         mymenu = (HMENU)dw_window_get_data(*menu, "_dw_menu");
+
+      popup = parent;
+      TrackPopupMenu(mymenu, 0, x, y, 0, parent, NULL);
+      PostMessage(DW_HWND_OBJECT, WM_USER+5, (LPARAM)mymenu, 0);
+   }
+}
+
+
+/*
+ * Create a container object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_container_new(ULONG id, int multi)
+{
+   HWND tmp = CreateWindow(WC_LISTVIEW,
+                     "",
+                     WS_VISIBLE | WS_CHILD |
+                     (multi ? 0 : LVS_SINGLESEL) |
+                     LVS_REPORT | LVS_SHOWSELALWAYS |
+                     LVS_SHAREIMAGELISTS | WS_BORDER |
+                     WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
+
+   if(!cinfo)
+   {
+      DestroyWindow(tmp);
+      return NULL;
+   }
+
+   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
+   cinfo->cinfo.fore = cinfo->cinfo.back = -1;
+   cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   /* If we are running XP or higher... */
+   if(IS_XPPLUS)
+   {
+      /* Enable double buffering to prevent flicker */
+      ListView_SetExtendedListViewStyleEx(tmp, LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER);
+   }
+   return tmp;
+}
+
+/*
+ * Create a tree object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND API dw_tree_new(ULONG id)
+{
+   HWND tmp = CreateWindow(WC_TREEVIEW,
+                     "",
+                     WS_VISIBLE | WS_CHILD |
+                     TVS_HASLINES | TVS_SHOWSELALWAYS |
+                     TVS_HASBUTTONS | TVS_LINESATROOT |
+                     WS_BORDER | WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
+   TreeView_SetItemHeight(tmp, 16);
+
+   if(!cinfo)
+   {
+      DestroyWindow(tmp);
+      return NULL;
+   }
+
+   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
+   cinfo->cinfo.fore = cinfo->cinfo.back = -1;
+   cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Returns the current X and Y coordinates of the mouse pointer.
+ * Parameters:
+ *       x: Pointer to variable to store X coordinate.
+ *       y: Pointer to variable to store Y coordinate.
+ */
+void API dw_pointer_query_pos(long *x, long *y)
+{
+   POINT ptl;
+
+   GetCursorPos(&ptl);
+   if(x && y)
+   {
+      *x = ptl.x;
+      *y = ptl.y;
+   }
+}
+
+/*
+ * Sets the X and Y coordinates of the mouse pointer.
+ * Parameters:
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_pointer_set_pos(long x, long y)
+{
+   SetCursorPos(x, y);
+}
+
+/*
+ * Create a new static text window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_text_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindow(STATICCLASSNAME,
+                     text,
+                     SS_NOPREFIX |
+                     BS_TEXT | WS_VISIBLE |
+                     WS_CHILD | WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new status text window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_status_text_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindow(ObjectClassName,
+                     text,
+                     BS_TEXT | WS_VISIBLE |
+                     WS_CHILD | WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   dw_window_set_font(tmp, DefaultFont);
+   SubclassWindow(tmp, _statuswndproc);
+   return tmp;
+}
+
+/*
+ * Create a new Multiline Editbox window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_mle_new(ULONG id)
+{
+
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                       EDITCLASSNAME,
+                       "",
+                       WS_VISIBLE | WS_BORDER |
+                       WS_VSCROLL | ES_MULTILINE |
+                       ES_WANTRETURN | WS_CHILD |
+                       WS_CLIPCHILDREN,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+   ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
+
+   if(!cinfo)
+   {
+      DestroyWindow(tmp);
+      return NULL;
+   }
+
+   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _treewndproc);
+   cinfo->cinfo.fore = cinfo->cinfo.back = -1;
+   cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new Entryfield window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_entryfield_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                       EDITCLASSNAME,
+                       text,
+                       ES_WANTRETURN | WS_CHILD |
+                       WS_BORDER | ES_AUTOHSCROLL |
+                       WS_VISIBLE | WS_CLIPCHILDREN,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   cinfo->back = cinfo->fore = -1;
+
+   cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new Entryfield passwird window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the entryfield widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_entryfield_password_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                       EDITCLASSNAME,
+                       text,
+                       ES_WANTRETURN | WS_CHILD |
+                       ES_PASSWORD | WS_BORDER | WS_VISIBLE |
+                       ES_AUTOHSCROLL | WS_CLIPCHILDREN,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   cinfo->back = cinfo->fore = -1;
+
+   cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+BOOL CALLBACK _subclass_child(HWND handle, LPARAM lp)
+{
+   ColorInfo *cinfo = (ColorInfo *)lp;
+
+   if(cinfo)
+   {
+      cinfo->buddy = handle;
+      cinfo->pOldProc = (WNDPROC)SubclassWindow(handle, _colorwndproc);
+      SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
+   }
+   return FALSE;
+}
+
+/*
+ * Create a new Combobox window (widget) to be packed.
+ * Parameters:
+ *       text: The default text to be in the combpbox widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_combobox_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindow(COMBOBOXCLASSNAME,
+                     text,
+                     WS_CHILD | CBS_DROPDOWN | WS_VSCROLL |
+                     WS_CLIPCHILDREN | CBS_AUTOHSCROLL | WS_VISIBLE,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo));
+   ColorInfo *cinfo2 = (ColorInfo *)calloc(1, sizeof(ColorInfo));
+
+   if(!cinfo || !cinfo2)
+   {
+      if(cinfo)
+         free(cinfo);
+      if(cinfo2)
+         free(cinfo2);
+      DestroyWindow(tmp);
+      return NULL;
+   }
+
+   cinfo2->fore = cinfo->fore = -1;
+   cinfo2->back = cinfo->back = -1;
+   cinfo2->combo = cinfo->combo = tmp;
+   EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo2);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   SetWindowText(tmp, text);
+   return tmp;
+}
+
+/*
+ * Create a new button window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_button_new(char *text, ULONG id)
+{
+   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+
+   HWND tmp = CreateWindow(BUTTONCLASSNAME,
+                     text,
+                     WS_CHILD | BS_PUSHBUTTON |
+                     WS_VISIBLE | WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID of a bitmap in the resource file.
+ */
+HWND API dw_bitmapbutton_new(char *text, ULONG id)
+{
+   HWND tmp;
+   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+   HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+   HICON icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED);
+
+   tmp = CreateWindow(BUTTONCLASSNAME,
+                  "",
+                  WS_CHILD | BS_PUSHBUTTON |
+                  WS_VISIBLE | WS_CLIPCHILDREN |
+                  (icon ? BS_ICON : BS_BITMAP),
+                  0,0,2000,1000,
+                  DW_HWND_OBJECT,
+                  (HMENU)id,
+                  DWInstance,
+                  NULL);
+
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+
+   _create_tooltip(tmp, text);
+
+   if(icon)
+   {
+      SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) icon);
+   }
+   else if(hbitmap)
+   {
+      SendMessage(tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
+   }
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from a file.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP or ICO on OS/2 or Windows, XPM on Unix)
+ */
+HWND API dw_bitmapbutton_new_from_file(char *text, unsigned long id, char *filename)
+{
+   HWND tmp;
+   BubbleButton *bubble;
+   HBITMAP hbitmap = 0;
+   HANDLE hicon = 0;
+   int windowtype = 0, len;
+
+   if (!(bubble = calloc(1, sizeof(BubbleButton))))
+      return 0;
+
+#ifdef GDIPLUS
+   if((hicon = _dw_load_icon(filename)))
+      windowtype = BS_ICON;
+   else
+   {
+      hbitmap = _dw_load_bitmap(filename, NULL);
+      windowtype = BS_BITMAP;
+   }
+#else
+   windowtype = _dw_get_image_handle(filename, &hicon, &hbitmap);
+#endif
+
+   tmp = CreateWindow( BUTTONCLASSNAME,
+                       "",
+                       windowtype | WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN | WS_VISIBLE,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+
+   _create_tooltip(tmp, text);
+
+   if (hicon)
+   {
+      SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_ICON,(LPARAM) hicon);
+   }
+   else if (hbitmap)
+   {
+      SendMessage(tmp, BM_SETIMAGE,(WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
+   }
+   return tmp;
+}
+
+/*
+ * Create a new bitmap button window (widget) to be packed from data.
+ * Parameters:
+ *       text: Bubble help text to be displayed.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       data: The contents of the image
+ *            (BMP or ICO on OS/2 or Windows, XPM on Unix)
+ *       len: length of str
+ */
+HWND API dw_bitmapbutton_new_from_data(char *text, unsigned long id, char *data, int len)
+{
+   HWND tmp;
+   BubbleButton *bubble;
+   HBITMAP hbitmap = 0;
+   HANDLE hicon = 0;
+   char *file;
+   FILE *fp;
+   int windowtype;
+
+   if ( !(bubble = calloc(1, sizeof(BubbleButton))) )
+      return 0;
+   file = _tempnam( _dw_alternate_temp_dir, "dw" );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+#ifdef GDIPLUS
+         if((hicon = _dw_load_icon(file)))
+            windowtype = BS_ICON;
+         else
+         {
+            hbitmap = _dw_load_bitmap(file, NULL);
+            windowtype = BS_BITMAP;
+         }
+#else
+         if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+         {
+            hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+            windowtype = BS_BITMAP;
+         }
+         else /* otherwise its assumed to be an ico */
+         {
+            hicon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+            windowtype = BS_ICON;
+         }
+#endif
+      }
+      else
+      {
+         unlink( file );
+         free( file );
+         return 0;
+      }
+      unlink( file );
+      free( file );
+   }
+
+   tmp = CreateWindow( BUTTONCLASSNAME,
+                       "",
+                       WS_CHILD | BS_PUSHBUTTON |
+                       windowtype | WS_CLIPCHILDREN |
+                       WS_VISIBLE,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL );
+
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow( tmp, _BtProc );
+
+   SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)bubble );
+
+   _create_tooltip(tmp, text);
+
+   if ( hicon )
+   {
+      SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) hicon);
+   }
+   else if( hbitmap )
+   {
+      SendMessage( tmp, BM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbitmap);
+   }
+   return tmp;
+}
+
+/*
+ * Create a new spinbutton window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_spinbutton_new(char *text, ULONG id)
+{
+   HWND buddy = CreateWindowEx(WS_EX_CLIENTEDGE,
+                        EDITCLASSNAME,
+                        text,
+                        WS_CHILD | WS_BORDER | WS_VISIBLE |
+                        ES_NUMBER | WS_CLIPCHILDREN,
+                        0,0,2000,1000,
+                        DW_HWND_OBJECT,
+                        NULL,
+                        DWInstance,
+                        NULL);
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                       UPDOWN_CLASS,
+                       NULL,
+                       WS_CHILD | UDS_ALIGNRIGHT | WS_BORDER |
+                       UDS_ARROWKEYS | UDS_SETBUDDYINT |
+                       UDS_WRAP | UDS_NOTHOUSANDS | WS_VISIBLE,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   SendMessage(tmp, UDM_SETRANGE32, (WPARAM)-65536,(LPARAM)65536);
+   SendMessage(tmp, UDM_SETBUDDY, (WPARAM)buddy, 0);
+   cinfo->back = cinfo->fore = -1;
+   cinfo->buddy = tmp;
+
+   cinfo->pOldProc = SubclassWindow(buddy, _colorwndproc);
+   SetWindowLongPtr(buddy, GWLP_USERDATA, (LONG_PTR)cinfo);
+
+   cinfo = calloc(1, sizeof(ColorInfo));
+   cinfo->buddy = buddy;
+   /* The horrible spinbutton workaround isn't necessary 
+    * any more on Vista or 7... but still seems necessary
+    * for XP, so only enable it if on XP or lower. 
+    */
+   if(!IS_VISTAPLUS)
+   {
+      cinfo->pOldProc = SubclassWindow(tmp, _spinnerwndproc);
+   }
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(buddy, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new radiobutton window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_radiobutton_new(char *text, ULONG id)
+{
+   HWND tmp = CreateWindow(BUTTONCLASSNAME,
+                     text,
+                     WS_CHILD | BS_AUTORADIOBUTTON |
+                     WS_CLIPCHILDREN | WS_VISIBLE,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+
+/*
+ * Create a new slider window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if slider is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_slider_new(int vertical, int increments, ULONG id)
+{
+   HWND tmp = CreateWindow(TRACKBAR_CLASS,
+                     "",
+                     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
+                     (vertical ? TBS_VERT : TBS_HORZ),
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   cinfo->back = cinfo->fore = -1;
+
+   cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(0, increments-1));
+   return tmp;
+}
+
+/*
+ * Create a new scrollbar window (widget) to be packed.
+ * Parameters:
+ *       vertical: TRUE or FALSE if scrollbar is vertical.
+ *       increments: Number of increments available.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_scrollbar_new(int vertical, ULONG id)
+{
+   HWND tmp = CreateWindow(SCROLLBARCLASSNAME,
+                     "",
+                     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
+                     (vertical ? SBS_VERT : SBS_HORZ),
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
+
+   cinfo->back = cinfo->fore = -1;
+
+   cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_data(tmp, "_dw_scrollbar", (void *)1);
+   return tmp;
+}
+
+/*
+ * Create a new percent bar window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_percent_new(ULONG id)
+{
+   return CreateWindow(PROGRESS_CLASS,
+                  "",
+                  WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
+                  0,0,2000,1000,
+                  DW_HWND_OBJECT,
+                  (HMENU)id,
+                  DWInstance,
+                  NULL);
+}
+
+/*
+ * Create a new checkbox window (widget) to be packed.
+ * Parameters:
+ *       text: The text to be display by the static text widget.
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ */
+HWND API dw_checkbox_new(char *text, ULONG id)
+{
+   BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
+   HWND tmp = CreateWindow(BUTTONCLASSNAME,
+                     text,
+                     WS_CHILD | BS_AUTOCHECKBOX |
+                     BS_TEXT | WS_CLIPCHILDREN | WS_VISIBLE,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   bubble->checkbox = 1;
+   bubble->cinfo.fore = bubble->cinfo.back = -1;
+   bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)bubble);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Create a new listbox window (widget) to be packed.
+ * Parameters:
+ *       id: An ID to be used with dw_window_from_id() or 0L.
+ *       multi: Multiple select TRUE or FALSE.
+ */
+HWND API dw_listbox_new(ULONG id, int multi)
+{
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                       LISTBOXCLASSNAME,
+                       "",
+                       WS_VISIBLE | LBS_NOINTEGRALHEIGHT |
+                       WS_CHILD | LBS_HASSTRINGS |
+                       LBS_NOTIFY | WS_BORDER  | WS_CLIPCHILDREN |
+                       WS_VSCROLL | (multi ? LBS_MULTIPLESEL : 0) ,
+                       0,0,2000,1000,
+                       DW_HWND_OBJECT,
+                       (HMENU)id,
+                       DWInstance,
+                       NULL);
+   ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo));
+
+   if(!cinfo)
+   {
+      DestroyWindow(tmp);
+      return NULL;
+   }
+
+   cinfo->cinfo.fore = cinfo->cinfo.back = -1;
+   cinfo->odd = cinfo->even = DW_RGB_TRANSPARENT;
+   cinfo->cinfo.pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc);
+
+   SetWindowLongPtr(tmp, GWLP_USERDATA, (LONG_PTR)cinfo);
+   dw_window_set_font(tmp, DefaultFont);
+   return tmp;
+}
+
+/*
+ * Sets the icon used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon.
+ */
+void API dw_window_set_icon(HWND handle, HICN icon)
+{
+   int iicon = (int)icon;
+   HICON hicon = iicon < 65536 ? LoadIcon(DWInstance, MAKEINTRESOURCE(iicon)) : (HICON)icon;
+
+   SendMessage(handle, WM_SETICON,
+            (WPARAM) IMAGE_ICON,
+            (LPARAM) hicon);
+}
+
+/*
+ * Sets the bitmap used for a given static window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon,
+ *           (pass 0 if you use the filename param)
+ *       filename: a path to a file (Bitmap on OS/2 or
+ *                 Windows and a pixmap on Unix, pass
+ *                 NULL if you use the id param)
+ */
+void API dw_window_set_bitmap(HWND handle, unsigned long id, char *filename)
+{
+   HBITMAP hbitmap;
+   HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
+   HICON icon = 0;
+   HICON oldicon = (HICON)SendMessage(handle, STM_GETIMAGE, IMAGE_ICON, 0);
+
+   if(id)
+   {
+      hbitmap = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS | LR_SHARED);
+      icon = LoadImage(DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED);
+   }
+   else if(filename)
+   {
+#ifdef GDIPLUS
+      hbitmap = _dw_load_bitmap(filename, NULL);
+#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);
+}
+
+/*
+ * Sets the bitmap used for a given static window from data.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       id: An ID to be used to specify the icon,
+ *           (pass 0 if you use the data param)
+ *       data: the image from meory
+ *                 Bitmap on Windows and a pixmap on Unix, pass
+ *                 NULL if you use the id param)
+ *       len: length of data
+ */
+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;
+
+   if ( id )
+   {
+      hbitmap = LoadBitmap( DWInstance, MAKEINTRESOURCE(id) );
+      icon = LoadImage( DWInstance, MAKEINTRESOURCE(id), IMAGE_ICON, 0, 0, LR_SHARED );
+   }
+   else if (data)
+   {
+      file = _tempnam( _dw_alternate_temp_dir, "dw" );
+      if ( file != NULL )
+      {
+         fp = fopen( file, "wb" );
+         if ( fp != NULL )
+         {
+            fwrite( data, 1, len, fp );
+            fclose( fp );
+#ifdef GDIPLUS
+            hbitmap = _dw_load_bitmap(file, NULL);
+#else
+            if ( len > 1 && data[0] == 'B' && data[1] == 'M' ) /* first 2 chars of data is BM, then its a BMP */
+               hbitmap = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+            else /* otherwise its assumed to be an ico */
+               icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+#endif
+         }
+         else
+         {
+            unlink( file );
+            free( file );
+            return;
+         }
+         unlink( file );
+         free( file );
+      }
+      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 );
+}
+
+
+/*
+ * Sets the text used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       text: The text associsated with a given window.
+ */
+void API dw_window_set_text(HWND handle, char *text)
+{
+   Box *thisbox;
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   SetWindowText(handle, text);
+
+   /* Combobox */
+   if ( strnicmp( tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1) == 0 )
+      SendMessage(handle, CB_SETEDITSEL, 0, MAKELPARAM(-1, 0));
+   else if ( strnicmp( tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1) == 0 )
+   {
+      ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+      if( cinfo && cinfo->buddy )
+         SetWindowText( cinfo->buddy, text );
+   }
+   else if ( strnicmp( tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1) == 0 )
+   {
+      /* groupbox */
+      thisbox = (Box *)GetWindowLongPtr( handle, GWLP_USERDATA );
+      if ( thisbox && thisbox->grouphwnd != (HWND)NULL )
+         SetWindowText( thisbox->grouphwnd, text );
+   }
+}
+
+/*
+ * Gets the text used for a given window.
+ * Parameters:
+ *       handle: Handle to the window.
+ * Returns:
+ *       text: The text associsated with a given window.
+ */
+char * API dw_window_get_text(HWND handle)
+{
+   char tmpbuf[100], *tempbuf;
+   int len;
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if ( strnicmp( tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1) == 0 )
+   {
+      ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+      if( cinfo && cinfo->buddy )
+        handle = cinfo->buddy;
+      else
+        return NULL;
+   }
+
+   len = GetWindowTextLength(handle);
+   tempbuf = calloc(1, len + 2);
+
+   GetWindowText(handle, tempbuf, len + 1);
+
+   return tempbuf;
+}
+
+/*
+ * Disables given window (widget).
+ * Parameters:
+ *       handle: Handle to the window.
+ */
+void API dw_window_disable(HWND handle)
+{
+   if(handle < (HWND)65536)
+   {
+      char buffer[31] = {0};
+      HMENU mymenu;
+      ULONG id = (ULONG)handle;
+      
+      _snprintf(buffer, 30, "_dw_id%ld", id);
+      mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      
+      if(mymenu && IsMenu(mymenu))
+         dw_menu_item_set_state((HMENUI)mymenu, id, DW_MIS_DISABLED);
+   }
+   else
+      EnableWindow(handle, FALSE);
+}
+
+/*
+ * Enables given window (widget).
+ * Parameters:
+ *       handle: Handle to the window.
+ */
+void API dw_window_enable(HWND handle)
+{
+   if(handle < (HWND)65536)
+   {
+      char buffer[31] = {0};
+      HMENU mymenu;
+      ULONG id = (ULONG)handle;
+      
+      _snprintf(buffer, 30, "_dw_id%ld", id);
+      mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      
+      if(mymenu && IsMenu(mymenu))
+         dw_menu_item_set_state((HMENUI)mymenu, id, DW_MIS_ENABLED);
+   }
+   else
+   EnableWindow(handle, TRUE);
+}
+
+static HWND _dw_wfid_hwnd = NULL;
+
+BOOL CALLBACK _wfid(HWND handle, LPARAM lParam)
+{
+   if(GetWindowLong(handle, GWL_ID) == lParam)
+   {
+      _dw_wfid_hwnd = handle;
+      return FALSE;
+   }
+   return TRUE;
+}
+
+/*
+ * Gets the child window handle with specified ID.
+ * Parameters:
+ *       handle: Handle to the parent window.
+ *       id: Integer ID of the child.
+ */
+HWND API dw_window_from_id(HWND handle, int id)
+{
+   _dw_wfid_hwnd = NULL;
+   EnumChildWindows(handle, _wfid, (LPARAM)id);
+    return _dw_wfid_hwnd;
+}
+
+/* Internal box packing function called by the other 3 functions */
+void _dw_box_pack(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad, char *funcname)
+{
+   Box *thisbox = NULL;
+   char tmpbuf[100];
+
+      /*
+       * If you try and pack an item into itself VERY bad things can happen; like at least an
+       * infinite loop on GTK! Lets be safe!
+       */
+   if(box == item)
+   {
+      dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Danger! Danger! Will Robinson; box and item are the same!");
+      return;
+   }
+
+   GetClassName(box, tmpbuf, 99);
+
+   /* If we are in a scrolled box... extract the interal box */
+   if(strnicmp(tmpbuf, ScrollClassName, strlen(ScrollClassName)+1)==0)
+   {
+        ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(box, GWLP_USERDATA);
+        if(cinfo)
+        {
+            box = cinfo->buddy;
+            thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+        }
+   }
+   else //if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+       thisbox = (Box *)GetWindowLongPtr(box, GWLP_USERDATA);
+   if(thisbox)
+   {
+      int z, x = 0;
+      Item *tmpitem, *thisitem = thisbox->items;
+
+      /* Do some sanity bounds checking */
+      if(index < 0)
+        index = 0;
+      if(index > thisbox->count)
+        index = thisbox->count;
+
+      tmpitem = malloc(sizeof(Item)*(thisbox->count+1));
+
+      for(z=0;z<thisbox->count;z++)
+      {
+         if(z == index)
+            x++;
+         tmpitem[x] = thisitem[z];
+         x++;
+      }
+
+      GetClassName(item, tmpbuf, 99);
+
+      if(vsize && !height)
+         height = 1;
+      if(hsize && !width)
+         width = 1;
+
+      if(strnicmp(tmpbuf, FRAMECLASSNAME, strlen(FRAMECLASSNAME)+1)==0)
+         tmpitem[index].type = TYPEBOX;
+      else if(strnicmp(tmpbuf, "SysMonthCal32", 13)==0)
+      {
+         RECT rc;
+         MonthCal_GetMinReqRect(item, &rc);
+         width = 1 + rc.right - rc.left;
+         height = 1 + rc.bottom - rc.top;
+         tmpitem[index].type = TYPEITEM;
+      }
+      else
+      {
+         if ( width == 0 && hsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Width and expand Horizonal both unset for box: %x item: %x",box,item);
+         if ( height == 0 && vsize == FALSE )
+            dw_messagebox(funcname, DW_MB_OK|DW_MB_ERROR, "Height and expand Vertical both unset for box: %x item: %x",box,item);
+
+         tmpitem[index].type = TYPEITEM;
+      }
+
+      tmpitem[index].hwnd = item;
+      tmpitem[index].origwidth = tmpitem[index].width = width;
+      tmpitem[index].origheight = tmpitem[index].height = height;
+      tmpitem[index].pad = pad;
+      if(hsize)
+         tmpitem[index].hsize = SIZEEXPAND;
+      else
+         tmpitem[index].hsize = SIZESTATIC;
+
+      if(vsize)
+         tmpitem[index].vsize = SIZEEXPAND;
+      else
+         tmpitem[index].vsize = SIZESTATIC;
+
+      thisbox->items = tmpitem;
+
+      if(thisbox->count)
+         free(thisitem);
+
+      thisbox->count++;
+
+      SetParent(item, box);
+      if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
+      {
+         ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(item, GWLP_USERDATA);
+
+         if(cinfo)
+         {
+            SetParent(cinfo->buddy, box);
+            ShowWindow(cinfo->buddy, SW_SHOW);
+            SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0);
+         }
+      }
+   }
+}
+
+/*
+ * Pack windows (widgets) into a box at an arbitrary location.
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       index: 0 based index of packed items.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_at_index(HWND box, HWND item, int index, int width, int height, int hsize, int vsize, int pad)
+{
+    _dw_box_pack(box, item, index, width, height, hsize, vsize, pad, "dw_box_pack_at_index()");
+}
+
+/*
+ * Pack windows (widgets) into a box from the start (or top).
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
+{
+    /* 65536 is the table limit on GTK...
+     * seems like a high enough value we will never hit it here either.
+     */
+    _dw_box_pack(box, item, 65536, width, height, hsize, vsize, pad, "dw_box_pack_start()");
+}
+
+/*
+ * Pack windows (widgets) into a box from the end (or bottom).
+ * Parameters:
+ *       box: Window handle of the box to be packed into.
+ *       item: Window handle of the item to be back.
+ *       width: Width in pixels of the item or -1 to be self determined.
+ *       height: Height in pixels of the item or -1 to be self determined.
+ *       hsize: TRUE if the window (widget) should expand horizontally to fill space given.
+ *       vsize: TRUE if the window (widget) should expand vertically to fill space given.
+ *       pad: Number of pixels of padding around the item.
+ */
+void API dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad)
+{
+    _dw_box_pack(box, item, 0, width, height, hsize, vsize, pad, "dw_box_pack_end()");
+}
+
+/*
+ * Sets the size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          width: New width in pixels.
+ *          height: New height in pixels.
+ */
+void API dw_window_set_size(HWND handle, ULONG width, ULONG height)
+{
+   int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
+   Box *thisbox;
+   /*
+    * The following is an attempt to dynamically size a window based on the size of its
+    * children before realization. Only applicable when width or height is zero.
+    * It doesn't work vey well :-(
+    */
+   thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   if ( thisbox )
+   {
+      _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady);
+      _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
+   }
+   if ( width == 0 ) width = usedx;
+   if ( height == 0 ) height = usedy;
+   SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE);
+}
+
+/*
+ * Returns the width of the screen.
+ */
+int API dw_screen_width(void)
+{
+   return screenx;
+}
+
+/*
+ * Returns the height of the screen.
+ */
+int API dw_screen_height(void)
+{
+   return screeny;
+}
+
+/* This should return the current color depth */
+unsigned long API dw_color_depth_get(void)
+{
+   int bpp;
+   HDC hdc = GetDC(HWND_DESKTOP);
+
+   bpp = GetDeviceCaps(hdc, BITSPIXEL);
+
+   ReleaseDC(HWND_DESKTOP, hdc);
+
+   return bpp;
+}
+
+
+/*
+ * Sets the position of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ */
+void API dw_window_set_pos(HWND handle, long x, long y)
+{
+   SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+/*
+ * Sets the position and size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ *          width: Width of the widget.
+ *          height: Height of the widget.
+ */
+void API dw_window_set_pos_size(HWND handle, long x, long y, ULONG width, ULONG height)
+{
+   int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0;
+   Box *thisbox;
+   /*
+    * The following is an attempt to dynamically size a window based on the size of its
+    * children before realization. Only applicable when width or height is zero.
+    * It doesn't work vey well :-(
+    */
+   thisbox = (Box *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   if ( thisbox )
+   {
+      _resize_box(thisbox, &depth, 0, 0, &usedx, &usedy, 1, &usedpadx, &usedpady);
+      _resize_box(thisbox, &depth, usedx, usedy, &usedx, &usedy, 2, &usedpadx, &usedpady);
+   }
+   if ( width == 0 ) width = usedx;
+   if ( height == 0 ) height = usedy;
+   SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+#if 0
+   /* force a configure event */
+   SendMessage( handle, WM_SIZE, 0, MAKELPARAM(width, height) );
+#endif
+}
+
+/*
+ * Gets the position and size of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          x: X location from the bottom left.
+ *          y: Y location from the bottom left.
+ *          width: Width of the widget.
+ *          height: Height of the widget.
+ */
+void API dw_window_get_pos_size(HWND handle, long *x, long *y, ULONG *width, ULONG *height)
+{
+   WINDOWPLACEMENT wp;
+
+   wp.length = sizeof(WINDOWPLACEMENT);
+
+   GetWindowPlacement(handle, &wp);
+   if( wp.showCmd == SW_SHOWMAXIMIZED)
+   {
+      if(x)
+         *x=0;
+      if(y)
+         *y=0;
+      if(width)
+         *width=dw_screen_width();
+      if(height)
+         *height=dw_screen_height();
+   }
+   else
+   {
+      if(x)
+         *x = wp.rcNormalPosition.left;
+      if(y)
+         *y = wp.rcNormalPosition.top;
+      if(width)
+         *width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;
+      if(height)
+         *height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
+   }
+}
+
+/*
+ * Sets the style of a given window (widget).
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          width: New width in pixels.
+ *          height: New height in pixels.
+ */
+void API dw_window_set_style(HWND handle, ULONG style, ULONG mask)
+{
+   ULONG tmp, currentstyle;
+   ColorInfo *cinfo;
+   
+   if(handle < (HWND)65536)
+   {
+      char buffer[31] = {0};
+      HMENU mymenu;
+      ULONG id = (ULONG)handle;
+      
+      _snprintf(buffer, 30, "_dw_id%ld", id);
+      mymenu = (HMENU)dw_window_get_data(DW_HWND_OBJECT, buffer);
+      
+      if(mymenu && IsMenu(mymenu))
+         dw_menu_item_set_state((HMENUI)mymenu, id, style & mask);
+      return;
+   }
+   
+   currentstyle = GetWindowLong(handle, GWL_STYLE);
+   cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   tmp = currentstyle | mask;
+   tmp ^= mask;
+   tmp |= style;
+
+   /* We are using SS_NOPREFIX as a VCENTER flag */
+   if(tmp & SS_NOPREFIX)
+   {
+
+      if(cinfo)
+         cinfo->vcenter = 1;
+      else
+      {
+         cinfo = calloc(1, sizeof(ColorInfo));
+         cinfo->fore = cinfo->back = -1;
+         cinfo->vcenter = 1;
+
+         cinfo->pOldProc = SubclassWindow(handle, _colorwndproc);
+         SetWindowLongPtr(handle, GWLP_USERDATA, (LONG_PTR)cinfo);
+      }
+   }
+   else if(cinfo)
+      cinfo->vcenter = 0;
+
+   SetWindowLong(handle, GWL_STYLE, tmp);
+}
+
+/* Finds the physical ID from the reference ID */
+int _findnotebookid(NotebookPage **array, int pageid)
+{
+   int z;
+
+   for(z=0;z<256;z++)
+   {
+      if(array[z] && array[z]->realid == pageid)
+         return z;
+   }
+   return -1;
+}
+
+/*
+ * Adds a new page to specified notebook.
+ * Parameters:
+ *          handle: Window (widget) handle.
+ *          flags: Any additional page creation flags.
+ *          front: If TRUE page is added at the beginning.
+ */
+unsigned long API dw_notebook_page_new(HWND handle, ULONG flags, int front)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+
+   if(array)
+   {
+      int z, refid = -1;
+
+      for(z=0;z<256;z++)
+      {
+         if(_findnotebookid(array, z) == -1)
+         {
+            refid = z;
+            break;
+         }
+      }
+
+      if(refid == -1)
+         return -1;
+
+      for(z=0;z<256;z++)
+      {
+         if(!array[z])
+         {
+            int oldpage = TabCtrl_GetCurSel(handle);
+
+            array[z] = calloc(1, sizeof(NotebookPage));
+            array[z]->realid = refid;
+            array[z]->item.mask = TCIF_TEXT;
+            array[z]->item.iImage = -1;
+            array[z]->item.pszText = "";
+            TabCtrl_InsertItem(handle, z, &(array[z]->item));
+            return refid;
+         }
+      }
+   }
+   return -1;
+}
+
+/*
+ * Sets the text on the specified notebook tab.
+ * Parameters:
+ *          handle: Notebook handle.
+ *          pageid: Page ID of the tab to set.
+ *          text: Pointer to the text to set.
+ */
+void API dw_notebook_page_set_text(HWND handle, ULONG pageidx, char *text)
+{
+
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+   int pageid;
+
+   if(!array)
+      return;
+
+   pageid = _findnotebookid(array, pageidx);
+
+   if(pageid > -1 && array[pageid])
+   {
+      array[pageid]->item.mask = TCIF_TEXT;
+      array[pageid]->item.pszText = text;
+      TabCtrl_SetItem(handle, pageid, &(array[pageid]->item));
+      _resize_notebook_page(handle, pageid);
+   }
+}
+
+/*
+ * Sets the text on the specified notebook tab status area.
+ * Parameters:
+ *          handle: Notebook handle.
+ *          pageid: Page ID of the tab to set.
+ *          text: Pointer to the text to set.
+ */
+void API dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text)
+{
+}
+
+/*
+ * Packs the specified box into the notebook page.
+ * Parameters:
+ *          handle: Handle to the notebook to be packed.
+ *          pageid: Page ID in the notebook which is being packed.
+ *          page: Box handle to be packed.
+ */
+void API dw_notebook_pack(HWND handle, ULONG pageidx, HWND page)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+   int pageid;
+
+   if(!array)
+      return;
+
+   pageid = _findnotebookid(array, pageidx);
+
+   if(pageid > -1 && array[pageid])
+   {
+      HWND tmpbox = dw_box_new(DW_VERT, 0);
+
+      dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0);
+      SubclassWindow(tmpbox, _wndproc);
+      if(array[pageid]->hwnd)
+         dw_window_destroy(array[pageid]->hwnd);
+      array[pageid]->hwnd = tmpbox;
+      if(pageidx == dw_notebook_page_get(handle))
+      {
+         ShowWindow(tmpbox, SW_HIDE);
+         SetParent(tmpbox, handle);
+         _resize_notebook_page(handle, pageid);
+      }
+   }
+}
+
+/*
+ * Remove a page from a notebook.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ *          pageid: ID of the page to be destroyed.
+ */
+void API dw_notebook_page_destroy(HWND handle, unsigned int pageidx)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+   int newid = -1, z, pageid;
+   HWND pagehwnd = 0;
+
+   if(!array)
+      return;
+
+   pageid = _findnotebookid(array, pageidx);
+
+   if(pageid < 0)
+      return;
+
+   if(array[pageid])
+   {
+      SetParent(array[pageid]->hwnd, DW_HWND_OBJECT);
+      pagehwnd = array[pageid]->hwnd;
+      free(array[pageid]);
+      array[pageid] = NULL;
+   }
+
+   TabCtrl_DeleteItem(handle, pageid);
+
+   /* Shift the pages over 1 */
+   for(z=pageid;z<255;z++)
+      array[z] = array[z+1];
+   array[255] = NULL;
+
+   for(z=0;z<256;z++)
+   {
+      if(array[z])
+      {
+         newid = z;
+         break;
+      }
+   }
+   if(newid > -1)
+   {
+      SetParent(array[newid]->hwnd, handle);
+      _resize_notebook_page(handle, newid);
+      dw_notebook_page_set(handle, array[newid]->realid);
+   }
+   if(pagehwnd)
+      dw_window_destroy(pagehwnd);
+}
+
+/*
+ * Queries the currently visible page ID.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ */
+unsigned long API dw_notebook_page_get(HWND handle)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+   int physid = TabCtrl_GetCurSel(handle);
+
+   if(physid > -1 && physid < 256 && array && array[physid])
+      return array[physid]->realid;
+   return -1;
+}
+
+/*
+ * Sets the currently visible page ID.
+ * Parameters:
+ *          handle: Handle to the notebook widget.
+ *          pageid: ID of the page to be made visible.
+ */
+void API dw_notebook_page_set(HWND handle, unsigned int pageidx)
+{
+   NotebookPage **array = (NotebookPage **)dw_window_get_data(handle, "_dw_array");
+   int pageid;
+
+   if(!array)
+      return;
+
+   pageid = _findnotebookid(array, pageidx);
+
+   if(pageid > -1 && pageid < 256)
+   {
+      int oldpage = TabCtrl_GetCurSel(handle);
+
+      if(oldpage > -1 && array && array[oldpage])
+         SetParent(array[oldpage]->hwnd, DW_HWND_OBJECT);
+
+      TabCtrl_SetCurSel(handle, pageid);
+
+      SetParent(array[pageid]->hwnd, handle);
+      _resize_notebook_page(handle, pageid);
+   }
+}
+
+/*
+ * Appends the specified text to the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be appended to.
+ *          text: Text to append into listbox.
+ */
+void API dw_listbox_append(HWND handle, char *text)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      SendMessage(handle,
+               CB_ADDSTRING,
+               0, (LPARAM)text);
+   else
+      SendMessage(handle,
+               LB_ADDSTRING,
+               0, (LPARAM)text);
+}
+
+/*
+ * Appends the specified text items to the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be appended to.
+ *          text: Text strings to append into listbox.
+ *          count: Number of text strings to append
+ */
+void API dw_listbox_list_append(HWND handle, char **text, int count)
+{
+   char tmpbuf[100];
+   int listbox_type;
+   int i;
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      listbox_type = CB_ADDSTRING;
+   else
+      listbox_type = LB_ADDSTRING;
+
+   for(i=0;i<count;i++)
+      SendMessage(handle,(WPARAM)listbox_type,0,(LPARAM)text[i]);
+}
+
+/*
+ * Inserts the specified text to the listbox's (or combobox) entry list.
+ * Parameters:
+ *          handle: Handle to the listbox to be appended to.
+ *          text: Text to append into listbox.
+ *          pos: 0 based position to insert text
+ */
+void API dw_listbox_insert(HWND handle, char *text, int pos)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      SendMessage(handle,
+               CB_INSERTSTRING,
+               pos, (LPARAM)text);
+   else
+      SendMessage(handle,
+               LB_INSERTSTRING,
+               pos, (LPARAM)text);
+}
+
+/*
+ * Clears the listbox's (or combobox) list of all entries.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ */
+void API dw_listbox_clear(HWND handle)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   {
+      char *buf = dw_window_get_text(handle);
+
+      SendMessage(handle,
+               CB_RESETCONTENT, 0L, 0L);
+
+      if(buf)
+      {
+         dw_window_set_text(handle, buf);
+         free(buf);
+      }
+   }
+   else
+      SendMessage(handle,
+               LB_RESETCONTENT, 0L, 0L);
+}
+
+/*
+ * Sets the text of a given listbox entry.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          index: Index into the list to be queried.
+ *          buffer: Buffer where text will be copied.
+ */
+void API dw_listbox_set_text(HWND handle, unsigned int index, char *buffer)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   {
+      SendMessage(handle,  CB_DELETESTRING, (WPARAM)index, 0);
+      SendMessage(handle, CB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer);
+   }
+   else
+   {
+      unsigned int sel = (unsigned int)SendMessage(handle, LB_GETCURSEL, 0, 0);
+      SendMessage(handle,  LB_DELETESTRING, (WPARAM)index, 0);
+      SendMessage(handle, LB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer);
+      SendMessage(handle, LB_SETCURSEL, (WPARAM)sel, 0);
+      SendMessage(handle, LB_SETSEL, (WPARAM)TRUE, (LPARAM)sel);
+   }
+}
+
+/*
+ * Copies the given index item's text into buffer.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          index: Index into the list to be queried.
+ *          buffer: Buffer where text will be copied.
+ *          length: Length of the buffer (including NULL).
+ */
+void API dw_listbox_get_text(HWND handle, unsigned int index, char *buffer, unsigned int length)
+{
+   char tmpbuf[100];
+   int len;
+
+   if(!buffer || !length)
+      return;
+
+   buffer[0] = 0;
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+   {
+      len = (int)SendMessage(handle, CB_GETLBTEXTLEN, (WPARAM)index, 0);
+
+      if(len < length && len != CB_ERR)
+         SendMessage(handle,
+                  CB_GETLBTEXT, (WPARAM)index, (LPARAM)buffer);
+   }
+   else
+   {
+      len = (int)SendMessage(handle, LB_GETTEXTLEN, (WPARAM)index, 0);
+
+      if(len < length && len != LB_ERR)
+         SendMessage(handle,
+                  LB_GETTEXT, (WPARAM)index, (LPARAM)buffer);
+   }
+}
+
+/*
+ * Returns the index to the item in the list currently selected.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ */
+int API dw_listbox_selected(HWND handle)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      return (unsigned int)SendMessage(handle,
+                               CB_GETCURSEL,
+                               0, 0);
+
+   return (unsigned int)SendMessage(handle,
+                            LB_GETCURSEL,
+                            0, 0);
+}
+
+/*
+ * Returns the index to the current selected item or -1 when done.
+ * Parameters:
+ *          handle: Handle to the listbox to be queried.
+ *          where: Either the previous return or -1 to restart.
+ */
+int API dw_listbox_selected_multi(HWND handle, int where)
+{
+   int *array, count, z;
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* This doesn't work on comboboxes */
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      return -1;
+
+   count = (int)SendMessage(handle, LB_GETSELCOUNT, 0, 0);
+   if(count > 0)
+   {
+      array = malloc(sizeof(int)*count);
+      SendMessage(handle, LB_GETSELITEMS, (WPARAM)count, (LPARAM)array);
+
+      if(where == -1)
+      {
+         int ret = array[0];
+         free(array);
+         return ret;
+      }
+      for(z=0;z<count;z++)
+      {
+         if(array[z] == where && (z+1) < count)
+         {
+            int ret = array[z+1];
+            free(array);
+            return ret;
+         }
+      }
+      free(array);
+   }
+   return -1;
+}
+
+/*
+ * Sets the selection state of a given index.
+ * Parameters:
+ *          handle: Handle to the listbox to be set.
+ *          index: Item index.
+ *          state: TRUE if selected FALSE if unselected.
+ */
+void API dw_listbox_select(HWND handle, int index, int state)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      SendMessage(handle, CB_SETCURSEL, (WPARAM)index, 0);
+   else
+   {
+      SendMessage(handle, LB_SETCURSEL, (WPARAM)index, 0);
+      SendMessage(handle, LB_SETSEL, (WPARAM)state, (LPARAM)index);
+   }
+   _wndproc(handle, WM_COMMAND, (WPARAM)(LBN_SELCHANGE << 16), (LPARAM)handle);
+}
+
+/*
+ * Deletes the item with given index from the list.
+ * Parameters:
+ *          handle: Handle to the listbox to be set.
+ *          index: Item index.
+ */
+void API dw_listbox_delete(HWND handle, int index)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      SendMessage(handle, CB_DELETESTRING, (WPARAM)index, 0);
+   else
+      SendMessage(handle, LB_DELETESTRING, (WPARAM)index, 0);
+}
+
+/*
+ * Returns the listbox's item count.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ */
+int API dw_listbox_count(HWND handle)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      return (int)SendMessage(handle,
+                        CB_GETCOUNT,0L, 0L);
+
+   return (int)SendMessage(handle,
+                     LB_GETCOUNT,0L, 0L);
+}
+
+/*
+ * Sets the topmost item in the viewport.
+ * Parameters:
+ *          handle: Handle to the listbox to be cleared.
+ *          top: Index to the top item.
+ */
+void API dw_listbox_set_top(HWND handle, int top)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   /* This doesn't work on comboboxes */
+   if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0)
+      return;
+
+   SendMessage(handle, LB_SETTOPINDEX, (WPARAM)top, 0);
+}
+
+/*
+ * Adds text to an MLE box and returns the current point.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          buffer: Text buffer to be imported.
+ *          startpoint: Point to start entering text.
+ */
+unsigned int API dw_mle_import(HWND handle, char *buffer, int startpoint)
+{
+   int textlen, len = GetWindowTextLength(handle);
+   char *tmpbuf;
+
+   if(startpoint < 0)
+      startpoint = 0;
+
+   if(!buffer || (textlen = strlen(buffer)) < 1)
+      return startpoint;
+
+   tmpbuf = calloc(1, len + textlen + startpoint + 2);
+
+   if(len)
+   {
+      char *dest, *start;
+      int copylen = len - startpoint;
+
+      GetWindowText(handle, tmpbuf, len+1);
+
+      dest = &tmpbuf[startpoint+textlen];
+      start = &tmpbuf[startpoint];
+
+      if(copylen > 0)
+         memcpy(dest, start, copylen);
+   }
+   memcpy(&tmpbuf[startpoint], buffer, textlen);
+
+   SetWindowText(handle, tmpbuf);
+
+   free(tmpbuf);
+   return (startpoint + textlen);
+}
+
+/*
+ * Grabs text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          buffer: Text buffer to be exported. MUST allow for trailing nul character.
+ *          startpoint: Point to start grabbing text.
+ *          length: Amount of text to be grabbed.
+ */
+void API dw_mle_export(HWND handle, char *buffer, int startpoint, int length)
+{
+   int max, len = GetWindowTextLength(handle);
+   char *tmpbuf = calloc(1, len+2);
+
+   if(len)
+      GetWindowText(handle, tmpbuf, len+1);
+
+   buffer[0] = 0;
+
+   if(startpoint < len)
+   {
+      max = MIN(length, len - startpoint);
+
+      memcpy(buffer, &tmpbuf[startpoint], max);
+      buffer[max] = '\0';
+   }
+
+   free(tmpbuf);
+}
+
+/*
+ * Obtains information about an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be queried.
+ *          bytes: A pointer to a variable to return the total bytes.
+ *          lines: A pointer to a variable to return the number of lines.
+ */
+void API dw_mle_get_size(HWND handle, unsigned long *bytes, unsigned long *lines)
+{
+   if(bytes)
+      *bytes = GetWindowTextLength(handle);
+   if(lines)
+      *lines = (unsigned long)SendMessage(handle, EM_GETLINECOUNT, 0, 0);
+}
+
+/*
+ * Deletes text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be deleted from.
+ *          startpoint: Point to start deleting text.
+ *          length: Amount of text to be deleted.
+ */
+void API dw_mle_delete(HWND handle, int startpoint, int length)
+{
+   int len = GetWindowTextLength(handle);
+   char *tmpbuf = calloc(1, len+2);
+
+   GetWindowText(handle, tmpbuf, len+1);
+
+   if(startpoint + length < len)
+   {
+      strcpy(&tmpbuf[startpoint], &tmpbuf[startpoint+length]);
+
+      SetWindowText(handle, tmpbuf);
+   }
+
+   free(tmpbuf);
+}
+
+/*
+ * Clears all text from an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be cleared.
+ */
+void API dw_mle_clear(HWND handle)
+{
+   SetWindowText(handle, "");
+}
+
+/*
+ * Sets the visible line of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          line: Line to be visible.
+ */
+void API dw_mle_set_visible(HWND handle, int line)
+{
+   int point = (int)SendMessage(handle, EM_LINEINDEX, (WPARAM)line, 0);
+   dw_mle_set_cursor(handle, point);
+}
+
+/*
+ * Sets the editablity of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: TRUE if it can be edited, FALSE for readonly.
+ */
+void API dw_mle_set_editable(HWND handle, int state)
+{
+   SendMessage(handle, EM_SETREADONLY, (WPARAM)(state ? FALSE : TRUE), 0);
+}
+
+/*
+ * Sets the word wrap state of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE.
+ *          state: TRUE if it wraps, FALSE if it doesn't.
+ */
+void API dw_mle_set_word_wrap(HWND handle, int state)
+{
+   /* If ES_AUTOHSCROLL is not set and there is not
+    * horizontal scrollbar it word wraps.
+    */
+   if(state)
+      dw_window_set_style(handle, 0, ES_AUTOHSCROLL);
+   else
+      dw_window_set_style(handle, ES_AUTOHSCROLL, ES_AUTOHSCROLL);
+}
+
+/*
+ * Sets the current cursor position of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be positioned.
+ *          point: Point to position cursor.
+ */
+void API dw_mle_set_cursor(HWND handle, int point)
+{
+   SendMessage(handle, EM_SETSEL, 0, MAKELONG(point,point));
+   SendMessage(handle, EM_SCROLLCARET, 0, 0);
+}
+
+/*
+ * Finds text in an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to be cleared.
+ *          text: Text to search for.
+ *          point: Start point of search.
+ *          flags: Search specific flags.
+ */
+int API dw_mle_search(HWND handle, char *text, int point, unsigned long flags)
+{
+   int len = GetWindowTextLength(handle);
+   char *tmpbuf = calloc(1, len+2);
+   int z, textlen, retval = 0;
+
+   GetWindowText(handle, tmpbuf, len+1);
+
+   textlen = strlen(text);
+
+   if(flags & DW_MLE_CASESENSITIVE)
+   {
+      for(z=point;z<(len-textlen) && !retval;z++)
+      {
+         if(strncmp(&tmpbuf[z], text, textlen) == 0)
+            retval = z + textlen;
+      }
+   }
+   else
+   {
+      for(z=point;z<(len-textlen) && !retval;z++)
+      {
+         if(strnicmp(&tmpbuf[z], text, textlen) == 0)
+            retval = z + textlen;
+      }
+   }
+
+   if(retval)
+   {
+      SendMessage(handle, EM_SETSEL, (WPARAM)retval - textlen, (LPARAM)retval);
+      SendMessage(handle, EM_SCROLLCARET, 0, 0);
+   }
+
+   free(tmpbuf);
+
+   return retval;
+}
+
+/*
+ * Stops redrawing of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to freeze.
+ */
+void API dw_mle_freeze(HWND handle)
+{
+}
+
+/*
+ * Resumes redrawing of an MLE box.
+ * Parameters:
+ *          handle: Handle to the MLE to thaw.
+ */
+void API dw_mle_thaw(HWND handle)
+{
+}
+
+/*
+ * Sets the percent bar position.
+ * Parameters:
+ *          handle: Handle to the percent bar to be set.
+ *          position: Position of the percent bar withing the range.
+ */
+void API dw_percent_set_pos(HWND handle, unsigned int position)
+{
+   if(position == DW_PERCENT_INDETERMINATE)
+   {
+      /* If our common controls supports it... */
+      if((dwComctlVer >= PACKVERSION(6,0)))
+      {
+          /* Enable the style on the control */
+          SetWindowLong(handle, GWL_STYLE, GetWindowLong(handle, GWL_STYLE) | PBS_MARQUEE);
+          /* Start the bar going */
+          SendMessage(handle, PBM_SETMARQUEE, 1, 100);
+      }
+      else
+         SendMessage(handle, PBM_SETPOS, 0, 0);
+   }
+   else
+   {
+      if((dwComctlVer >= PACKVERSION(6,0)))
+      {
+          unsigned long style = GetWindowLong(handle, GWL_STYLE);
+  
+          if(style & PBS_MARQUEE)
+          {
+             /* Stop the bar */
+             SendMessage(handle, PBM_SETMARQUEE, 0, 0);
+             /* Disable the style on the control */
+             SetWindowLong(handle, GWL_STYLE, style & ~PBS_MARQUEE);
+          }
+      }
+      /* Otherwise just set the position */
+      SendMessage(handle, PBM_SETPOS, (WPARAM)position, 0);
+   }
+}
+
+/*
+ * Returns the position of the slider.
+ * Parameters:
+ *          handle: Handle to the slider to be queried.
+ */
+unsigned int API dw_slider_get_pos(HWND handle)
+{
+   int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
+   ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
+
+   if(currentstyle & TBS_VERT)
+      return max - (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
+   return (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
+}
+
+/*
+ * Sets the slider position.
+ * Parameters:
+ *          handle: Handle to the slider to be set.
+ *          position: Position of the slider withing the range.
+ */
+void API dw_slider_set_pos(HWND handle, unsigned int position)
+{
+   int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
+   ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
+
+   if(currentstyle & TBS_VERT)
+      SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)max - position);
+   else
+      SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)position);
+}
+
+/*
+ * Returns the position of the scrollbar.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be queried.
+ */
+unsigned int API dw_scrollbar_get_pos(HWND handle)
+{
+   return (unsigned int)SendMessage(handle, SBM_GETPOS, 0, 0);
+}
+
+/*
+ * Sets the scrollbar position.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          position: Position of the scrollbar withing the range.
+ */
+void API dw_scrollbar_set_pos(HWND handle, unsigned int position)
+{
+   dw_window_set_data(handle, "_dw_scrollbar_value", (void *)position);
+   SendMessage(handle, SBM_SETPOS, (WPARAM)position, (LPARAM)TRUE);
+}
+
+/*
+ * Sets the scrollbar range.
+ * Parameters:
+ *          handle: Handle to the scrollbar to be set.
+ *          range: Maximum range value.
+ *          visible: Visible area relative to the range.
+ */
+void API dw_scrollbar_set_range(HWND handle, unsigned int range, unsigned int visible)
+{
+   SCROLLINFO si;
+
+   si.cbSize = sizeof(SCROLLINFO);
+   si.fMask = SIF_RANGE | SIF_PAGE;
+   si.nMin = 0;
+   si.nMax = range - 1;
+   si.nPage = visible;
+   SendMessage(handle, SBM_SETSCROLLINFO, (WPARAM)TRUE, (LPARAM)&si);
+}
+
+/*
+ * Sets the spinbutton value.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          position: Current value of the spinbutton.
+ */
+void API dw_spinbutton_set_pos(HWND handle, long position)
+{
+   char tmpbuf[101] = {0};
+   ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   _snprintf(tmpbuf, 100, "%ld", position);
+
+   if(cinfo && cinfo->buddy)
+      SetWindowText(cinfo->buddy, tmpbuf);
+
+   SendMessage(handle, UDM_SETPOS32, 0, (LPARAM)position);
+}
+
+/*
+ * Sets the spinbutton limits.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          position: Current value of the spinbutton.
+ *          position: Current value of the spinbutton.
+ */
+void API dw_spinbutton_set_limits(HWND handle, long upper, long lower)
+{
+   SendMessage(handle, UDM_SETRANGE32, (WPARAM)lower,(LPARAM)upper);
+}
+
+/*
+ * Sets the entryfield character limit.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be set.
+ *          limit: Number of characters the entryfield will take.
+ */
+void API dw_entryfield_set_limit(HWND handle, ULONG limit)
+{
+   SendMessage(handle, EM_SETLIMITTEXT, (WPARAM)limit, 0);
+}
+
+/*
+ * Returns the current value of the spinbutton.
+ * Parameters:
+ *          handle: Handle to the spinbutton to be queried.
+ */
+long API dw_spinbutton_get_pos(HWND handle)
+{
+   return (long)SendMessage(handle, UDM_GETPOS32, 0, 0);
+}
+
+/*
+ * Returns the state of the checkbox.
+ * Parameters:
+ *          handle: Handle to the checkbox to be queried.
+ */
+int API dw_checkbox_get(HWND handle)
+{
+   if(SendMessage(handle, BM_GETCHECK, 0, 0) == BST_CHECKED)
+      return (in_checkbox_handler ? FALSE : TRUE);
+   return (in_checkbox_handler ? TRUE : FALSE);
+}
+
+/* This function unchecks all radiobuttons on a box */
+BOOL CALLBACK _uncheck_radios(HWND handle, LPARAM lParam)
+{
+   char tmpbuf[100];
+
+   GetClassName(handle, tmpbuf, 99);
+
+   if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
+   {
+      BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+      if(bubble && !bubble->checkbox)
+         SendMessage(handle, BM_SETCHECK, 0, 0);
+   }
+   return TRUE;
+}
+/*
+ * Sets the state of the checkbox.
+ * Parameters:
+ *          handle: Handle to the checkbox to be queried.
+ *          value: TRUE for checked, FALSE for unchecked.
+ */
+void API dw_checkbox_set(HWND handle, int value)
+{
+   BubbleButton *bubble= (BubbleButton *)GetWindowLongPtr(handle, GWLP_USERDATA);
+
+   if(bubble && !bubble->checkbox)
+   {
+      HWND parent = GetParent(handle);
+
+      if(parent)
+         EnumChildWindows(parent, _uncheck_radios, 0);
+   }
+   SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0);
+}
+
+/*
+ * Inserts an item into a tree window (widget) after another item.
+ * Parameters:
+ *          handle: Handle to the tree to be inserted.
+ *          item: Handle to the item to be positioned after.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ *          parent: Parent handle or 0 if root.
+ *          itemdata: Item specific data.
+ */
+HTREEITEM API dw_tree_insert_after(HWND handle, HTREEITEM item, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   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 = title;
+   tvi.lParam = (LONG)ptrs;
+   tvi.cchTextMax = strlen(title);
+   tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
+
+   tvins.item = tvi;
+   tvins.hParent = parent;
+   tvins.hInsertAfter = item ? item : TVI_FIRST;
+
+   hti = TreeView_InsertItem(handle, &tvins);
+
+   return hti;
+}
+
+/*
+ * Inserts an item into a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree to be inserted.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ *          parent: Parent handle or 0 if root.
+ *          itemdata: Item specific data.
+ */
+HTREEITEM API dw_tree_insert(HWND handle, char *title, HICN icon, HTREEITEM parent, void *itemdata)
+{
+   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 = title;
+   tvi.lParam = (LONG)ptrs;
+   tvi.cchTextMax = strlen(title);
+   tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
+
+   tvins.item = tvi;
+   tvins.hParent = parent;
+   tvins.hInsertAfter = TVI_LAST;
+
+   hti = TreeView_InsertItem(handle, &tvins);
+
+   return hti;
+}
+
+/*
+ * Sets the text and icon of an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ *          title: The text title of the entry.
+ *          icon: Handle to coresponding icon.
+ */
+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 = title;
+      tvi.cchTextMax = strlen(title);
+      tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
+      tvi.hItem = (HTREEITEM)item;
+
+      TreeView_SetItem(handle, &tvi);
+   }
+}
+
+/*
+ * Sets the item data of a tree item.
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ *          itemdata: User defined data to be associated with item.
+ */
+void API dw_tree_item_set_data(HWND handle, HTREEITEM item, void *itemdata)
+{
+   TVITEM tvi;
+   void **ptrs;
+
+   tvi.mask = TVIF_HANDLE;
+   tvi.hItem = item;
+
+   if(TreeView_GetItem(handle, &tvi))
+   {
+      ptrs = (void **)tvi.lParam;
+      ptrs[1] = itemdata;
+   }
+}
+
+/*
+ * Gets the item data of a tree item.
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+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 NULL;
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+char * API dw_tree_get_title(HWND handle, HTREEITEM item)
+{
+   TVITEM tvi;
+
+   tvi.mask = TVIF_HANDLE;
+   tvi.hItem = item;
+
+   if(TreeView_GetItem(handle, &tvi))
+      return tvi.pszText;
+    return NULL;
+}
+
+/*
+ * Gets the text an item in a tree window (widget).
+ * Parameters:
+ *          handle: Handle to the tree containing the item.
+ *          item: Handle of the item to be modified.
+ */
+HTREEITEM API dw_tree_get_parent(HWND handle, HTREEITEM item)
+{
+   return TreeView_GetParent(handle, item);
+}
+
+/*
+ * Sets this item as the active selection.
+ * Parameters:
+ *       handle: Handle to the tree window (widget) to be selected.
+ *       item: Handle to the item to be selected.
+ */
+void API dw_tree_item_select(HWND handle, HTREEITEM item)
+{
+   dw_window_set_data(handle, "_dw_select_item", (void *)1);
+   TreeView_SelectItem(handle, item);
+   dw_window_set_data(handle, "_dw_select_item", (void *)0);
+}
+
+/* Delete all tree subitems */
+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:
+ *       handle: Handle to the window (widget) to be cleared.
+ */
+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);
+}
+
+/*
+ * Expands a node on a tree.
+ * Parameters:
+ *       handle: Handle to the tree window (widget).
+ *       item: Handle to node to be expanded.
+ */
+void API dw_tree_item_expand(HWND handle, HTREEITEM item)
+{
+   TreeView_Expand(handle, item, TVE_EXPAND);
+}
+
+/*
+ * Collapses a node on a tree.
+ * Parameters:
+ *       handle: Handle to the tree window (widget).
+ *       item: Handle to node to be collapsed.
+ */
+void API dw_tree_item_collapse(HWND handle, HTREEITEM item)
+{
+   TreeView_Expand(handle, item, TVE_COLLAPSE);
+}
+
+/*
+ * Removes a node from a tree.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be cleared.
+ *       item: Handle to node to be deleted.
+ */
+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);
+}
+
+/*
+ * Sets up the container columns.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          flags: An array of unsigned longs with column flags.
+ *          titles: An array of strings with column text titles.
+ *          count: The number of columns (this should match the arrays).
+ *          separator: The column number that contains the main separator.
+ *                     (only used on OS/2 but must be >= 0 on all)
+ */
+int API dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator)
+{
+   ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   int z, l = 0;
+   unsigned long *tempflags = calloc(sizeof(unsigned long), count + 2);
+   LVCOLUMN lvc;
+
+   if(separator == -1)
+   {
+      tempflags[0] = DW_CFA_RESERVED;
+      l = 1;
+   }
+
+   memcpy(&tempflags[l], flags, sizeof(unsigned long) * count);
+   tempflags[count + l] = 0;
+   cinfo->flags = tempflags;
+   cinfo->columns = count + l;
+
+
+   for(z=0;z<count;z++)
+   {
+      if(titles[z])
+      {
+         lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;
+         lvc.pszText = titles[z];
+         lvc.cchTextMax = strlen(titles[z]);
+         if(flags[z] & DW_CFA_RIGHT)
+            lvc.fmt = LVCFMT_RIGHT;
+         else if(flags[z] & DW_CFA_CENTER)
+            lvc.fmt = LVCFMT_CENTER;
+         else
+            lvc.fmt = LVCFMT_LEFT;
+         lvc.cx = 75;
+         lvc.iSubItem = count;
+         SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)z + l, (LPARAM)&lvc);
+      }
+   }
+   ListView_SetExtendedListViewStyle(handle, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
+   return DW_ERROR_NONE;
+}
+
+/*
+ * Sets up the filesystem columns, note: filesystem always has an icon/filename field.
+ * Parameters:
+ *          handle: Handle to the container to be configured.
+ *          flags: An array of unsigned longs with column flags.
+ *          titles: An array of strings with column text titles.
+ *          count: The number of columns (this should match the arrays).
+ */
+int API dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count)
+{
+   LV_COLUMN lvc;
+
+   lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
+   lvc.pszText = "Filename";
+   lvc.cchTextMax = 8;
+   lvc.fmt = 0;
+   if(!count)
+      lvc.cx = 300;
+   else
+      lvc.cx = 150;
+   lvc.iSubItem = count;
+   SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)0, (LPARAM)&lvc);
+   dw_container_setup(handle, flags, titles, count, -1);
+   return DW_ERROR_NONE;
+}
+
+/*
+ * Obtains an icon from a module (or header in GTK).
+ * Parameters:
+ *          module: Handle to module (DLL) in OS/2 and Windows.
+ *          id: A unsigned long id int the resources on OS/2 and
+ *              Windows, on GTK this is converted to a pointer
+ *              to an embedded XPM.
+ */
+HICN API dw_icon_load(unsigned long module, unsigned long id)
+{
+   return (HICN)LoadIcon(DWInstance, MAKEINTRESOURCE(id));
+}
+
+/*
+ * Obtains an icon from a file.
+ * Parameters:
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (ICO on OS/2 or Windows, XPM on Unix)
+ */
+HICN API dw_icon_load_from_file(char *filename)
+{
+#ifdef GDIPLUS
+    return _dw_load_icon(filename);
+#else
+   char *file = malloc(strlen(filename) + 5);
+   HANDLE icon;
+
+   if(!file)
+      return 0;
+
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if(access(file, 04) != 0)
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".ico");
+      if(access(file, 04) != 0)
+      {
+         free(file);
+         return 0;
+      }
+   }
+   icon = LoadImage(NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
+   free(file);
+   return (HICN)icon;
+#endif
+}
+
+/*
+ * Obtains an icon from data
+ * Parameters:
+ *       data: Source of icon data
+ *                 DW pick the appropriate file extension.
+ *                 (ICO on OS/2 or Windows, XPM on Unix)
+ */
+HICN API dw_icon_load_from_data(char *data, int len)
+{
+   HANDLE icon;
+   char *file;
+   FILE *fp;
+
+   if ( !data )
+      return 0;
+   file = _tempnam( _dw_alternate_temp_dir, "dw" );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+#ifdef GDIPLUS
+         icon = _dw_load_icon(file);
+#else
+         icon = LoadImage( NULL, file, IMAGE_ICON, 0, 0, LR_LOADFROMFILE );
+#endif
+      }
+      else
+      {
+         unlink( file );
+         free( file );
+         return 0;
+      }
+      unlink( file );
+      free( file );
+   }
+   return (HICN)icon;
+}
+
+/*
+ * Frees a loaded resource in OS/2 and Windows.
+ * Parameters:
+ *          handle: Handle to icon returned by dw_icon_load().
+ */
+void API dw_icon_free(HICN handle)
+{
+   DestroyIcon((HICON)handle);
+}
+
+/*
+ * Allocates memory used to populate a container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          rowcount: The number of items to be populated.
+ */
+void * API dw_container_alloc(HWND handle, int rowcount)
+{
+   LV_ITEM lvi;
+   int z, item;
+
+   lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT | LVIF_IMAGE;
+   lvi.iSubItem = 0;
+   /* Insert at the end */
+   lvi.iItem = 1000000;
+   lvi.pszText = "";
+   lvi.cchTextMax = 1;
+   lvi.iImage = -1;
+
+   ShowWindow(handle, SW_HIDE);
+   item = ListView_InsertItem(handle, &lvi);
+   for(z=1;z<rowcount;z++)
+      ListView_InsertItem(handle, &lvi);
+   dw_window_set_data(handle, "_dw_insertitem", (void *)item);
+   return (void *)handle;
+}
+
+/* Finds a icon in the table, otherwise it adds it to the table
+ * and returns the index in the table.
+ */
+int _lookup_icon(HWND handle, HICON hicon, int type)
+{
+   int z;
+   static HWND lasthwnd = NULL;
+
+   if(!hSmall || !hLarge)
+   {
+      hSmall = ImageList_Create(16, 16, ILC_COLOR16 | ILC_MASK, ICON_INDEX_LIMIT, 0);
+      hLarge = ImageList_Create(32, 32, ILC_COLOR16 | ILC_MASK, ICON_INDEX_LIMIT, 0);
+   }
+   for(z=0;z<ICON_INDEX_LIMIT;z++)
+   {
+      if(!lookup[z])
+      {
+         lookup[z] = hicon;
+         ImageList_AddIcon(hSmall, hicon);
+         ImageList_AddIcon(hLarge, hicon);
+         if(type)
+         {
+            TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+         }
+         else
+         {
+            ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+            ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+         }
+         lasthwnd = handle;
+         return z;
+      }
+
+      if(hicon == lookup[z])
+      {
+         if(lasthwnd != handle)
+         {
+            if(type)
+            {
+               TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL);
+            }
+            else
+            {
+               ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
+               ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+            }
+                lasthwnd = handle;
+         }
+         return z;
+      }
+   }
+   return -1;
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, HICN icon)
+{
+   LV_ITEM lvi;
+   int item = 0;
+
+   if(pointer)
+   {
+      item = (int)dw_window_get_data(handle, "_dw_insertitem");
+   }
+
+   lvi.iItem = row + item;
+   lvi.iSubItem = 0;
+   lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE | LVIF_TEXT;
+   lvi.pszText = filename;
+   lvi.cchTextMax = strlen(filename);
+   lvi.iImage = _lookup_icon(handle, (HICON)icon, 0);
+
+   ListView_SetItem(handle, &lvi);
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data)
+{
+   dw_container_set_item(handle, pointer, column + 1, row, data);
+}
+
+/*
+ * Sets an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
+{
+   ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   ULONG *flags;
+   LV_ITEM lvi;
+   char textbuffer[101] = {0}, *destptr = textbuffer;
+   int item = 0;
+
+   if(pointer)
+   {
+      item = (int)dw_window_get_data(handle, "_dw_insertitem");
+   }
+
+   if(!cinfo || !cinfo->flags || !data)
+      return;
+
+   flags = cinfo->flags;
+
+   lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT;
+   lvi.iItem = row + item;
+   lvi.iSubItem = column;
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+   {
+      HICON hicon = *((HICON *)data);
+
+      lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE;
+      lvi.pszText = NULL;
+      lvi.cchTextMax = 0;
+
+      lvi.iImage = _lookup_icon(handle, hicon, 0);
+   }
+   else if(flags[column] & DW_CFA_STRING)
+   {
+      char *tmp = *((char **)data);
+
+      if(!tmp)
+         tmp = "";
+
+      lvi.pszText = tmp;
+      lvi.cchTextMax = strlen(tmp);
+      destptr = tmp;
+   }
+   else if(flags[column] & DW_CFA_ULONG)
+   {
+      ULONG tmp = *((ULONG *)data);
+
+      _snprintf(textbuffer, 100, "%lu", tmp);
+
+      lvi.pszText = textbuffer;
+      lvi.cchTextMax = strlen(textbuffer);
+   }
+   else if(flags[column] & DW_CFA_DATE)
+   {
+      struct tm curtm;
+      CDATE cdate = *((CDATE *)data);
+
+      memset(&curtm, 0, sizeof(struct tm));
+
+      /* Safety check... zero dates are crashing
+       * Visual Studio 2008. -Brian
+       */
+      if(cdate.year > 1900 && cdate.year < 2100)
+      {
+          curtm.tm_mday = (cdate.day >= 0 && cdate.day < 32) ? cdate.day : 1;
+          curtm.tm_mon = (cdate.month > 0 && cdate.month < 13) ? cdate.month - 1 : 0;
+          curtm.tm_year = cdate.year - 1900;
+          strftime(textbuffer, 100, "%x", &curtm);
+      }
+      else
+      {
+          textbuffer[0] = 0;
+      }
+
+      lvi.pszText = textbuffer;
+      lvi.cchTextMax = strlen(textbuffer);
+   }
+   else if(flags[column] & DW_CFA_TIME)
+   {
+      struct tm curtm;
+      CTIME ctime = *((CTIME *)data);
+
+      curtm.tm_hour = (ctime.hours >= 0 && ctime.hours < 24) ? ctime.hours : 0;
+      curtm.tm_min = (ctime.minutes >= 0 && ctime.minutes < 60) ? ctime.minutes : 0;
+      curtm.tm_sec = (ctime.seconds >= 0 && ctime.seconds < 60) ? ctime.seconds : 0;
+
+      strftime(textbuffer, 100, "%X", &curtm);
+
+      lvi.pszText = textbuffer;
+      lvi.cchTextMax = strlen(textbuffer);
+   }
+
+   ListView_SetItem(handle, &lvi);
+}
+
+/*
+ * Changes an existing item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_container_change_item(HWND handle, int column, int row, void *data)
+{
+   dw_container_set_item(handle, NULL, column, row, data);
+}
+
+/*
+ * Changes an existing item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_change_item(HWND handle, int column, int row, void *data)
+{
+   dw_filesystem_set_item(handle, NULL, column, row, data);
+}
+
+/*
+ * Changes an item in specified row and column to the given data.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          column: Zero based column of data being set.
+ *          row: Zero based row of data being set.
+ *          data: Pointer to the data to be added.
+ */
+void API dw_filesystem_change_file(HWND handle, int row, char *filename, HICN icon)
+{
+   dw_filesystem_set_file(handle, NULL, row, filename, icon);
+}
+
+/*
+ * Gets column type for a container column
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column.
+ */
+int API dw_container_get_column_type(HWND handle, int column)
+{
+   ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   ULONG *flags;
+   int rc;
+
+   if(!cinfo || !cinfo->flags)
+      return 0;
+
+   flags = cinfo->flags;
+
+   if(flags[column] & DW_CFA_BITMAPORICON)
+      rc = DW_CFA_BITMAPORICON;
+   else if(flags[column] & DW_CFA_STRING)
+      rc = DW_CFA_STRING;
+   else if(flags[column] & DW_CFA_ULONG)
+      rc = DW_CFA_ULONG;
+   else if(flags[column] & DW_CFA_DATE)
+      rc = DW_CFA_DATE;
+   else if(flags[column] & DW_CFA_TIME)
+      rc = DW_CFA_TIME;
+   else
+      rc = 0;
+   return rc;
+}
+
+/*
+ * Gets column type for a filesystem container column
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          column: Zero based column.
+ */
+int API dw_filesystem_get_column_type(HWND handle, int column)
+{
+   return dw_container_get_column_type( handle, column + 1 );
+}
+
+/*
+ * Sets the alternating row colors for container window (widget) handle.
+ * Parameters:
+ *          handle: The window (widget) handle.
+ *          oddcolor: Odd row background color in DW_RGB format or a default color index.
+ *          evencolor: Even row background color in DW_RGB format or a default color index.
+ *                    DW_RGB_TRANSPARENT will disable coloring rows.
+ *                    DW_CLR_DEFAULT will use the system default alternating row colors.
+ */
+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;
+}
+
+/*
+ * Sets the width of a column in the container.
+ * Parameters:
+ *          handle: Handle to window (widget) of container.
+ *          column: Zero based column of width being set.
+ *          width: Width of column in pixels.
+ */
+void API dw_container_set_column_width(HWND handle, int column, int width)
+{
+   ListView_SetColumnWidth(handle, column, width);
+}
+
+/* Internal version that handles both types */
+void _dw_container_set_row_title(HWND handle, void *pointer, int row, char *title)
+{
+   LV_ITEM lvi;
+   int item = 0;
+
+   if(pointer)
+   {
+      item = (int)dw_window_get_data(handle, "_dw_insertitem");
+   }
+
+   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;
+
+}
+
+/*
+ * Sets the title 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.
+ *          title: String title of the item.
+ */
+void API dw_container_set_row_title(void *pointer, int row, char *title)
+{
+   _dw_container_set_row_title(pointer, pointer, row, title);
+}
+
+/*
+ * Changes the title of a row already inserted in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          row: Zero based row of data being set.
+ *          title: String title of the item.
+ */
+void API dw_container_change_row_title(HWND handle, int row, char *title)
+{
+   _dw_container_set_row_title(handle, NULL, row, title);
+}
+
+/*
+ * Sets the title of a row in the container.
+ * Parameters:
+ *          handle: Handle to the container window (widget).
+ *          pointer: Pointer to the allocated memory in dw_container_alloc().
+ *          rowcount: The number of rows to be inserted.
+ */
+void API dw_container_insert(HWND handle, void *pointer, int rowcount)
+{
+   ShowWindow(handle, SW_SHOW);
+}
+
+/*
+ * Removes all rows from a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be cleared.
+ *       redraw: TRUE to cause the container to redraw immediately.
+ */
+void API dw_container_clear(HWND handle, int redraw)
+{
+   ListView_DeleteAllItems(handle);
+}
+
+/*
+ * Removes the first x rows from a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be deleted from.
+ *       rowcount: The number of rows to be deleted.
+ */
+void API dw_container_delete(HWND handle, int rowcount)
+{
+   int z, _index = (int)dw_window_get_data(handle, "_dw_index");
+
+   for(z=0;z<rowcount;z++)
+   {
+      ListView_DeleteItem(handle, 0);
+   }
+   if(rowcount > _index)
+      dw_window_set_data(handle, "_dw_index", 0);
+   else
+      dw_window_set_data(handle, "_dw_index", (void *)(_index - rowcount));
+}
+
+/*
+ * Scrolls container up or down.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be scrolled.
+ *       direction: DW_SCROLL_UP, DW_SCROLL_DOWN, DW_SCROLL_TOP or
+ *                  DW_SCROLL_BOTTOM. (rows is ignored for last two)
+ *       rows: The number of rows to be scrolled.
+ */
+void API dw_container_scroll(HWND handle, int direction, long rows)
+{
+   switch(direction)
+   {
+   case DW_SCROLL_TOP:
+      ListView_Scroll(handle, 0, -10000000);
+        break;
+   case DW_SCROLL_BOTTOM:
+      ListView_Scroll(handle, 0, 10000000);
+      break;
+   }
+}
+
+/*
+ * Starts a new query of a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       flags: If this parameter is DW_CRA_SELECTED it will only
+ *              return items that are currently selected.  Otherwise
+ *              it will return all records in the container.
+ */
+char * API dw_container_query_start(HWND handle, unsigned long flags)
+{
+   LV_ITEM lvi;
+   int _index = ListView_GetNextItem(handle, -1, flags);
+
+   if(_index == -1)
+      return NULL;
+
+   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;
+}
+
+/*
+ * Continues an existing query of a container.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be queried.
+ *       flags: If this parameter is DW_CRA_SELECTED it will only
+ *              return items that are currently selected.  Otherwise
+ *              it will return all records in the container.
+ */
+char * API dw_container_query_next(HWND handle, unsigned long flags)
+{
+   LV_ITEM lvi;
+   int _index = (int)dw_window_get_data(handle, "_dw_index");
+
+   _index = ListView_GetNextItem(handle, _index, flags);
+
+   if(_index == -1)
+      return NULL;
+
+   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;
+}
+
+/*
+ * 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(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;
+
+      memset(&lvi, 0, sizeof(LV_ITEM));
+
+      lvi.iItem = index;
+      lvi.mask = LVIF_PARAM;
+
+      ListView_GetItem( handle, &lvi );
+
+      if ( (textcomp && lvi.lParam && strcmp( (char *)lvi.lParam, text ) == 0) || (!textcomp && (char *)lvi.lParam == text) )
+      {
+
+         ListView_SetItemState( handle, index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED );
+         ListView_EnsureVisible( handle, index, TRUE );
+         return;
+      }
+
+      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(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;
+
+      memset(&lvi, 0, sizeof(LV_ITEM));
+
+      lvi.iItem = index;
+      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");
+
+         if(index < _index)
+            dw_window_set_data(handle, "_dw_index", (void *)(_index - 1));
+
+         ListView_DeleteItem(handle, index);
+         return;
+      }
+
+        index = ListView_GetNextItem(handle, index, LVNI_ALL);
+   }
+}
+
+/*
+ * Optimizes the column widths so that all data is visible.
+ * Parameters:
+ *       handle: Handle to the window (widget) to be optimized.
+ */
+void API dw_container_optimize(HWND handle)
+{
+   ContainerInfo *cinfo = (ContainerInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   if(cinfo && cinfo->columns == 1)
+   {
+      ListView_SetColumnWidth(handle, 0, LVSCW_AUTOSIZE);
+   }
+   else if(cinfo && cinfo->columns > 1)
+   {
+      int z, index;
+      ULONG *flags = cinfo->flags, *columns = calloc(sizeof(ULONG), cinfo->columns);
+      char *text = malloc(1024);
+
+      /* Initialize with sizes of column labels */
+      for(z=0;z<cinfo->columns;z++)
+      {
+         if(flags[z] & DW_CFA_BITMAPORICON)
+            columns[z] = 5;
+         else
+         {
+            LVCOLUMN lvc;
+
+            lvc.mask = LVCF_TEXT;
+            lvc.cchTextMax = 1023;
+            lvc.pszText = text;
+
+            if(ListView_GetColumn(handle, z, &lvc))
+               columns[z] = ListView_GetStringWidth(handle, lvc.pszText);
+
+            if(flags[z] & DW_CFA_RESERVED)
+               columns[z] += 20;
+         }
+      }
+
+      index = ListView_GetNextItem(handle, -1, LVNI_ALL);
+
+      /* Query all the item texts */
+      while(index != -1)
+      {
+         for(z=0;z<cinfo->columns;z++)
+         {
+            LV_ITEM lvi;
+
+            memset(&lvi, 0, sizeof(LV_ITEM));
+
+            lvi.iItem = index;
+            lvi.iSubItem = z;
+            lvi.mask = LVIF_TEXT;
+            lvi.cchTextMax = 1023;
+            lvi.pszText = text;
+
+            if(ListView_GetItem(handle, &lvi))
+            {
+               int width = ListView_GetStringWidth(handle, lvi.pszText);
+               if(width > columns[z])
+               {
+                  if(z == 0)
+                     columns[z] = width + 20;
+                  else
+                     columns[z] = width;
+               }
+            }
+         }
+
+         index = ListView_GetNextItem(handle, index, LVNI_ALL);
+      }
+
+      /* Set the new sizes */
+      for(z=0;z<cinfo->columns;z++)
+         ListView_SetColumnWidth(handle, z, columns[z] + 16);
+
+      free(columns);
+      free(text);
+   }
+}
+
+/*
+ * Inserts an icon into the taskbar.
+ * Parameters:
+ *       handle: Window handle that will handle taskbar icon messages.
+ *       icon: Icon handle to display in the taskbar.
+ *       bubbletext: Text to show when the mouse is above the icon.
+ */
+void API dw_taskbar_insert(HWND handle, HICN icon, char *bubbletext)
+{
+   NOTIFYICONDATA tnid;
+
+   tnid.cbSize = sizeof(NOTIFYICONDATA);
+   tnid.hWnd = handle;
+   tnid.uID = (UINT)icon;
+   tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
+   tnid.uCallbackMessage = WM_USER+2;
+   tnid.hIcon = (HICON)icon;
+   if(bubbletext)
+      strncpy(tnid.szTip, bubbletext, sizeof(tnid.szTip));
+   else
+      tnid.szTip[0] = 0;
+
+   Shell_NotifyIcon(NIM_ADD, &tnid);
+}
+
+/*
+ * Deletes an icon from the taskbar.
+ * Parameters:
+ *       handle: Window handle that was used with dw_taskbar_insert().
+ *       icon: Icon handle that was used with dw_taskbar_insert().
+ */
+void API dw_taskbar_delete(HWND handle, HICN icon)
+{
+   NOTIFYICONDATA tnid;
+
+   tnid.cbSize = sizeof(NOTIFYICONDATA);
+   tnid.hWnd = handle;
+   tnid.uID = (UINT)icon;
+
+   Shell_NotifyIcon(NIM_DELETE, &tnid);
+}
+
+/*
+ * Creates a rendering context widget (window) to be packed.
+ * Parameters:
+ *       id: An id to be used with dw_window_from_id.
+ * Returns:
+ *       A handle to the widget or NULL on failure.
+ */
+HWND API dw_render_new(unsigned long id)
+{
+   Box *newbox = calloc(sizeof(Box), 1);
+   HWND tmp = CreateWindow(ObjectClassName,
+                     "",
+                     WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
+                     0,0,screenx,screeny,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+   newbox->pad = 0;
+   newbox->type = 0;
+   newbox->count = 0;
+   newbox->grouphwnd = (HWND)NULL;
+   newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc);
+   newbox->cinfo.fore = newbox->cinfo.back = -1;
+   SetWindowLongPtr( tmp, GWLP_USERDATA, (LONG_PTR)newbox );
+   return tmp;
+}
+
+/* Sets the current foreground drawing color.
+ * Parameters:
+ *       red: red value.
+ *       green: green value.
+ *       blue: blue value.
+ */
+void API dw_color_foreground_set(unsigned long value)
+{
+   HPEN hPen = TlsGetValue(_hPen);
+   HBRUSH hBrush = TlsGetValue(_hBrush);
+   COLORREF foreground;
+
+   value = _internal_color(value);
+   foreground = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
+
+   DeleteObject(hPen);
+   DeleteObject(hBrush);
+   TlsSetValue(_foreground, (LPVOID)foreground);
+   TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
+   TlsSetValue(_hBrush, CreateSolidBrush(foreground));
+}
+
+/* Sets the current background drawing color.
+ * Parameters:
+ *       red: red value.
+ *       green: green value.
+ *       blue: blue value.
+ */
+void API dw_color_background_set(unsigned long value)
+{
+   COLORREF background;
+
+   value = _internal_color(value);
+   background = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
+
+   if(value == DW_RGB_TRANSPARENT)
+      TlsSetValue(_background, (LPVOID)DW_RGB_TRANSPARENT);
+   else
+      TlsSetValue(_background, (LPVOID)background);
+}
+
+/* Allows the user to choose a color using the system's color chooser dialog.
+ * Parameters:
+ *       value: current color
+ * Returns:
+ *       The selected color or the current color if cancelled.
+ */
+unsigned long API dw_color_choose(unsigned long value)
+{
+   CHOOSECOLOR cc;
+   unsigned long newcolor;
+   COLORREF acrCustClr[16] = {0};
+
+   value = _internal_color(value);
+   if(value == DW_RGB_TRANSPARENT)
+      newcolor = DW_RGB_TRANSPARENT;
+   else
+      newcolor = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value));
+   ZeroMemory(&cc, sizeof(CHOOSECOLOR));
+   cc.lStructSize = sizeof(CHOOSECOLOR);
+   cc.rgbResult = newcolor;
+   cc.hwndOwner = HWND_DESKTOP;
+   cc.lpCustColors = (LPDWORD)acrCustClr;
+   cc.Flags = CC_FULLOPEN | CC_RGBINIT;
+   if (ChooseColor(&cc) == TRUE)
+      newcolor = DW_RGB(DW_RED_VALUE(cc.rgbResult), DW_GREEN_VALUE(cc.rgbResult), DW_BLUE_VALUE(cc.rgbResult));
+   return newcolor;
+}
+
+/* Draw a point on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ */
+void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y)
+{
+   HDC hdcPaint;
+
+   if(handle)
+      hdcPaint = GetDC(handle);
+   else if(pixmap)
+      hdcPaint = pixmap->hdc;
+   else
+      return;
+
+   SetPixel(hdcPaint, x, y, (COLORREF)TlsGetValue(_foreground));
+   if(!pixmap)
+      ReleaseDC(handle, hdcPaint);
+}
+
+/* Draw a line on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x1: First X coordinate.
+ *       y1: First Y coordinate.
+ *       x2: Second X coordinate.
+ *       y2: Second Y coordinate.
+ */
+void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2)
+{
+   HDC hdcPaint;
+   HPEN oldPen;
+
+   if(handle)
+      hdcPaint = GetDC(handle);
+   else if(pixmap)
+      hdcPaint = pixmap->hdc;
+   else
+      return;
+
+   oldPen = SelectObject(hdcPaint, TlsGetValue(_hPen));
+   MoveToEx(hdcPaint, x1, y1, NULL);
+   LineTo(hdcPaint, x2, y2);
+   SelectObject(hdcPaint, oldPen);
+   /* For some reason Win98 (at least) fails
+    * to draw the last pixel.  So I do it myself.
+    */
+   SetPixel(hdcPaint, x2, y2, (COLORREF)TlsGetValue(_foreground));
+   if(!pixmap)
+      ReleaseDC(handle, hdcPaint);
+}
+
+/* Draw a closed polygon on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the polygon or DW_DRAW_DEFAULT (0).
+ *       number of points
+ *       x[]: X coordinates.
+ *       y[]: Y coordinates.
+ */
+void API dw_draw_polygon(HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y)
+{
+   HDC hdcPaint;
+   HBRUSH oldBrush;
+   HPEN oldPen;
+   POINT *points;
+   int i;
+
+   if ( handle )
+      hdcPaint = GetDC( handle );
+   else if ( pixmap )
+      hdcPaint = pixmap->hdc;
+   else
+      return;
+   if ( npoints )
+   {
+      /*
+       * Allocate enough space for the number of points supplied plus 1.
+       * Under windows, unless the first and last points are the same
+       * the polygon won't be closed
+       */
+      points = (POINT *)malloc( (npoints+1) * sizeof(POINT) );
+      /*
+       * should check for NULL pointer return!
+       */
+      for ( i = 0 ; i < npoints ; i++ )
+      {
+         points[i].x = x[i];
+         points[i].y = y[i];
+      }
+      if ( !( points[0].x == points[npoints-1].x
+      &&   points[0].y == points[npoints-1].y ) )
+      {
+         /* set the last point to be the same as the first point... */
+         points[npoints].x = points[0].x;
+         points[npoints].y = points[0].y;
+         /* ... and increment the number of points */
+         npoints++;
+      }
+   }
+
+   oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) );
+   oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) );
+   if ( flags & DW_DRAW_FILL )
+      Polygon( hdcPaint, points, npoints );
+   else
+      Polyline( hdcPaint, points, npoints );
+   SelectObject( hdcPaint, oldBrush );
+   SelectObject( hdcPaint, oldPen );
+   if ( !pixmap )
+      ReleaseDC( handle, hdcPaint );
+   free(points);
+}
+
+/* Draw a rectangle on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the box or DW_DRAW_DEFAULT (0).
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       width: Width of rectangle.
+ *       height: Height of rectangle.
+ */
+void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height)
+{
+   HDC hdcPaint;
+   RECT Rect;
+
+   if(handle)
+      hdcPaint = GetDC(handle);
+   else if(pixmap)
+      hdcPaint = pixmap->hdc;
+   else
+      return;
+
+   SetRect(&Rect, x, y, x + width , y + height );
+   if(flags & DW_DRAW_FILL)
+      FillRect(hdcPaint, &Rect, TlsGetValue(_hBrush));
+   else
+      FrameRect(hdcPaint, &Rect, TlsGetValue(_hBrush));
+   if(!pixmap)
+      ReleaseDC(handle, hdcPaint);
+}
+
+/* Draw an arc on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       flags: DW_DRAW_FILL (1) to fill the arc or DW_DRAW_DEFAULT (0).
+ *              DW_DRAW_FULL will draw a complete circle/elipse.
+ *       xorigin: X coordinate of center of arc.
+ *       yorigin: Y coordinate of center of arc.
+ *       x1: X coordinate of first segment of arc.
+ *       y1: Y coordinate of first segment of arc.
+ *       x2: X coordinate of second segment of arc.
+ *       y2: Y coordinate of second segment of arc.
+ */
+void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2)
+{
+   HDC hdcPaint;
+   HBRUSH oldBrush;
+   HPEN oldPen;
+   double dx = xorigin - x1;
+   double dy = yorigin - y1;
+   double r = sqrt(dx*dx + dy*dy);
+
+   if(handle)
+      hdcPaint = GetDC(handle);
+   else if(pixmap)
+      hdcPaint = pixmap->hdc;
+   else
+      return;
+     
+   if(flags & DW_DRAW_FILL)     
+      oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) );
+   else
+      oldBrush = SelectObject( hdcPaint, GetStockObject(HOLLOW_BRUSH) );
+   oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) );
+   if(flags & DW_DRAW_FULL)
+      Ellipse(hdcPaint, x1, y1, x2, y2);
+   else
+      Arc(hdcPaint, xorigin-r, yorigin-r, xorigin+r, yorigin+r, x2, y2, x1, y1);
+   SelectObject( hdcPaint, oldBrush );
+   SelectObject( hdcPaint, oldPen );
+
+   if(!pixmap)
+      ReleaseDC(handle, hdcPaint);
+}
+
+/* Draw text on a window (preferably a render window).
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       x: X coordinate.
+ *       y: Y coordinate.
+ *       text: Text to be displayed.
+ */
+void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text)
+{
+   HDC hdc;
+   int mustdelete = 0;
+   HFONT hFont = 0, oldFont = 0;
+   ColorInfo *cinfo = NULL;
+   COLORREF background;
+
+   if(handle)
+      hdc = GetDC(handle);
+   else if(pixmap)
+      hdc = pixmap->hdc;
+   else
+      return;
+
+   if(handle)
+      cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+   else if(pixmap->font)
+      hFont = pixmap->font;
+   else if(pixmap->handle)
+      cinfo = (ColorInfo *)GetWindowLongPtr(pixmap->handle, GWLP_USERDATA);
+
+   if(cinfo)
+   {
+      hFont = _acquire_font(handle, cinfo->fontname);
+      mustdelete = 1;
+   }
+
+   background = (COLORREF)TlsGetValue(_background);
+   if(hFont)
+      oldFont = SelectObject(hdc, hFont);
+   SetTextColor(hdc, (COLORREF)TlsGetValue(_foreground));
+   if(background == DW_RGB_TRANSPARENT)
+      SetBkMode(hdc, TRANSPARENT);
+   else
+   {
+      SetBkMode(hdc, OPAQUE);
+      SetBkColor(hdc, background);
+   }
+   TextOut(hdc, x, y, text, strlen(text));
+   if(oldFont)
+      SelectObject(hdc, oldFont);
+   if(mustdelete)
+      DeleteObject(hFont);
+   if(!pixmap)
+      ReleaseDC(handle, hdc);
+}
+
+/* Query the width and height of a text string.
+ * Parameters:
+ *       handle: Handle to the window.
+ *       pixmap: Handle to the pixmap. (choose only one of these)
+ *       text: Text to be queried.
+ *       width: Pointer to a variable to be filled in with the width.
+ *       height Pointer to a variable to be filled in with the height.
+ */
+void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height)
+{
+   HDC hdc;
+   int mustdelete = 0;
+   HFONT hFont = NULL, oldFont;
+   SIZE sz;
+
+   if(handle)
+      hdc = GetDC(handle);
+   else if(pixmap)
+      hdc = pixmap->hdc;
+   else
+      return;
+
+   if(pixmap && pixmap->font)
+   {
+       hFont = pixmap->font;
+   }
+   else
+   {
+      ColorInfo *cinfo;
+
+      if(handle)
+         cinfo = (ColorInfo *)GetWindowLongPtr(handle, GWLP_USERDATA);
+      else
+         cinfo = (ColorInfo *)GetWindowLongPtr(pixmap->handle, GWLP_USERDATA);
+
+      if(cinfo)
+      {
+         hFont = _acquire_font(handle, cinfo->fontname);
+         mustdelete = 1;
+      }
+   }
+   oldFont = SelectObject(hdc, hFont);
+
+   GetTextExtentPoint32(hdc, text, strlen(text), &sz);
+
+   if(width)
+      *width = sz.cx;
+
+   if(height)
+      *height = sz.cy;
+
+   SelectObject(hdc, oldFont);
+   if(mustdelete)
+      DeleteObject(hFont);
+   if(!pixmap)
+      ReleaseDC(handle, hdc);
+}
+
+/* Call this after drawing to the screen to make sure
+ * anything you have drawn is visible.
+ */
+void API dw_flush(void)
+{
+}
+
+/*
+ * Creates a pixmap with given parameters.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       width: Width of the pixmap in pixels.
+ *       height: Height of the pixmap in pixels.
+ *       depth: Color depth of the pixmap.
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth)
+{
+   HPIXMAP pixmap;
+   HDC hdc;
+   COLORREF bkcolor;
+   ULONG cx, cy;
+
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hdc = GetDC(handle);
+
+   pixmap->width = width; pixmap->height = height;
+
+   pixmap->handle = handle;
+   pixmap->hbm = CreateCompatibleBitmap(hdc, width, height);
+   pixmap->hdc = CreateCompatibleDC(hdc);
+   pixmap->transcolor = DW_RGB_TRANSPARENT;
+
+   SelectObject(pixmap->hdc, pixmap->hbm);
+
+   ReleaseDC(handle, hdc);
+
+   return pixmap;
+}
+
+#ifndef GDIPLUS
+/* Read the file bitmap header ourselves...
+ * apparently we can't check the depth once loaded...
+ * since it seems to normalize it to our screen depth.
+ */
+unsigned long _read_bitmap_header(char *file)
+{
+    BITMAPFILEHEADER header;
+    BITMAPINFO *info;
+    FILE *fp;
+    int infosize;
+    int depth = 0;
+
+    /* Try opening the file; use "rb" mode to read this *binary* file. */
+    if((fp = fopen(file, "rb")) == NULL)
+        return 0;
+
+    /* Read the file header and any following bitmap information... */
+    if(fread(&header, sizeof(BITMAPFILEHEADER), 1, fp) < 1)
+    {
+        /* Couldn't read the file header */
+        fclose(fp);
+        return 0;
+    }
+
+    if(header.bfType != 'MB') /* Check for BM reversed... */
+    {
+        /* Not a bitmap file */
+        fclose(fp);
+        return 0;
+    }
+
+    infosize = header.bfOffBits - sizeof(BITMAPFILEHEADER);
+    if((info = (BITMAPINFO *)calloc(infosize, 1)) == NULL)
+    {
+        /* Couldn't allocate memory for bitmap info */
+        fclose(fp);
+        return 0;
+    }
+
+    if(fread(info, 1, infosize, fp) == infosize)
+    {
+        /* Read the bitmap header */
+        depth = info->bmiHeader.biBitCount;
+    }
+    free(info);
+    fclose(fp);
+    return depth;
+}
+#endif
+
+/*
+ * Creates a pixmap from a file.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       filename: Name of the file, omit extention to have
+ *                 DW pick the appropriate file extension.
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename)
+{
+   HPIXMAP pixmap;
+   BITMAP bm;
+   HDC hdc;
+   ULONG cx, cy;
+   BITMAPINFO *info;
+#ifndef GDIPLUS
+   char *file;
+#endif
+
+   if (!filename || !(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+#ifdef GDIPLUS
+   pixmap->hbm = _dw_load_bitmap(filename, &pixmap->depth);
+#else
+   file = _alloca(strlen(filename) + 5);
+   strcpy(file, filename);
+
+   /* check if we can read from this file (it exists and read permission) */
+   if(access(file, 04) != 0)
+   {
+      /* Try with .bmp extention */
+      strcat(file, ".bmp");
+      if(access(file, 04) != 0)
+      {
+         free(pixmap);
+         free(file);
+         return NULL;
+      }
+   }
+
+   pixmap->hbm = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+   pixmap->depth = _read_bitmap_header(file);
+#endif
+
+   pixmap->handle = handle;
+
+   if ( !pixmap->hbm )
+   {
+      free(pixmap);
+      return NULL;
+   }
+
+   hdc = GetDC(handle);
+
+   pixmap->hdc = CreateCompatibleDC( hdc );
+   GetObject( pixmap->hbm, sizeof(bm), &bm );
+   pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
+   SelectObject( pixmap->hdc, pixmap->hbm );
+   ReleaseDC( handle, hdc );
+   pixmap->transcolor = DW_RGB_TRANSPARENT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a pixmap from memory.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       data: Source of the image data
+ *                 (BMP on OS/2 or Windows, XPM on Unix)
+ *       le: length of data
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len)
+{
+   HPIXMAP pixmap;
+   BITMAP bm;
+   HDC hdc;
+   char *file;
+   FILE *fp;
+   ULONG cx, cy;
+
+   if ( !(pixmap = calloc(1,sizeof(struct _hpixmap))) )
+   {
+      return NULL;
+   }
+
+   hdc = GetDC(handle);
+
+   pixmap->handle = handle;
+
+   file = _tempnam( _dw_alternate_temp_dir, "dw" );
+   if ( file != NULL )
+   {
+      fp = fopen( file, "wb" );
+      if ( fp != NULL )
+      {
+         fwrite( data, 1, len, fp );
+         fclose( fp );
+#ifdef GDIPLUS
+         pixmap->hbm = _dw_load_bitmap(file, NULL);
+#else
+         pixmap->hbm = (HBITMAP)LoadImage( NULL, file, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
+         pixmap->depth = _read_bitmap_header(file);
+#endif
+      }
+      else
+      {
+         unlink( file );
+         free( file );
+         free( pixmap );
+         return NULL;
+      }
+      unlink( file );
+      free( file );
+   }
+
+   if ( !pixmap->hbm )
+   {
+      free( pixmap );
+      ReleaseDC( handle, hdc );
+      return NULL;
+   }
+
+   pixmap->hdc = CreateCompatibleDC( hdc );
+
+   GetObject( pixmap->hbm, sizeof(bm), &bm );
+
+   pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
+
+   SelectObject( pixmap->hdc, pixmap->hbm );
+
+   ReleaseDC( handle, hdc );
+   pixmap->transcolor = DW_RGB_TRANSPARENT;
+
+   return pixmap;
+}
+
+/*
+ * Creates a bitmap mask for rendering bitmaps with transparent backgrounds
+ */
+void API dw_pixmap_set_transparent_color( HPIXMAP pixmap, ULONG color )
+{
+   if ( pixmap && pixmap->depth < 32)
+   {
+      pixmap->transcolor = _internal_color(color);
+   }
+}
+
+/*
+ * Creates a pixmap from internal resource graphic specified by id.
+ * Parameters:
+ *       handle: Window handle the pixmap is associated with.
+ *       id: Resource ID associated with requested pixmap.
+ * Returns:
+ *       A handle to a pixmap or NULL on failure.
+ */
+HPIXMAP API dw_pixmap_grab(HWND handle, ULONG id)
+{
+   HPIXMAP pixmap;
+   BITMAP bm;
+   HDC hdc;
+
+   if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+      return NULL;
+
+   hdc = GetDC(handle);
+
+   pixmap->hbm = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+   pixmap->hdc = CreateCompatibleDC(hdc);
+
+   GetObject(pixmap->hbm, sizeof(BITMAP), (void *)&bm);
+
+   pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight;
+   pixmap->depth = bm.bmBitsPixel;
+
+   SelectObject(pixmap->hdc, pixmap->hbm);
+
+   ReleaseDC(handle, hdc);
+   pixmap->transcolor = DW_RGB_TRANSPARENT;
+
+   return pixmap;
+}
+
+/*
+ * Sets the font used by a specified pixmap.
+ * Normally the pixmap font is obtained from the associated window handle.
+ * However this can be used to override that, or for pixmaps with no window.
+ * Parameters:
+ *          pixmap: Handle to a pixmap returned by dw_pixmap_new() or
+ *                  passed to the application via a callback.
+ *          fontname: Name and size of the font in the form "size.fontname"
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_set_font(HPIXMAP pixmap, char *fontname)
+{
+    if(pixmap)
+    {
+        HFONT hfont = _acquire_font2(pixmap->hdc, fontname);
+        
+        if(hfont)
+        {
+            HFONT oldfont = pixmap->font;
+            pixmap->font = hfont;
+            if(oldfont)
+                DeleteObject(oldfont);
+            return DW_ERROR_NONE;
+        }
+    }
+    return DW_ERROR_GENERAL;
+}
+
+/*
+ * Destroys an allocated pixmap.
+ * Parameters:
+ *       pixmap: Handle to a pixmap returned by
+ *               dw_pixmap_new..
+ */
+void API dw_pixmap_destroy(HPIXMAP pixmap)
+{
+   if(pixmap)
+   {
+      DeleteDC(pixmap->hdc);
+      DeleteObject(pixmap->hbm);
+      if(pixmap->font)
+        DeleteObject(pixmap->font);
+      free(pixmap);
+   }
+}
+
+/*
+ * Copies from one item to another.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of area to copy.
+ *       height: Height of area to copy.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ */
+void API dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc)
+{
+    dw_pixmap_stretch_bitblt(dest, destp, xdest, ydest, width, height, src, srcp, xsrc, ysrc, -1, -1);
+}
+
+/*
+ * Copies from one surface to another allowing for stretching.
+ * Parameters:
+ *       dest: Destination window handle.
+ *       destp: Destination pixmap. (choose only one).
+ *       xdest: X coordinate of destination.
+ *       ydest: Y coordinate of destination.
+ *       width: Width of the target area.
+ *       height: Height of the target area.
+ *       src: Source window handle.
+ *       srcp: Source pixmap. (choose only one).
+ *       xsrc: X coordinate of source.
+ *       ysrc: Y coordinate of source.
+ *       srcwidth: Width of area to copy.
+ *       srcheight: Height of area to copy.
+ * Returns:
+ *       DW_ERROR_NONE on success and DW_ERROR_GENERAL on failure.
+ */
+int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight)
+{
+   HDC hdcdest;
+   HDC hdcsrc;
+   static BLENDFUNCTION bf = { AC_SRC_OVER, 0, 0xFF, AC_SRC_ALPHA };
+   int swidth = srcwidth, sheight = srcheight;
+
+   /* Do some sanity checks */
+   if ( dest )
+      hdcdest = GetDC( dest );
+   else if ( destp )
+      hdcdest = destp->hdc;
+   else
+      return DW_ERROR_GENERAL;
+
+   if ( src )
+      hdcsrc = GetDC( src );
+   else if ( srcp )
+      hdcsrc = srcp->hdc;
+   else
+      return DW_ERROR_GENERAL;
+
+   if((srcheight == -1 || srcwidth == -1) && srcheight != srcwidth)
+      return DW_ERROR_GENERAL;
+
+   if(srcheight == -1 && srcwidth == -1)
+   {
+       swidth = width;
+       sheight = height;
+   }
+
+   /* If it is a 32bpp bitmap (with alpha) use AlphaBlend unless it fails */
+   if ( srcp && srcp->depth == 32 && AlphaBlend( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, bf ) )
+   {
+        /* Don't do anything */
+   }
+   /* Otherwise perform special bitblt with manual transparency */
+   else if ( srcp && srcp->transcolor != DW_RGB_TRANSPARENT )
+   {
+      TransparentBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, RGB( DW_RED_VALUE(srcp->transcolor), DW_GREEN_VALUE(srcp->transcolor), DW_BLUE_VALUE(srcp->transcolor)) );
+   }
+   else
+   {
+      /* Finally fall back to the classic BitBlt */
+      if( srcwidth == -1 && srcheight == -1)
+         BitBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY );
+      else
+         StretchBlt( hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, swidth, sheight, SRCCOPY );
+   }
+   if ( !destp )
+      ReleaseDC( dest, hdcdest );
+   if ( !srcp )
+      ReleaseDC( src, hdcsrc );
+
+   return DW_ERROR_NONE;
+}
+
+/* Run Beep() in a separate thread so it doesn't block */
+void _beepthread(void *data)
+{
+   int *info = (int *)data;
+
+   if(data)
+   {
+      Beep(info[0], info[1]);
+      free(data);
+   }
+}
+
+/*
+ * Emits a beep.
+ * Parameters:
+ *       freq: Frequency.
+ *       dur: Duration.
+ */
+void API dw_beep(int freq, int dur)
+{
+   int *info = malloc(sizeof(int) * 2);
+
+   if(info)
+   {
+      info[0] = freq;
+      info[1] = dur;
+
+      _beginthread(_beepthread, 100, (void *)info);
+   }
+}
+
+/* Open a shared library and return a handle.
+ * Parameters:
+ *         name: Base name of the shared library.
+ *         handle: Pointer to a module handle,
+ *                 will be filled in with the handle.
+ */
+int API dw_module_load(char *name, HMOD *handle)
+{
+   if(!handle)
+      return DW_ERROR_UNKNOWN;
+
+   *handle = LoadLibrary(name);
+   return (NULL == *handle);
+}
+
+/* Queries the address of a symbol within open handle.
+ * Parameters:
+ *         handle: Module handle returned by dw_module_load()
+ *         name: Name of the symbol you want the address of.
+ *         func: A pointer to a function pointer, to obtain
+ *               the address.
+ */
+int API dw_module_symbol(HMOD handle, char *name, void**func)
+{
+   if(!func || !name)
+      return DW_ERROR_UNKNOWN;
+
+   if(0 == strlen(name))
+      return DW_ERROR_UNKNOWN;
+
+   *func = (void*)GetProcAddress(handle, name);
+   return   (NULL == *func);
+}
+
+/* Frees the shared library previously opened.
+ * Parameters:
+ *         handle: Module handle returned by dw_module_load()
+ */
+int API dw_module_close(HMOD handle)
+{
+   return FreeLibrary(handle);
+}
+
+/*
+ * Returns the handle to an unnamed mutex semaphore.
+ */
+HMTX API dw_mutex_new(void)
+{
+   return (HMTX)CreateMutex(NULL, FALSE, NULL);
+}
+
+/*
+ * Closes a semaphore created by dw_mutex_new().
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_close(HMTX mutex)
+{
+   CloseHandle((HANDLE)mutex);
+}
+
+/*
+ * Tries to gain access to the semaphore, if it can't it blocks.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_lock(HMTX mutex)
+{
+   if(_dwtid == dw_thread_id())
+   {
+      int rc = WaitForSingleObject((HANDLE)mutex, 0);
+
+      while(rc == WAIT_TIMEOUT)
+      {
+         dw_main_sleep(1);
+         rc = WaitForSingleObject((HANDLE)mutex, 0);
+      }
+   }
+    else
+      WaitForSingleObject((HANDLE)mutex, INFINITE);
+}
+
+/*
+ * Tries to gain access to the semaphore.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ * Returns:
+ *       DW_ERROR_NONE on success, DW_ERROR_TIMEOUT if it is already locked.
+ */
+int API dw_mutex_trylock(HMTX mutex)
+{
+    if(WaitForSingleObject((HANDLE)mutex, 0) == WAIT_OBJECT_0)
+        return DW_ERROR_NONE;
+    return DW_ERROR_TIMEOUT;
+}
+
+/*
+ * Reliquishes the access to the semaphore.
+ * Parameters:
+ *       mutex: The handle to the mutex returned by dw_mutex_new().
+ */
+void API dw_mutex_unlock(HMTX mutex)
+{
+   ReleaseMutex((HANDLE)mutex);
+}
+
+/*
+ * Returns the handle to an unnamed event semaphore.
+ */
+HEV API dw_event_new(void)
+{
+    return CreateEvent(NULL, TRUE, FALSE, NULL);
+}
+
+/*
+ * Resets a semaphore created by dw_event_new().
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_reset(HEV eve)
+{
+   if(ResetEvent(eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Posts a semaphore created by dw_event_new(). Causing all threads
+ * waiting on this event in dw_event_wait to continue.
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_post(HEV eve)
+{
+   if(SetEvent(eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Waits on a semaphore created by dw_event_new(), until the
+ * event gets posted or until the timeout expires.
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_wait(HEV eve, unsigned long timeout)
+{
+   int rc;
+
+   rc = WaitForSingleObject(eve, timeout != -1 ? timeout : INFINITE);
+   if(rc == WAIT_OBJECT_0)
+      return DW_ERROR_NONE;
+   if(rc == WAIT_TIMEOUT)
+      return DW_ERROR_TIMEOUT;
+   if(rc == WAIT_ABANDONED)
+      return DW_ERROR_INTERRUPT;
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Closes a semaphore created by dw_event_new().
+ * Parameters:
+ *       eve: The handle to the event returned by dw_event_new().
+ */
+int API dw_event_close(HEV *eve)
+{
+   if(eve && CloseHandle(*eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/* Create a named event semaphore which can be
+ * opened from other processes.
+ * Parameters:
+ *         eve: Pointer to an event handle to receive handle.
+ *         name: Name given to semaphore which can be opened
+ *               by other processes.
+ */
+HEV API dw_named_event_new(char *name)
+{
+   SECURITY_ATTRIBUTES sa;
+
+   sa.nLength = sizeof( SECURITY_ATTRIBUTES);
+   sa.lpSecurityDescriptor = &_dwsd;
+   sa.bInheritHandle = FALSE;
+
+   return CreateEvent(&sa, TRUE, FALSE, name);
+}
+
+/* Destroy this semaphore.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              a create call.
+ */
+HEV API dw_named_event_get(char *name)
+{
+   return OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
+}
+
+/* Resets the event semaphore so threads who call wait
+ * on this semaphore will block.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_reset(HEV eve)
+{
+   if(ResetEvent(eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/* Sets the posted state of an event semaphore, any threads
+ * waiting on the semaphore will no longer block.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_post(HEV eve)
+{
+   if(SetEvent(eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/* Waits on the specified semaphore until it becomes
+ * posted, or returns immediately if it already is posted.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ *         timeout: Number of milliseconds before timing out
+ *                  or -1 if indefinite.
+ */
+int API dw_named_event_wait(HEV eve, unsigned long timeout)
+{
+   int rc;
+
+   rc = WaitForSingleObject(eve, timeout != -1 ? timeout : INFINITE);
+   if(rc == WAIT_OBJECT_0)
+      return DW_ERROR_NONE;
+   if(rc == WAIT_TIMEOUT)
+      return DW_ERROR_TIMEOUT;
+   if(rc == WAIT_ABANDONED)
+      return DW_ERROR_INTERRUPT;
+   return DW_ERROR_GENERAL;
+}
+
+/* Release this semaphore, if there are no more open
+ * handles on this semaphore the semaphore will be destroyed.
+ * Parameters:
+ *         eve: Handle to the semaphore obtained by
+ *              an open or create call.
+ */
+int API dw_named_event_close(HEV eve)
+{
+   if(CloseHandle(eve))
+      return DW_ERROR_NONE;
+   return DW_ERROR_GENERAL;
+}
+
+/*
+ * Allocates a shared memory region with a name.
+ * Parameters:
+ *         handle: A pointer to receive a SHM identifier.
+ *         dest: A pointer to a pointer to receive the memory address.
+ *         size: Size in bytes of the shared memory region to allocate.
+ *         name: A string pointer to a unique memory name.
+ */
+HSHM API dw_named_memory_new(void **dest, int size, char *name)
+{
+   SECURITY_ATTRIBUTES sa;
+   HSHM handle;
+
+   sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+   sa.lpSecurityDescriptor = &_dwsd;
+   sa.bInheritHandle = FALSE;
+
+   handle = CreateFileMapping((HANDLE)0xFFFFFFFF, &sa, PAGE_READWRITE, 0, size, name);
+
+   if(!handle)
+      return 0;
+
+   *dest = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+
+   if(!*dest)
+   {
+      CloseHandle(handle);
+      return 0;
+   }
+
+   return handle;
+}
+
+/*
+ * Aquires shared memory region with a name.
+ * Parameters:
+ *         dest: A pointer to a pointer to receive the memory address.
+ *         size: Size in bytes of the shared memory region to requested.
+ *         name: A string pointer to a unique memory name.
+ */
+HSHM API dw_named_memory_get(void **dest, int size, char *name)
+{
+   HSHM handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
+
+   if(!handle)
+      return 0;
+
+   *dest = MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+
+   if(!*dest)
+   {
+      CloseHandle(handle);
+      return 0;
+   }
+
+   return handle;
+}
+
+/*
+ * Frees a shared memory region previously allocated.
+ * Parameters:
+ *         handle: Handle obtained from DB_named_memory_allocate.
+ *         ptr: The memory address aquired with DB_named_memory_allocate.
+ */
+int API dw_named_memory_free(HSHM handle, void *ptr)
+{
+   UnmapViewOfFile(ptr);
+   CloseHandle(handle);
+   return 0;
+}
+
+/*
+ * Encapsulate thread creation on Win32.
+ */
+void _dwthreadstart(void *data)
+{
+   void (* threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+   HPEN hPen;
+   HBRUSH hBrush;
+
+   _init_thread();
+
+   threadfunc = (void (*)(void *))tmp[0];
+   threadfunc(tmp[1]);
+
+   free(tmp);
+   if((hPen = TlsGetValue(_hPen)))
+       DeleteObject(hPen);
+   if((hBrush = TlsGetValue(_hBrush)))
+       DeleteObject(hBrush);
+}
+
+/*
+ * Creates a new thread with a starting point of func.
+ * Parameters:
+ *       func: Function which will be run in the new thread.
+ *       data: Parameter(s) passed to the function.
+ *       stack: Stack size of new thread (OS/2 and Windows only).
+ */
+DWTID API dw_thread_new(void *func, void *data, int stack)
+{
+#if defined(__CYGWIN__)
+   return 0;
+#else
+   void **tmp = malloc(sizeof(void *) * 2);
+
+   tmp[0] = func;
+   tmp[1] = data;
+
+   return (DWTID)_beginthread((void(*)(void *))_dwthreadstart, stack, tmp);
+#endif
+}
+
+/*
+ * Ends execution of current thread immediately.
+ */
+void API dw_thread_end(void)
+{
+#if !defined(__CYGWIN__)
+   _endthread();
+#endif
+}
+
+/*
+ * Returns the current thread's ID.
+ */
+DWTID API dw_thread_id(void)
+{
+#if defined(__CYGWIN__)
+   return 0;
+#else
+   return (DWTID)GetCurrentThreadId();
+#endif
+}
+
+/*
+ * 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)
+{
+   OleUninitialize();
+   exit(exitcode);
+}
+
+/*
+ * Creates a splitbar window (widget) with given parameters.
+ * Parameters:
+ *       type: Value can be DW_VERT or DW_HORZ.
+ *       topleft: Handle to the window to be top or left.
+ *       bottomright:  Handle to the window to be bottom or right.
+ * Returns:
+ *       A handle to a splitbar window or NULL on failure.
+ */
+HWND API dw_splitbar_new(int type, HWND topleft, HWND bottomright, unsigned long id)
+{
+   HWND tmp = CreateWindow(SplitbarClassName,
+                     "",
+                     WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN,
+                     0,0,2000,1000,
+                     DW_HWND_OBJECT,
+                     (HMENU)id,
+                     DWInstance,
+                     NULL);
+
+   if(tmp)
+   {
+      HWND tmpbox = dw_box_new(DW_VERT, 0);
+        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);
+
+      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);
+      *percent = 50.0;
+      dw_window_set_data(tmp, "_dw_percent", (void *)percent);
+      dw_window_set_data(tmp, "_dw_type", (void *)type);
+   }
+   return tmp;
+}
+
+/*
+ * Sets the position of a splitbar (pecentage).
+ * Parameters:
+ *       handle: The handle to the splitbar returned by dw_splitbar_new().
+ */
+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;
+
+   if(mypercent)
+      *mypercent = percent;
+
+   dw_window_get_pos_size(handle, NULL, NULL, &width, &height);
+
+   _handle_splitbar_resize(handle, percent, type, width, height);
+}
+
+/*
+ * Gets the position of a splitbar (pecentage).
+ * Parameters:
+ *       handle: The handle to the splitbar returned by dw_splitbar_new().
+ */
+float API dw_splitbar_get(HWND handle)
+{
+   float *percent = (float *)dw_window_get_data(handle, "_dw_percent");
+
+   if(percent)
+      return *percent;
+   return 0.0;
+}
+
+/*
+ * Creates a calendar window (widget) with given parameters.
+ * Parameters:
+ *       type: Value can be DW_VERT or DW_HORZ.
+ *       topleft: Handle to the window to be top or left.
+ *       bottomright:  Handle to the window to be bottom or right.
+ * Classname: SysMonthCal32
+ * Returns:
+ *       A handle to a calendar window or NULL on failure.
+ */
+HWND API dw_calendar_new(unsigned long id)
+{
+   RECT rc;
+   MONTHDAYSTATE mds[3];
+   HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
+                           MONTHCAL_CLASS,
+                           "",
+                           WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | MCS_DAYSTATE,
+                           0,0,2000,1000, // resize it later
+                           DW_HWND_OBJECT,
+                           (HMENU)id,
+                           DWInstance,
+                           NULL);
+   if ( tmp )
+   {
+      // Get the size required to show an entire month.
+      MonthCal_GetMinReqRect(tmp, &rc);
+      // Resize the control now that the size values have been obtained.
+      SetWindowPos(tmp, NULL, 0, 0,
+               rc.right, rc.bottom,
+               SWP_NOZORDER | SWP_NOMOVE);
+      mds[0] = mds[1] = mds[2] = (MONTHDAYSTATE)0;
+      MonthCal_SetDayState(tmp,3,mds);
+      return tmp;
+   }
+   else
+      return NULL;
+}
+
+/*
+ * Sets the current date of a calendar
+ * Parameters:
+ *       handle: The handle to the calendar returned by dw_calendar_new().
+ *       year:   The year to set the date to
+ *       month:  The month to set the date to
+ *       day:    The day to set the date to
+ */
+void API dw_calendar_set_date(HWND handle, unsigned int year, unsigned int month, unsigned int day)
+{
+   MONTHDAYSTATE mds[3];
+   SYSTEMTIME date;
+   date.wYear = year;
+   date.wMonth = month;
+   date.wDay = day;
+   if ( MonthCal_SetCurSel( handle, &date ) )
+   {
+   }
+   else
+   {
+   }
+   mds[0] = mds[1] = mds[2] = (MONTHDAYSTATE)0;
+   MonthCal_SetDayState(handle,3,mds);
+}
+
+/*
+ * Gets the date from the calendar
+ * Parameters:
+ *       handle: The handle to the calendar returned by dw_calendar_new().
+ *       year:   Pointer to the year to get the date to
+ *       month:  Pointer to the month to get the date to
+ *       day:    Pointer to the day to get the date to
+ */
+void API dw_calendar_get_date(HWND handle, unsigned int *year, unsigned int *month, unsigned int *day)
+{
+   SYSTEMTIME date;
+   if ( MonthCal_GetCurSel( handle, &date ) )
+   {
+      *year = date.wYear;
+      *month = date.wMonth;
+      *day = date.wDay;
+   }
+   else
+   {
+      *year = *month = *day = 0;
+   }
+}
+
+/*
+ * Sets the default focus item for a window/dialog.
+ * Parameters:
+ *         window: Toplevel window or dialog.
+ *         defaultitem: Handle to the dialog item to be default.
+ */
+void API dw_window_default(HWND window, HWND defaultitem)
+{
+   Box *thisbox = (Box *)GetWindowLongPtr(window, GWLP_USERDATA);
+
+   if(thisbox)
+      thisbox->defaultitem = defaultitem;
+}
+
+/*
+ * Sets window to click the default dialog item when an ENTER is pressed.
+ * Parameters:
+ *         window: Window (widget) to look for the ENTER press.
+ *         next: Window (widget) to move to next (or click)
+ */
+void API dw_window_click_default(HWND window, HWND next)
+{
+   ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
+
+   if (cinfo)
+   {
+      cinfo->clickdefault = next;
+   }
+}
+
+/*
+ * Gets the contents of the default clipboard as text.
+ * Parameters:
+ *       None.
+ * Returns:
+ *       Pointer to an allocated string of text or NULL if clipboard empty or contents could not
+ *       be converted to text.
+ */
+char *dw_clipboard_get_text()
+{
+   HANDLE handle;
+   char *tmp, *ret = NULL;
+
+   if ( !OpenClipboard( NULL ) )
+      return ret;
+
+   if ( ( handle = GetClipboardData( CF_TEXT) ) == NULL )
+   {
+      CloseClipboard();
+      return ret;
+   }
+
+   if ( (tmp = GlobalLock(handle)) && strlen(tmp) )
+   {
+        ret = strdup(tmp);
+        GlobalUnlock(handle);
+   }
+   CloseClipboard();
+   return ret;
+}
+
+/*
+ * Sets the contents of the default clipboard to the supplied text.
+ * Parameters:
+ *       Text.
+ */
+void dw_clipboard_set_text( char *str, int len )
+{
+   HGLOBAL ptr1;
+   LPTSTR ptr2;
+
+   if ( !OpenClipboard( NULL ) )
+      return;
+
+   ptr1 = GlobalAlloc( GMEM_MOVEABLE|GMEM_DDESHARE, (len + 1) * sizeof(TCHAR) );
+
+   if ( !ptr1 )
+      return;
+
+   ptr2 = GlobalLock( ptr1 );
+
+   memcpy( (char *)ptr2, str, len + 1);
+   GlobalUnlock( ptr1 );
+   EmptyClipboard();
+
+   SetClipboardData( CF_TEXT, ptr1 );
+
+   CloseClipboard();
+   GlobalFree( ptr1 );
+
+   return;
+}
+
+/*
+ * Returns some information about the current operating environment.
+ * Parameters:
+ *       env: Pointer to a DWEnv struct.
+ */
+void API dw_environment_query(DWEnv *env)
+{
+   if(!env)
+      return;
+
+   /* Get the Windows version. */
+
+   env->MajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
+   env->MinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
+
+   /* Get the build number for Windows NT/Windows 2000. */
+
+   env->MinorBuild =  0;
+
+   if (dwVersion < 0x80000000)
+   {
+      if(env->MajorVersion == 5 && env->MinorVersion == 0)
+         strcpy(env->osName, "Windows 2000");
+      else if(env->MajorVersion == 5 && env->MinorVersion > 0)
+         strcpy(env->osName, "Windows XP");
+      else if(env->MajorVersion == 6 && env->MinorVersion == 0)
+         strcpy(env->osName, "Windows Vista");
+      else if(env->MajorVersion == 6 && env->MinorVersion > 0)
+         strcpy(env->osName, "Windows 7");
+      else
+         strcpy(env->osName, "Windows NT");
+
+      env->MajorBuild = (DWORD)(HIWORD(dwVersion));
+   }
+   else
+   {
+      strcpy(env->osName, "Windows 95/98/ME");
+      env->MajorBuild =  0;
+   }
+
+   strcpy(env->buildDate, __DATE__);
+   strcpy(env->buildTime, __TIME__);
+   env->DWMajorVersion = DW_MAJOR_VERSION;
+   env->DWMinorVersion = DW_MINOR_VERSION;
+#ifdef VER_REV
+   env->DWSubVersion = VER_REV;
+#else
+   env->DWSubVersion = DW_SUB_VERSION;
+#endif
+}
+
+/* Helper to make sure all /s are \s */
+void _to_dos(char *dst, char *src)
+{
+   int x = 0;
+   
+   while(src[x])
+   {
+      if(src[x] == '/')
+         dst[x] = '\\';
+      else
+         dst[x] = src[x];
+      x++;
+   }
+   dst[x] = 0;
+}
+
+/*
+ * Opens a file dialog and queries user selection.
+ * Parameters:
+ *       title: Title bar text for dialog.
+ *       defpath: The default path of the open dialog.
+ *       ext: Default file extention.
+ *       flags: DW_FILE_OPEN or DW_FILE_SAVE or DW_DIRECTORY_OPEN.
+ * Returns:
+ *       NULL on error. A malloced buffer containing
+ *       the file path on success.
+ *
+ */
+char * API dw_file_browse(char *title, char *defpath, char *ext, int flags)
+{
+   OPENFILENAME of;
+   char filenamebuf[1001] = {0};
+   char filterbuf[1001] = {0};
+   int rc;
+
+   BROWSEINFO bi;
+   TCHAR szDir[MAX_PATH];
+   LPITEMIDLIST pidl;
+   LPMALLOC pMalloc;
+
+   if ( flags == DW_DIRECTORY_OPEN )
+   {
+   /* If we aren't building a DLL, use the more simple browser */
+#ifndef BUILD_DLL
+      if (SUCCEEDED(SHGetMalloc(&pMalloc)))
+      {
+         ZeroMemory(&bi,sizeof(bi));
+         bi.hwndOwner = NULL;
+         bi.pszDisplayName = 0;
+         bi.pidlRoot = 0;
+         bi.lpszTitle = title;
+         bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
+         bi.lpfn = NULL; /*BrowseCallbackProc*/
+
+         pidl = SHBrowseForFolder(&bi);
+         if (pidl)
+         {
+            if (SHGetPathFromIDList(pidl,szDir))
+            {
+               strncpy(filenamebuf,szDir,1000);
+            }
+
+            // In C++: pMalloc->Free(pidl); pMalloc->Release();
+            pMalloc->lpVtbl->Free(pMalloc,pidl);
+            pMalloc->lpVtbl->Release(pMalloc);
+            return strdup(filenamebuf);
+         }
+      }
+#else
+     if ( XBrowseForFolder( NULL,
+                            (LPCTSTR)defpath,
+                            -1,
+                            (LPCTSTR)title,
+                            (LPTSTR)filenamebuf,
+                            1000,
+                            FALSE ) )
+     {
+        return strdup( filenamebuf );
+     }
+#endif
+   }
+   else
+   {
+      DWORD att = defpath ? GetFileAttributes(defpath) : INVALID_FILE_ATTRIBUTES;
+      
+      if (ext)
+      {
+         /*
+          * The following mess is because sprintf() trunates at first \0
+          * and format of filter is eg: "c files (*.c)\0*.c\0All Files\0*.*\0\0"
+          */
+         int len;
+         char *ptr = filterbuf;
+         memset( filterbuf, 0, sizeof(filterbuf) );
+         len = sprintf( ptr, "%s Files (*.%s)", ext, ext );
+         ptr = ptr + len + 1; // past first \0
+         len = sprintf( ptr, "*.%s", ext );
+         ptr = ptr + len + 1; // past next \0
+         len = sprintf( ptr, "All Files" );
+         ptr = ptr + len + 1; // past next \0
+         len = sprintf( ptr, "*.*" );
+      }
+
+      memset( &of, 0, sizeof(OPENFILENAME) );
+
+      of.lStructSize = sizeof(OPENFILENAME);
+      of.hwndOwner = HWND_DESKTOP;
+      of.hInstance = DWInstance;
+      of.lpstrTitle = title;
+      of.lpstrInitialDir = ".";
+      if(att != INVALID_FILE_ATTRIBUTES && (att & FILE_ATTRIBUTE_DIRECTORY))
+        of.lpstrInitialDir = defpath;
+      else if(defpath)
+        _to_dos(filenamebuf, defpath);
+      of.lpstrFile = filenamebuf;
+      of.lpstrFilter = filterbuf;
+      of.nFilterIndex = 1;
+      of.nMaxFile = 1000;
+      /*of.lpstrDefExt = ext;*/
+      of.Flags = OFN_NOCHANGEDIR;
+
+      if (flags & DW_FILE_SAVE)
+      {
+         of.Flags |= OFN_OVERWRITEPROMPT;
+         rc = GetSaveFileName(&of);
+      }
+      else
+      {
+         of.Flags |= OFN_FILEMUSTEXIST;
+         rc = GetOpenFileName(&of);
+      }
+
+      if (rc)
+         return strdup(of.lpstrFile);
+   }
+   return NULL;
+}
+
+/*
+ * Execute and external program in a seperate session.
+ * Parameters:
+ *       program: Program name with optional path.
+ *       type: Either DW_EXEC_CON or DW_EXEC_GUI.
+ *       params: An array of pointers to string arguements.
+ * Returns:
+ *       -1 on error.
+ */
+int API dw_exec(char *program, int type, char **params)
+{
+   char **newparams;
+   int retcode, count = 0, z;
+
+   while(params[count])
+   {
+      count++;
+   }
+
+   newparams = (char **)malloc(sizeof(char *) * (count+1));
+
+   for(z=0;z<count;z++)
+   {
+      newparams[z] = malloc(strlen(params[z])+3);
+      strcpy(newparams[z], "\"");
+      strcat(newparams[z], params[z]);
+      strcat(newparams[z], "\"");
+   }
+   newparams[count] = NULL;
+
+   retcode = spawnvp(P_NOWAIT, program, newparams);
+
+   for(z=0;z<count;z++)
+   {
+      free(newparams[z]);
+   }
+   free(newparams);
+
+   return retcode;
+}
+
+/*
+ * Loads a web browser pointed at the given URL.
+ * Parameters:
+ *       url: Uniform resource locator.
+ */
+int API dw_browse(char *url)
+{
+   char *browseurl = url;
+   int retcode;
+
+   if(strlen(url) > 7 && strncmp(url, "file://", 7) == 0)
+   {
+      int len, z;
+
+      browseurl = &url[7];
+      len = strlen(browseurl);
+
+      for(z=0;z<len;z++)
+      {
+         if(browseurl[z] == '|')
+            browseurl[z] = ':';
+         if(browseurl[z] == '/')
+            browseurl[z] = '\\';
+      }
+   }
+
+   retcode = (int)ShellExecute(NULL, "open", browseurl, NULL, NULL, SW_SHOWNORMAL);
+   if(retcode<33 && retcode != 2)
+      return DW_ERROR_UNKNOWN;
+   return DW_ERROR_NONE;
+}
+
+typedef struct _dwprint 
+{
+    PRINTDLG pd;
+    DOCINFO di;
+    int (*drawfunc)(HPRINT, HPIXMAP, int, void *);
+    void *drawdata;
+    unsigned long flags;
+} DWPrint;
+
+/*
+ * Creates a new print object.
+ * Parameters:
+ *       jobname: Name of the print job to show in the queue.
+ *       flags: Flags to initially configure the print object.
+ *       pages: Number of pages to print.
+ *       drawfunc: The pointer to the function to be used as the callback.
+ *       drawdata: User data to be passed to the handler function.
+ * Returns:
+ *       A handle to the print object or NULL on failure.
+ */
+HPRINT API dw_print_new(char *jobname, unsigned long flags, unsigned int pages, void *drawfunc, void *drawdata)
+{
+    DWPrint *print;
+    
+    if(!drawfunc || !(print = calloc(1, sizeof(DWPrint))))
+        return NULL;
+    
+    print->drawfunc = drawfunc;
+    print->drawdata = drawdata;
+    print->pd.lStructSize = sizeof(PRINTDLG);
+    print->pd.hwndOwner = HWND_DESKTOP;
+    print->pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC;
+    print->pd.nCopies = 1;
+    print->pd.nFromPage = 1;
+    print->pd.nToPage = pages;
+    print->pd.nMinPage = 1;
+    print->pd.nMaxPage = pages;
+
+    if(!PrintDlg(&(print->pd)))
+    {
+        free(print);
+        return NULL;
+    }
+
+    print->di.cbSize = sizeof(DOCINFO);
+    print->di.lpszDocName = jobname ? jobname : "Dynamic Windows Print Job";
+    return print;
+}
+
+/*
+ * Runs the print job, causing the draw page callbacks to fire.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ *       flags: Flags to run the print job.
+ * Returns:
+ *       DW_ERROR_UNKNOWN on error or DW_ERROR_NONE on success.
+ */
+int API dw_print_run(HPRINT print, unsigned long flags)
+{
+    DWPrint *p = print;
+    HPIXMAP pixmap;
+    int x, result = DW_ERROR_UNKNOWN;
+    
+    if(!p)
+        return result;
+        
+    if (!(pixmap = calloc(1,sizeof(struct _hpixmap))))
+        return result;
+
+    pixmap->width = GetDeviceCaps(p->pd.hDC, HORZRES); 
+    pixmap->height = GetDeviceCaps(p->pd.hDC, VERTRES);
+
+    pixmap->hbm = CreateCompatibleBitmap(p->pd.hDC, pixmap->width, pixmap->height);
+    pixmap->hdc = p->pd.hDC;
+    pixmap->transcolor = DW_RGB_TRANSPARENT;
+
+    SelectObject(pixmap->hdc, pixmap->hbm);
+
+    /* Start the job */
+    StartDoc(p->pd.hDC, &(p->di));
+    
+    /* Cycle through each page */
+    for(x=p->pd.nFromPage-1; x<p->pd.nToPage && p->drawfunc; x++)
+    {
+        StartPage(p->pd.hDC);
+        p->drawfunc(print, pixmap, x, p->drawdata);
+        EndPage(p->pd.hDC);
+    }
+    EndDoc(p->pd.hDC);
+    if(p->drawfunc)
+        result = DW_ERROR_NONE;
+    /* Free memory */
+    dw_pixmap_destroy(pixmap);
+    free(p);
+    return result;
+}
+
+/*
+ * Cancels the print job, typically called from a draw page callback.
+ * Parameters:
+ *       print: Handle to the print object returned by dw_print_new().
+ */
+void API dw_print_cancel(HPRINT print)
+{
+    DWPrint *p = print;
+    
+    if(p)
+        p->drawfunc = NULL;
+}
+
+/*
+ * Returns a pointer to a static buffer which containes the
+ * current user directory.  Or the root directory (C:\ on
+ * OS/2 and Windows).
+ */
+char * API dw_user_dir(void)
+{
+    static char _user_dir[1024] = "";
+
+    if(!_user_dir[0])
+    {
+        HANDLE hToken = 0;
+
+        /* Use the Windows API to get the user's profile directory */
+        if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
+        {
+            DWORD BufSize = 1024;
+
+            GetUserProfileDirectory(hToken, _user_dir, &BufSize);
+            CloseHandle(hToken);
+        }
+        /* If it fails set it to the root directory */
+        if(!_user_dir[0])
+        {
+            strcpy(_user_dir, "C:\\");
+        }
+    }
+    return _user_dir;
+}
+
+/*
+ * Call a function from the window (widget)'s context.
+ * Parameters:
+ *       handle: Window handle of the widget.
+ *       function: Function pointer to be called.
+ *       data: Pointer to the data to be passed to the function.
+ */
+void API dw_window_function(HWND handle, void *function, void *data)
+{
+   SendMessage(handle, WM_USER, (WPARAM)function, (LPARAM)data);
+}
+
+/* Functions for managing the user data lists that are associated with
+ * a given window handle.  Used in dw_window_set_data() and
+ * dw_window_get_data().
+ */
+UserData *_find_userdata(UserData **root, char *varname)
+{
+   UserData *tmp = *root;
+
+   while(tmp)
+   {
+      if(stricmp(tmp->varname, varname) == 0)
+         return tmp;
+      tmp = tmp->next;
+   }
+   return NULL;
+}
+
+int _new_userdata(UserData **root, char *varname, void *data)
+{
+   UserData *new = _find_userdata(root, varname);
+
+   if(new)
+   {
+      new->data = data;
+      return TRUE;
+   }
+   else
+   {
+      new = malloc(sizeof(UserData));
+      if(new)
+      {
+         new->varname = strdup(varname);
+         new->data = data;
+
+         new->next = NULL;
+
+         if (!*root)
+            *root = new;
+         else
+         {
+            UserData *prev = *root, *tmp = prev->next;
+
+            while(tmp)
+            {
+               prev = tmp;
+               tmp = tmp->next;
+            }
+            prev->next = new;
+         }
+         return TRUE;
+      }
+   }
+   return FALSE;
+}
+
+int _remove_userdata(UserData **root, char *varname, int all)
+{
+   UserData *prev = NULL, *tmp = *root;
+
+   while(tmp)
+   {
+      if(all || stricmp(tmp->varname, varname) == 0)
+      {
+         if(!prev)
+         {
+            *root = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            if(!all)
+               return 0;
+            tmp = *root;
+         }
+         else
+         {
+            /* If all is true we should
+             * never get here.
+             */
+            prev->next = tmp->next;
+            free(tmp->varname);
+            free(tmp);
+            return 0;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+   return 0;
+}
+
+/*
+ * Add a named user data item to a window handle.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       dataname: A string pointer identifying which signal to be hooked.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_window_set_data(HWND window, char *dataname, void *data)
+{
+   ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
+
+   if(!cinfo)
+   {
+      if(!dataname)
+         return;
+
+      cinfo = calloc(1, sizeof(ColorInfo));
+      cinfo->fore = cinfo->back = -1;
+      SetWindowLongPtr(window, GWLP_USERDATA, (LONG_PTR)cinfo);
+   }
+
+   if(cinfo)
+   {
+      if(data)
+         _new_userdata(&(cinfo->root), dataname, data);
+      else
+      {
+         if(dataname)
+            _remove_userdata(&(cinfo->root), dataname, FALSE);
+         else
+            _remove_userdata(&(cinfo->root), NULL, TRUE);
+      }
+   }
+}
+
+/*
+ * Gets a named user data item to a window handle.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       dataname: A string pointer identifying which signal to be hooked.
+ *       data: User data to be passed to the handler function.
+ */
+void * API dw_window_get_data(HWND window, char *dataname)
+{
+   ColorInfo *cinfo = (ColorInfo *)GetWindowLongPtr(window, GWLP_USERDATA);
+
+   if(cinfo && cinfo->root && dataname)
+   {
+      UserData *ud = _find_userdata(&(cinfo->root), dataname);
+      if(ud)
+         return ud->data;
+   }
+   return NULL;
+}
+
+/*
+ * Add a callback to a timer event.
+ * Parameters:
+ *       interval: Milliseconds to delay between calls.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       data: User data to be passed to the handler function.
+ * Returns:
+ *       Timer ID for use with dw_timer_disconnect(), 0 on error.
+ */
+int API dw_timer_connect(int interval, void *sigfunc, void *data)
+{
+   if(sigfunc)
+   {
+      int timerid = SetTimer(NULL, 0, interval, _TimerProc);
+
+      if(timerid)
+      {
+         _new_signal(WM_TIMER, NULL, timerid, sigfunc, data);
+         return timerid;
+      }
+   }
+   return 0;
+}
+
+/*
+ * Removes timer callback.
+ * Parameters:
+ *       id: Timer ID returned by dw_timer_connect().
+ */
+void API dw_timer_disconnect(int id)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   /* 0 is an invalid timer ID */
+   if(!id)
+      return;
+
+   KillTimer(NULL, id);
+
+   while(tmp)
+   {
+      if(tmp->id == id)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Add a callback to a window event.
+ * 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.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
+{
+   ULONG message = 0, id = 0;
+
+   if (window && signame && sigfunc)
+   {
+      if (stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
+         window = _normalize_handle(window);
+
+      if ((message = _findsigmessage(signame)) != 0)
+      {
+         /* Handle special case of the menu item */
+         if (message == WM_COMMAND && window < (HWND)65536)
+         {
+            char buffer[16];
+            HWND owner;
+
+            _snprintf(buffer, 15, "_dw_id%d", (int)window);
+            owner = (HWND)dw_window_get_data(DW_HWND_OBJECT, buffer);
+
+            /* Make sure there are no dupes from popups */
+            dw_signal_disconnect_by_window(window);
+
+            if (owner)
+            {
+               id = (ULONG)window;
+               window = owner;
+            }
+         }
+         _new_signal(message, window, id, sigfunc, data);
+      }
+   }
+}
+
+/*
+ * Removes callbacks for a given window with given name.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ */
+void API dw_signal_disconnect_by_name(HWND window, char *signame)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+   ULONG message;
+
+   if(!window || !signame || (message = _findsigmessage(signame)) == 0)
+      return;
+
+   while(tmp)
+   {
+      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->message == message)
+      {
+        if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Removes all callbacks for a given window.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ */
+void API dw_signal_disconnect_by_window(HWND window)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window)
+      {
+         if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}
+
+/*
+ * Removes all callbacks for a given window with specified data.
+ * Parameters:
+ *       window: Window handle of callback to be removed.
+ *       data: Pointer to the data to be compared against.
+ */
+void API dw_signal_disconnect_by_data(HWND window, void *data)
+{
+   SignalHandler *prev = NULL, *tmp = Root;
+
+   while(tmp)
+   {
+      if(((window < (HWND)65536 && (int)window == tmp->id) || tmp->window == window) && tmp->data == data)
+      {
+        if(prev)
+         {
+            prev->next = tmp->next;
+            free(tmp);
+            tmp = prev->next;
+         }
+         else
+         {
+            Root = tmp->next;
+            free(tmp);
+            tmp = Root;
+         }
+      }
+      else
+      {
+         prev = tmp;
+         tmp = tmp->next;
+      }
+   }
+}