comparison 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
comparison
equal deleted inserted replaced
53:8add9a616d0e 54:c4e1139d9872
104 { WM_PAINT, "expose_event" }, 104 { WM_PAINT, "expose_event" },
105 { WM_COMMAND, "clicked" }, 105 { WM_COMMAND, "clicked" },
106 { CN_ENTER, "container-select" }, 106 { CN_ENTER, "container-select" },
107 { CN_CONTEXTMENU, "container-context" }, 107 { CN_CONTEXTMENU, "container-context" },
108 { LN_SELECT, "item-select" }, 108 { LN_SELECT, "item-select" },
109 { WM_USER+1, "tree-select" }, 109 { CN_EMPHASIS, "tree-select" },
110 { WM_SETFOCUS, "set-focus" } 110 { WM_SETFOCUS, "set-focus" }
111 }; 111 };
112 112
113 /* This function adds a signal handler callback into the linked list. 113 /* This function adds a signal handler callback into the linked list.
114 */ 114 */
151 } 151 }
152 return 0L; 152 return 0L;
153 } 153 }
154 #endif 154 #endif
155 155
156 typedef struct _CNRITEM
157 {
158 MINIRECORDCORE rc;
159 HPOINTER hptrIcon;
160 PVOID user;
161
162 } CNRITEM, *PCNRITEM;
163
164
156 /* This function changes the owner of buttons in to the 165 /* This function changes the owner of buttons in to the
157 * dynamicwindows handle to fix a problem in notebooks. 166 * dynamicwindows handle to fix a problem in notebooks.
158 */ 167 */
159 void _fix_button_owner(HWND handle, HWND dw) 168 void _fix_button_owner(HWND handle, HWND dw)
160 { 169 {
184 */ 193 */
185 void _free_window_memory(HWND handle) 194 void _free_window_memory(HWND handle)
186 { 195 {
187 HENUM henum; 196 HENUM henum;
188 HWND child; 197 HWND child;
198 void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
189 199
190 #ifndef NO_SIGNALS 200 #ifndef NO_SIGNALS
191 dw_signal_disconnect_by_window(handle); 201 dw_signal_disconnect_by_window(handle);
192 #endif 202 #endif
193 203
204 if(ptr)
205 {
206 WinSetWindowPtr(handle, QWP_USER, 0);
207 free(ptr);
208 }
209
194 henum = WinBeginEnumWindows(handle); 210 henum = WinBeginEnumWindows(handle);
195 while((child = WinGetNextWindow(henum)) != NULLHANDLE) 211 while((child = WinGetNextWindow(henum)) != NULLHANDLE)
196 {
197 void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER);
198
199 if(ptr)
200 {
201 WinSetWindowPtr(handle, QWP_USER, 0);
202 free(ptr);
203 }
204
205 _free_window_memory(child); 212 _free_window_memory(child);
206 } 213
207 WinEndEnumWindows(henum); 214 WinEndEnumWindows(henum);
208 return; 215 return;
209 } 216 }
210 217
211 /* This function returns 1 if the window (widget) handle 218 /* This function returns 1 if the window (widget) handle
1577 } 1584 }
1578 } 1585 }
1579 break; 1586 break;
1580 case CN_CONTEXTMENU: 1587 case CN_CONTEXTMENU:
1581 { 1588 {
1582 int (*containercontextfunc)(HWND, char *, int, int, void *) = (int (*)(HWND, char *, int, int, void *))tmp->signalfunction; 1589 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (*)(HWND, char *, int, int, void *, void *))tmp->signalfunction;
1583 int id = SHORT1FROMMP(mp1); 1590 int id = SHORT1FROMMP(mp1);
1584 HWND conthwnd = dw_window_from_id(hWnd, id); 1591 HWND conthwnd = dw_window_from_id(hWnd, id);
1585 char *text = NULL; 1592 char *text = NULL;
1593 void *user = NULL;
1586 LONG x,y; 1594 LONG x,y;
1587 1595
1588 if(mp2) 1596 if(mp2)
1589 { 1597 {
1590 PRECORDCORE pre; 1598 PCNRITEM pci;
1591 1599
1592 pre = (PRECORDCORE)mp2; 1600 pci = (PCNRITEM)mp2;
1593 text = pre->pszIcon; 1601
1602 text = pci->rc.pszIcon;
1603 user = pci->user;
1594 } 1604 }
1595
1596 1605
1597 dw_pointer_query_pos(&x, &y); 1606 dw_pointer_query_pos(&x, &y);
1598 1607
1599 if(tmp->window == conthwnd) 1608 if(tmp->window == conthwnd)
1600 { 1609 {
1601 result = containercontextfunc(tmp->window, text, x, y, tmp->data); 1610 if(mp2)
1611 {
1612 NOTIFYRECORDEMPHASIS pre;
1613
1614 dw_tree_item_select(tmp->window, (HWND)mp2);
1615 pre.pRecord = mp2;
1616 pre.fEmphasisMask = CRA_CURSORED;
1617 pre.hwndCnr = tmp->window;
1618 _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre);
1619 }
1620 result = containercontextfunc(tmp->window, text, x, y, tmp->data, user);
1602 tmp = NULL; 1621 tmp = NULL;
1622 }
1623 }
1624 break;
1625 case CN_EMPHASIS:
1626 {
1627 PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2;
1628 static int emph_recurse = 0;
1629
1630 if(!emph_recurse)
1631 {
1632 emph_recurse = 1;
1633
1634 if(mp2)
1635 {
1636 if(tmp->window == pre->hwndCnr)
1637 {
1638 PCNRITEM pci = (PCNRITEM)pre->pRecord;
1639
1640 if(pci && pre->fEmphasisMask & CRA_CURSORED)
1641 {
1642 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = (int (*)(HWND, HWND, char *, void *, void *))tmp->signalfunction;
1643
1644 result = treeselectfunc(tmp->window, (HWND)pci, pci->rc.pszIcon, pci->user, tmp->data);
1645
1646 tmp = NULL;
1647 }
1648 }
1649 }
1650 emph_recurse = 0;
1603 } 1651 }
1604 } 1652 }
1605 break; 1653 break;
1606 case LN_SELECT: 1654 case LN_SELECT:
1607 { 1655 {
1645 } 1693 }
1646 break; 1694 break;
1647 } 1695 }
1648 } 1696 }
1649 break; 1697 break;
1650 }
1651 }
1652
1653 if(tmp && origmsg == WM_BUTTON1DOWN)
1654 {
1655 if(tmp->message == WM_USER+1)
1656 {
1657 if(tmp->window == hWnd)
1658 {
1659 QUERYRECFROMRECT rc;
1660 POINTS pts = (*((POINTS*)&mp1));
1661 RECORDCORE *prc;
1662
1663 rc.cb = sizeof(QUERYRECFROMRECT);
1664 rc.rect.xLeft = pts.x;
1665 rc.rect.xRight = pts.x + 1;
1666 rc.rect.yTop = pts.y;
1667 rc.rect.yBottom = pts.y - 1;
1668 rc.fsSearch = CMA_PARTIAL | CMA_ITEMORDER;
1669
1670 prc = (RECORDCORE *)WinSendMsg(hWnd, CM_QUERYRECORDFROMRECT, (MPARAM)CMA_FIRST, MPFROMP(&rc));
1671
1672 if(prc)
1673 {
1674 int (*treeselectfunc)(HWND, HWND, char *, void *) = (int (*)(HWND, HWND, char *, void *))tmp->signalfunction;
1675
1676 result = treeselectfunc(tmp->window, (HWND)prc, prc->pszIcon, tmp->data);
1677
1678 tmp = NULL;
1679 }
1680 }
1681 } 1698 }
1682 } 1699 }
1683 1700
1684 if(tmp) 1701 if(tmp)
1685 tmp = tmp->next; 1702 tmp = tmp->next;
2220 */ 2237 */
2221 2238
2222 MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 2239 MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2223 { 2240 {
2224 BubbleButton *bubble; 2241 BubbleButton *bubble;
2242 PFNWP oldproc;
2225 2243
2226 bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER); 2244 bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER);
2227 2245
2228 if(!bubble) 2246 if(!bubble)
2229 return WinDefWindowProc(hwnd, msg, mp1, mp2); 2247 return WinDefWindowProc(hwnd, msg, mp1, mp2);
2248
2249 oldproc = bubble->pOldProc;
2230 2250
2231 switch(msg) 2251 switch(msg)
2232 { 2252 {
2233 #ifndef NO_SIGNALS 2253 #ifndef NO_SIGNALS
2234 case WM_SETFOCUS: 2254 case WM_SETFOCUS:
2406 SWP_SIZE | SWP_MOVE | SWP_SHOW); 2426 SWP_SIZE | SWP_MOVE | SWP_SHOW);
2407 } 2427 }
2408 break; 2428 break;
2409 } 2429 }
2410 2430
2411 if(!bubble->pOldProc) 2431 if(!oldproc)
2412 return WinDefWindowProc(hwnd, msg, mp1, mp2); 2432 return WinDefWindowProc(hwnd, msg, mp1, mp2);
2413 return bubble->pOldProc(hwnd, msg, mp1, mp2); 2433 return oldproc(hwnd, msg, mp1, mp2);
2414 } 2434 }
2415 2435
2416 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 2436 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2417 { 2437 {
2418 int res = 0; 2438 int res = 0;
2729 * Parameters: 2749 * Parameters:
2730 * handle: The window handle to destroy. 2750 * handle: The window handle to destroy.
2731 */ 2751 */
2732 int dw_window_destroy(HWND handle) 2752 int dw_window_destroy(HWND handle)
2733 { 2753 {
2754 HWND parent = WinQueryWindow(handle, QW_PARENT);
2755 Box *thisbox = WinQueryWindowPtr(parent, QWP_USER);
2756
2757 if(!handle)
2758 return -1;
2759
2760 if(parent != HWND_DESKTOP && thisbox && thisbox->count)
2761 {
2762 int z, index = -1;
2763 Item *tmpitem, *thisitem = thisbox->items;
2764
2765 for(z=0;z<thisbox->count;z++)
2766 {
2767 if(thisitem[z].hwnd == handle)
2768 index = z;
2769 }
2770
2771 if(index == -1)
2772 return 0;
2773
2774 tmpitem = malloc(sizeof(Item)*(thisbox->count-1));
2775
2776 /* Copy all but the current entry to the new list */
2777 for(z=0;z<index;z++)
2778 {
2779 tmpitem[z] = thisitem[z];
2780 }
2781 for(z=index+1;z<thisbox->count;z++)
2782 {
2783 tmpitem[z-1] = thisitem[z];
2784 }
2785
2786 thisbox->items = tmpitem;
2787 free(thisitem);
2788 thisbox->count--;
2789 }
2790 _free_window_memory(handle);
2734 return WinDestroyWindow(handle); 2791 return WinDestroyWindow(handle);
2792 }
2793
2794 /* Causes entire window to be invalidated and redrawn.
2795 * Parameters:
2796 * handle: Toplevel window handle to be redrawn.
2797 */
2798 void dw_window_redraw(HWND handle)
2799 {
2800 HWND window = WinWindowFromID(handle, FID_CLIENT);
2801 Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER);
2802
2803 if(window && mybox)
2804 {
2805 unsigned long width, height;
2806
2807 dw_window_get_pos_size(window, NULL, NULL, &width, &height);
2808
2809 WinShowWindow(mybox->items[0].hwnd, FALSE);
2810 _do_resize(mybox, width, height);
2811 WinShowWindow(mybox->items[0].hwnd, TRUE);
2812 }
2735 } 2813 }
2736 2814
2737 /* 2815 /*
2738 * Changes a window's parent to newparent. 2816 * Changes a window's parent to newparent.
2739 * Parameters: 2817 * Parameters:
4570 void dw_checkbox_set(HWND handle, int value) 4648 void dw_checkbox_set(HWND handle, int value)
4571 { 4649 {
4572 WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0); 4650 WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0);
4573 } 4651 }
4574 4652
4575 typedef struct _CNRITEM
4576 {
4577 MINIRECORDCORE rc;
4578 HPOINTER hptrIcon;
4579
4580 } CNRITEM, *PCNRITEM;
4581
4582 /* 4653 /*
4583 * Inserts an item into a tree window (widget). 4654 * Inserts an item into a tree window (widget).
4584 * Parameters: 4655 * Parameters:
4585 * handle: Handle to the tree to be inserted. 4656 * handle: Handle to the tree to be inserted.
4586 * title: The text title of the entry. 4657 * title: The text title of the entry.
4587 * icon: Handle to coresponding icon. 4658 * icon: Handle to coresponding icon.
4588 * parent: Parent handle or 0 if root. 4659 * parent: Parent handle or 0 if root.
4589 */ 4660 * itemdata: Item specific data.
4590 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent) 4661 */
4662 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata)
4591 { 4663 {
4592 ULONG cbExtra; 4664 ULONG cbExtra;
4593 PCNRITEM pci; 4665 PCNRITEM pci;
4594 RECORDINSERT ri; 4666 RECORDINSERT ri;
4595 4667
4608 pci->rc.cb = sizeof(MINIRECORDCORE); 4680 pci->rc.cb = sizeof(MINIRECORDCORE);
4609 pci->rc.pszIcon = title; 4681 pci->rc.pszIcon = title;
4610 pci->rc.hptrIcon = icon; 4682 pci->rc.hptrIcon = icon;
4611 4683
4612 pci->hptrIcon = icon; 4684 pci->hptrIcon = icon;
4685 pci->user = itemdata;
4613 4686
4614 memset(&ri, 0, sizeof(RECORDINSERT)); 4687 memset(&ri, 0, sizeof(RECORDINSERT));
4615 4688
4616 ri.cb = sizeof(RECORDINSERT); 4689 ri.cb = sizeof(RECORDINSERT);
4617 ri.pRecordOrder = (PRECORDCORE)CMA_END; 4690 ri.pRecordOrder = (PRECORDCORE)CMA_END;
4630 4703
4631 return (HWND)pci; 4704 return (HWND)pci;
4632 } 4705 }
4633 4706
4634 /* 4707 /*
4708 * Sets the text and icon of an item in a tree window (widget).
4709 * Parameters:
4710 * handle: Handle to the tree containing the item.
4711 * item: Handle of the item to be modified.
4712 * title: The text title of the entry.
4713 * icon: Handle to coresponding icon.
4714 */
4715 void dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon)
4716 {
4717 PCNRITEM pci = (PCNRITEM)item;
4718
4719 if(!pci)
4720 return;
4721
4722 pci->rc.pszIcon = title;
4723 pci->rc.hptrIcon = icon;
4724
4725 pci->hptrIcon = icon;
4726
4727 WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED));
4728 }
4729
4730 /*
4731 * Sets the item data of a tree item.
4732 * Parameters:
4733 * handle: Handle to the tree containing the item.
4734 * item: Handle of the item to be modified.
4735 * itemdata: User defined data to be associated with item.
4736 */
4737 void dw_tree_set_data(HWND handle, HWND item, void *itemdata)
4738 {
4739 PCNRITEM pci = (PCNRITEM)item;
4740
4741 if(!pci)
4742 return;
4743
4744 pci->user = itemdata;
4745 }
4746
4747 /*
4748 * Sets this item as the active selection.
4749 * Parameters:
4750 * handle: Handle to the tree window (widget) to be selected.
4751 * item: Handle to the item to be selected.
4752 */
4753 void dw_tree_item_select(HWND handle, HWND item)
4754 {
4755 PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER));
4756
4757 while(pCore)
4758 {
4759 if(pCore->flRecordAttr & CRA_SELECTED)
4760 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED));
4761 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER));
4762 }
4763 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED));
4764 }
4765
4766 /*
4635 * Removes all nodes from a tree. 4767 * Removes all nodes from a tree.
4636 * Parameters: 4768 * Parameters:
4637 * handle: Handle to the window (widget) to be cleared. 4769 * handle: Handle to the window (widget) to be cleared.
4638 */ 4770 */
4639 void dw_tree_clear(HWND handle) 4771 void dw_tree_clear(HWND handle)
4640 { 4772 {
4641 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, CMA_INVALIDATE | CMA_FREE)); 4773 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, CMA_INVALIDATE | CMA_FREE));
4774 }
4775
4776 /*
4777 * Expands a node on a tree.
4778 * Parameters:
4779 * handle: Handle to the tree window (widget).
4780 * item: Handle to node to be expanded.
4781 */
4782 void dw_tree_expand(HWND handle, HWND item)
4783 {
4784 WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0);
4785 }
4786
4787 /*
4788 * Collapses a node on a tree.
4789 * Parameters:
4790 * handle: Handle to the tree window (widget).
4791 * item: Handle to node to be collapsed.
4792 */
4793 void dw_tree_collapse(HWND handle, HWND item)
4794 {
4795 WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0);
4642 } 4796 }
4643 4797
4644 /* 4798 /*
4645 * Removes a node from a tree. 4799 * Removes a node from a tree.
4646 * Parameters: 4800 * Parameters: