changeset 167:0b3debaa9c6c

Added new container functions, and fixed resource leaks.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Tue, 26 Nov 2002 07:10:37 +0000
parents fb2987817924
children 627e531ca530
files dw.def dw.h dww.def gtk/dw.c os2/dw.c win/dw.c
diffstat 6 files changed, 376 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/dw.def	Tue Nov 19 20:27:45 2002 +0000
+++ b/dw.def	Tue Nov 26 07:10:37 2002 +0000
@@ -133,6 +133,8 @@
   dw_container_set_column_width          @232
   dw_container_cursor                    @233
   dw_container_optimize                  @234
+  dw_container_delete_row                @235
+  dw_container_change_item               @236
 
   dw_filesystem_setup                    @240
   dw_filesystem_set_item                 @241
--- a/dw.h	Tue Nov 19 20:27:45 2002 +0000
+++ b/dw.h	Tue Nov 26 07:10:37 2002 +0000
@@ -709,6 +709,7 @@
 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_change_item(HWND handle, 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);
@@ -719,6 +720,7 @@
 char *dw_container_query_next(HWND handle, unsigned long flags);
 void dw_container_scroll(HWND handle, int direction, long rows);
 void dw_container_cursor(HWND handle, char *text);
+void dw_container_delete_row(HWND handle, char *text);
 void dw_container_optimize(HWND handle);
 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);
--- a/dww.def	Tue Nov 19 20:27:45 2002 +0000
+++ b/dww.def	Tue Nov 26 07:10:37 2002 +0000
@@ -130,6 +130,8 @@
   dw_container_set_column_width          @232
   dw_container_cursor                    @233
   dw_container_optimize                  @234
+  dw_container_delete_row                @235
+  dw_container_change_item               @236
 
   dw_filesystem_setup                    @240
   dw_filesystem_set_item                 @241
--- a/gtk/dw.c	Tue Nov 19 20:27:45 2002 +0000
+++ b/gtk/dw.c	Tue Nov 26 07:10:37 2002 +0000
@@ -4145,6 +4145,19 @@
 }
 
 /*
+ * 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 dw_container_change_item(HWND handle, int column, int row, void *data)
+{
+	dw_container_set_item(handle, NULL, column, row, data);
+}
+
+/*
  * Sets an item in specified row and column to the given data.
  * Parameters:
  *          handle: Handle to the container window (widget).
@@ -4495,6 +4508,49 @@
 }
 
 /*
+ * Deletes the item with the text speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       text:  Text usually returned by dw_container_query().
+ */
+void dw_container_delete_row(HWND handle, char *text)
+{
+	int _locked_by_me = FALSE;
+	GtkWidget *clist;
+	int rowcount, z;
+	char *rowdata;
+
+	DW_MUTEX_LOCK;
+	clist = (GtkWidget*)gtk_object_get_user_data(GTK_OBJECT(handle));
+
+	if(!clist)
+	{
+		DW_MUTEX_UNLOCK;
+		return;
+	}
+	rowcount = (int)gtk_object_get_data(GTK_OBJECT(clist), "rowcount");
+
+	for(z=0;z<rowcount;z++)
+	{
+		rowdata = gtk_clist_get_row_data(GTK_CLIST(clist), z);
+		if(rowdata == text)
+		{
+			_dw_unselect(clist);
+
+			gtk_clist_remove(GTK_CLIST(clist), z);
+
+			rowcount--;
+
+			gtk_object_set_data(GTK_OBJECT(clist), "rowcount", (gpointer)rowcount);
+			DW_MUTEX_UNLOCK;
+			return;
+		}
+	}
+
+	DW_MUTEX_UNLOCK;
+}
+
+/*
  * Optimizes the column widths so that all data is visible.
  * Parameters:
  *       handle: Handle to the window (widget) to be optimized.
--- a/os2/dw.c	Tue Nov 19 20:27:45 2002 +0000
+++ b/os2/dw.c	Tue Nov 26 07:10:37 2002 +0000
@@ -28,6 +28,7 @@
 
 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);
 
 char ClassName[] = "dynamicwindows";
 char SplitbarClassName[] = "dwsplitbar";
@@ -220,20 +221,6 @@
 	return;
 }
 
-void _disconnect_windows(HWND handle)
-{
-	HENUM henum;
-	HWND child;
-
-	dw_signal_disconnect_by_window(handle);
-
-	henum = WinBeginEnumWindows(handle);
-	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-		_disconnect_windows(child);
-
-	WinEndEnumWindows(henum);
-}
-
 /* This function removes and handlers on windows and frees
  * the user memory allocated to it.
  */
