changeset 22:6a246b3bb14f

Added tree widgets, fixed some delete event processing, fixed a layout bug on OS/2 and Win32. Added another function to compat to deal with MSVC runtime library conflicts.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Thu, 02 Aug 2001 09:57:21 +0000
parents c6e76b796b28
children 2932f9d2c7d5
files compat.c dw.def dw.h dwcompat.def dwcompatw.def dww.def gtk/dw.c os2/dw.c win/dw.c
diffstat 9 files changed, 772 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/compat.c	Fri Jul 27 07:12:35 2001 +0000
+++ b/compat.c	Thu Aug 02 09:57:21 2001 +0000
@@ -377,3 +377,7 @@
 	return fgets(str, size, stream);
 }
 
+int fsseek(FILE *stream, long offset, int whence)
+{
+	return fseek(stream, offset, whence);
+}
--- a/dw.def	Fri Jul 27 07:12:35 2001 +0000
+++ b/dw.def	Thu Aug 02 09:57:21 2001 +0000
@@ -54,6 +54,7 @@
   dw_window_from_id                      @71
   dw_window_set_border                   @72
   dw_window_minimize                     @73
+  dw_window_pointer                      @74
 
   dw_bitmap_new                          @80
 
@@ -123,6 +124,9 @@
   dw_container_set_view                  @227
   dw_container_query_start               @228
   dw_container_query_next                @229
+  dw_container_delete                    @230
+  dw_container_scroll                    @231
+  dw_container_set_column_width          @232
 
   dw_filesystem_setup                    @240
   dw_filesystem_set_item                 @241
@@ -189,3 +193,5 @@
   dw_signal_disconnect_by_data           @362
   dw_signal_disconnect_by_name           @363
 
+  dw_tree_new                            @370
+  dw_tree_insert                         @371
\ No newline at end of file
--- a/dw.h	Fri Jul 27 07:12:35 2001 +0000
+++ b/dw.h	Thu Aug 02 09:57:21 2001 +0000
@@ -109,6 +109,9 @@
 
 #define DW_MLE_CASESENSITIVE     MLFSEARCH_CASESENSITIVE
 
+#define DW_POINTER_ARROW         SPTR_ARROW
+#define DW_POINTER_CLOCK         SPTR_WAIT
+
 typedef struct _hpixmap {
 	unsigned long width, height;
 	HDC hdc;
@@ -228,6 +231,9 @@
 
 #define DW_MLE_CASESENSITIVE     1
 
+#define DW_POINTER_ARROW         32512
+#define DW_POINTER_CLOCK         32514
+
 #define STATICCLASSNAME "STATIC"
 #define COMBOBOXCLASSNAME "COMBOBOX"
 #define LISTBOXCLASSNAME "LISTBOX"
@@ -424,6 +430,9 @@
 
 #define DW_MLE_CASESENSITIVE     1
 
+#define DW_POINTER_ARROW         GDK_ARROW
+#define DW_POINTER_CLOCK         GDK_CLOCK
+
 #define DW_DESKTOP               ((HWND)0)
 #define HWND_DESKTOP             ((HWND)0)
 
@@ -528,6 +537,11 @@
 #define BOXHORZ 0
 #define BOXVERT 1
 
+#define DW_SCROLL_UP 0
+#define DW_SCROLL_DOWN 1
+#define DW_SCROLL_TOP 2
+#define DW_SCROLL_BOTTOM 3
+
 #define DW_PIXMAP_WIDTH(x) (x ? x->width : 0)
 #define DW_PIXMAP_HEIGHT(x) (x ? x->height : 0)
 
@@ -569,6 +583,7 @@
 HWND dw_bitmap_new(unsigned long id);
 HWND dw_bitmapbutton_new(char *text, unsigned long id);
 HWND dw_container_new(unsigned long id);
+HWND dw_tree_new(unsigned long id);
 HWND dw_text_new(char *text, unsigned long id);
 HWND dw_status_text_new(char *text, unsigned long id);
 HWND dw_mle_new(unsigned long id);
@@ -608,6 +623,7 @@
 void dw_window_capture(HWND handle);
 void dw_window_release(void);
 void dw_window_reparent(HWND handle, HWND newparent);
+void dw_window_pointer(HWND handle, int pointertype);
 unsigned int dw_mle_import(HWND handle, char *buffer, int startpoint);
 void dw_mle_export(HWND handle, char *buffer, int startpoint, int length);
 void dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines);
@@ -626,17 +642,21 @@
 long dw_spinbutton_query(HWND handle);
 int dw_checkbox_query(HWND handle);
 void dw_checkbox_set(HWND handle, int value);
+HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent);
 int dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator);
 unsigned long dw_icon_load(unsigned long module, unsigned long id);
 void dw_icon_free(unsigned long handle);
 void *dw_container_alloc(HWND handle, int rowcount);
 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data);
