comparison win/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
comparison
equal deleted inserted replaced
53:8add9a616d0e 54:c4e1139d9872
1152 } 1152 }
1153 } 1153 }
1154 break; 1154 break;
1155 case WM_NOTIFY: 1155 case WM_NOTIFY:
1156 { 1156 {
1157 if(tmp->message == TVN_SELCHANGED) 1157 if(tmp->message == TVN_SELCHANGED || tmp->message == NM_RCLICK)
1158 { 1158 {
1159 NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2; 1159 NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2;
1160 char tmpbuf[100]; 1160 char tmpbuf[100];
1161 1161
1162 GetClassName(tem->hdr.hwndFrom, tmpbuf, 99); 1162 GetClassName(tem->hdr.hwndFrom, tmpbuf, 99);
1163 1163
1164 if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0) 1164 if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0)
1165 { 1165 {
1166 if(tem->hdr.code == TVN_SELCHANGED) 1166 if(tem->hdr.code == TVN_SELCHANGED && tmp->message == TVN_SELCHANGED)
1167 { 1167 {
1168 if(tmp->window == tem->hdr.hwndFrom) 1168 if(tmp->window == tem->hdr.hwndFrom)
1169 { 1169 {
1170 int (*treeselectfunc)(HWND, HWND, char *, void *) = tmp->signalfunction; 1170 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction;
1171 TVITEM tvi; 1171 TVITEM tvi;
1172 void **ptrs;
1172 1173
1173 tvi.mask = TVIF_HANDLE; 1174 tvi.mask = TVIF_HANDLE;
1174 tvi.hItem = tem->itemNew.hItem; 1175 tvi.hItem = tem->itemNew.hItem;
1175 1176
1176 TreeView_GetItem(tmp->window, &tvi); 1177 TreeView_GetItem(tmp->window, &tvi);
1177 1178
1178 result = treeselectfunc(tmp->window, (HWND)tem->itemNew.hItem, (char *)tvi.lParam, tmp->data); 1179 ptrs = (void **)tvi.lParam;
1179 1180 if(ptrs)
1181 result = treeselectfunc(tmp->window, (HWND)tem->itemNew.hItem, (char *)ptrs[0], (void *)ptrs[1], tmp->data);
1182
1183 tmp = NULL;
1184 }
1185 }
1186 else if(tem->hdr.code == NM_RCLICK && tmp->message == NM_RCLICK)
1187 {
1188 if(tmp->window == tem->hdr.hwndFrom)
1189 {
1190 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction;
1191 HTREEITEM hti;
1192 TVITEM tvi;
1193 TVHITTESTINFO thi;
1194 void **ptrs = NULL;
1195 LONG x, y;
1196
1197 dw_pointer_query_pos(&x, &y);
1198
1199 thi.pt.x = x;
1200 thi.pt.y = y;
1201
1202 MapWindowPoints(HWND_DESKTOP, tmp->window, &thi.pt, 1);
1203
1204 hti = TreeView_HitTest(tmp->window, &thi);
1205
1206 if(hti)
1207 {
1208 tvi.mask = TVIF_HANDLE;
1209 tvi.hItem = hti;
1210
1211 TreeView_GetItem(tmp->window, &tvi);
1212 dw_tree_item_select(tmp->window, (HWND)hti);
1213
1214 ptrs = (void **)tvi.lParam;
1215
1216 }
1217 containercontextfunc(tmp->window, ptrs ? (char *)ptrs[0] : NULL, x, y, tmp->data, ptrs ? ptrs[1] : NULL);
1180 tmp = NULL; 1218 tmp = NULL;
1181 } 1219 }
1182 } 1220 }
1183 } 1221 }
1184 } 1222 }
1299 return 0; 1337 return 0;
1300 } 1338 }
1301 break; 1339 break;
1302 case WM_DESTROY: 1340 case WM_DESTROY:
1303 /* Free memory before destroying */ 1341 /* Free memory before destroying */
1304 #if 0
1305 /* Is this the right message? I seem to be
1306 * getting WM_DESTROY on windows that aren't
1307 * being destroyed.
1308 */
1309 _free_window_memory(hWnd, 0); 1342 _free_window_memory(hWnd, 0);
1310 EnumChildWindows(hWnd, _free_window_memory, 0); 1343 EnumChildWindows(hWnd, _free_window_memory, 0);
1311 #endif
1312 break; 1344 break;
1313 case WM_CTLCOLORSTATIC: 1345 case WM_CTLCOLORSTATIC:
1314 case WM_CTLCOLORLISTBOX: 1346 case WM_CTLCOLORLISTBOX:
1315 case WM_CTLCOLORBTN: 1347 case WM_CTLCOLORBTN:
1316 case WM_CTLCOLOREDIT: 1348 case WM_CTLCOLOREDIT:
1317 case WM_CTLCOLORMSGBOX: 1349 case WM_CTLCOLORMSGBOX:
1318 case WM_CTLCOLORSCROLLBAR: 1350 case WM_CTLCOLORSCROLLBAR:
1319 case WM_CTLCOLORDLG: 1351 case WM_CTLCOLORDLG:
1352 {
1353 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong((HWND)mp2, GWL_USERDATA);
1354 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1)
1320 { 1355 {
1321 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong((HWND)mp2, GWL_USERDATA); 1356 if(thiscinfo->fore > -1 && thiscinfo->back > -1 &&
1322 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1) 1357 thiscinfo->fore < 18 && thiscinfo->back < 18)
1323 { 1358 {
1324 if(thiscinfo->fore > -1 && thiscinfo->back > -1 && 1359 SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
1325 thiscinfo->fore < 18 && thiscinfo->back < 18) 1360 _green[thiscinfo->fore],
1326 {
1327 SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore],
1328 _green[thiscinfo->fore],
1329 _blue[thiscinfo->fore])); 1361 _blue[thiscinfo->fore]));
1330 SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back], 1362 SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back],
1331 _green[thiscinfo->back], 1363 _green[thiscinfo->back],
1332 _blue[thiscinfo->back])); 1364 _blue[thiscinfo->back]));
1333 DeleteObject(thiscinfo->hbrush); 1365 DeleteObject(thiscinfo->hbrush);
1334 thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back], 1366 thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back],
1335 _green[thiscinfo->back], 1367 _green[thiscinfo->back],
1336 _blue[thiscinfo->back])); 1368 _blue[thiscinfo->back]));
1337 SelectObject((HDC)mp1, thiscinfo->hbrush); 1369 SelectObject((HDC)mp1, thiscinfo->hbrush);
1338 return (LONG)thiscinfo->hbrush; 1370 return (LONG)thiscinfo->hbrush;
1339 } 1371 }
1340 if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR) 1372 if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR)
1341 { 1373 {
1342 SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore), 1374 SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore),
1343 DW_GREEN_VALUE(thiscinfo->fore), 1375 DW_GREEN_VALUE(thiscinfo->fore),
1344 DW_BLUE_VALUE(thiscinfo->fore))); 1376 DW_BLUE_VALUE(thiscinfo->fore)));
1345 SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back), 1377 SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back),
1346 DW_GREEN_VALUE(thiscinfo->back), 1378 DW_GREEN_VALUE(thiscinfo->back),
1347 DW_BLUE_VALUE(thiscinfo->back))); 1379 DW_BLUE_VALUE(thiscinfo->back)));
1348 DeleteObject(thiscinfo->hbrush); 1380 DeleteObject(thiscinfo->hbrush);
1349 thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back), 1381 thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back),
1350 DW_GREEN_VALUE(thiscinfo->back), 1382 DW_GREEN_VALUE(thiscinfo->back),
1351 DW_BLUE_VALUE(thiscinfo->back))); 1383 DW_BLUE_VALUE(thiscinfo->back)));
1352 SelectObject((HDC)mp1, thiscinfo->hbrush); 1384 SelectObject((HDC)mp1, thiscinfo->hbrush);
1353 return (LONG)thiscinfo->hbrush; 1385 return (LONG)thiscinfo->hbrush;
1354 }
1355 } 1386 }
1356
1357 } 1387 }
1358 break; 1388
1389 }
1390 break;
1359 } 1391 }
1360 if(result != -1) 1392 if(result != -1)
1361 return result; 1393 return result;
1362 else 1394 else
1363 return DefWindowProc(hWnd, msg, mp1, mp2); 1395 return DefWindowProc(hWnd, msg, mp1, mp2);
1570 if(cinfo) 1602 if(cinfo)
1571 { 1603 {
1572 switch( msg ) 1604 switch( msg )
1573 { 1605 {
1574 case WM_SETFOCUS: 1606 case WM_SETFOCUS:
1575 _wndproc(hWnd, msg, mp1, mp2); 1607 if(cinfo->combo)
1608 _wndproc(cinfo->combo, msg, mp1, mp2);
1609 else
1610 _wndproc(hWnd, msg, mp1, mp2);
1576 break; 1611 break;
1577 case WM_CHAR: 1612 case WM_CHAR:
1578 if(LOWORD(mp1) == '\t') 1613 if(LOWORD(mp1) == '\t')
1579 { 1614 {
1580 if(cinfo->combo) 1615 if(cinfo->combo)
1752 } 1787 }
1753 } 1788 }
1754 break; 1789 break;
1755 case WM_CONTEXTMENU: 1790 case WM_CONTEXTMENU:
1756 { 1791 {
1757 LONG x,y; 1792 SignalHandler *tmp = Root;
1758 LV_ITEM lvi; 1793
1759 int iItem; 1794 while(tmp)
1760
1761 iItem = ListView_GetNextItem(hWnd, -1, LVNI_FOCUSED);
1762
1763 if(iItem > -1)
1764 { 1795 {
1765 lvi.iItem = iItem; 1796 if(tmp->message == NM_RCLICK && tmp->window == hWnd)
1766 lvi.mask = LVIF_PARAM;
1767
1768 ListView_GetItem(hWnd, &lvi);
1769 }
1770 else
1771 lvi.lParam = (LPARAM)NULL;
1772
1773 dw_pointer_query_pos(&x, &y);
1774
1775 {
1776 SignalHandler *tmp = Root;
1777
1778 while(tmp)
1779 { 1797 {
1780 if(tmp->message == NM_RCLICK && tmp->window == hWnd) 1798 int (*containercontextfunc)(HWND, char *, int, int, void *) = tmp->signalfunction;
1799 LONG x,y;
1800 LV_ITEM lvi;
1801 int iItem;
1802 LVHITTESTINFO lhi;
1803
1804 dw_pointer_query_pos(&x, &y);
1805
1806 lhi.pt.x = x;
1807 lhi.pt.y = y;
1808
1809 MapWindowPoints(HWND_DESKTOP, tmp->window, &lhi.pt, 1);
1810
1811 iItem = ListView_HitTest(tmp->window, &lhi);
1812
1813 if(iItem > -1)
1781 { 1814 {
1782 int (*containercontextfunc)(HWND, char *, int, int, void *) = tmp->signalfunction; 1815 lvi.iItem = iItem;
1783 1816 lvi.mask = LVIF_PARAM;
1784 /* Seems to be having lParam as 1 which really sucks */ 1817
1785 if(lvi.lParam < 100) 1818 ListView_GetItem(tmp->window, &lvi);
1786 lvi.lParam = 0; 1819 ListView_SetSelectionMark(tmp->window, iItem);
1787
1788 containercontextfunc(tmp->window, (char *)lvi.lParam, x, y, tmp->data);
1789 tmp = NULL;
1790 } 1820 }
1791 if(tmp) 1821 else
1792 tmp = tmp->next; 1822 lvi.lParam = (LPARAM)NULL;
1823
1824 /* Seems to be having lParam as 1 which really sucks */
1825 if(lvi.lParam < 100)
1826 lvi.lParam = 0;
1827
1828 containercontextfunc(tmp->window, (char *)lvi.lParam, x, y, tmp->data);
1829 tmp = NULL;
1793 } 1830 }
1831 if(tmp)
1832 tmp = tmp->next;
1794 } 1833 }
1795 } 1834 }
1796 break; 1835 break;
1797 #else 1836 #else
1798 case WM_CHAR: 1837 case WM_CHAR:
2098 { 2137 {
2099 BubbleButton *bubble; 2138 BubbleButton *bubble;
2100 static int bMouseOver = 0; 2139 static int bMouseOver = 0;
2101 POINT point; 2140 POINT point;
2102 RECT rect; 2141 RECT rect;
2142 WNDPROC pOldProc;
2103 2143
2104 bubble = (BubbleButton *)GetWindowLong(hwnd, GWL_USERDATA); 2144 bubble = (BubbleButton *)GetWindowLong(hwnd, GWL_USERDATA);
2105 2145
2106 if(!bubble) 2146 if(!bubble)
2107 return DefWindowProc(hwnd, msg, mp1, mp2); 2147 return DefWindowProc(hwnd, msg, mp1, mp2);
2148
2149 /* We must save a pointer to the old
2150 * window procedure because if a signal
2151 * handler attached here destroys this
2152 * window it will then be invalid.
2153 */
2154 pOldProc = bubble->pOldProc;
2108 2155
2109 switch(msg) 2156 switch(msg)
2110 { 2157 {
2111 #ifndef NO_SIGNALS 2158 #ifndef NO_SIGNALS
2112 case WM_SETFOCUS: 2159 case WM_SETFOCUS:
2284 KillTimer(hwndBubbleLast, 1); 2331 KillTimer(hwndBubbleLast, 1);
2285 } 2332 }
2286 break; 2333 break;
2287 } 2334 }
2288 2335
2289 if(!bubble->pOldProc) 2336 if(!pOldProc)
2290 return DefWindowProc(hwnd, msg, mp1, mp2); 2337 return DefWindowProc(hwnd, msg, mp1, mp2);
2291 return CallWindowProc(bubble->pOldProc, hwnd, msg, mp1, mp2); 2338 return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2);
2292 } 2339 }
2293 2340
2294 /* This function recalculates a notebook page for example 2341 /* This function recalculates a notebook page for example
2295 * during switching of notebook pages. 2342 * during switching of notebook pages.
2296 */ 2343 */
2648 * Parameters: 2695 * Parameters:
2649 * handle: The window handle to destroy. 2696 * handle: The window handle to destroy.
2650 */ 2697 */
2651 int dw_window_destroy(HWND handle) 2698 int dw_window_destroy(HWND handle)
2652 { 2699 {
2700 HWND parent = GetParent(handle);
2701 Box *thisbox = (Box *)GetWindowLong(parent, GWL_USERDATA);
2702
2703 if(parent != HWND_DESKTOP && thisbox && thisbox->count)
2704 {
2705 int z, index = -1;
2706 Item *tmpitem, *thisitem = thisbox->items;
2707
2708 for(z=0;z<thisbox->count;z++)
2709 {
2710 if(thisitem[z].hwnd == handle)
2711 index = z;
2712 }
2713
2714 if(index == -1)
2715 return 0;
2716
2717 tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
2718
2719 /* Copy all but the current entry to the new list */
2720 for(z=0;z<index;z++)
2721 {
2722 tmpitem[z] = thisitem[z];
2723 }
2724 for(z=index+1;z<thisbox->count;z++)
2725 {
2726 tmpitem[z-1] = thisitem[z];
2727 }
2728
2729 thisbox->items = tmpitem;
2730 free(thisitem);
2731 thisbox->count--;
2732 }
2653 return DestroyWindow(handle); 2733 return DestroyWindow(handle);
2734 }
2735
2736 /* Causes entire window to be invalidated and redrawn.
2737 * Parameters:
2738 * handle: Toplevel window handle to be redrawn.
2739 */
2740 void dw_window_redraw(HWND handle)
2741 {
2742 Box *mybox = (Box *)GetWindowLong(handle, GWL_USERDATA);
2743
2744 if(mybox)
2745 {
2746 RECT rect;
2747
2748 GetClientRect(handle, &rect);
2749
2750 ShowWindow(mybox->items[0].hwnd, SW_HIDE);
2751 _do_resize(mybox, rect.right - rect.left, rect.bottom - rect.top);
2752 ShowWindow(mybox->items[0].hwnd, SW_SHOW);
2753 }
2654 } 2754 }
2655 2755
2656 /* 2756 /*
2657 * Changes a window's parent to newparent. 2757 * Changes a window's parent to newparent.
2658 * Parameters: 2758 * Parameters:
3400 DW_HWND_OBJECT, 3500 DW_HWND_OBJECT,
3401 (HMENU)id, 3501 (HMENU)id,
3402 NULL, 3502 NULL,
3403 NULL); 3503 NULL);
3404 ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo)); 3504 ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo));
3505 ColorInfo *cinfo2 = (ColorInfo *)calloc(1, sizeof(ColorInfo));
3405 3506
3406 if(!cinfo) 3507 if(!cinfo)
3407 { 3508 {
3408 DestroyWindow(tmp); 3509 DestroyWindow(tmp);
3409 return NULL; 3510 return NULL;
3410 } 3511 }
3411 3512
3412 cinfo->fore = -1; 3513 cinfo2->fore = cinfo->fore = -1;
3413 cinfo->back = -1; 3514 cinfo2->back = cinfo->back = -1;
3414 cinfo->combo = tmp; 3515 cinfo2->combo = cinfo->combo = tmp;
3415 EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo); 3516 EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo2);
3416 3517
3417 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); 3518 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo);
3418 dw_window_set_font(tmp, DefaultFont); 3519 dw_window_set_font(tmp, DefaultFont);
3419 return tmp; 3520 return tmp;
3420 } 3521 }
4698 * Parameters: 4799 * Parameters:
4699 * handle: Handle to the tree to be inserted. 4800 * handle: Handle to the tree to be inserted.
4700 * title: The text title of the entry. 4801 * title: The text title of the entry.
4701 * icon: Handle to coresponding icon. 4802 * icon: Handle to coresponding icon.
4702 * parent: Parent handle or 0 if root. 4803 * parent: Parent handle or 0 if root.
4703 */ 4804 * itemdata: Item specific data.
4704 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent) 4805 */
4806 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata)
4705 { 4807 {
4706 TVITEM tvi; 4808 TVITEM tvi;
4707 TVINSERTSTRUCT tvins; 4809 TVINSERTSTRUCT tvins;
4708 HTREEITEM hti; 4810 HTREEITEM hti;
4811 void **ptrs= malloc(sizeof(void *) * 2);
4812
4813 ptrs[0] = title;
4814 ptrs[1] = itemdata;
4709 4815
4710 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; 4816 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
4711 tvi.pszText = title; 4817 tvi.pszText = title;
4712 tvi.lParam = (LONG)title; 4818 tvi.lParam = (LONG)ptrs;
4713 tvi.cchTextMax = strlen(title); 4819 tvi.cchTextMax = strlen(title);
4714 tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1); 4820 tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
4715 4821
4716 tvins.item = tvi; 4822 tvins.item = tvi;
4717 tvins.hParent = (HTREEITEM)parent; 4823 tvins.hParent = (HTREEITEM)parent;
4721 4827
4722 return (HWND)hti; 4828 return (HWND)hti;
4723 } 4829 }
4724 4830
4725 /* 4831 /*
4832 * Sets the text and icon of an item in a tree window (widget).
4833 * Parameters:
4834 * handle: Handle to the tree containing the item.
4835 * item: Handle of the item to be modified.
4836 * title: The text title of the entry.
4837 * icon: Handle to coresponding icon.
4838 */
4839 void dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon)
4840 {
4841 TVITEM tvi;
4842 void **ptrs;
4843
4844 tvi.mask = TVIF_HANDLE;
4845 tvi.hItem = (HTREEITEM)item;
4846
4847 TreeView_GetItem(handle, &tvi);
4848
4849 ptrs = (void **)tvi.lParam;
4850 ptrs[0] = title;
4851
4852 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
4853 tvi.pszText = title;
4854 tvi.cchTextMax = strlen(title);
4855 tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1);
4856 tvi.hItem = (HTREEITEM)item;
4857
4858 TreeView_SetItem(handle, &tvi);
4859 }
4860
4861 /*
4862 * Sets the item data of a tree item.
4863 * Parameters:
4864 * handle: Handle to the tree containing the item.
4865 * item: Handle of the item to be modified.
4866 * itemdata: User defined data to be associated with item.
4867 */
4868 void dw_tree_set_data(HWND handle, HWND item, void *itemdata)
4869 {
4870 TVITEM tvi;
4871 void **ptrs;
4872
4873 tvi.mask = TVIF_HANDLE;
4874 tvi.hItem = (HTREEITEM)item;
4875
4876 TreeView_GetItem(handle, &tvi);
4877
4878 ptrs = (void **)tvi.lParam;
4879 ptrs[1] = itemdata;
4880 }
4881
4882 /*
4883 * Sets this item as the active selection.
4884 * Parameters:
4885 * handle: Handle to the tree window (widget) to be selected.
4886 * item: Handle to the item to be selected.
4887 */
4888 void dw_tree_item_select(HWND handle, HWND item)
4889 {
4890 TreeView_SelectItem(handle, (HTREEITEM)item);
4891 SetFocus(handle);
4892 }
4893
4894 /*
4726 * Removes all nodes from a tree. 4895 * Removes all nodes from a tree.
4727 * Parameters: 4896 * Parameters:
4728 * handle: Handle to the window (widget) to be cleared. 4897 * handle: Handle to the window (widget) to be cleared.
4729 */ 4898 */
4730 void dw_tree_clear(HWND handle) 4899 void dw_tree_clear(HWND handle)
4731 { 4900 {
4732 TreeView_DeleteAllItems(handle); 4901 TreeView_DeleteAllItems(handle);
4902 }
4903
4904 /*
4905 * Expands a node on a tree.
4906 * Parameters:
4907 * handle: Handle to the tree window (widget).
4908 * item: Handle to node to be expanded.
4909 */
4910 void dw_tree_expand(HWND handle, HWND item)
4911 {
4912 TreeView_Expand(handle, (HTREEITEM)item, TVE_EXPAND);
4913 }
4914
4915 /*
4916 * Collapses a node on a tree.
4917 * Parameters:
4918 * handle: Handle to the tree window (widget).
4919 * item: Handle to node to be collapsed.
4920 */
4921 void dw_tree_collapse(HWND handle, HWND item)
4922 {
4923 TreeView_Expand(handle, (HTREEITEM)item, TVE_COLLAPSE);
4733 } 4924 }
4734 4925
4735 /* 4926 /*
4736 * Removes a node from a tree. 4927 * Removes a node from a tree.
4737 * Parameters: 4928 * Parameters: