diff os2/dw.c @ 54:c4e1139d9872

Added new tree functions, and fixed a memory leak as well as use of invalid memory when a button destroys itself.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 17 Nov 2001 17:40:16 +0000
parents 0804483f6320
children b6948eac375a
line wrap: on
line diff
--- a/os2/dw.c	Tue Nov 13 11:14:00 2001 +0000
+++ b/os2/dw.c	Sat Nov 17 17:40:16 2001 +0000
@@ -106,7 +106,7 @@
 	{ CN_ENTER, "container-select" },
 	{ CN_CONTEXTMENU, "container-context" },
 	{ LN_SELECT, "item-select" },
-	{ WM_USER+1, "tree-select" },
+	{ CN_EMPHASIS, "tree-select" },
 	{ WM_SETFOCUS, "set-focus" }
 };
 
@@ -153,6 +153,15 @@
 }
 #endif
 
+typedef struct _CNRITEM
+{
+	MINIRECORDCORE rc;
+	HPOINTER       hptrIcon;
+	PVOID          user;
+
+} CNRITEM, *PCNRITEM;
+
+
 /* This function changes the owner of buttons in to the
  * dynamicwindows handle to fix a problem in notebooks.
  */
@@ -186,24 +195,22 @@
 {
 	HENUM henum;
 	HWND child;
+	void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
 
 #ifndef NO_SIGNALS
 	dw_signal_disconnect_by_window(handle);
 #endif
 
+	if(ptr)
+	{
+		WinSetWindowPtr(handle, QWP_USER, 0);
+		free(ptr);
+	}
+
 	henum = WinBeginEnumWindows(handle);
 	while((child = WinGetNextWindow(henum)) != NULLHANDLE)
-	{
-		void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
-
-		if(ptr)
-		{
-			WinSetWindowPtr(handle, QWP_USER, 0);
-			free(ptr);
-		}
-
 		_free_window_memory(child);
-	}
+
 	WinEndEnumWindows(henum);
 	return;
 }
@@ -1579,30 +1586,71 @@
 						break;
 					case CN_CONTEXTMENU:
 						{
-							int (*containercontextfunc)(HWND, char *, int, int, void *) = (int (*)(HWND, char *, int, int, void *))tmp->signalfunction;
+							int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (*)(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)
 							{
-								PRECORDCORE pre;
-
-								pre = (PRECORDCORE)mp2;
-								text = pre->pszIcon;
+								PCNRITEM pci;
+
+								pci = (PCNRITEM)mp2;
+
+								text = pci->rc.pszIcon;
+								user = pci->user;
 							}
 
-
 							dw_pointer_query_pos(&x, &y);
 
 							if(tmp->window == conthwnd)
 							{
-								result = containercontextfunc(tmp->window, text, x, y, tmp->data);
+								if(mp2)
+								{
+									NOTIFYRECORDEMPHASIS pre;
+
+									dw_tree_item_select(tmp->window, (HWND)mp2);
+									pre.pRecord = mp2;
+									pre.fEmphasisMask = CRA_CURSORED;
+									pre.hwndCnr = tmp->window;
+									_run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
+								}
+								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)
+										{
+											int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = (int (*)(HWND, HWND, char *, void *, void *))tmp->signalfunction;
+
+											result = treeselectfunc(tmp->window, (HWND)pci, pci->rc.pszIcon, pci->user, tmp->data);
+
+											tmp = NULL;
+										}
+									}
+								}
+								emph_recurse = 0;
+							}
+						}
+						break;
 					case LN_SELECT:
 						{
 							int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction;
@@ -1650,37 +1698,6 @@
 			}
 		}
 