+void dw_container_set_column_width(HWND handle, int column, int width);
 void dw_container_set_row_title(void *pointer, int row, char *title);
 void dw_container_insert(HWND handle, void *pointer, int rowcount);
 void dw_container_clear(HWND handle);
+void dw_container_delete(HWND handle, int rowcount);
 void dw_container_set_view(HWND handle, unsigned long flags, int iconwidth, int iconheight);
 char *dw_container_query_start(HWND handle, unsigned long flags);
 char *dw_container_query_next(HWND handle, unsigned long flags);
+void dw_container_scroll(HWND handle, int direction, long rows);
 int dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count);
 void dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data);
 void dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon);
--- a/dwcompat.def	Fri Jul 27 07:12:35 2001 +0000
+++ b/dwcompat.def	Thu Aug 02 09:57:21 2001 +0000
@@ -32,3 +32,4 @@
   fsopen             @40
   fsclose            @41
   fsgets             @42
+  fsseek             @43
--- a/dwcompatw.def	Fri Jul 27 07:12:35 2001 +0000
+++ b/dwcompatw.def	Thu Aug 02 09:57:21 2001 +0000
@@ -27,4 +27,5 @@
   fsopen             @40
   fsclose            @41
   fsgets             @42
+  fsseek             @43
 
--- a/dww.def	Fri Jul 27 07:12:35 2001 +0000
+++ b/dww.def	Thu Aug 02 09:57:21 2001 +0000
@@ -51,6 +51,7 @@
   dw_window_from_id                      @71
   dw_window_set_border                   @72
   dw_window_minimize                     @73
+  dw_window_pointer                      @74
 
   dw_bitmap_new                          @80
 
@@ -120,6 +121,9 @@
   dw_container_set_view                  @227
   dw_container_query_start               @228
   dw_container_query_next                @229
+  dw_container_delete                    @230
+  dw_container_scroll                    @231
+  dw_container_set_column_width          @232
 
   dw_filesystem_setup                    @240
   dw_filesystem_set_item                 @241
@@ -186,3 +190,6 @@
   dw_signal_disconnect_by_data           @362
   dw_signal_disconnect_by_name           @363
 
+  dw_tree_new                            @370
+  dw_tree_insert                         @371
+
--- a/gtk/dw.c	Fri Jul 27 07:12:35 2001 +0000
+++ b/gtk/dw.c	Thu Aug 02 09:57:21 2001 +0000
@@ -50,8 +50,7 @@
 GdkColor _foreground = { 0, 0x0000, 0x0000, 0x0000 };
 GdkColor _background = { 0, 0xaaaa, 0xaaaa, 0xaaaa };
 
-char *_dw_browse_file = NULL;
-int _dw_file_active = 0, _dw_file_ready = 0, _dw_ignore_click = 0;
+int _dw_file_active = 0, _dw_ignore_click = 0;
 pthread_t _dw_thread = (pthread_t)-1;
 int _dw_mutex_locked = FALSE;
 
@@ -609,6 +608,28 @@
 	return strlen(outbuf);
 }
 
+void _dw_yes_func(HWND window, void *data)
+{
+	DWDialog *dwwait = (DWDialog *)data;
+
+	if(!dwwait)
+		return;
+
+	dw_window_destroy((HWND)dwwait->data);
+	dw_dialog_dismiss((DWDialog *)data, (void *)1);
+}
+
+void _dw_no_func(HWND window, void *data)
+{
+	DWDialog *dwwait = (DWDialog *)data;
+
+	if(!dwwait)
+		return;
+
+	dw_window_destroy((HWND)dwwait->data);
+	dw_dialog_dismiss((DWDialog *)data, (void *)0);
+}
+
 /*
  * Displays a Message Box with given text and title..
  * Parameters:
@@ -619,7 +640,44 @@
  */
 int dw_yesno(char *title, char *text)
 {
-	return FALSE;
+	HWND entrywindow, mainbox, nobutton, yesbutton, buttonbox, stext;
+	ULONG flStyle = DW_FCF_TITLEBAR | DW_FCF_SHELLPOSITION | DW_FCF_DLGBORDER;
+	DWDialog *dwwait;
+
+	entrywindow = dw_window_new(HWND_DESKTOP, title, flStyle);
+
+	mainbox = dw_box_new(BOXVERT, 10);
+
+	dw_box_pack_start(entrywindow, mainbox, 0, 0, TRUE, TRUE, 0);
+
+	/* Archive Name */
+	stext = dw_text_new(text, 0);
+
+	dw_box_pack_start(mainbox, stext, 130, 20, TRUE, TRUE, 2);
+
+	/* Buttons */
+	buttonbox = dw_box_new(BOXHORZ, 10);
+
+	dw_box_pack_start(mainbox, buttonbox, 0, 0, TRUE, TRUE, 0);
+
+	yesbutton = dw_button_new("Yes", 1001L);
+
+	dw_box_pack_start(buttonbox, yesbutton, 130, 30, TRUE, TRUE, 2);
+
+	nobutton = dw_button_new("No", 1002L);
+
+	dw_box_pack_start(buttonbox, nobutton, 130, 30, TRUE, TRUE, 2);
+
+	dwwait = dw_dialog_new((void *)entrywindow);
+
+	dw_signal_connect(yesbutton, "clicked", DW_SIGNAL_FUNC(_dw_yes_func), (void *)dwwait);
+	dw_signal_connect(nobutton, "clicked", DW_SIGNAL_FUNC(_dw_no_func), (void *)dwwait);
+
+	dw_window_set_usize(entrywindow, 340, 150);
+
+	dw_window_show(entrywindow);
+
+	return (int)dw_dialog_wait(dwwait);;
 }
 
 /*
@@ -911,6 +969,19 @@
 }
 
 /*
+ * Changes the appearance of the mouse pointer.
+ * Parameters:
+ *       handle: Handle to widget for which to change.
+ *       cursortype: ID of the pointer you want.
+ */
+void dw_window_pointer(HWND handle, int pointertype)
+{
+	GdkCursor *cursor = gdk_cursor_new(pointertype);
+	gdk_window_set_cursor(handle->window, cursor);
+	gdk_cursor_destroy(cursor);
+}
+
+/*
  * Releases previous mouse capture.
  */
 void dw_window_release(void)
@@ -1385,6 +1456,43 @@
 }
 
 /*
+ * Create a tree object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND dw_tree_new(ULONG id)
+{
+	GtkWidget *tmp, *tree;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	tmp = gtk_scrolled_window_new(NULL, NULL);
+	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (tmp),
+					GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+
+	gtk_object_set_data(GTK_OBJECT(tmp), "id", (gpointer)id);
+	gtk_widget_show(tmp);
+	tree = gtk_tree_new();
+	if(!tree)
+	{
+		gtk_widget_destroy(tmp);
+		DW_MUTEX_UNLOCK;
+		return FALSE;
+	}
+	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(tmp), tree);
+	/* Set the selection mode */
+	gtk_tree_set_selection_mode (GTK_TREE(tree), GTK_SELECTION_SINGLE);
+
+	gtk_object_set_user_data(GTK_OBJECT(tmp), (gpointer)tree);
+	gtk_widget_show(tree);
+
+	DW_MUTEX_UNLOCK;
+	return tmp;
+}
+
+
+/*
  * Create a new static text window (widget) to be packed.
  * Parameters:
  *       text: The text to be display by the static text widget.
@@ -2292,6 +2400,61 @@
 	DW_MUTEX_UNLOCK;
 }
 
+/*
+ * 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.
+ */
+HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent)
+{
+	GtkWidget *item, *tree, *subtree, *label, *hbox, *pixmap;
+	GdkPixmap *gdkpix;
+	GdkBitmap *gdkbmp;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	tree = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(handle));
+	if(!tree || !GTK_IS_TREE(tree))
+	{
+		DW_MUTEX_UNLOCK;
+		return NULL;
+	}
+	item = gtk_tree_item_new();
+	label = gtk_label_new(title);
+	hbox = gtk_hbox_new(FALSE, 2);
+	gdkpix = _find_pixmap(&gdkbmp, icon, hbox);
+	pixmap = gtk_pixmap_new(gdkpix, gdkbmp);
+	gtk_container_add(GTK_CONTAINER(item), hbox);
+	gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+	gtk_widget_show(label);
+	gtk_widget_show(pixmap);
+	gtk_widget_show(hbox);
+
+	if(parent)
+	{
+		subtree = (GtkWidget *)gtk_object_get_user_data(GTK_OBJECT(parent));
+		if(!subtree)
+		{
+			subtree = gtk_tree_new();
+			gtk_object_set_user_data(GTK_OBJECT(parent), subtree);
+			gtk_tree_set_selection_mode(GTK_TREE(subtree), GTK_SELECTION_SINGLE);
+			gtk_tree_set_view_mode(GTK_TREE(subtree), GTK_TREE_VIEW_ITEM);
+			gtk_tree_item_set_subtree(GTK_TREE_ITEM(parent), subtree);
+			gtk_widget_show(subtree);
+		}
+		gtk_tree_append(GTK_TREE(subtree), item);
+	}
+	else
+		gtk_tree_append(GTK_TREE(tree), item);
+	gtk_widget_show(item);
+	DW_MUTEX_UNLOCK;
+	return item;
+}
+
 int _dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator, int extra)
 {
 	GtkWidget *clist;
@@ -2546,6 +2709,26 @@
 }
 
 /*
+ * 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 dw_container_set_column_width(HWND handle, int column, int width)
+{
+	GtkWidget *clist;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	clist = gtk_object_get_user_data(GTK_OBJECT(handle));
+
+	if(clist && GTK_IS_CLIST(clist))
+		gtk_clist_set_column_width(GTK_CLIST(clist), column, width);
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Sets the title of a row in the container.
  * Parameters:
  *          pointer: Pointer to the allocated memory in dw_container_alloc().
@@ -2586,6 +2769,42 @@
 }
 
 /*
+ * 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 dw_container_delete(HWND handle, int rowcount)
+{
+	GtkWidget *clist;
+	GList *list;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
+	if(clist && GTK_IS_CLIST(clist))
+	{
+		int rows, z;
+
+		list = (GList *)gtk_object_get_data(GTK_OBJECT(clist), "selectlist");
+		rows = (int)gtk_object_get_data(GTK_OBJECT(clist), "rowcount");
+		g_list_free(list);
+
+		for(z=0;z<rowcount;z++)
+			gtk_clist_remove(GTK_CLIST(clist), 0);
+
+		if(rows - rowcount < 0)
+			rows = 0;
+		else
+			rows -= rowcount;
+
+		gtk_object_set_data(GTK_OBJECT(clist), "selectlist", NULL);
+		gtk_object_set_data(GTK_OBJECT(clist), "rowcount", (gpointer)rows);
+	}
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Removes all rows from a container.
  * Parameters:
  *       handle: Handle to the window (widget) to be cleared.
@@ -2619,6 +2838,42 @@
 }
 
 /*
+ * 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 dw_container_scroll(HWND handle, int direction, long rows)
+{
+	GtkAdjustment *adj;
+	GtkWidget *clist;
+	int _locked_by_me = FALSE;
+
+	DW_MUTEX_LOCK;
+	clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
+	if(clist && GTK_IS_CLIST(clist))
+	{
+		adj = gtk_clist_get_vadjustment(GTK_CLIST(clist));
+		if(adj)
+		{
+			switch(direction)
+			{
+			case DW_SCROLL_TOP:
+				adj->value = adj->lower;
+				break;
+			case DW_SCROLL_BOTTOM:
+				adj->value = adj->upper;
+				break;
+			}
+			gtk_clist_set_vadjustment(GTK_CLIST(clist), adj);
+		}
+	}
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Starts a new query of a container.
  * Parameters:
  *       handle: Handle to the window (widget) to be queried.
@@ -4130,27 +4385,28 @@
 }
 
 /* Internal function to handle the file OK press */