@@ -1186,6 +1173,20 @@
 									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,
@@ -1439,23 +1440,22 @@
 		{
 		case WM_CONTEXTMENU:
 			{
-				HWND menuitem;
 				HMENUI hwndMenu = dw_menu_new(0L);
 				long x, y;
 
 				if(strncmp(tmpbuf, "#10", 4)==0 && !WinSendMsg(hWnd, MLM_QUERYREADONLY, 0, 0))
 				{
-					menuitem = dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, FALSE, 0L);
+					dw_menu_append_item(hwndMenu, "Undo", ENTRY_UNDO, 0L, TRUE, FALSE, 0L);
 					dw_menu_append_item(hwndMenu, "", 0L, 0L, TRUE, FALSE, 0L);
 				}
-				menuitem = dw_menu_append_item(hwndMenu, "Copy", ENTRY_COPY, 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)))
 				{
-					menuitem = dw_menu_append_item(hwndMenu, "Cut", ENTRY_CUT, 0L, TRUE, FALSE, 0L);
-					menuitem = dw_menu_append_item(hwndMenu, "Paste", ENTRY_PASTE, 0L, TRUE, FALSE, 0L);
+					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);
-				menuitem = dw_menu_append_item(hwndMenu, "Select All", ENTRY_SALL, 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);
@@ -1537,7 +1537,7 @@
 		_run_event(hWnd, msg, mp1, mp2);
 		break;
 	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == TRUE)
+		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
 			return (MRESULT)TRUE;
 		if(SHORT1FROMMP(mp2) == '\t')
 		{
@@ -1591,7 +1591,7 @@
 		_run_event(hWnd, msg, mp1, mp2);
 		break;
 	case WM_CHAR:
-		if(_run_event(hWnd, msg, mp1, mp2) == TRUE)
+		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)
@@ -1726,7 +1726,7 @@
 	case WM_BUTTON1DOWN:
 	case WM_BUTTON2DOWN:
 	case WM_BUTTON3DOWN:
-		if(_run_event(hWnd, msg, mp1, mp2) == TRUE)
+		if(_run_event(hWnd, msg, mp1, mp2) == (MRESULT)TRUE)
 			return (MRESULT)TRUE;
 		_run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE);
 		break;
@@ -2410,44 +2410,56 @@
 	{
 		int newx = x - SPLITBAR_WIDTH;
 		float ratio = (float)percent/(float)100.0;
-		HWND handle = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		Box *tmp = WinQueryWindowPtr(handle, QWP_USER);
+		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);
 
-		WinSetWindowPos(handle, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+		WinSetWindowPos(handle1, NULLHANDLE, 0, 0, newx, y, SWP_MOVE | SWP_SIZE);
 		_do_resize(tmp, newx, y);
 
 		dw_window_set_data(hwnd, "_dw_start", (void *)newx);
 
-		handle = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		tmp = WinQueryWindowPtr(handle, QWP_USER);
+		tmp = WinQueryWindowPtr(handle2, QWP_USER);
 
 		newx = x - newx - SPLITBAR_WIDTH;
 
-		WinSetWindowPos(handle, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+		WinSetWindowPos(handle2, NULLHANDLE, x - newx, 0, newx, y, SWP_MOVE | SWP_SIZE);
 		_do_resize(tmp, newx, y);
+
+		WinShowWindow(handle1, TRUE);
+		WinShowWindow(handle2, TRUE);
 	}
 	else
 	{
 		int newy = y - SPLITBAR_WIDTH;
 		float ratio = (float)percent/(float)100.0;
-		HWND handle = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		Box *tmp = WinQueryWindowPtr(handle, QWP_USER);
+		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);
 
-		WinSetWindowPos(handle, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+		WinSetWindowPos(handle1, NULLHANDLE, 0, y - newy, x, newy, SWP_MOVE | SWP_SIZE);
 		_do_resize(tmp, x, newy);
 
-		handle = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		tmp = WinQueryWindowPtr(handle, QWP_USER);
+		tmp = WinQueryWindowPtr(handle2, QWP_USER);
 
 		newy = y - newy - SPLITBAR_WIDTH;
 
-		WinSetWindowPos(handle, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE | SWP_SHOW);
+		WinSetWindowPos(handle2, NULLHANDLE, 0, 0, x, newy, SWP_MOVE | SWP_SIZE);
 		_do_resize(tmp, x, newy);
 
+		WinShowWindow(handle1, TRUE);
+		WinShowWindow(handle2, TRUE);
+
 		dw_window_set_data(hwnd, "_dw_start", (void *)newy);
 	}
 }
@@ -2466,26 +2478,31 @@
 	case WM_SETFOCUS:
 		return (MRESULT)(FALSE);
 
-	case WM_SIZE:
-		{
-			int x = SHORT1FROMMP(mp2), y = SHORT2FROMMP(mp2);
-
-			if(x > 0 && y > 0 && percent)
-				_handle_splitbar_resize(hwnd, *percent, type, x, y);
-		}
-		break;
 	case WM_PAINT:
 		{
 			HPS hps;
+			POINTL ptl[2];
 			RECTL rcl;
-			POINTL ptl[2];
 
 			hps = WinBeginPaint(hwnd, 0, 0);
+
 			WinQueryWindowRect(hwnd, &rcl);
-			ptl[0].x = rcl.xLeft;
-			ptl[0].y = rcl.yBottom;
-			ptl[1].x = rcl.xRight;
-			ptl[1].y = rcl.yTop;
+
+			if(type == BOXHORZ)
+			{
+				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]);
@@ -3234,8 +3251,8 @@
 		thisbox->items = tmpitem;
 		free(thisitem);
 		thisbox->count--;
-	}
-	_disconnect_windows(handle);
+		_free_window_memory(handle);
+	}
 	return WinDestroyWindow(handle);
 }
 
@@ -3245,7 +3262,8 @@
  */
 void dw_window_redraw(HWND handle)
 {
-	HWND window = WinWindowFromID(handle, FID_CLIENT);
+	HWND client = WinWindowFromID(handle, FID_CLIENT);
+	HWND window = client ? client : handle;
 	Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
 
 	if(window && mybox)
@@ -3254,9 +3272,9 @@
 
 		dw_window_get_pos_size(window, NULL, NULL, &width, &height);
 
-		WinShowWindow(mybox->items[0].hwnd, FALSE);
+		WinShowWindow(client ? mybox->items[0].hwnd : handle, FALSE);
 		_do_resize(mybox, width, height);
-		WinShowWindow(mybox->items[0].hwnd, TRUE);
+		WinShowWindow(client ? mybox->items[0].hwnd : handle, TRUE);
 	}
 }
 
@@ -5632,33 +5650,18 @@
 	return (void *)ci;
 }
 
-/*
- * 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 dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data)
+/* 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;
-	ContainerInfo *ci = (ContainerInfo *)pointer;
-	PRECORDCORE temp;
 	CNRINFO cnr;
     void *dest;
 
-	if(!ci)
-		return;
-
 	if(!flags)
 		return;
 
-	temp = (PRECORDCORE)ci->data;
-
 	z = 0;
 
 	while(WinSendMsg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO))) == 0)
@@ -5713,6 +5716,51 @@
  *          row: Zero based row of data being set.
  *          data: Pointer to the data to be added.
  */
+void 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 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, row, 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 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);
@@ -6002,6 +6050,27 @@
 }
 
 /*
+ * Deletes the item with the text speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       text:  Text usually returned by dw_container_query().
+ */
+void 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.
--- a/win/dw.c	Tue Nov 19 20:27:45 2002 +0000
+++ b/win/dw.c	Tue Nov 26 07:10:37 2002 +0000
@@ -59,6 +59,7 @@
 
 
 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);
 
 typedef struct _sighandler
@@ -322,6 +323,52 @@
 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam)
 {
 	ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong(handle, GWL_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, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) /* Notebook */
+	{
+		NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA);
+
+		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]);
+				}
+			}
+		}
+	}
 
 	dw_signal_disconnect_by_window(handle);
 
@@ -336,9 +383,7 @@
 			dw_window_set_data(handle, NULL, NULL);
 
 		SetWindowLong(handle, GWL_USERDATA, 0);
-#if 0
 		free(thiscinfo);
-#endif
 	}
 	return TRUE;
 }
@@ -1006,7 +1051,7 @@
 				{
 					/* Handle special case Combobox */
 					MoveWindow(handle, currentx + pad, currenty + pad,
-							   width + vectorx, (height + vectory) + 400, TRUE);
+							   width + vectorx, (height + vectory) + 400, FALSE);
 				}
 				else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0)
 				{
@@ -1014,14 +1059,28 @@
 					ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA);
 
 					MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad,
-							   20, height + vectory, TRUE);
+							   20, height + vectory, FALSE);
 
 					if(cinfo)
 					{
 						MoveWindow(cinfo->buddy, currentx + pad, currenty + pad,
-								   (width + vectorx) - 20, height + vectory, TRUE);
+								   (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 */
@@ -1041,26 +1100,26 @@
 						diff = (total - textheight) / 2;
 
 						MoveWindow(handle, currentx + pad, currenty + pad + diff,
-								   width + vectorx, height + vectory - diff, TRUE);
+								   width + vectorx, height + vectory - diff, FALSE);
 					}
 					else
 					{
 						MoveWindow(handle, currentx + pad, currenty + pad,
-								   width + vectorx, height + vectory, TRUE);
+								   width + vectorx, height + vectory, FALSE);
 					}
 				}
 				else
 				{
 					/* Everything else */
 					MoveWindow(handle, currentx + pad, currenty + pad,
-							   width + vectorx, height + vectory, TRUE);
+							   width + vectorx, height + vectory, FALSE);
 					if(thisbox->items[z].type == TYPEBOX)
 					{
 						Box *boxinfo = (Box *)GetWindowLong(handle, GWL_USERDATA);
 
 						if(boxinfo && boxinfo->grouphwnd)
 							MoveWindow(boxinfo->grouphwnd, 0, 0,
-									   width + vectorx, height + vectory, TRUE);
+									   width + vectorx, height + vectory, FALSE);
 
 					}
 				}
@@ -1077,7 +1136,7 @@
 						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);
+								   rect.right - rect.left, rect.bottom-rect.top, FALSE);
 					}
 				}
 
@@ -2247,44 +2306,56 @@
 	{
 		int newx = x - SPLITBAR_WIDTH, newy = y;
 		float ratio = (float)percent/(float)100.0;
-		HWND handle = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		Box *tmp = (Box *)GetWindowLong(handle, GWL_USERDATA);
+		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+		Box *tmp = (Box *)GetWindowLong(handle1, GWL_USERDATA);
 
 		newx = (int)((float)newx * ratio);
 
-		SetWindowPos(handle, (HWND)NULL, 0, 0, newx, y, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+		ShowWindow(handle1, SW_HIDE);
+		ShowWindow(handle2, SW_HIDE);
+
+		MoveWindow(handle1, 0, 0, newx, y, FALSE);
 		_do_resize(tmp, newx, y);
 
-		handle = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		tmp = (Box *)GetWindowLong(handle, GWL_USERDATA);
+		tmp = (Box *)GetWindowLong(handle2, GWL_USERDATA);
 
 		newx = x - newx - SPLITBAR_WIDTH;
 
-		SetWindowPos(handle, (HWND)NULL, x - newx, 0, newx, y, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+		MoveWindow(handle2, x - newx, 0, newx, y, FALSE);
 		_do_resize(tmp, newx, y);
 
+		ShowWindow(handle1, SW_SHOW);
+		ShowWindow(handle2, SW_SHOW);
+
 		dw_window_set_data(hwnd, "_dw_start", (void *)newx);
 	}
 	else
 	{
 		int newx = x, newy = y - SPLITBAR_WIDTH;
 		float ratio = (float)(100.0-percent)/(float)100.0;
-		HWND handle = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
-		Box *tmp = (Box *)GetWindowLong(handle, GWL_USERDATA);
+		HWND handle1 = (HWND)dw_window_get_data(hwnd, "_dw_bottomright");
+		HWND handle2 = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
+		Box *tmp = (Box *)GetWindowLong(handle1, GWL_USERDATA);
 
 		newy = (int)((float)newy * ratio);
 
-		SetWindowPos(handle, (HWND)NULL, 0, y - newy, x, newy, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+		ShowWindow(handle1, SW_HIDE);
+		ShowWindow(handle2, SW_HIDE);
+
+		MoveWindow(handle1, 0, y - newy, x, newy, FALSE);
 		_do_resize(tmp, x, newy);
 
-		handle = (HWND)dw_window_get_data(hwnd, "_dw_topleft");
-		tmp = (Box *)GetWindowLong(handle, GWL_USERDATA);
+		tmp = (Box *)GetWindowLong(handle2, GWL_USERDATA);
 
 		newy = y - newy - SPLITBAR_WIDTH;
 
-		SetWindowPos(handle, (HWND)NULL, 0, 0, x, newy, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE);
+		MoveWindow(handle2, 0, 0, x, newy, FALSE);
 		_do_resize(tmp, x, newy);
 
+		ShowWindow(handle1, SW_SHOW);
+		ShowWindow(handle2, SW_SHOW);
+
 		dw_window_set_data(hwnd, "_dw_start", (void *)newy);
 	}
 }
@@ -2302,13 +2373,32 @@
 	case WM_SETFOCUS:
 		return FALSE;
 
-	case WM_SIZE:
+	case WM_PAINT:
 		{
-			int x = LOWORD(mp2), y = HIWORD(mp2);
-
-			if(x > 0 && y > 0 && percent)
-				_handle_splitbar_resize(hwnd, *percent, type, x, y);
-    	}
+			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 == BOXHORZ)
+					Rectangle(hdcPaint, cx - start - 3, 0, cx - start, cy);
+				else
+					Rectangle(hdcPaint, 0, start, cx, start + 3);
+
+				SelectObject(hdcPaint, oldBrush);
+				DeleteObject(SelectObject(hdcPaint, oldPen));
+				ReleaseDC(hwnd, hdcPaint);
+			}
+			EndPaint(hwnd, &ps);
+		}
 		break;
 	case WM_LBUTTONDOWN:
 		{
@@ -2747,7 +2837,7 @@
 	wc.lpfnWndProc = (WNDPROC)_splitwndproc;
 	wc.cbClsExtra = 0;
 	wc.cbWndExtra = 0;
-	wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_3DFACE);
+	wc.hbrBackground = NULL;
 	wc.lpszMenuName = NULL;
 	wc.lpszClassName = SplitbarClassName;
 
