Mercurial > dwindows
diff 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 |
line wrap: on
line diff
--- a/win/dw.c Sat Dec 08 04:47:43 2001 +0000 +++ b/win/dw.c Mon Jan 14 00:48:08 2002 +0000 @@ -2,7 +2,7 @@ * Dynamic Windows: * A GTK like implementation of the Win32 GUI * - * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> + * (C) 2000-2002 Brian Smith <dbsoft@technologist.com> * */ #define _WIN32_IE 0x0500 @@ -26,6 +26,7 @@ HINSTANCE DWInstance = NULL; DWORD dwVersion = 0; +DWTID _dwtid = -1; /* I should probably check the actual file version, but this will do for now */ #define IS_WIN98PLUS (LOBYTE(LOWORD(dwVersion)) > 4 || \ @@ -101,7 +102,7 @@ static int in_checkbox_handler = 0; /* List of signals and their equivilent Win32 message */ -#define SIGNALMAX 14 +#define SIGNALMAX 15 SignalList SignalTranslate[SIGNALMAX] = { { WM_SIZE, "configure_event" }, @@ -117,7 +118,8 @@ { LBN_SELCHANGE, "item-select" }, { TVN_SELCHANGED, "tree-select" }, { WM_SETFOCUS, "set-focus" }, - { WM_USER+1, "lose-focus" } + { WM_USER+1, "lose-focus" }, + { WM_VSCROLL, "value_changed" } }; #ifdef BUILD_DLL @@ -324,12 +326,13 @@ /* These are the window classes which can * obtain input focus. */ - if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME))==0 || /* Entryfield */ - strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0 || /* Button */ - strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0 || /* Combobox */ - strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME))==0 || /* List box */ - strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0 || /* Spinbutton */ - strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))== 0) /* Container */ + if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME)+1)==0 || /* Entryfield */ + strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0 || /* Button */ + strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME)+1)==0 || /* Combobox */ + strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME)+1)==0 || /* List box */ + strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS)+1)==0 || /* Spinbutton */ + strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0 || /* Slider */ + strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW)+1)== 0) /* Container */ return 1; return 0; } @@ -1164,6 +1167,8 @@ msg = WM_LBUTTONDOWN; if(msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) msg = WM_LBUTTONUP; + if(msg == WM_HSCROLL) + msg = WM_VSCROLL; if(filterfunc) result = filterfunc(hWnd, msg, mp1, mp2); @@ -1412,6 +1417,33 @@ } } break; + case WM_HSCROLL: + case WM_VSCROLL: + { + char tmpbuf[100]; + HWND handle = (HWND)mp2; + + GetClassName(handle, tmpbuf, 99); + + if(strnicmp(tmpbuf, TRACKBAR_CLASS, strlen(TRACKBAR_CLASS)+1)==0) + { + int (*valuechangefunc)(HWND, int, void *) = tmp->signalfunction; + + if(handle == tmp->window) + { + int value = (int)SendMessage(handle, TBM_GETPOS, 0, 0); + int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0); + ULONG currentstyle = GetWindowLong(handle, GWL_STYLE); + + if(currentstyle & TBS_VERT) + result = valuechangefunc(tmp->window, max - value, tmp->data); + else + result = valuechangefunc(tmp->window, value, tmp->data); + tmp = NULL; + } + } + } + break; } } if(tmp) @@ -1779,6 +1811,10 @@ else _wndproc(hWnd, msg, mp1, mp2); break; + case WM_VSCROLL: + case WM_HSCROLL: + _wndproc(hWnd, msg, mp1, mp2); + break; case WM_CHAR: if(LOWORD(mp1) == '\t') { @@ -2702,6 +2738,8 @@ /* Setup the filter function */ filterfunc = func; + _dwtid = dw_thread_id(); + while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); @@ -2714,16 +2752,16 @@ } /* - * Runs a message loop for Dynamic Windows, for a period of seconds. - * Parameters: - * seconds: Number of seconds to run the loop for. - */ -void dw_main_sleep(int seconds) + * Runs a message loop for Dynamic Windows, for a period of milliseconds. + * Parameters: + * milliseconds: Number of milliseconds to run the loop for. + */ +void dw_main_sleep(int milliseconds) { MSG msg; - time_t start = time(NULL); - - while(time(NULL) - start <= seconds) + double start = (double)clock(); + + while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds) { if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { @@ -3602,17 +3640,18 @@ HWND dw_mle_new(ULONG id) { - HWND tmp = CreateWindow(EDITCLASSNAME, - "", - WS_BORDER | - WS_VSCROLL | ES_MULTILINE | - ES_WANTRETURN | WS_CHILD | - WS_CLIPCHILDREN, - 0,0,2000,1000, - DW_HWND_OBJECT, - (HMENU)id, - NULL, - NULL); + HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE, + EDITCLASSNAME, + "", + WS_BORDER | + WS_VSCROLL | ES_MULTILINE | + ES_WANTRETURN | WS_CHILD | + WS_CLIPCHILDREN, + 0,0,2000,1000, + DW_HWND_OBJECT, + (HMENU)id, + NULL, + NULL); dw_window_set_font(tmp, DefaultFont); return tmp; } @@ -3625,16 +3664,17 @@ */ HWND dw_entryfield_new(char *text, ULONG id) { - HWND tmp = CreateWindow(EDITCLASSNAME, - text, - ES_WANTRETURN | WS_CHILD | - WS_BORDER | ES_AUTOHSCROLL | - WS_CLIPCHILDREN, - 0,0,2000,1000, - DW_HWND_OBJECT, - (HMENU)id, - NULL, - NULL); + HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE, + EDITCLASSNAME, + text, + ES_WANTRETURN | WS_CHILD | + WS_BORDER | ES_AUTOHSCROLL | + WS_CLIPCHILDREN, + 0,0,2000,1000, + DW_HWND_OBJECT, + (HMENU)id, + NULL, + NULL); ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); cinfo->back = cinfo->fore = -1; @@ -3654,16 +3694,17 @@ */ HWND dw_entryfield_password_new(char *text, ULONG id) { - HWND tmp = CreateWindow(EDITCLASSNAME, - text, - ES_WANTRETURN | WS_CHILD | - ES_PASSWORD | WS_BORDER | - ES_AUTOHSCROLL | WS_CLIPCHILDREN, - 0,0,2000,1000, - DW_HWND_OBJECT, - (HMENU)id, - NULL, - NULL); + HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE, + EDITCLASSNAME, + text, + ES_WANTRETURN | WS_CHILD | + ES_PASSWORD | WS_BORDER | + ES_AUTOHSCROLL | WS_CLIPCHILDREN, + 0,0,2000,1000, + DW_HWND_OBJECT, + (HMENU)id, + NULL, + NULL); ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); cinfo->back = cinfo->fore = -1; @@ -3795,32 +3836,30 @@ HWND dw_spinbutton_new(char *text, ULONG id) { ULONG *data = malloc(sizeof(ULONG)); - HWND buddy = CreateWindow(EDITCLASSNAME, - text, - WS_CHILD | WS_BORDER | - ES_NUMBER | WS_CLIPCHILDREN, + HWND buddy = CreateWindowEx(WS_EX_CLIENTEDGE, + EDITCLASSNAME, + text, + WS_CHILD | WS_BORDER | + ES_NUMBER | WS_CLIPCHILDREN, + 0,0,2000,1000, + DW_HWND_OBJECT, + NULL, + NULL, + NULL); + HWND tmp = CreateWindowEx(WS_EX_CLIENTEDGE, + UPDOWN_CLASS, + NULL, + WS_CHILD | UDS_ALIGNRIGHT | WS_BORDER | + UDS_ARROWKEYS | UDS_SETBUDDYINT | + UDS_WRAP | UDS_NOTHOUSANDS, 0,0,2000,1000, DW_HWND_OBJECT, - NULL, + (HMENU)id, NULL, NULL); - HWND tmp = CreateUpDownControl( - WS_CHILD | UDS_ALIGNRIGHT | - UDS_ARROWKEYS | UDS_SETBUDDYINT | - UDS_WRAP | UDS_NOTHOUSANDS, - 0, - 0, - 2000, - 1000, - DW_HWND_OBJECT, - id, - DWInstance, - buddy, - 0, - 100, - 0); ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); + SendMessage(tmp, UDM_SETBUDDY, (WPARAM)buddy, 0); cinfo->back = cinfo->fore = -1; cinfo->buddy = tmp; @@ -3853,7 +3892,35 @@ (HMENU)id, NULL, NULL); - + BubbleButton *bubble = calloc(1, sizeof(BubbleButton)); + bubble->id = id; + bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc); + bubble->cinfo.fore = -1; + bubble->cinfo.back = -1; + SetWindowLong(tmp, GWL_USERDATA, (ULONG)bubble); + dw_window_set_font(tmp, DefaultFont); + return tmp; +} + + +/* + * Create a new slider window (widget) to be packed. + * Parameters: + * vertical: TRUE or FALSE if slider is vertical. + * increments: Number of increments available. + * id: An ID to be used with WinWindowFromID() or 0L. + */ +HWND dw_slider_new(int vertical, int increments, ULONG id) +{ + HWND tmp = CreateWindow(TRACKBAR_CLASS, + "", + WS_CHILD | WS_CLIPCHILDREN | + (vertical ? TBS_VERT : TBS_HORZ), + 0,0,2000,1000, + DW_HWND_OBJECT, + NULL, + NULL, + NULL); ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); cinfo->back = cinfo->fore = -1; @@ -3862,11 +3929,10 @@ cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); - dw_window_set_font(tmp, DefaultFont); + SendMessage(tmp, TBM_SETRANGE, (WPARAM)FALSE, (LPARAM)MAKELONG(0, increments-1)); return tmp; } - /* * Create a new percent bar window (widget) to be packed. * Parameters: @@ -4889,7 +4955,7 @@ /* * Returns the range of the percent bar. * Parameters: - * handle: Handle to the slider to be queried. + * handle: Handle to the percent bar to be queried. */ unsigned int dw_percent_query_range(HWND handle) { @@ -4899,8 +4965,8 @@ /* * Sets the percent bar position. * Parameters: - * handle: Handle to the slider to be set. - * position: Position of the slider withing the range. + * handle: Handle to the percent bar to be set. + * position: Position of the percent bar withing the range. */ void dw_percent_set_pos(HWND handle, unsigned int position) { @@ -4908,6 +4974,38 @@ } /* + * Returns the position of the slider. + * Parameters: + * handle: Handle to the slider to be queried. + */ +unsigned int dw_slider_query_pos(HWND handle) +{ + int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0); + ULONG currentstyle = GetWindowLong(handle, GWL_STYLE); + + if(currentstyle & TBS_VERT) + return max - (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0); + return (unsigned int)SendMessage(handle, TBM_GETPOS, 0, 0); +} + +/* + * Sets the slider position. + * Parameters: + * handle: Handle to the slider to be set. + * position: Position of the slider withing the range. + */ +void dw_slider_set_pos(HWND handle, unsigned int position) +{ + int max = (int)SendMessage(handle, TBM_GETRANGEMAX, 0, 0); + ULONG currentstyle = GetWindowLong(handle, GWL_STYLE); + + if(currentstyle & TBS_VERT) + SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)max - position); + else + SendMessage(handle, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)position); +} + +/* * Sets the spinbutton value. * Parameters: * handle: Handle to the spinbutton to be set. @@ -4981,6 +5079,22 @@ return (in_checkbox_handler ? TRUE : FALSE); } +/* This function unchecks all radiobuttons on a box */ +BOOL CALLBACK _uncheck_radios(HWND handle, LPARAM lParam) +{ + char tmpbuf[100]; + + GetClassName(handle, tmpbuf, 99); + + if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME)+1)==0) + { + BubbleButton *bubble= (BubbleButton *)GetWindowLong(handle, GWL_USERDATA); + + if(bubble && !bubble->checkbox) + SendMessage(handle, BM_SETCHECK, 0, 0); + } + return TRUE; +} /* * Sets the state of the checkbox. * Parameters: @@ -4989,10 +5103,15 @@ */ void dw_checkbox_set(HWND handle, int value) { - ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); - - if(cinfo && !cinfo->user) - SendMessage(handle, BM_CLICK, 0, 0); + BubbleButton *bubble= (BubbleButton *)GetWindowLong(handle, GWL_USERDATA); + + if(bubble && !bubble->checkbox) + { + HWND parent = GetParent(handle); + + if(parent) + EnumChildWindows(parent, _uncheck_radios, 0); + } SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0); } @@ -6056,7 +6175,18 @@ */ void dw_mutex_lock(HMTX mutex) { - WaitForSingleObject((HANDLE)mutex, INFINITE); + if(_dwtid == dw_thread_id()) + { + int rc = WaitForSingleObject((HANDLE)mutex, 0); + + while(rc == WAIT_TIMEOUT) + { + dw_main_sleep(1); + rc = WaitForSingleObject((HANDLE)mutex, 0); + } + } + else + WaitForSingleObject((HANDLE)mutex, INFINITE); } /*