-void _gtk_file_ok(GtkWidget *widget, GtkWidget *window)
+void _gtk_file_ok(GtkWidget *widget, DWDialog *dwwait)
 {
 	char *tmp;
 
-	tmp = gtk_file_selection_get_filename(GTK_FILE_SELECTION(window));
-	if(tmp)
-		_dw_browse_file = strdup(tmp);
-	gtk_widget_destroy(GTK_WIDGET(window));
-	if(pthread_self() == _dw_thread)
-		gtk_main_quit();
-	_dw_file_ready = 1;
+	if(!dwwait)
+		return;
+
+	tmp = gtk_file_selection_get_filename(GTK_FILE_SELECTION(dwwait->data));
+	gtk_widget_destroy(GTK_WIDGET(dwwait->data));
+	_dw_file_active = 0;
+	dw_dialog_dismiss(dwwait, (void *)(tmp ? strdup(tmp) : NULL));
 }
 
 /* Internal function to handle the file Cancel press */
-void _gtk_file_cancel(GtkWidget *widget, GtkWidget *window)
+void _gtk_file_cancel(GtkWidget *widget, DWDialog *dwwait)
 {
-	gtk_widget_destroy(GTK_WIDGET(window));
-	if(pthread_self() == _dw_thread)
-		gtk_main_quit();
-	_dw_file_ready = 1;
-
+	if(!dwwait)
+		return;
+
+	gtk_widget_destroy(GTK_WIDGET(dwwait->data));
+	_dw_file_active = 0;
+	dw_dialog_dismiss(dwwait, NULL);
 }
 
 /*
@@ -4168,8 +4424,8 @@
 char *dw_file_browse(char *title, char *defpath, char *ext, int flags)
 {
 	GtkWidget *filew;
-	char *tmpvar;
 	int _locked_by_me = FALSE;
+	DWDialog *dwwait;
 
 	DW_MUTEX_LOCK;
 
@@ -4183,12 +4439,13 @@
 	}
 
 	_dw_file_active = 1;
-	_dw_file_ready = 0;
 
 	filew = gtk_file_selection_new(title);
 
-	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->ok_button), "clicked", (GtkSignalFunc) _gtk_file_ok, filew);
-	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->cancel_button), "clicked", (GtkSignalFunc) _gtk_file_cancel, filew);
+	dwwait = dw_dialog_new((void *)filew);
+
+	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->ok_button), "clicked", (GtkSignalFunc) _gtk_file_ok, dwwait);
+	gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filew)->cancel_button), "clicked", (GtkSignalFunc) _gtk_file_cancel, dwwait);
 
 	if(defpath)
 		gtk_file_selection_set_filename(GTK_FILE_SELECTION(filew), defpath);
@@ -4197,20 +4454,7 @@
 
 	DW_MUTEX_UNLOCK;
 
-	if(pthread_self() == _dw_thread)
-		gtk_main();
-	else
-	{
-		/* This should be an event semaphore */
-		while(!_dw_file_ready)
-			usleep(100);
-	}
-
-	tmpvar = _dw_browse_file;
-	_dw_browse_file = NULL;
-	_dw_file_ready = _dw_file_active = 0;
-
-	return tmpvar;
+	return (char *)dw_dialog_wait(dwwait);
 }
 
 