@@ -3052,6 +3142,8 @@
 		thisbox->items = tmpitem;
 		free(thisitem);
 		thisbox->count--;
+		_free_window_memory(handle, 0);
+		EnumChildWindows(handle, _free_window_memory, 0);
 	}
 	return DestroyWindow(handle);
 }
@@ -3067,12 +3159,13 @@
 	if(mybox)
 	{
 		RECT rect;
+		int istoplevel = (GetParent(handle) == HWND_DESKTOP);
 
 		GetClientRect(handle, &rect);
 
-		ShowWindow(mybox->items[0].hwnd, SW_HIDE);
+		ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_HIDE);
 		_do_resize(mybox, rect.right - rect.left, rect.bottom - rect.top);
-		ShowWindow(mybox->items[0].hwnd, SW_SHOW);
+		ShowWindow(istoplevel ? mybox->items[0].hwnd : handle, SW_SHOW);
 	}
 }
 
@@ -3141,6 +3234,7 @@
  */
 int 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;
 
@@ -3165,6 +3259,8 @@
 		}
 	}
 	SendMessage(handle, WM_SETFONT, (WPARAM)hfont, (LPARAM)TRUE);
+	if(oldfont)
+		DeleteObject(oldfont);
 	return 0;
 }
 
@@ -4171,10 +4267,14 @@
 void dw_window_set_bitmap(HWND handle, ULONG id)
 {
 	HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id));
+	HBITMAP oldbitmap = (HBITMAP)SendMessage(handle, STM_GETIMAGE, IMAGE_BITMAP, 0);
 
 	SendMessage(handle, STM_SETIMAGE,
 				(WPARAM) IMAGE_BITMAP,
 				(LPARAM) hbitmap);
+
+	if(oldbitmap)
+		DeleteObject(oldbitmap);
 }
 
 /*
@@ -5758,6 +5858,19 @@
 }
 
 /*
+ * 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 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.
@@ -5949,6 +6062,37 @@
 }
 
 /*
+ * Deletes the item with the text speficied.
+ * Parameters:
+ *       handle: Handle to the window (widget).
+ *       text:  Text usually returned by dw_container_query().
+ */
+void 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.