-		if(tmp && origmsg == WM_BUTTON1DOWN)
-		{
-			if(tmp->message == WM_USER+1)
-			{
-				if(tmp->window == hWnd)
-				{
-					QUERYRECFROMRECT rc;
-					POINTS pts = (*((POINTS*)&mp1));
-					RECORDCORE *prc;
-
-					rc.cb = sizeof(QUERYRECFROMRECT);
-					rc.rect.xLeft = pts.x;
-					rc.rect.xRight = pts.x + 1;
-					rc.rect.yTop = pts.y;
-					rc.rect.yBottom = pts.y - 1;
-					rc.fsSearch = CMA_PARTIAL | CMA_ITEMORDER;
-
-					prc = (RECORDCORE *)WinSendMsg(hWnd, CM_QUERYRECORDFROMRECT, (MPARAM)CMA_FIRST, MPFROMP(&rc));
-
-					if(prc)
-					{
-						int (*treeselectfunc)(HWND, HWND, char *, void *) = (int (*)(HWND, HWND, char *, void *))tmp->signalfunction;
-
-						result = treeselectfunc(tmp->window, (HWND)prc, prc->pszIcon, tmp->data);
-
-						tmp = NULL;
-					}
-				}
-			}
-		}
-
 		if(tmp)
 			tmp = tmp->next;
 
@@ -2222,12 +2239,15 @@
 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)
 	{
 #ifndef NO_SIGNALS
@@ -2408,9 +2428,9 @@
 		break;
 	}
 
-	if(!bubble->pOldProc)
+	if(!oldproc)
 		return WinDefWindowProc(hwnd, msg, mp1, mp2);
-	return bubble->pOldProc(hwnd, msg, mp1, mp2);
+	return oldproc(hwnd, msg, mp1, mp2);
 }
 
 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
@@ -2731,9 +2751,67 @@
  */
 int dw_window_destroy(HWND handle)
 {
+	HWND parent = WinQueryWindow(handle, QW_PARENT);
+	Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
+
+	if(!handle)
+		return -1;
+
+	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);
 	return WinDestroyWindow(handle);
 }
 
+/* Causes entire window to be invalidated and redrawn.
+ * Parameters:
+ *           handle: Toplevel window handle to be redrawn.
+ */
+void dw_window_redraw(HWND handle)
+{
+	HWND window = WinWindowFromID(handle, FID_CLIENT);
+	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(mybox->items[0].hwnd, FALSE);
+		_do_resize(mybox, width, height);
+		WinShowWindow(mybox->items[0].hwnd, TRUE);
+	}
+}
+
 /*
  * Changes a window's parent to newparent.
  * Parameters:
@@ -4572,13 +4650,6 @@
 	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:
@@ -4586,8 +4657,9 @@
  *          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)
+ *          itemdata: Item specific data.
+ */
+HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata)
 {
 	ULONG        cbExtra;
 	PCNRITEM     pci;
@@ -4610,6 +4682,7 @@
 	pci->rc.hptrIcon    = icon;
 
 	pci->hptrIcon       = icon;
+	pci->user           = itemdata;
 
 	memset(&ri, 0, sizeof(RECORDINSERT));
 
@@ -4632,6 +4705,65 @@
 }
 
 /*
+ * 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 dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon)
+{
+	PCNRITEM pci = (PCNRITEM)item;
+
+	if(!pci)
+		return;
+
+	pci->rc.pszIcon     = title;
+	pci->rc.hptrIcon    = icon;
+
+	pci->hptrIcon       = icon;
+
+	WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
+}
+
+/*
+ * 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 dw_tree_set_data(HWND handle, HWND item, void *itemdata)
+{
+	PCNRITEM pci = (PCNRITEM)item;
+
+	if(!pci)
+		return;
+
+	pci->user = itemdata;
+}
+
+/*
+ * 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 dw_tree_item_select(HWND handle, HWND 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));
+}
+
+/*
  * Removes all nodes from a tree.
  * Parameters:
  *       handle: Handle to the window (widget) to be cleared.
@@ -4642,6 +4774,28 @@
 }
 
 /*
+ * Expands a node on a tree.
+ * Parameters:
+ *       handle: Handle to the tree window (widget).
+ *       item: Handle to node to be expanded.
+ */
+void dw_tree_expand(HWND handle, HWND 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 dw_tree_collapse(HWND handle, HWND item)
+{
+	WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
+}
+
+/*
  * Removes a node from a tree.
  * Parameters:
  *       handle: Handle to the window (widget) to be cleared.