--- a/os2/dw.c	Fri Jul 27 07:12:35 2001 +0000
+++ b/os2/dw.c	Thu Aug 02 09:57:21 2001 +0000
@@ -55,7 +55,7 @@
 void reopen(void)
 {
 	fclose(f);
-	f = fopen("dw.log", "at");
+	f = fopen("dw.log", "a+");
 }
 #endif
 
@@ -618,6 +618,7 @@
 						reopen();
 					}
 #endif
+
 					if(thisbox->type == BOXVERT)
 					{
 						if((thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))!=0)
@@ -686,6 +687,18 @@
 				thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))))/((float)(thisbox->minheight-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))));
 			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;
+				}
+			}
+
 #ifdef DWDEBUG
 			fprintf(f, "RATIO- xratio = %f, yratio = %f, width = %d, height = %d, pad = %d, box xratio = %f, box yratio = %f, parent xratio = %f, parent yratio = %f, minwidth = %d, minheight = %d, width = %d, height = %d, upx = %d, upy = %d\r\n\r\n",
 					thisbox->items[z].xratio, thisbox->items[z].yratio, thisbox->items[z].width, thisbox->items[z].height, thisbox->items[z].pad, thisbox->xratio, thisbox->yratio, thisbox->parentxratio, thisbox->parentyratio, thisbox->minwidth, thisbox->minheight, thisbox->width, thisbox->height, thisbox->upx, thisbox->upy);
@@ -1283,6 +1296,8 @@
 					if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT))
 					{
 						result = closefunc(tmp->window, tmp->data);
+						if(result)
+							result = FALSE;
 						tmp = NULL;
 					}
 				}
@@ -1597,8 +1612,12 @@
 		}
 		break;
 	case WM_CLOSE:
-		dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
-		return (MRESULT)TRUE;
+		if(result == -1)
+		{
+			dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT));
+			return (MRESULT)TRUE;
+		}
+		break;
 	case WM_USER:
 		windowfunc = (void (*)(void *))mp1;
 
@@ -1617,7 +1636,7 @@
 		_free_window_memory(hWnd);
 		break;
 	}
-	if(filterfunc && result != -1)
+	if(result != -1)
 		return (MRESULT)result;
 	else
 		return WinDefWindowProc(hWnd, msg, mp1, mp2);
@@ -1850,7 +1869,9 @@
 					if(thisbox->items[z].type == TYPEBOX)
 					{
 						Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER);
-						_changebox(tmp, percent, thisbox->type);
+
+						if(tmp)
+							_changebox(tmp, percent, thisbox->type);
 					}
 					else
 					{
@@ -2164,7 +2185,7 @@
 	DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
 
 #ifdef DWDEBUG
-	f = fopen("dw.log", "wt");
+	f = fopen("dw.log", "w");
 #endif
 	return rc;
 }
