comparison win/dw.c @ 63:a6801a2260af

Synched up with the latest dynamic windows, has new slider support and transparency, focus, and other bug fixes on various platforms.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 14 Jan 2002 00:48:08 +0000
parents 4a02842f8074
children ab9b0fa6c66e
comparison
equal deleted inserted replaced
62:2be5174bdb5d 63:a6801a2260af
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like implementation of the Win32 GUI 3 * A GTK like implementation of the Win32 GUI
4 * 4 *
5 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> 5 * (C) 2000-2002 Brian Smith <dbsoft@technologist.com>
6 * 6 *
7 */ 7 */
8 #define _WIN32_IE 0x0500 8 #define _WIN32_IE 0x0500
9 #define WINVER 0x400 9 #define WINVER 0x400
10 #include <windows.h> 10 #include <windows.h>
24 HWND hwndBubble = (HWND)NULL, hwndBubbleLast, DW_HWND_OBJECT = (HWND)NULL; 24 HWND hwndBubble = (HWND)NULL, hwndBubbleLast, DW_HWND_OBJECT = (HWND)NULL;
25 25
26 HINSTANCE DWInstance = NULL; 26 HINSTANCE DWInstance = NULL;
27 27
28 DWORD dwVersion = 0; 28 DWORD dwVersion = 0;
29 DWTID _dwtid = -1;
29 30
30 /* I should probably check the actual file version, but this will do for now */ 31 /* I should probably check the actual file version, but this will do for now */
31 #define IS_WIN98PLUS (LOBYTE(LOWORD(dwVersion)) > 4 || \ 32 #define IS_WIN98PLUS (LOBYTE(LOWORD(dwVersion)) > 4 || \
32 (LOBYTE(LOWORD(dwVersion)) == 4 && HIBYTE(LOWORD(dwVersion)) > 0)) 33 (LOBYTE(LOWORD(dwVersion)) == 4 && HIBYTE(LOWORD(dwVersion)) > 0))
33 34
99 } SignalList; 100 } SignalList;
100 101
101 static int in_checkbox_handler = 0; 102 static int in_checkbox_handler = 0;
102 103
103 /* List of signals and their equivilent Win32 message */ 104 /* List of signals and their equivilent Win32 message */
104 #define SIGNALMAX 14 105 #define SIGNALMAX 15
105 106
106 SignalList SignalTranslate[SIGNALMAX] = { 107 SignalList SignalTranslate[SIGNALMAX] = {
107 { WM_SIZE, "configure_event" }, 108 { WM_SIZE, "configure_event" },
108 { WM_CHAR, "key_press_event" }, 109 { WM_CHAR, "key_press_event" },
109 { WM_LBUTTONDOWN, "button_press_event" }, 110 { WM_LBUTTONDOWN, "button_press_event" },
115 { NM_DBLCLK, "container-select" }, 116 { NM_DBLCLK, "container-select" },
116 { NM_RCLICK, "container-context" }, 117 { NM_RCLICK, "container-context" },
117 { LBN_SELCHANGE, "item-select" }, 118 { LBN_SELCHANGE, "item-select" },
118 { TVN_SELCHANGED, "tree-select" }, 119 { TVN_SELCHANGED, "tree-select" },
119 { WM_SETFOCUS, "set-focus" }, 120 { WM_SETFOCUS, "set-focus" },
120 { WM_USER+1, "lose-focus" } 121 { WM_USER+1, "lose-focus" },
122 { WM_VSCROLL, "value_changed" }
121 }; 123 };
122 124
123 #ifdef BUILD_DLL 125 #ifdef BUILD_DLL
124 void Win32_Set_Instance(HINSTANCE hInstance) 126 void Win32_Set_Instance(HINSTANCE hInstance)
125 { 127 {
322 GetClassName(handle, tmpbuf, 99); 324 GetClassName(handle, tmpbuf, 99);
323 325
324 /* These are the window classes which can 326 /* These are the window classes which can
325 * obtain input focus. 327 * obtain input focus.
326 */ 328 */
327 if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME))==0 || /* Entryfield */ 329 if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1)==0 || /* Entryfield */
328 strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0 || /* Button */ 330 strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0 || /* Button */
329 strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0 || /* Combobox */ 331 strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0 || /* Combobox */
330 strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME))==0 || /* List box */ 332 strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME)+1)==0 || /* List box */
331 strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0 || /* Spinbutton */ 333 strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0 || /* Spinbutton */
332 strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))== 0) /* Container */ 334 strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0 || /* Slider */
335 strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)== 0) /* Container */
333 return 1; 336 return 1;
334 return 0; 337 return 0;
335 } 338 }
336 339
337 HWND _normalize_handle(HWND handle) 340 HWND _normalize_handle(HWND handle)
1162 1165
1163 if(msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) 1166 if(msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN)
1164 msg = WM_LBUTTONDOWN; 1167 msg = WM_LBUTTONDOWN;
1165 if(msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) 1168 if(msg == WM_RBUTTONUP || msg == WM_MBUTTONUP)
1166 msg = WM_LBUTTONUP; 1169 msg = WM_LBUTTONUP;
1170 if(msg == WM_HSCROLL)
1171 msg = WM_VSCROLL;
1167 1172
1168 if(filterfunc) 1173 if(filterfunc)
1169 result = filterfunc(hWnd, msg, mp1, mp2); 1174 result = filterfunc(hWnd, msg, mp1, mp2);
1170 1175
1171 #ifndef NO_SIGNALS 1176 #ifndef NO_SIGNALS
1407 } /* Make sure it's the right window, and the right ID */ 1412 } /* Make sure it's the right window, and the right ID */
1408 else if(tmp->window < (HWND)65536 && command == tmp->window) 1413 else if(tmp->window < (HWND)65536 && command == tmp->window)
1409 { 1414 {
1410 result = clickfunc(tmp->window, tmp->data); 1415 result = clickfunc(tmp->window, tmp->data);
1411 tmp = NULL; 1416 tmp = NULL;
1417 }
1418 }
1419 break;
1420 case WM_HSCROLL:
1421 case WM_VSCROLL:
1422 {
1423 char tmpbuf[100];
1424 HWND handle = (HWND)mp2;
1425
1426 GetClassName(handle, tmpbuf, 99);
1427
1428 if(strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0)
1429 {
1430 int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction;
1431
1432 if(handle == tmp->window)
1433 {
1434 int value = (int)SendMessage(handle, TBM_GETPOS, 0, 0);
1435 int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
1436 ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
1437
1438 if(currentstyle & TBS_VERT)
1439 result = valuechangefunc(tmp->window, max - value, tmp->data);
1440 else
1441 result = valuechangefunc(tmp->window, value, tmp->data);
1442 tmp = NULL;
1443 }
1412 } 1444 }
1413 } 1445 }
1414 break; 1446 break;
1415 } 1447 }
1416 } 1448 }
1776 case WM_SETFOCUS: 1808 case WM_SETFOCUS:
1777 if(cinfo->combo) 1809 if(cinfo->combo)
1778 _wndproc(cinfo->combo, msg, mp1, mp2); 1810 _wndproc(cinfo->combo, msg, mp1, mp2);
1779 else 1811 else
1780 _wndproc(hWnd, msg, mp1, mp2); 1812 _wndproc(hWnd, msg, mp1, mp2);
1813 break;
1814 case WM_VSCROLL:
1815 case WM_HSCROLL:
1816 _wndproc(hWnd, msg, mp1, mp2);
1781 break; 1817 break;
1782 case WM_CHAR: 1818 case WM_CHAR:
1783 if(LOWORD(mp1) == '\t') 1819 if(LOWORD(mp1) == '\t')
1784 { 1820 {
1785 if(GetAsyncKeyState(VK_SHIFT)) 1821 if(GetAsyncKeyState(VK_SHIFT))
2700 MSG msg; 2736 MSG msg;
2701 2737
2702 /* Setup the filter function */ 2738 /* Setup the filter function */
2703 filterfunc = func; 2739 filterfunc = func;
2704 2740
2741 _dwtid = dw_thread_id();
2742
2705 while (GetMessage(&msg, NULL, 0, 0)) 2743 while (GetMessage(&msg, NULL, 0, 0))
2706 { 2744 {
2707 TranslateMessage(&msg); 2745 TranslateMessage(&msg);
2708 DispatchMessage(&msg); 2746 DispatchMessage(&msg);
2709 } 2747 }
2712 fclose(f); 2750 fclose(f);
2713 #endif 2751 #endif
2714 } 2752 }
2715 2753
2716 /* 2754 /*
2717 * Runs a message loop for Dynamic Windows, for a period of seconds. 2755 * Runs a message loop for Dynamic Windows, for a period of milliseconds.
2718 * Parameters: 2756 * Parameters:
2719 * seconds: Number of seconds to run the loop for. 2757 * milliseconds: Number of milliseconds to run the loop for.
2720 */ 2758 */
2721 void dw_main_sleep(int seconds) 2759 void dw_main_sleep(int milliseconds)
2722 { 2760 {
2723 MSG msg; 2761 MSG msg;
2724 time_t start = time(NULL); 2762 double start = (double)clock();
2725 2763
2726 while(time(NULL) - start <= seconds) 2764 while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds)
2727 { 2765 {
2728 if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 2766 if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
2729 { 2767 {
2730 GetMessage(&msg, NULL, 0, 0); 2768 GetMessage(&msg, NULL, 0, 0);
2731 TranslateMessage(&msg); 2769 TranslateMessage(&msg);
3600 * id: An ID to be used with WinWindowFromID() or 0L. 3638 * id: An ID to be used with WinWindowFromID() or 0L.
3601 */ 3639 */
3602 HWND dw_mle_new(ULONG id) 3640 HWND dw_mle_new(ULONG id)
3603 { 3641 {
3604 3642
3605 HWND tmp = CreateWindow(EDITCLASSNAME, 3643 HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
3606 "", 3644 EDITCLASSNAME,
3607 WS_BORDER | 3645 "",
3608 WS_VSCROLL | ES_MULTILINE | 3646 WS_BORDER |
3609 ES_WANTRETURN | WS_CHILD | 3647 WS_VSCROLL | ES_MULTILINE |
3610 WS_CLIPCHILDREN, 3648 ES_WANTRETURN | WS_CHILD |
3611 0,0,2000,1000, 3649 WS_CLIPCHILDREN,
3612 DW_HWND_OBJECT, 3650 0,0,2000,1000,
3613 (HMENU)id, 3651 DW_HWND_OBJECT,
3614 NULL, 3652 (HMENU)id,
3615 NULL); 3653 NULL,
3654 NULL);
3616 dw_window_set_font(tmp, DefaultFont); 3655 dw_window_set_font(tmp, DefaultFont);
3617 return tmp; 3656 return tmp;
3618 } 3657 }
3619 3658
3620 /* 3659 /*
3623 * text: The default text to be in the entryfield widget. 3662 * text: The default text to be in the entryfield widget.
3624 * id: An ID to be used with WinWindowFromID() or 0L. 3663 * id: An ID to be used with WinWindowFromID() or 0L.
3625 */ 3664 */
3626 HWND dw_entryfield_new(char *text, ULONG id) 3665 HWND dw_entryfield_new(char *text, ULONG id)
3627 { 3666 {
3628 HWND tmp = CreateWindow(EDITCLASSNAME, 3667 HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
3629 text, 3668 EDITCLASSNAME,
3630 ES_WANTRETURN | WS_CHILD | 3669 text,
3631 WS_BORDER | ES_AUTOHSCROLL | 3670 ES_WANTRETURN | WS_CHILD |
3632 WS_CLIPCHILDREN, 3671 WS_BORDER | ES_AUTOHSCROLL |
3633 0,0,2000,1000, 3672 WS_CLIPCHILDREN,
3634 DW_HWND_OBJECT, 3673 0,0,2000,1000,
3635 (HMENU)id, 3674 DW_HWND_OBJECT,
3636 NULL, 3675 (HMENU)id,
3637 NULL); 3676 NULL,
3677 NULL);
3638 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); 3678 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
3639 3679
3640 cinfo->back = cinfo->fore = -1; 3680 cinfo->back = cinfo->fore = -1;
3641 cinfo->buddy = 0; 3681 cinfo->buddy = 0;
3642 3682
3652 * text: The default text to be in the entryfield widget. 3692 * text: The default text to be in the entryfield widget.
3653 * id: An ID to be used with WinWindowFromID() or 0L. 3693 * id: An ID to be used with WinWindowFromID() or 0L.
3654 */ 3694 */
3655 HWND dw_entryfield_password_new(char *text, ULONG id) 3695 HWND dw_entryfield_password_new(char *text, ULONG id)
3656 { 3696 {
3657 HWND tmp = CreateWindow(EDITCLASSNAME, 3697 HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
3658 text, 3698 EDITCLASSNAME,
3659 ES_WANTRETURN | WS_CHILD | 3699 text,
3660 ES_PASSWORD | WS_BORDER | 3700 ES_WANTRETURN | WS_CHILD |
3661 ES_AUTOHSCROLL | WS_CLIPCHILDREN, 3701 ES_PASSWORD | WS_BORDER |
3662 0,0,2000,1000, 3702 ES_AUTOHSCROLL | WS_CLIPCHILDREN,
3663 DW_HWND_OBJECT, 3703 0,0,2000,1000,
3664 (HMENU)id, 3704 DW_HWND_OBJECT,
3665 NULL, 3705 (HMENU)id,
3666 NULL); 3706 NULL,
3707 NULL);
3667 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); 3708 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
3668 3709
3669 cinfo->back = cinfo->fore = -1; 3710 cinfo->back = cinfo->fore = -1;
3670 cinfo->buddy = 0; 3711 cinfo->buddy = 0;
3671 3712
3793 * id: An ID to be used with WinWindowFromID() or 0L. 3834 * id: An ID to be used with WinWindowFromID() or 0L.
3794 */ 3835 */
3795 HWND dw_spinbutton_new(char *text, ULONG id) 3836 HWND dw_spinbutton_new(char *text, ULONG id)
3796 { 3837 {
3797 ULONG *data = malloc(sizeof(ULONG)); 3838 ULONG *data = malloc(sizeof(ULONG));
3798 HWND buddy = CreateWindow(EDITCLASSNAME, 3839 HWND buddy = CreateWindowEx(WS_EX_CLIENTEDGE,
3799 text, 3840 EDITCLASSNAME,
3800 WS_CHILD | WS_BORDER | 3841 text,
3801 ES_NUMBER | WS_CLIPCHILDREN, 3842 WS_CHILD | WS_BORDER |
3843 ES_NUMBER | WS_CLIPCHILDREN,
3844 0,0,2000,1000,
3845 DW_HWND_OBJECT,
3846 NULL,
3847 NULL,
3848 NULL);
3849 HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE,
3850 UPDOWN_CLASS,
3851 NULL,
3852 WS_CHILD | UDS_ALIGNRIGHT | WS_BORDER |
3853 UDS_ARROWKEYS | UDS_SETBUDDYINT |
3854 UDS_WRAP | UDS_NOTHOUSANDS,
3802 0,0,2000,1000, 3855 0,0,2000,1000,
3803 DW_HWND_OBJECT, 3856 DW_HWND_OBJECT,
3804 NULL, 3857 (HMENU)id,
3805 NULL, 3858 NULL,
3806 NULL); 3859 NULL);
3807 HWND tmp = CreateUpDownControl(
3808 WS_CHILD | UDS_ALIGNRIGHT |
3809 UDS_ARROWKEYS | UDS_SETBUDDYINT |
3810 UDS_WRAP | UDS_NOTHOUSANDS,
3811 0,
3812 0,
3813 2000,
3814 1000,
3815 DW_HWND_OBJECT,
3816 id,
3817 DWInstance,
3818 buddy,
3819 0,
3820 100,
3821 0);
3822 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); 3860 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
3823 3861
3862 SendMessage(tmp, UDM_SETBUDDY, (WPARAM)buddy, 0);
3824 cinfo->back = cinfo->fore = -1; 3863 cinfo->back = cinfo->fore = -1;
3825 cinfo->buddy = tmp; 3864 cinfo->buddy = tmp;
3826 3865
3827 cinfo->pOldProc = SubclassWindow(buddy, _colorwndproc); 3866 cinfo->pOldProc = SubclassWindow(buddy, _colorwndproc);
3828 SetWindowLong(buddy, GWL_USERDATA, (ULONG)cinfo); 3867 SetWindowLong(buddy, GWL_USERDATA, (ULONG)cinfo);
3851 0,0,2000,1000, 3890 0,0,2000,1000,
3852 DW_HWND_OBJECT, 3891 DW_HWND_OBJECT,
3853 (HMENU)id, 3892 (HMENU)id,
3854 NULL, 3893 NULL,
3855 NULL); 3894 NULL);
3856 3895 BubbleButton *bubble = calloc(1, sizeof(BubbleButton));
3896 bubble->id = id;
3897 bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc);
3898 bubble->cinfo.fore = -1;
3899 bubble->cinfo.back = -1;
3900 SetWindowLong(tmp, GWL_USERDATA, (ULONG)bubble);
3901 dw_window_set_font(tmp, DefaultFont);
3902 return tmp;
3903 }
3904
3905
3906 /*
3907 * Create a new slider window (widget) to be packed.
3908 * Parameters:
3909 * vertical: TRUE or FALSE if slider is vertical.
3910 * increments: Number of increments available.
3911 * id: An ID to be used with WinWindowFromID() or 0L.
3912 */
3913 HWND dw_slider_new(int vertical, int increments, ULONG id)
3914 {
3915 HWND tmp = CreateWindow(TRACKBAR_CLASS,
3916 "",
3917 WS_CHILD | WS_CLIPCHILDREN |
3918 (vertical ? TBS_VERT : TBS_HORZ),
3919 0,0,2000,1000,
3920 DW_HWND_OBJECT,
3921 NULL,
3922 NULL,
3923 NULL);
3857 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); 3924 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo));
3858 3925
3859 cinfo->back = cinfo->fore = -1; 3926 cinfo->back = cinfo->fore = -1;
3860 cinfo->buddy = 0; 3927 cinfo->buddy = 0;
3861 cinfo->user = 0; 3928 cinfo->user = 0;
3862 3929
3863 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); 3930 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc);
3864 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); 3931 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo);
3865 dw_window_set_font(tmp, DefaultFont); 3932 SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(0, increments-1));
3866 return tmp; 3933 return tmp;
3867 } 3934 }
3868
3869 3935
3870 /* 3936 /*
3871 * Create a new percent bar window (widget) to be packed. 3937 * Create a new percent bar window (widget) to be packed.
3872 * Parameters: 3938 * Parameters:
3873 * id: An ID to be used with WinWindowFromID() or 0L. 3939 * id: An ID to be used with WinWindowFromID() or 0L.
4887 } 4953 }
4888 4954
4889 /* 4955 /*
4890 * Returns the range of the percent bar. 4956 * Returns the range of the percent bar.
4891 * Parameters: 4957 * Parameters:
4958 * handle: Handle to the percent bar to be queried.
4959 */
4960 unsigned int dw_percent_query_range(HWND handle)
4961 {
4962 return (unsigned int)SendMessage(handle, PBM_GETRANGE, (WPARAM)FALSE, 0);
4963 }
4964
4965 /*
4966 * Sets the percent bar position.
4967 * Parameters:
4968 * handle: Handle to the percent bar to be set.
4969 * position: Position of the percent bar withing the range.
4970 */
4971 void dw_percent_set_pos(HWND handle, unsigned int position)
4972 {
4973 SendMessage(handle, PBM_SETPOS, (WPARAM)position, 0);
4974 }
4975
4976 /*
4977 * Returns the position of the slider.
4978 * Parameters:
4892 * handle: Handle to the slider to be queried. 4979 * handle: Handle to the slider to be queried.
4893 */ 4980 */
4894 unsigned int dw_percent_query_range(HWND handle) 4981 unsigned int dw_slider_query_pos(HWND handle)
4895 { 4982 {
4896 return (unsigned int)SendMessage(handle, PBM_GETRANGE, (WPARAM)FALSE, 0); 4983 int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
4897 } 4984 ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
4898 4985
4899 /* 4986 if(currentstyle & TBS_VERT)
4900 * Sets the percent bar position. 4987 return max - (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
4988 return (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0);
4989 }
4990
4991 /*
4992 * Sets the slider position.
4901 * Parameters: 4993 * Parameters:
4902 * handle: Handle to the slider to be set. 4994 * handle: Handle to the slider to be set.
4903 * position: Position of the slider withing the range. 4995 * position: Position of the slider withing the range.
4904 */ 4996 */
4905 void dw_percent_set_pos(HWND handle, unsigned int position) 4997 void dw_slider_set_pos(HWND handle, unsigned int position)
4906 { 4998 {
4907 SendMessage(handle, PBM_SETPOS, (WPARAM)position, 0); 4999 int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0);
5000 ULONG currentstyle = GetWindowLong(handle, GWL_STYLE);
5001
5002 if(currentstyle & TBS_VERT)
5003 SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)max - position);
5004 else
5005 SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)position);
4908 } 5006 }
4909 5007
4910 /* 5008 /*
4911 * Sets the spinbutton value. 5009 * Sets the spinbutton value.
4912 * Parameters: 5010 * Parameters:
4979 if(SendMessage(handle, BM_GETCHECK, 0, 0) == BST_CHECKED) 5077 if(SendMessage(handle, BM_GETCHECK, 0, 0) == BST_CHECKED)
4980 return (in_checkbox_handler ? FALSE : TRUE); 5078 return (in_checkbox_handler ? FALSE : TRUE);
4981 return (in_checkbox_handler ? TRUE : FALSE); 5079 return (in_checkbox_handler ? TRUE : FALSE);
4982 } 5080 }
4983 5081
5082 /* This function unchecks all radiobuttons on a box */
5083 BOOL CALLBACK _uncheck_radios(HWND handle, LPARAM lParam)
5084 {
5085 char tmpbuf[100];
5086
5087 GetClassName(handle, tmpbuf, 99);
5088
5089 if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0)
5090 {
5091 BubbleButton *bubble= (BubbleButton *)GetWindowLong(handle, GWL_USERDATA);
5092
5093 if(bubble && !bubble->checkbox)
5094 SendMessage(handle, BM_SETCHECK, 0, 0);
5095 }
5096 return TRUE;
5097 }
4984 /* 5098 /*
4985 * Sets the state of the checkbox. 5099 * Sets the state of the checkbox.
4986 * Parameters: 5100 * Parameters:
4987 * handle: Handle to the checkbox to be queried. 5101 * handle: Handle to the checkbox to be queried.
4988 * value: TRUE for checked, FALSE for unchecked. 5102 * value: TRUE for checked, FALSE for unchecked.
4989 */ 5103 */
4990 void dw_checkbox_set(HWND handle, int value) 5104 void dw_checkbox_set(HWND handle, int value)
4991 { 5105 {
4992 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); 5106 BubbleButton *bubble= (BubbleButton *)GetWindowLong(handle, GWL_USERDATA);
4993 5107
4994 if(cinfo && !cinfo->user) 5108 if(bubble && !bubble->checkbox)
4995 SendMessage(handle, BM_CLICK, 0, 0); 5109 {
5110 HWND parent = GetParent(handle);
5111
5112 if(parent)
5113 EnumChildWindows(parent, _uncheck_radios, 0);
5114 }
4996 SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0); 5115 SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0);
4997 } 5116 }
4998 5117
4999 /* 5118 /*
5000 * Inserts an item into a tree window (widget) after another item. 5119 * Inserts an item into a tree window (widget) after another item.
6054 * Parameters: 6173 * Parameters:
6055 * mutex: The handle to the mutex returned by dw_mutex_new(). 6174 * mutex: The handle to the mutex returned by dw_mutex_new().
6056 */ 6175 */
6057 void dw_mutex_lock(HMTX mutex) 6176 void dw_mutex_lock(HMTX mutex)
6058 { 6177 {
6059 WaitForSingleObject((HANDLE)mutex, INFINITE); 6178 if(_dwtid == dw_thread_id())
6179 {
6180 int rc = WaitForSingleObject((HANDLE)mutex, 0);
6181
6182 while(rc == WAIT_TIMEOUT)
6183 {
6184 dw_main_sleep(1);
6185 rc = WaitForSingleObject((HANDLE)mutex, 0);
6186 }
6187 }
6188 else
6189 WaitForSingleObject((HANDLE)mutex, INFINITE);
6060 } 6190 }
6061 6191
6062 /* 6192 /*
6063 * Reliquishes the access to the semaphore. 6193 * Reliquishes the access to the semaphore.
6064 * Parameters: 6194 * Parameters: