Mercurial > dwindows
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: |