@@ -2491,6 +2512,20 @@
 }
 
 /*
+ * Changes the appearance of the mouse pointer.
+ * Parameters:
+ *       handle: Handle to widget for which to change.
+ *       cursortype: ID of the pointer you want.
+ */
+void dw_window_pointer(HWND handle, int pointertype)
+{
+	WinSetPointer(handle,
+				  WinQuerySysPointer(HWND_DESKTOP,
+									 pointertype,
+									 FALSE));
+}
+
+/*
  * Create a new Window Frame.
  * Parameters:
  *       owner: The Owner's window handle or HWND_DESKTOP.
@@ -2880,6 +2915,36 @@
 }
 
 /*
+ * Create a tree object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND dw_tree_new(ULONG id)
+{
+	CNRINFO cnrinfo;
+	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;
+
+	WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON));
+	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.
@@ -4125,6 +4190,72 @@
 	WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
 }
 
+typedef struct _CNRITEM
+{
+	MINIRECORDCORE rc;
+	HPOINTER       hptrIcon;
+
+} CNRITEM, *PCNRITEM;
+
+/*
+ * 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.
+ */
+HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent)
+{
+	ULONG        cbExtra;
+	PCNRITEM     pci;
+	RECORDINSERT ri;
+
+	/* 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 */
+
+	pci = WinSendMsg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1));
+
+	/* Fill in the parent record data */
+
+	pci->rc.cb          = sizeof(MINIRECORDCORE);
+	pci->rc.pszIcon     = title;
+	pci->rc.hptrIcon    = icon;
+
+	pci->hptrIcon       = icon;
+
+	memset(&ri, 0, sizeof(RECORDINSERT));
+
+	ri.cb                 = sizeof(RECORDINSERT);
+	ri.pRecordOrder       = (PRECORDCORE)CMA_END;
+	ri.pRecordParent      = (PRECORDCORE)NULL;
+	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 (HWND)pci;
+}
+
+/* Some OS/2 specific container structs */
+typedef struct _containerinfo {
+	int count;
+	void *data;
+	HWND handle;
+} ContainerInfo;
+
 /*
  * Sets up the container columns.
  * Parameters:
@@ -4281,6 +4412,7 @@
 	ULONG *flags = (ULONG *)WinQueryWindowPtr(handle, 0);
 	int z, size = 0, totalsize, count = 0;
 	PRECORDCORE temp;
+	ContainerInfo *ci;
 	void *blah;
 
 	if(!flags)
@@ -4319,7 +4451,13 @@
 		temp = temp->preccNextRecord;
 	}
 
-	return blah;
+	ci = malloc(sizeof(struct _containerinfo));
+
+	ci->count = rowcount;
+	ci->data = blah;
+	ci->handle = handle;
+
+	return (void *)ci;
 }
 
 /*
@@ -4334,13 +4472,23 @@
 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
 {
 	ULONG totalsize, size = 0, *flags = (ULONG *)WinQueryWindowPtr(handle, 0);
-	int z;
-	PRECORDCORE temp = (PRECORDCORE)pointer;
+	int z, currentcount;
+	ContainerInfo *ci = (ContainerInfo *)pointer;
+	PRECORDCORE temp;
+	CNRINFO cnr;
     void *dest;
 
+	if(!ci)
+		return;
+
 	if(!flags)
 		return;
 
+	temp = (PRECORDCORE)ci->data;
+
+	WinSendMsg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)));
+	currentcount = cnr.cRecords;
+
 	/* Figure out the offsets to the items in the struct */
 	for(z=0;z<column;z++)
 	{
@@ -4358,7 +4506,7 @@
 
 	totalsize = size + sizeof(RECORDCORE);
 
-	for(z=0;z<row;z++)
+	for(z=0;z<(row-currentcount);z++)
 		temp = temp->preccNextRecord;
 
 	dest = (void *)(((ULONG)temp)+((ULONG)totalsize));
@@ -4405,6 +4553,17 @@
 }
 
 /*
+ * 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 dw_container_set_column_width(HWND handle, int column, int width)
+{
+}
+
+/*
  * Sets the title of a row in the container.
  * Parameters:
  *          pointer: Pointer to the allocated memory in dw_container_alloc().
@@ -4413,10 +4572,15 @@
  */
 void dw_container_set_row_title(void *pointer, int row, char *title)
 {
-	PRECORDCORE temp = (PRECORDCORE)pointer;
-	int z;
-
-	for(z=0;z<row;z++)
+	ContainerInfo *ci = (ContainerInfo *)pointer;
+	PRECORDCORE temp = (PRECORDCORE)ci->data;
+	int z, currentcount;
+	CNRINFO cnr;
+
+	WinSendMsg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO)));
+	currentcount = cnr.cRecords;
+
+	for(z=0;z<(row-currentcount);z++)
 		temp = temp->preccNextRecord;
 
 	temp->pszIcon = title;
