Mercurial > dwindows
comparison os2/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 | 2be5174bdb5d |
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 PM GUI | 3 * A GTK like implementation of the PM GUI |
4 * | 4 * |
5 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> | 5 * (C) 2000-2002 Brian Smith <dbsoft@technologist.com> |
6 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> | 6 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> |
7 * (C) 2000 Peter Nielsen <peter@pmview.com> | 7 * (C) 2000 Peter Nielsen <peter@pmview.com> |
8 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) | 8 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) |
9 * | 9 * |
10 */ | 10 */ |
91 char name[30]; | 91 char name[30]; |
92 | 92 |
93 } SignalList; | 93 } SignalList; |
94 | 94 |
95 /* List of signals and their equivilent OS/2 message */ | 95 /* List of signals and their equivilent OS/2 message */ |
96 #define SIGNALMAX 14 | 96 #define SIGNALMAX 15 |
97 | 97 |
98 SignalList SignalTranslate[SIGNALMAX] = { | 98 SignalList SignalTranslate[SIGNALMAX] = { |
99 { WM_SIZE, "configure_event" }, | 99 { WM_SIZE, "configure_event" }, |
100 { WM_CHAR, "key_press_event" }, | 100 { WM_CHAR, "key_press_event" }, |
101 { WM_BUTTON1DOWN, "button_press_event" }, | 101 { WM_BUTTON1DOWN, "button_press_event" }, |
107 { CN_ENTER, "container-select" }, | 107 { CN_ENTER, "container-select" }, |
108 { CN_CONTEXTMENU, "container-context" }, | 108 { CN_CONTEXTMENU, "container-context" }, |
109 { LN_SELECT, "item-select" }, | 109 { LN_SELECT, "item-select" }, |
110 { CN_EMPHASIS, "tree-select" }, | 110 { CN_EMPHASIS, "tree-select" }, |
111 { WM_SETFOCUS, "set-focus" }, | 111 { WM_SETFOCUS, "set-focus" }, |
112 { WM_USER+1, "lose-focus" } | 112 { WM_USER+1, "lose-focus" }, |
113 { SLN_SLIDERTRACK, "value_changed" } | |
113 }; | 114 }; |
114 | 115 |
115 /* This function adds a signal handler callback into the linked list. | 116 /* This function adds a signal handler callback into the linked list. |
116 */ | 117 */ |
117 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) | 118 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) |
184 | 185 |
185 WinQueryClassName(child, 99, tmpbuf); | 186 WinQueryClassName(child, 99, tmpbuf); |
186 | 187 |
187 if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ | 188 if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ |
188 WinSetOwner(child, dw); | 189 WinSetOwner(child, dw); |
189 if(strncmp(tmpbuf, "#38", 4)==0 && dw) /* Slider */ | |
190 WinSetOwner(child, 0); | |
191 else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) | 190 else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) |
192 dw = child; | 191 dw = child; |
193 | 192 |
194 _fix_button_owner(child, dw); | 193 _fix_button_owner(child, dw); |
195 } | 194 } |
260 */ | 259 */ |
261 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ | 260 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ |
262 strncmp(tmpbuf, "#3", 3)==0 || /* Button */ | 261 strncmp(tmpbuf, "#3", 3)==0 || /* Button */ |
263 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ | 262 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ |
264 strncmp(tmpbuf, "#7", 3)==0 || /* List box */ | 263 strncmp(tmpbuf, "#7", 3)==0 || /* List box */ |
265 strncmp(tmpbuf, "#10", 3)==0 || /* MLE */ | 264 strncmp(tmpbuf, "#10", 4)==0 || /* MLE */ |
266 strncmp(tmpbuf, "#32", 3)==0 || /* Spinbutton */ | 265 strncmp(tmpbuf, "#32", 4)==0 || /* Spinbutton */ |
267 strncmp(tmpbuf, "#37", 3)== 0) /* Container */ | 266 strncmp(tmpbuf, "#37", 4)==0 || /* Container */ |
267 strncmp(tmpbuf, "#38", 4)== 0) /* Slider */ | |
268 return 1; | 268 return 1; |
269 return 0; | 269 return 0; |
270 } | 270 } |
271 | 271 |
272 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) | 272 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) |
348 else | 348 else |
349 { | 349 { |
350 char tmpbuf[100] = ""; | 350 char tmpbuf[100] = ""; |
351 | 351 |
352 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | 352 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); |
353 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | 353 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ |
354 { | 354 { |
355 Box *notebox; | 355 Box *notebox; |
356 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, | 356 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, |
357 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); | 357 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); |
358 | 358 |
418 else | 418 else |
419 { | 419 { |
420 char tmpbuf[100] = ""; | 420 char tmpbuf[100] = ""; |
421 | 421 |
422 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | 422 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); |
423 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | 423 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ |
424 { | 424 { |
425 Box *notebox; | 425 Box *notebox; |
426 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, | 426 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, |
427 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); | 427 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); |
428 | 428 |
520 else | 520 else |
521 { | 521 { |
522 char tmpbuf[100] = ""; | 522 char tmpbuf[100] = ""; |
523 | 523 |
524 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | 524 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); |
525 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | 525 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ |
526 { | 526 { |
527 Box *notebox; | 527 Box *notebox; |
528 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, | 528 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, |
529 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); | 529 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); |
530 | 530 |
590 else | 590 else |
591 { | 591 { |
592 char tmpbuf[100] = ""; | 592 char tmpbuf[100] = ""; |
593 | 593 |
594 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | 594 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); |
595 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | 595 if(strncmp(tmpbuf, "#40", 4)==0) /* Notebook */ |
596 { | 596 { |
597 Box *notebox; | 597 Box *notebox; |
598 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, | 598 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, |
599 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); | 599 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); |
600 | 600 |
695 SWP swp; | 695 SWP swp; |
696 | 696 |
697 WinQueryWindowPos(hwndFrame, &swp); | 697 WinQueryWindowPos(hwndFrame, &swp); |
698 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy-1, SWP_SIZE); | 698 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy-1, SWP_SIZE); |
699 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_SIZE); | 699 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_SIZE); |
700 } | |
701 | |
702 /* Focus toplevel window */ | |
703 void _toplevel_focus(HWND handle) | |
704 { | |
705 HWND box, lastbox = WinQueryWindow(handle, QW_PARENT); | |
706 | |
707 /* Find the toplevel window */ | |
708 while((box = WinQueryWindow(lastbox, QW_PARENT)) > 0x80000001) | |
709 { | |
710 lastbox = box; | |
711 } | |
712 | |
713 box = WinWindowFromID(lastbox, FID_CLIENT); | |
714 if(box) | |
715 WinSetActiveWindow(HWND_DESKTOP, lastbox); | |
700 } | 716 } |
701 | 717 |
702 /* This function will recursively search a box and add up the total height of it */ | 718 /* This function will recursively search a box and add up the total height of it */ |
703 void _count_size(HWND box, int type, int *xsize, int *xorigsize) | 719 void _count_size(HWND box, int type, int *xsize, int *xorigsize) |
704 { | 720 { |
1236 | 1252 |
1237 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ | 1253 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ |
1238 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | 1254 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
1239 { | 1255 { |
1240 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); | 1256 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); |
1241 | 1257 Box *thisbox = NULL; |
1242 switch(msg) | 1258 HWND box; |
1243 { | 1259 |
1244 case WM_QUERYTRACKINFO: | 1260 box = WinWindowFromID(hWnd, FID_CLIENT); |
1261 if(box) | |
1262 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
1263 | |
1264 if(thisbox && !thisbox->titlebar) | |
1265 { | |
1266 switch(msg) | |
1245 { | 1267 { |
1246 if(blah && *blah) | 1268 case WM_QUERYTRACKINFO: |
1247 { | 1269 { |
1248 PTRACKINFO ptInfo; | 1270 if(blah && *blah) |
1249 int res; | 1271 { |
1250 PFNWP myfunc = *blah; | 1272 PTRACKINFO ptInfo; |
1251 res = (int)myfunc(hWnd, msg, mp1, mp2); | 1273 int res; |
1252 | 1274 PFNWP myfunc = *blah; |
1253 ptInfo = (PTRACKINFO)(mp2); | 1275 res = (int)myfunc(hWnd, msg, mp1, mp2); |
1254 | 1276 |
1255 ptInfo->ptlMinTrackSize.y = 8; | 1277 ptInfo = (PTRACKINFO)(mp2); |
1256 ptInfo->ptlMinTrackSize.x = 8; | 1278 |
1257 | 1279 ptInfo->ptlMinTrackSize.y = 8; |
1258 return (MRESULT)res; | 1280 ptInfo->ptlMinTrackSize.x = 8; |
1281 | |
1282 return (MRESULT)res; | |
1283 } | |
1259 } | 1284 } |
1260 } | 1285 } |
1261 } | 1286 } |
1287 | |
1262 if(blah && *blah) | 1288 if(blah && *blah) |
1263 { | 1289 { |
1264 PFNWP myfunc = *blah; | 1290 PFNWP myfunc = *blah; |
1265 return myfunc(hWnd, msg, mp1, mp2); | 1291 return myfunc(hWnd, msg, mp1, mp2); |
1266 } | 1292 } |
1356 return (MRESULT)TRUE; | 1382 return (MRESULT)TRUE; |
1357 } | 1383 } |
1358 } | 1384 } |
1359 return myfunc(hWnd, msg, mp1, mp2); | 1385 return myfunc(hWnd, msg, mp1, mp2); |
1360 } | 1386 } |
1361 | |
1362 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1363 } | |
1364 | |
1365 /* This procedure handles drawing of a percent bar */ | |
1366 MRESULT EXPENTRY _percentproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1367 { | |
1368 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); | |
1369 | |
1370 if(blah) | |
1371 return blah->oldproc(hWnd, msg, mp1, mp2); | |
1372 | 1387 |
1373 return WinDefWindowProc(hWnd, msg, mp1, mp2); | 1388 return WinDefWindowProc(hWnd, msg, mp1, mp2); |
1374 } | 1389 } |
1375 | 1390 |
1376 void _click_default(HWND handle) | 1391 void _click_default(HWND handle) |
1414 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); | 1429 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); |
1415 | 1430 |
1416 switch(msg) | 1431 switch(msg) |
1417 { | 1432 { |
1418 case WM_SETFOCUS: | 1433 case WM_SETFOCUS: |
1434 _toplevel_focus(hWnd); | |
1419 _run_event(hWnd, msg, mp1, mp2); | 1435 _run_event(hWnd, msg, mp1, mp2); |
1420 break; | 1436 break; |
1421 } | 1437 } |
1422 | 1438 |
1423 if(blah && blah->oldproc) | 1439 if(blah && blah->oldproc) |
1445 { | 1461 { |
1446 char tmpbuf[100]; | 1462 char tmpbuf[100]; |
1447 | 1463 |
1448 WinQueryClassName(hWnd, 99, tmpbuf); | 1464 WinQueryClassName(hWnd, 99, tmpbuf); |
1449 | 1465 |
1450 if(strncmp(tmpbuf, "#32", 3)==0) | 1466 if(strncmp(tmpbuf, "#32", 4)==0) |
1451 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); | 1467 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); |
1452 } | 1468 } |
1453 break; | 1469 break; |
1470 case WM_CONTROL: | |
1471 { | |
1472 char tmpbuf[100]; | |
1473 | |
1474 WinQueryClassName(hWnd, 99, tmpbuf); | |
1475 | |
1476 if(strncmp(tmpbuf, "#38", 4)==0) | |
1477 _run_event(hWnd, msg, mp1, mp2); | |
1478 } | |
1479 break; | |
1454 case WM_SETFOCUS: | 1480 case WM_SETFOCUS: |
1481 _toplevel_focus(hWnd); | |
1455 _run_event(hWnd, msg, mp1, mp2); | 1482 _run_event(hWnd, msg, mp1, mp2); |
1456 break; | 1483 break; |
1457 case WM_CHAR: | 1484 case WM_CHAR: |
1458 if(SHORT1FROMMP(mp2) == '\t') | 1485 if(SHORT1FROMMP(mp2) == '\t') |
1459 { | 1486 { |
1504 case WM_BUTTON2DOWN: | 1531 case WM_BUTTON2DOWN: |
1505 case WM_BUTTON3DOWN: | 1532 case WM_BUTTON3DOWN: |
1506 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); | 1533 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); |
1507 break; | 1534 break; |
1508 case WM_SETFOCUS: | 1535 case WM_SETFOCUS: |
1536 _toplevel_focus(hWnd); | |
1509 _run_event(hWnd, msg, mp1, mp2); | 1537 _run_event(hWnd, msg, mp1, mp2); |
1510 break; | 1538 break; |
1511 case WM_PAINT: | 1539 case WM_PAINT: |
1512 { | 1540 { |
1513 HWND parent = WinQueryWindow(hWnd, QW_PARENT); | 1541 HWND parent = WinQueryWindow(hWnd, QW_PARENT); |
1758 tmp = NULL; | 1786 tmp = NULL; |
1759 } | 1787 } |
1760 } | 1788 } |
1761 break; | 1789 break; |
1762 case WM_CONTROL: | 1790 case WM_CONTROL: |
1763 if(tmp->message == SHORT2FROMMP(mp1)) | 1791 if(tmp->message == SHORT2FROMMP(mp1) || (tmp->message == SLN_SLIDERTRACK && SHORT2FROMMP(mp1) == SLN_CHANGE)) |
1764 { | 1792 { |
1765 switch(SHORT2FROMMP(mp1)) | 1793 switch(SHORT2FROMMP(mp1)) |
1766 { | 1794 { |
1767 case CN_ENTER: | 1795 case CN_ENTER: |
1768 { | 1796 { |
1864 } | 1892 } |
1865 } | 1893 } |
1866 break; | 1894 break; |
1867 case LN_SELECT: | 1895 case LN_SELECT: |
1868 { | 1896 { |
1869 int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; | 1897 char classbuf[100]; |
1870 int id = SHORT1FROMMP(mp1); | 1898 |
1871 HWND conthwnd = dw_window_from_id(hWnd, id); | 1899 WinQueryClassName(tmp->window, 99, classbuf); |
1872 static int _recursing = 0; | 1900 |
1873 | 1901 if(strncmp(classbuf, "#38", 4) == 0) |
1874 if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2))) | |
1875 { | 1902 { |
1876 char buf1[500], classbuf[100]; | 1903 int (*valuechangedfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; |
1877 unsigned int index = dw_listbox_selected(tmp->window); | 1904 |
1878 | 1905 if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd) |
1879 dw_listbox_query_text(tmp->window, index, buf1, 500); | |
1880 | |
1881 WinQueryClassName(tmp->window, 99, classbuf); | |
1882 | |
1883 _recursing = 1; | |
1884 | |
1885 if(id && strncmp(classbuf, "#2", 3)==0) | |
1886 { | 1906 { |
1887 char *buf2; | 1907 static int lastvalue = -1; |
1888 | 1908 static HWND lasthwnd = NULLHANDLE; |
1889 buf2 = dw_window_get_text(tmp->window); | 1909 int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); |
1890 | 1910 if(lastvalue != ulValue || lasthwnd != tmp->window) |
1891 /* This is to make sure the listboxselect function doesn't | 1911 { |
1892 * get called if the user is modifying the entry text. | 1912 result = valuechangedfunc(tmp->window, ulValue, tmp->data); |
1893 */ | 1913 lastvalue = ulValue; |
1894 if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) | 1914 lasthwnd = tmp->window; |
1915 } | |
1916 tmp = NULL; | |
1917 } | |
1918 } | |
1919 else | |
1920 { | |
1921 int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; | |
1922 int id = SHORT1FROMMP(mp1); | |
1923 HWND conthwnd = dw_window_from_id(hWnd, id); | |
1924 static int _recursing = 0; | |
1925 | |
1926 if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2))) | |
1927 { | |
1928 char buf1[500]; | |
1929 unsigned int index = dw_listbox_selected(tmp->window); | |
1930 | |
1931 dw_listbox_query_text(tmp->window, index, buf1, 500); | |
1932 | |
1933 _recursing = 1; | |
1934 | |
1935 if(id && strncmp(classbuf, "#2", 3)==0) | |
1936 { | |
1937 char *buf2; | |
1938 | |
1939 buf2 = dw_window_get_text(tmp->window); | |
1940 | |
1941 /* This is to make sure the listboxselect function doesn't | |
1942 * get called if the user is modifying the entry text. | |
1943 */ | |
1944 if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) | |
1945 result = listboxselectfunc(tmp->window, index, tmp->data); | |
1946 | |
1947 if(buf2) | |
1948 free(buf2); | |
1949 } | |
1950 else | |
1895 result = listboxselectfunc(tmp->window, index, tmp->data); | 1951 result = listboxselectfunc(tmp->window, index, tmp->data); |
1896 | 1952 |
1897 if(buf2) | 1953 _recursing = 0; |
1898 free(buf2); | 1954 tmp = NULL; |
1899 } | 1955 } |
1900 else | 1956 } |
1901 result = listboxselectfunc(tmp->window, index, tmp->data); | 1957 } |
1902 | 1958 break; |
1903 _recursing = 0; | 1959 case SLN_SLIDERTRACK: |
1960 { | |
1961 int (*valuechangedfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; | |
1962 | |
1963 if(tmp->window == hWnd || WinQueryWindow(tmp->window, QW_PARENT) == hWnd) | |
1964 { | |
1965 static int lastvalue = -1; | |
1966 static HWND lasthwnd = NULLHANDLE; | |
1967 int ulValue = (int)WinSendMsg(tmp->window, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); | |
1968 if(lastvalue != ulValue || lasthwnd != tmp->window) | |
1969 { | |
1970 result = valuechangedfunc(tmp->window, ulValue, tmp->data); | |
1971 lastvalue = ulValue; | |
1972 lasthwnd = tmp->window; | |
1973 } | |
1904 tmp = NULL; | 1974 tmp = NULL; |
1905 } | 1975 } |
1906 } | 1976 } |
1977 | |
1907 break; | 1978 break; |
1908 } | 1979 } |
1909 } | 1980 } |
1910 break; | 1981 break; |
1911 } | 1982 } |
1918 | 1989 |
1919 return (MRESULT)result; | 1990 return (MRESULT)result; |
1920 } | 1991 } |
1921 #endif | 1992 #endif |
1922 | 1993 |
1994 int _warp4_focus_fix(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1995 { | |
1996 /* This is a hack to stop an infinite loop in the | |
1997 * Warp 4 default window procedure. It seems that | |
1998 * under very rare circumstances, the same WM_FOCUSCHANGE | |
1999 * message will bounce between an entryfield and | |
2000 * the frame it sits on, this will stop duplicate | |
2001 * messages and thus prevent the infinite loop. | |
2002 */ | |
2003 if(msg == WM_FOCUSCHANGE && SHORT1FROMMP(mp2)) | |
2004 { | |
2005 static HWND lastfocus = 0; | |
2006 static time_t lasttime = 0; | |
2007 static int count = 0; | |
2008 time_t currtime = time(NULL); | |
2009 | |
2010 if(lastfocus == (HWND)mp1 && currtime == lasttime) | |
2011 { | |
2012 if(count > 5) | |
2013 { | |
2014 count = 0; | |
2015 return 1; | |
2016 } | |
2017 count++; | |
2018 return 0; | |
2019 } | |
2020 | |
2021 count = 0; | |
2022 lastfocus = (HWND)mp1; | |
2023 lasttime = currtime; | |
2024 } | |
2025 return 0; | |
2026 } | |
2027 | |
1923 /* Handles control messages sent to the box (owner). */ | 2028 /* Handles control messages sent to the box (owner). */ |
1924 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | 2029 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
1925 { | 2030 { |
1926 Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); | 2031 Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); |
1927 | 2032 |
1931 case WM_CONTROL: | 2036 case WM_CONTROL: |
1932 _run_event(hWnd, msg, mp1, mp2); | 2037 _run_event(hWnd, msg, mp1, mp2); |
1933 break; | 2038 break; |
1934 } | 2039 } |
1935 #endif | 2040 #endif |
2041 | |
2042 if(_warp4_focus_fix(hWnd, msg, mp1, mp2)) | |
2043 return (MRESULT)0; | |
2044 if(msg == WM_SETFOCUS) | |
2045 _toplevel_focus(hWnd); | |
2046 | |
1936 if(blah && blah->oldproc) | 2047 if(blah && blah->oldproc) |
1937 { | |
1938 return blah->oldproc(hWnd, msg, mp1, mp2); | 2048 return blah->oldproc(hWnd, msg, mp1, mp2); |
1939 } | |
1940 | 2049 |
1941 return WinDefWindowProc(hWnd, msg, mp1, mp2); | 2050 return WinDefWindowProc(hWnd, msg, mp1, mp2); |
1942 } | 2051 } |
1943 | 2052 |
1944 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ | 2053 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ |
2042 char tmpbuf[100]; | 2151 char tmpbuf[100]; |
2043 | 2152 |
2044 WinQueryClassName(mybox->items[z].hwnd, 99, tmpbuf); | 2153 WinQueryClassName(mybox->items[z].hwnd, 99, tmpbuf); |
2045 | 2154 |
2046 /* If we have a notebook we resize the page again. */ | 2155 /* If we have a notebook we resize the page again. */ |
2047 if(strncmp(tmpbuf, "#40", 3)==0) | 2156 if(strncmp(tmpbuf, "#40", 4)==0) |
2048 { | 2157 { |
2049 unsigned long x, y, width, height; | 2158 unsigned long x, y, width, height; |
2050 int page = dw_notebook_page_query(mybox->items[z].hwnd); | 2159 int page = dw_notebook_page_query(mybox->items[z].hwnd); |
2051 HWND pagehwnd = (HWND)WinSendMsg(mybox->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); | 2160 HWND pagehwnd = (HWND)WinSendMsg(mybox->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); |
2052 RECTL rc; | 2161 RECTL rc; |
2129 case WM_DESTROY: | 2238 case WM_DESTROY: |
2130 /* Free memory before destroying */ | 2239 /* Free memory before destroying */ |
2131 _free_window_memory(hWnd); | 2240 _free_window_memory(hWnd); |
2132 break; | 2241 break; |
2133 } | 2242 } |
2243 | |
2244 if(_warp4_focus_fix(hWnd, msg, mp1, mp2)) | |
2245 return (MRESULT)0; | |
2246 | |
2134 if(result != -1) | 2247 if(result != -1) |
2135 return (MRESULT)result; | 2248 return (MRESULT)result; |
2136 else | 2249 else |
2137 return WinDefWindowProc(hWnd, msg, mp1, mp2); | 2250 return WinDefWindowProc(hWnd, msg, mp1, mp2); |
2138 } | 2251 } |
2671 { | 2784 { |
2672 case WM_BUTTON1DOWN: | 2785 case WM_BUTTON1DOWN: |
2673 case WM_BUTTON2DOWN: | 2786 case WM_BUTTON2DOWN: |
2674 case WM_BUTTON3DOWN: | 2787 case WM_BUTTON3DOWN: |
2675 if(!res) | 2788 if(!res) |
2676 WinSetFocus(HWND_DESKTOP, hwnd); | 2789 _toplevel_focus(hwnd); |
2677 return (MPARAM)TRUE; | 2790 return (MPARAM)TRUE; |
2678 } | 2791 } |
2679 return WinDefWindowProc(hwnd, msg, mp1, mp2); | 2792 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2680 } | 2793 } |
2681 | 2794 |
2754 WinTerminate(dwhab); | 2867 WinTerminate(dwhab); |
2755 } | 2868 } |
2756 } | 2869 } |
2757 | 2870 |
2758 /* | 2871 /* |
2759 * Runs a message loop for Dynamic Windows, for a period of seconds. | 2872 * Runs a message loop for Dynamic Windows, for a period of milliseconds. |
2760 * Parameters: | 2873 * Parameters: |
2761 * seconds: Number of seconds to run the loop for. | 2874 * milliseconds: Number of milliseconds to run the loop for. |
2762 */ | 2875 */ |
2763 void dw_main_sleep(int seconds) | 2876 void dw_main_sleep(int milliseconds) |
2764 { | 2877 { |
2765 QMSG qmsg; | 2878 QMSG qmsg; |
2766 time_t start = time(NULL); | 2879 double start = (double)clock(); |
2767 | 2880 |
2768 while(time(NULL) - start <= seconds) | 2881 while(((clock() - start) / (CLOCKS_PER_SEC/1000)) <= milliseconds) |
2769 { | 2882 { |
2770 if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) | 2883 if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) |
2771 { | 2884 { |
2772 WinGetMsg(dwhab, &qmsg, 0, 0, 0); | 2885 WinGetMsg(dwhab, &qmsg, 0, 0, 0); |
2773 WinDispatchMsg(dwhab, &qmsg); | 2886 WinDispatchMsg(dwhab, &qmsg); |
3702 NULLHANDLE, | 3815 NULLHANDLE, |
3703 HWND_TOP, | 3816 HWND_TOP, |
3704 id, | 3817 id, |
3705 NULL, | 3818 NULL, |
3706 NULL); | 3819 NULL); |
3707 dw_window_set_font(tmp, DefaultFont); | |
3708 dw_window_set_font(tmp, DefaultFont); | 3820 dw_window_set_font(tmp, DefaultFont); |
3709 blah->oldproc = WinSubclassWindow(tmp, _comboentryproc); | 3821 blah->oldproc = WinSubclassWindow(tmp, _comboentryproc); |
3710 WinSetWindowPtr(tmp, QWP_USER, blah); | 3822 WinSetWindowPtr(tmp, QWP_USER, blah); |
3711 return tmp; | 3823 return tmp; |
3712 } | 3824 } |
3950 WinSetWindowPtr(tmp, QWP_USER, blah); | 4062 WinSetWindowPtr(tmp, QWP_USER, blah); |
3951 return tmp; | 4063 return tmp; |
3952 } | 4064 } |
3953 | 4065 |
3954 /* | 4066 /* |
4067 * Create a new slider window (widget) to be packed. | |
4068 * Parameters: | |
4069 * vertical: TRUE or FALSE if slider is vertical. | |
4070 * increments: Number of increments available. | |
4071 * id: An ID to be used with WinWindowFromID() or 0L. | |
4072 */ | |
4073 HWND dw_slider_new(int vertical, int increments, ULONG id) | |
4074 { | |
4075 WindowData *blah = calloc(1, sizeof(WindowData)); | |
4076 SLDCDATA sldcData = { sizeof(SLDCDATA), increments, 0, 0, 0 }; | |
4077 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
4078 WC_SLIDER, | |
4079 "", | |
4080 WS_VISIBLE | SLS_SNAPTOINCREMENT | | |
4081 (vertical ? SLS_VERTICAL : SLS_HORIZONTAL), | |
4082 0,0,2000,1000, | |
4083 NULLHANDLE, | |
4084 HWND_TOP, | |
4085 id, | |
4086 &sldcData, | |
4087 NULL); | |
4088 | |
4089 blah->oldproc = WinSubclassWindow(tmp, _entryproc); | |
4090 WinSetWindowPtr(tmp, QWP_USER, blah); | |
4091 return tmp; | |
4092 } | |
4093 | |
4094 /* | |
3955 * Create a new percent bar window (widget) to be packed. | 4095 * Create a new percent bar window (widget) to be packed. |
3956 * Parameters: | 4096 * Parameters: |
3957 * id: An ID to be used with WinWindowFromID() or 0L. | 4097 * id: An ID to be used with WinWindowFromID() or 0L. |
3958 */ | 4098 */ |
3959 HWND dw_percent_new(ULONG id) | 4099 HWND dw_percent_new(ULONG id) |
3960 { | 4100 { |
3961 WindowData *blah = calloc(1, sizeof(WindowData)); | |
3962 HWND tmp = WinCreateWindow(HWND_OBJECT, | 4101 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3963 WC_SLIDER, | 4102 WC_SLIDER, |
3964 "", | 4103 "", |
3965 WS_VISIBLE | SLS_READONLY | 4104 WS_VISIBLE | SLS_READONLY |
3966 | SLS_RIBBONSTRIP, | 4105 | SLS_RIBBONSTRIP, |
3968 NULLHANDLE, | 4107 NULLHANDLE, |
3969 HWND_TOP, | 4108 HWND_TOP, |
3970 id, | 4109 id, |
3971 NULL, | 4110 NULL, |
3972 NULL); | 4111 NULL); |
3973 | 4112 dw_window_disable(tmp); |
3974 blah->oldproc = WinSubclassWindow(tmp, _percentproc); | |
3975 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3976 return tmp; | 4113 return tmp; |
3977 } | 4114 } |
3978 | 4115 |
3979 /* | 4116 /* |
3980 * Create a new checkbox window (widget) to be packed. | 4117 * Create a new checkbox window (widget) to be packed. |
4176 } | 4313 } |
4177 } | 4314 } |
4178 | 4315 |
4179 void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | 4316 void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) |
4180 { | 4317 { |
4181 HWND boxowner = NULLHANDLE; | |
4182 Box *thisbox; | 4318 Box *thisbox; |
4183 | 4319 |
4184 if(WinWindowFromID(box, FID_CLIENT)) | 4320 if(WinWindowFromID(box, FID_CLIENT)) |
4185 { | 4321 { |
4186 box = WinWindowFromID(box, FID_CLIENT); | 4322 box = WinWindowFromID(box, FID_CLIENT); |
4241 | 4377 |
4242 thisbox->count++; | 4378 thisbox->count++; |
4243 | 4379 |
4244 /* Don't set the ownership if it's an entryfield or spinbutton */ | 4380 /* Don't set the ownership if it's an entryfield or spinbutton */ |
4245 WinQueryClassName(item, 99, tmpbuf); | 4381 WinQueryClassName(item, 99, tmpbuf); |
4246 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) | 4382 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0) |
4247 { | 4383 WinSetOwner(item, box); |
4248 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0) | |
4249 WinSetOwner(item, boxowner); | |
4250 else | |
4251 WinSetOwner(item, box); | |
4252 } | |
4253 WinSetParent(item, box, FALSE); | 4384 WinSetParent(item, box, FALSE); |
4254 } | 4385 } |
4255 } | 4386 } |
4256 | 4387 |
4257 /* | 4388 /* |
4820 } | 4951 } |
4821 | 4952 |
4822 /* | 4953 /* |
4823 * Returns the range of the percent bar. | 4954 * Returns the range of the percent bar. |
4824 * Parameters: | 4955 * Parameters: |
4956 * handle: Handle to the percent bar to be queried. | |
4957 */ | |
4958 unsigned int dw_percent_query_range(HWND handle) | |
4959 { | |
4960 return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); | |
4961 } | |
4962 | |
4963 /* | |
4964 * Sets the percent bar position. | |
4965 * Parameters: | |
4966 * handle: Handle to the percent bar to be set. | |
4967 * position: Position of the percent bar withing the range. | |
4968 */ | |
4969 void dw_percent_set_pos(HWND handle, unsigned int position) | |
4970 { | |
4971 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)position); | |
4972 } | |
4973 | |
4974 /* | |
4975 * Returns the position of the slider. | |
4976 * Parameters: | |
4825 * handle: Handle to the slider to be queried. | 4977 * handle: Handle to the slider to be queried. |
4826 */ | 4978 */ |
4827 unsigned int dw_percent_query_range(HWND handle) | 4979 unsigned int dw_slider_query_pos(HWND handle) |
4828 { | 4980 { |
4829 return SHORT2FROMMP(WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0)); | 4981 return (unsigned int)WinSendMsg(handle, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), 0); |
4830 } | 4982 } |
4831 | 4983 |
4832 /* | 4984 /* |
4833 * Sets the percent bar position. | 4985 * Sets the slider position. |
4834 * Parameters: | 4986 * Parameters: |
4835 * handle: Handle to the slider to be set. | 4987 * handle: Handle to the slider to be set. |
4836 * position: Position of the slider withing the range. | 4988 * position: Position of the slider withing the range. |
4837 */ | 4989 */ |
4838 void dw_percent_set_pos(HWND handle, unsigned int position) | 4990 void dw_slider_set_pos(HWND handle, unsigned int position) |
4839 { | 4991 { |
4840 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), (MPARAM)position); | 4992 WinSendMsg(handle, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION, SMA_INCREMENTVALUE), (MPARAM)position); |
4841 } | 4993 } |
4842 | 4994 |
4843 /* | 4995 /* |
4844 * Sets the spinbutton value. | 4996 * Sets the spinbutton value. |
4845 * Parameters: | 4997 * Parameters: |
6158 DosCloseMutexSem(mutex); | 6310 DosCloseMutexSem(mutex); |
6159 } | 6311 } |
6160 | 6312 |
6161 /* | 6313 /* |
6162 * Tries to gain access to the semaphore, if it can't it blocks. | 6314 * Tries to gain access to the semaphore, if it can't it blocks. |
6315 * If we are in a callback we must keep the message loop running | |
6316 * while blocking. | |
6163 * Parameters: | 6317 * Parameters: |
6164 * mutex: The handle to the mutex returned by dw_mutex_new(). | 6318 * mutex: The handle to the mutex returned by dw_mutex_new(). |
6165 */ | 6319 */ |
6166 void dw_mutex_lock(HMTX mutex) | 6320 void dw_mutex_lock(HMTX mutex) |
6167 { | 6321 { |
6168 DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); | 6322 if(_dwtid == dw_thread_id()) |
6323 { | |
6324 int rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); | |
6325 | |
6326 while(rc == ERROR_TIMEOUT) | |
6327 { | |
6328 dw_main_sleep(10); | |
6329 rc = DosRequestMutexSem(mutex, SEM_IMMEDIATE_RETURN); | |
6330 } | |
6331 } | |
6332 else | |
6333 DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); | |
6169 } | 6334 } |
6170 | 6335 |
6171 /* | 6336 /* |
6172 * Reliquishes the access to the semaphore. | 6337 * Reliquishes the access to the semaphore. |
6173 * Parameters: | 6338 * Parameters: |
6419 } | 6584 } |
6420 } | 6585 } |
6421 | 6586 |
6422 void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | 6587 void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) |
6423 { | 6588 { |
6424 HWND boxowner = NULLHANDLE; | |
6425 Box *thisbox; | 6589 Box *thisbox; |
6426 | 6590 |
6427 if(WinWindowFromID(box, FID_CLIENT)) | 6591 if(WinWindowFromID(box, FID_CLIENT)) |
6428 { | 6592 { |
6429 box = WinWindowFromID(box, FID_CLIENT); | 6593 box = WinWindowFromID(box, FID_CLIENT); |
6474 | 6638 |
6475 thisbox->count++; | 6639 thisbox->count++; |
6476 | 6640 |
6477 WinQueryClassName(item, 99, tmpbuf); | 6641 WinQueryClassName(item, 99, tmpbuf); |
6478 /* Don't set the ownership if it's an entryfield or spinbutton */ | 6642 /* Don't set the ownership if it's an entryfield or spinbutton */ |
6479 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) | 6643 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 4)!=0) |
6480 { | 6644 WinSetOwner(item, box); |
6481 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0) | |
6482 WinSetOwner(item, boxowner); | |
6483 else | |
6484 WinSetOwner(item, box); | |
6485 } | |
6486 WinSetParent(item, box, FALSE); | 6645 WinSetParent(item, box, FALSE); |
6487 } | 6646 } |
6488 } | 6647 } |
6489 | 6648 |
6490 /* The following two functions graciously contributed by Peter Nielsen. */ | 6649 /* The following two functions graciously contributed by Peter Nielsen. */ |