@@ -4434,6 +4598,7 @@
 void dw_container_insert(HWND handle, void *pointer, int rowcount)
 {
 	RECORDINSERT recin;
+	ContainerInfo *ci = (ContainerInfo *)pointer;
 
 	recin.cb = sizeof(RECORDINSERT);
 	recin.pRecordOrder = (PRECORDCORE)CMA_END;
@@ -4442,7 +4607,7 @@
 	recin.fInvalidateRecord = TRUE;
 	recin.cRecordsInsert = rowcount;
 
-	WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pointer), MPFROMP(&recin));
+	WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin));
 }
 
 /*
@@ -4456,6 +4621,49 @@
 }
 
 /*
+ * 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 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)
+	{
+		prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
+		current++;
+	}
+	WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE));
+	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 dw_container_scroll(HWND handle, int direction, long rows)
+{
+	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;
+	}
+}
+
+/*
  * Removes all rows from a container.
  * Parameters:
  *       handle: Handle to the window (widget) to be cleared.
--- a/win/dw.c	Fri Jul 27 07:12:35 2001 +0000
+++ b/win/dw.c	Thu Aug 02 09:57:21 2001 +0000
@@ -37,7 +37,7 @@
 
 #define ICON_INDEX_LIMIT 200
 HICON lookup[200];
-HIMAGELIST hSmall, hLarge;
+HIMAGELIST hSmall  = 0, hLarge = 0;
 
 #define THREAD_LIMIT 128
 COLORREF _foreground[THREAD_LIMIT];
@@ -72,6 +72,7 @@
 };
 
 void _resize_notebook_page(HWND handle, int pageid);
+int _lookup_icon(HWND handle, HICON hicon, int type);
 
 #ifdef NO_SIGNALS
 #define USE_FILTER
@@ -672,6 +673,18 @@
 				thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))))/((float)(thisbox->minheight-((thisbox->items[z].pad*2)+(thisbox->parentpad*2))));
 			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 *)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA);
+
+				if(tmp)
+				{
+					tmp->parentxratio = thisbox->items[z].xratio;
+					tmp->parentyratio = thisbox->items[z].yratio;
+				}
+			}
+
 #ifdef DWDEBUG
 			fprintf(f, "RATIO- xratio = %f, yratio = %f, width = %d, height = %d, pad = %d, box xratio = %f, box yratio = %f, parent xratio = %f, parent yratio = %f, minwidth = %d, minheight = %d, width = %d, height = %d, upx = %d, upy = %d\r\n\r\n",
 					thisbox->items[z].xratio, thisbox->items[z].yratio, thisbox->items[z].width, thisbox->items[z].height, thisbox->items[z].pad, thisbox->xratio, thisbox->yratio, thisbox->parentxratio, thisbox->parentyratio, thisbox->minwidth, thisbox->minheight, thisbox->width, thisbox->height, thisbox->upx, thisbox->upy);
@@ -1235,8 +1248,54 @@
 		EnumChildWindows(hWnd, _free_window_memory, 0);
 #endif
 		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 *)GetWindowLong((HWND)mp2, GWL_USERDATA);
+				if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
+				{
+					if(thiscinfo->fore > -1 && thiscinfo->back > -1 &&
+					   thiscinfo->fore < 18 && thiscinfo->back < 18)
+					{
+						SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
+												   _green[thiscinfo->fore],
+											   _blue[thiscinfo->fore]));
+						SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
+												 _green[thiscinfo->back],
+												 _blue[thiscinfo->back]));
+						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;
+					}
+					if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & 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)));
+						SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
+												 DW_GREEN_VALUE(thiscinfo->back),
+												 DW_BLUE_VALUE(thiscinfo->back)));
+						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(filterfunc && result != -1)
+	if(result != -1)
 		return result;
 	else
 		return DefWindowProc(hWnd, msg, mp1, mp2);
@@ -1407,6 +1466,7 @@
 		case WM_CTLCOLOREDIT:
 		case WM_CTLCOLORMSGBOX:
 		case WM_CTLCOLORSCROLLBAR:
+		case WM_CTLCOLORDLG:
 			{
 				ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong((HWND)mp2, GWL_USERDATA);
 				if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
@@ -1420,8 +1480,12 @@
 						SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
 												 _green[thiscinfo->back],
 												 _blue[thiscinfo->back]));
-						SelectObject((HDC)mp1, _colors[thiscinfo->back]);
-						return (LONG)_colors[thiscinfo->back];
+						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;
 					}
 					if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
 					{
@@ -1805,7 +1869,8 @@
 
 			dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy);
 
-			_hBrush[threadid] = GetStockObject(LTGRAY_BRUSH);
+ 
+			_hBrush[threadid] = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
 
 			dw_draw_rect(hwnd, 0, TRUE, 0, 0, cx, cy);
 
@@ -1839,6 +1904,7 @@
 
 			SelectObject(hdcPaint, hFont);
 
+			DeleteObject(_hBrush[threadid]);
 			_hBrush[threadid] = oldBrush;
 			_hPen[threadid] = oldPen;
 			ReleaseDC(hwnd, hdcPaint);
@@ -2179,6 +2245,17 @@
 		_hBrush[z] = CreateSolidBrush(_foreground[z]);
 	}
 
+#if 0
+	{
+		DWORD dwResult = GetSysColor(COLOR_3DFACE);
+ 
+		dw_messagebox("DW",
+					  "Window color: {%x, %x, %x}",
+					  GetRValue(dwResult),
+					  GetGValue(dwResult),
+					  GetBValue(dwResult));
+	}
+#endif
 	return 0;
 }
 
@@ -2305,7 +2382,7 @@
  */
 int dw_yesno(char *title, char *text)
 {
-	if(MessageBox(HWND_DESKTOP, text, title, MB_YESNO)==IDYES)
+	if(MessageBox(HWND_DESKTOP, text, title, MB_YESNO) == IDYES)
 		return TRUE;
 	return FALSE;
 }
@@ -2520,6 +2597,17 @@
 }
 
 /*
+ * Changes the appearance of the mouse pointer.
+ * Parameters:
+ *       handle: Handle to widget for which to change.
+ *       cursortype: ID of the pointer you want.
+ */
+void dw_window_pointer(HWND handle, int pointertype)
+{
+	SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(pointertype)));
+}
+
+/*
  * Create a new Window Frame.
  * Parameters:
  *       owner: The Owner's window handle or HWND_DESKTOP.
@@ -2891,6 +2979,29 @@
 }
 
 /*
+ * Create a tree object to be packed.
+ * Parameters:
+ *       id: An ID to be used for getting the resource from the
+ *           resource file.
+ */
+HWND dw_tree_new(ULONG id)
+{
+	HWND tmp = CreateWindow(WC_TREEVIEW,
+							"",
+							WS_CHILD | TVS_HASLINES |
+							TVS_HASBUTTONS | TVS_LINESATROOT |
+							WS_BORDER | WS_CLIPCHILDREN,
+							0,0,2000,1000,
+							DW_HWND_OBJECT,
+							(HMENU)id,
+							NULL,
+							NULL);
+	TreeView_SetItemHeight(tmp, 16);
+	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.
@@ -2970,7 +3081,7 @@
     
 	HWND tmp = CreateWindow(EDITCLASSNAME,
 							"",
-							WS_BORDER | ES_AUTOHSCROLL |
+							WS_BORDER |
 							WS_VSCROLL | ES_MULTILINE |
 							ES_WANTRETURN | WS_CHILD |
 							WS_CLIPCHILDREN,
@@ -4144,6 +4255,13 @@
  */
 void 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);
 }
 
 /*
@@ -4334,6 +4452,34 @@
 }
 
 /*
+ * 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.
+ */
+HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent)
+{
+	TVITEM tvi;
+	TVINSERTSTRUCT tvins;
+	HTREEITEM hti;
+
+	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);
+
+	tvins.item = tvi;
+	tvins.hParent = (HTREEITEM)parent;
+	tvins.hInsertAfter = TVI_LAST;
+
+	hti = TreeView_InsertItem(handle, &tvins);
+
+	return (HWND)hti;
+}
+
+/*
  * Sets up the container columns.
  * Parameters:
  *          handle: Handle to the container to be configured.
@@ -4434,6 +4580,8 @@
 
 	lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT;
 	lvi.iSubItem = 0;
+	/* Insert at the end */
+	lvi.iItem = 1000000;
 	lvi.pszText = "";
 	lvi.cchTextMax = 1;
 
@@ -4445,12 +4593,12 @@
 /* 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 _lookup_icon(HWND handle, HICON hicon, int type)
 {
 	int z;
 	static HWND lasthwnd = NULL;
 
-	if(!lookup[0])
+	if(!hSmall || !hLarge)
 	{
 		hSmall = ImageList_Create(16, 16, FALSE, ICON_INDEX_LIMIT, 0);
 		hLarge = ImageList_Create(32, 32, FALSE, ICON_INDEX_LIMIT, 0);
@@ -4462,8 +4610,15 @@
 			lookup[z] = hicon;
 			ImageList_AddIcon(hSmall, hicon);
 			ImageList_AddIcon(hLarge, hicon);
-			ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-			ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+			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;
 		}
@@ -4472,8 +4627,15 @@
 		{
 			if(lasthwnd != handle)
 			{
-				ListView_SetImageList(handle, hSmall, LVSIL_SMALL);
-				ListView_SetImageList(handle, hLarge, LVSIL_NORMAL);
+				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;
@@ -4500,7 +4662,7 @@
 	lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE | LVIF_TEXT;
 	lvi.pszText = filename;
 	lvi.cchTextMax = strlen(filename);
-	lvi.iImage = _lookup_icon(handle, (HICON)icon);
+	lvi.iImage = _lookup_icon(handle, (HICON)icon, 0);
 
 	ListView_SetItem(handle, &lvi);
 }
@@ -4551,12 +4713,16 @@
 		lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE;
 		lvi.pszText = NULL;
 		lvi.cchTextMax = 0;
-		lvi.iImage = _lookup_icon(handle, hicon);
+
+		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;
@@ -4590,7 +4756,19 @@
 		lvi.cchTextMax = strlen(textbuffer);
 	}
 
-	ListView_SetItemText(handle, row, column, destptr);
+	ListView_SetItem(handle, &lvi);
+}
+
+/*
+ * 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 dw_container_set_column_width(HWND handle, int column, int width)
+{
+	ListView_SetColumnWidth(handle, column, width);
 }
 
 /*
@@ -4634,14 +4812,47 @@
  */
 void dw_container_clear(HWND handle)
 {
-	/* May need to delete manually so I can
-	 * remove the memory allocated for the
-	 * lParam field.
-	 */
 	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 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 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;
+	}
+}
+
+/*
  * Removes all rows from a container.
  * Parameters:
  *       handle: Handle to the window (widget) to be cleared.