Mercurial > dwindows
comparison win/dw.c @ 57:1ed95c8ec2ff
Added a mutex lock and unlock in the pointer calls. And fixed a warning
on OS/2.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Wed, 21 Nov 2001 23:30:24 +0000 |
parents | b6948eac375a |
children | 5c66a108aa47 |
comparison
equal
deleted
inserted
replaced
56:b0f94956c981 | 57:1ed95c8ec2ff |
---|---|
1 /* | 1 /* |
2 * Dynamic Windows: | 2 * Dynamic Windows: |
3 * A GTK like implementation of the Win32 GUI | 3 * A GTK like implementation of the PM GUI |
4 * | 4 * |
5 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> | 5 * (C) 2000,2001 Brian Smith <dbsoft@technologist.com> |
6 * (C) 2000 Achim Hasenmueller <achimha@innotek.de> | |
7 * (C) 2000 Peter Nielsen <peter@pmview.com> | |
8 * (C) 1998 Sergey I. Yevtushenko (some code borrowed from cell toolkit) | |
6 * | 9 * |
7 */ | 10 */ |
8 #define _WIN32_IE 0x0500 | 11 #define INCL_DOS |
9 #define WINVER 0x400 | 12 #define INCL_DOSERRORS |
10 #include <windows.h> | 13 #define INCL_WIN |
11 #include <windowsx.h> | 14 #define INCL_GPI |
12 #include <commctrl.h> | 15 |
16 #include <os2.h> | |
13 #include <stdlib.h> | 17 #include <stdlib.h> |
14 #include <string.h> | 18 #include <string.h> |
15 #include <stdio.h> | 19 #include <stdio.h> |
20 #include <stdarg.h> | |
21 #include <stddef.h> | |
22 #include <ctype.h> | |
16 #include <process.h> | 23 #include <process.h> |
17 #include <time.h> | 24 #include <time.h> |
18 #include "dw.h" | 25 #include "dw.h" |
19 | 26 |
20 /* this is the callback handle for the window procedure */ | 27 #define QWP_USER 0 |
21 /* make sure you always match the calling convention! */ | 28 |
22 int (*filterfunc)(HWND, UINT, WPARAM, LPARAM) = 0L; | 29 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2); |
23 | 30 |
24 HWND hwndBubble = (HWND)NULL, hwndBubbleLast, DW_HWND_OBJECT = (HWND)NULL; | 31 char ClassName[] = "dynamicwindows"; |
25 | 32 char SplitbarClassName[] = "dwsplitbar"; |
26 HINSTANCE DWInstance = NULL; | 33 char DefaultFont[] = "9.WarpSans"; |
27 | 34 |
28 DWORD dwVersion = 0; | 35 /* this is the callback handle for the window procedure |
29 | 36 * make sure you always match the calling convention! |
30 /* I should probably check the actual file version, but this will do for now */ | 37 */ |
31 #define IS_WIN98PLUS (LOBYTE(LOWORD(dwVersion)) > 4 || \ | 38 int (* EXPENTRY filterfunc)(HWND, ULONG, MPARAM, MPARAM) = 0L; |
32 (LOBYTE(LOWORD(dwVersion)) == 4 && HIBYTE(LOWORD(dwVersion)) > 0)) | 39 |
33 | 40 HAB dwhab = 0; |
34 char monthlist[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", | 41 HMQ dwhmq = 0; |
35 "Sep", "Oct", "Nov", "Dec" }; | 42 DWTID _dwtid = 0; |
36 | 43 LONG _foreground = 0xAAAAAA, _background = 0; |
37 int main(int argc, char *argv[]); | 44 |
38 | 45 HWND hwndBubble = NULLHANDLE, hwndBubbleLast = NULLHANDLE; |
39 #define ICON_INDEX_LIMIT 200 | 46 PRECORDCORE pCore = NULL; |
40 HICON lookup[200]; | 47 ULONG aulBuffer[4]; |
41 HIMAGELIST hSmall = 0, hLarge = 0; | 48 HWND lasthcnr = 0, lastitem = 0; |
42 | 49 |
43 #define THREAD_LIMIT 128 | 50 #define IS_WARP4() (aulBuffer[0] == 20 && aulBuffer[1] >= 40) |
44 COLORREF _foreground[THREAD_LIMIT]; | 51 |
45 COLORREF _background[THREAD_LIMIT]; | 52 #ifndef min |
46 HPEN _hPen[THREAD_LIMIT]; | 53 #define min(a, b) (((a < b) ? a : b)) |
47 HBRUSH _hBrush[THREAD_LIMIT]; | 54 #endif |
48 | 55 |
49 #ifdef DWDEBUG | 56 #ifdef DWDEBUG |
50 FILE *f; | 57 FILE *f; |
51 | 58 |
52 void reopen(void) | 59 void reopen(void) |
53 { | 60 { |
54 fclose(f); | 61 fclose(f); |
55 f = fopen("dw.log", "at"); | 62 f = fopen("dw.log", "a+"); |
56 } | 63 } |
57 #endif | 64 #endif |
58 | |
59 BYTE _red[] = { 0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77, | |
60 0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 }; | |
61 BYTE _green[] = { 0x00, 0x00, 0xbb, 0xaa, 0x00, 0x00, 0xbb, 0xaa, 0x77, | |
62 0x00, 0xff, 0xee, 0x00, 0x00, 0xee, 0xff, 0xaa, 0x00 }; | |
63 BYTE _blue[] = { 0x00, 0x00, 0x00, 0x00, 0xcc, 0xbb, 0xbb, 0xaa, 0x77, | |
64 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0xff, 0xaa, 0x00}; | |
65 | |
66 HBRUSH _colors[18]; | |
67 | 65 |
68 static LONG lColor[SPLITBAR_WIDTH] = | 66 static LONG lColor[SPLITBAR_WIDTH] = |
69 { | 67 { |
70 DW_CLR_BLACK, | 68 DW_CLR_BLACK, |
71 DW_CLR_PALEGRAY, | 69 DW_CLR_PALEGRAY, |
72 DW_CLR_WHITE | 70 DW_CLR_WHITE |
73 }; | 71 }; |
74 | |
75 void _resize_notebook_page(HWND handle, int pageid); | |
76 int _lookup_icon(HWND handle, HICON hicon, int type); | |
77 | 72 |
78 #ifdef NO_SIGNALS | 73 #ifdef NO_SIGNALS |
79 #define USE_FILTER | 74 #define USE_FILTER |
80 #else | 75 #else |
81 typedef struct _sighandler | 76 typedef struct _sighandler |
87 void *data; | 82 void *data; |
88 | 83 |
89 } SignalHandler; | 84 } SignalHandler; |
90 | 85 |
91 SignalHandler *Root = NULL; | 86 SignalHandler *Root = NULL; |
92 int _index; | |
93 | 87 |
94 typedef struct | 88 typedef struct |
95 { | 89 { |
96 ULONG message; | 90 ULONG message; |
97 char name[30]; | 91 char name[30]; |
98 | 92 |
99 } SignalList; | 93 } SignalList; |
100 | 94 |
101 /* List of signals and their equivilent Win32 message */ | 95 /* List of signals and their equivilent OS/2 message */ |
102 #define SIGNALMAX 14 | 96 #define SIGNALMAX 14 |
103 | 97 |
104 SignalList SignalTranslate[SIGNALMAX] = { | 98 SignalList SignalTranslate[SIGNALMAX] = { |
105 { WM_SIZE, "configure_event" }, | 99 { WM_SIZE, "configure_event" }, |
106 { WM_CHAR, "key_press_event" }, | 100 { WM_CHAR, "key_press_event" }, |
107 { WM_LBUTTONDOWN, "button_press_event" }, | 101 { WM_BUTTON1DOWN, "button_press_event" }, |
108 { WM_LBUTTONUP, "button_release_event" }, | 102 { WM_BUTTON1UP, "button_release_event"}, |
109 { WM_MOUSEMOVE, "motion_notify_event" }, | 103 { WM_MOUSEMOVE, "motion_notify_event" }, |
110 { WM_CLOSE, "delete_event" }, | 104 { WM_CLOSE, "delete_event" }, |
111 { WM_PAINT, "expose_event" }, | 105 { WM_PAINT, "expose_event" }, |
112 { WM_COMMAND, "clicked" }, | 106 { WM_COMMAND, "clicked" }, |
113 { NM_DBLCLK, "container-select" }, | 107 { CN_ENTER, "container-select" }, |
114 { NM_RCLICK, "container-context" }, | 108 { CN_CONTEXTMENU, "container-context" }, |
115 { LBN_SELCHANGE, "item-select" }, | 109 { LN_SELECT, "item-select" }, |
116 { TVN_SELCHANGED, "tree-select" }, | 110 { CN_EMPHASIS, "tree-select" }, |
117 { WM_SETFOCUS, "set-focus" }, | 111 { WM_SETFOCUS, "set-focus" }, |
118 { WM_USER+1, "lose-focus" } | 112 { WM_USER+1, "lose-focus" } |
119 }; | 113 }; |
120 | |
121 #ifdef BUILD_DLL | |
122 void Win32_Set_Instance(HINSTANCE hInstance) | |
123 { | |
124 DWInstance = hInstance; | |
125 } | |
126 #else | |
127 char **_convertargs(int *count, char *start) | |
128 { | |
129 char *tmp, *argstart, **argv; | |
130 int loc = 0, inquotes = 0; | |
131 | |
132 (*count) = 1; | |
133 | |
134 tmp = start; | |
135 | |
136 /* Count the number of entries */ | |
137 if(*start) | |
138 { | |
139 (*count)++; | |
140 | |
141 while(*tmp) | |
142 { | |
143 if(*tmp == '"' && inquotes) | |
144 inquotes = 0; | |
145 else if(*tmp == '"' && !inquotes) | |
146 inquotes = 1; | |
147 else if(*tmp == ' ' && !inquotes) | |
148 { | |
149 /* Push past any white space */ | |
150 while(*(tmp+1) == ' ') | |
151 tmp++; | |
152 /* If we aren't at the end of the command | |
153 * line increment the count. | |
154 */ | |
155 if(*(tmp+1)) | |
156 (*count)++; | |
157 } | |
158 tmp++; | |
159 } | |
160 } | |
161 | |
162 argv = (char **)malloc(sizeof(char *) * ((*count)+1)); | |
163 argv[0] = malloc(260); | |
164 GetModuleFileName(DWInstance, argv[0], 260); | |
165 | |
166 argstart = tmp = start; | |
167 | |
168 if(*start) | |
169 { | |
170 loc = 1; | |
171 | |
172 while(*tmp) | |
173 { | |
174 if(*tmp == '"' && inquotes) | |
175 { | |
176 *tmp = 0; | |
177 inquotes = 0; | |
178 } | |
179 else if(*tmp == '"' && !inquotes) | |
180 { | |
181 argstart = tmp+1; | |
182 inquotes = 1; | |
183 } | |
184 else if(*tmp == ' ' && !inquotes) | |
185 { | |
186 *tmp = 0; | |
187 argv[loc] = strdup(argstart); | |
188 | |
189 /* Push past any white space */ | |
190 while(*(tmp+1) == ' ') | |
191 tmp++; | |
192 | |
193 /* Move the start pointer */ | |
194 argstart = tmp+1; | |
195 | |
196 /* If we aren't at the end of the command | |
197 * line increment the count. | |
198 */ | |
199 if(*(tmp+1)) | |
200 loc++; | |
201 } | |
202 tmp++; | |
203 } | |
204 if(*argstart) | |
205 argv[loc] = strdup(argstart); | |
206 } | |
207 argv[loc+1] = NULL; | |
208 return argv; | |
209 } | |
210 | |
211 /* Ok this is a really big hack but what the hell ;) */ | |
212 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) | |
213 { | |
214 char **argv; | |
215 int argc; | |
216 | |
217 DWInstance = hInstance; | |
218 | |
219 argv = _convertargs(&argc, lpCmdLine); | |
220 | |
221 return main(argc, argv); | |
222 } | |
223 #endif | |
224 | |
225 /* This should return true for WinNT/2K/XP and false on Win9x */ | |
226 int IsWinNT(void) | |
227 { | |
228 static int isnt = -1; | |
229 | |
230 if(isnt == -1) | |
231 { | |
232 if (GetVersion() < 0x80000000) | |
233 isnt = 1; | |
234 else | |
235 isnt = 0; | |
236 } | |
237 return isnt; | |
238 } | |
239 | 114 |
240 /* This function adds a signal handler callback into the linked list. | 115 /* This function adds a signal handler callback into the linked list. |
241 */ | 116 */ |
242 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) | 117 void _new_signal(ULONG message, HWND window, void *signalfunction, void *data) |
243 { | 118 { |
283 } | 158 } |
284 return 0L; | 159 return 0L; |
285 } | 160 } |
286 #endif | 161 #endif |
287 | 162 |
288 /* This function removes and handlers on windows and frees | 163 typedef struct _CNRITEM |
289 * the user memory allocated to it. | 164 { |
290 */ | 165 MINIRECORDCORE rc; |
291 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam) | 166 HPOINTER hptrIcon; |
292 { | 167 PVOID user; |
293 void *ptr = (void *)GetWindowLong(handle, GWL_USERDATA); | 168 |
169 } CNRITEM, *PCNRITEM; | |
170 | |
171 | |
172 /* This function changes the owner of buttons in to the | |
173 * dynamicwindows handle to fix a problem in notebooks. | |
174 */ | |
175 void _fix_button_owner(HWND handle, HWND dw) | |
176 { | |
177 HENUM henum; | |
178 HWND child; | |
179 | |
180 henum = WinBeginEnumWindows(handle); | |
181 while((child = WinGetNextWindow(henum)) != NULLHANDLE) | |
182 { | |
183 char tmpbuf[100]; | |
184 | |
185 WinQueryClassName(child, 99, tmpbuf); | |
186 | |
187 if(strncmp(tmpbuf, "#3", 3)==0 && dw) /* Button */ | |
188 WinSetOwner(child, dw); | |
189 else if(strncmp(tmpbuf, "dynamicwindows", 14) == 0) | |
190 dw = child; | |
191 | |
192 _fix_button_owner(child, dw); | |
193 } | |
194 WinEndEnumWindows(henum); | |
195 return; | |
196 } | |
197 | |
198 void _disconnect_windows(HWND handle) | |
199 { | |
200 HENUM henum; | |
201 HWND child; | |
294 | 202 |
295 #ifndef NO_SIGNALS | 203 #ifndef NO_SIGNALS |
296 dw_signal_disconnect_by_window(handle); | 204 dw_signal_disconnect_by_window(handle); |
297 #endif | 205 #endif |
298 | 206 |
207 henum = WinBeginEnumWindows(handle); | |
208 while((child = WinGetNextWindow(henum)) != NULLHANDLE) | |
209 _disconnect_windows(child); | |
210 | |
211 WinEndEnumWindows(henum); | |
212 } | |
213 | |
214 /* This function removes and handlers on windows and frees | |
215 * the user memory allocated to it. | |
216 */ | |
217 void _free_window_memory(HWND handle) | |
218 { | |
219 HENUM henum; | |
220 HWND child; | |
221 void *ptr = (void *)WinQueryWindowPtr(handle, QWP_USER); | |
222 | |
223 #ifndef NO_SIGNALS | |
224 dw_signal_disconnect_by_window(handle); | |
225 #endif | |
226 | |
299 if(ptr) | 227 if(ptr) |
300 { | 228 { |
301 SetWindowLong(handle, GWL_USERDATA, 0); | 229 WinSetWindowPtr(handle, QWP_USER, 0); |
302 free(ptr); | 230 free(ptr); |
303 } | 231 } |
304 return TRUE; | 232 |
233 henum = WinBeginEnumWindows(handle); | |
234 while((child = WinGetNextWindow(henum)) != NULLHANDLE) | |
235 _free_window_memory(child); | |
236 | |
237 WinEndEnumWindows(henum); | |
238 return; | |
305 } | 239 } |
306 | 240 |
307 /* This function returns 1 if the window (widget) handle | 241 /* This function returns 1 if the window (widget) handle |
308 * passed to it is a valid window that can gain input focus. | 242 * passed to it is a valid window that can gain input focus. |
309 */ | 243 */ |
312 char tmpbuf[100]; | 246 char tmpbuf[100]; |
313 | 247 |
314 if(!handle) | 248 if(!handle) |
315 return 0; | 249 return 0; |
316 | 250 |
317 if(!IsWindowEnabled(handle)) | 251 if(!WinIsWindowEnabled(handle)) |
318 return 0; | 252 return 0; |
319 | 253 |
320 GetClassName(handle, tmpbuf, 99); | 254 WinQueryClassName(handle, 99, tmpbuf); |
321 | 255 |
322 /* These are the window classes which can | 256 /* These are the window classes which can |
323 * obtain input focus. | 257 * obtain input focus. |
324 */ | 258 */ |
325 if(strnicmp(tmpbuf, EDITCLASSNAME, strlen(EDITCLASSNAME))==0 || /* Entryfield */ | 259 if(strncmp(tmpbuf, "#2", 3)==0 || /* Combobox */ |
326 strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0 || /* Button */ | 260 strncmp(tmpbuf, "#3", 3)==0 || /* Button */ |
327 strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0 || /* Combobox */ | 261 strncmp(tmpbuf, "#6", 3)==0 || /* Entryfield */ |
328 strnicmp(tmpbuf, LISTBOXCLASSNAME, strlen(LISTBOXCLASSNAME))==0 || /* List box */ | 262 strncmp(tmpbuf, "#7", 3)==0 || /* List box */ |
329 strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0 || /* Spinbutton */ | 263 strncmp(tmpbuf, "#10", 3)==0 || /* MLE */ |
330 strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))== 0) /* Container */ | 264 strncmp(tmpbuf, "#32", 3)==0 || /* Spinbutton */ |
265 strncmp(tmpbuf, "#37", 3)== 0) /* Container */ | |
331 return 1; | 266 return 1; |
332 return 0; | 267 return 0; |
333 } | |
334 | |
335 HWND _normalize_handle(HWND handle) | |
336 { | |
337 char tmpbuf[100] = ""; | |
338 | |
339 GetClassName(handle, tmpbuf, 99); | |
340 if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) /* Spinner */ | |
341 { | |
342 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | |
343 | |
344 if(cinfo && cinfo->buddy) | |
345 return cinfo->buddy; | |
346 } | |
347 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) /* Combobox */ | |
348 { | |
349 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | |
350 | |
351 if(cinfo && cinfo->buddy) | |
352 return cinfo->buddy; | |
353 } | |
354 return handle; | |
355 } | 268 } |
356 | 269 |
357 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) | 270 int _focus_check_box(Box *box, HWND handle, int start, HWND defaultitem) |
358 { | 271 { |
359 int z; | 272 int z; |
365 * that was valid. | 278 * that was valid. |
366 */ | 279 */ |
367 if(start == 2) | 280 if(start == 2) |
368 { | 281 { |
369 if(lasthwnd) | 282 if(lasthwnd) |
370 SetFocus(lasthwnd); | 283 WinSetFocus(HWND_DESKTOP, lasthwnd); |
371 return 0; | 284 return 0; |
372 } | 285 } |
373 | 286 |
374 /* Start is 1 when we are entering the function | 287 /* Start is 1 when we are entering the function |
375 * for the first time, it is zero when entering | 288 * for the first time, it is zero when entering |
380 lasthwnd = handle; | 293 lasthwnd = handle; |
381 finish_searching = 0; | 294 finish_searching = 0; |
382 firsthwnd = 0; | 295 firsthwnd = 0; |
383 } | 296 } |
384 | 297 |
385 for(z=box->count-1;z>-1;z--) | 298 /* Vertical boxes are inverted on OS/2 */ |
386 { | 299 if(box->type == BOXVERT) |
387 if(box->items[z].type == TYPEBOX) | 300 { |
301 for(z=0;z<box->count;z++) | |
388 { | 302 { |
389 Box *thisbox = (Box *)GetWindowLong(box->items[z].hwnd, GWL_USERDATA); | 303 if(box->items[z].type == TYPEBOX) |
390 | |
391 if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) | |
392 return 1; | |
393 } | |
394 else | |
395 { | |
396 if(box->items[z].hwnd == handle) | |
397 { | 304 { |
398 if(lasthwnd == handle && firsthwnd) | 305 Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); |
399 SetFocus(firsthwnd); | 306 |
400 else if(lasthwnd == handle && !firsthwnd) | 307 if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) |
401 finish_searching = 1; | |
402 else | |
403 SetFocus(lasthwnd); | |
404 | |
405 /* If we aren't looking for the last handle, | |
406 * return immediately. | |
407 */ | |
408 if(!finish_searching) | |
409 return 1; | 308 return 1; |
410 } | |
411 if(_validate_focus(box->items[z].hwnd)) | |
412 { | |
413 /* Start is 3 when we are looking for the | |
414 * first valid item in the layout. | |
415 */ | |
416 if(start == 3) | |
417 { | |
418 if(!defaultitem || (defaultitem && box->items[z].hwnd == defaultitem)) | |
419 { | |
420 SetFocus(_normalize_handle(box->items[z].hwnd)); | |
421 return 1; | |
422 } | |
423 } | |
424 | |
425 if(!firsthwnd) | |
426 firsthwnd = _normalize_handle(box->items[z].hwnd); | |
427 | |
428 lasthwnd = _normalize_handle(box->items[z].hwnd); | |
429 } | 309 } |
430 else | 310 else |
431 { | 311 { |
432 char tmpbuf[100] = ""; | 312 if(box->items[z].hwnd == handle) |
433 | |
434 GetClassName(box->items[z].hwnd, tmpbuf, 99); | |
435 | |
436 if(strnicmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) /* Notebook */ | |
437 { | 313 { |
438 NotebookPage **array = (NotebookPage **)GetWindowLong(box->items[z].hwnd, GWL_USERDATA); | 314 if(lasthwnd == handle && firsthwnd) |
439 int pageid = TabCtrl_GetCurSel(box->items[z].hwnd); | 315 WinSetFocus(HWND_DESKTOP, firsthwnd); |
440 | 316 else if(lasthwnd == handle && !firsthwnd) |
441 if(pageid > -1 && array && array[pageid]) | 317 finish_searching = 1; |
318 else | |
319 WinSetFocus(HWND_DESKTOP, lasthwnd); | |
320 | |
321 /* If we aren't looking for the last handle, | |
322 * return immediately. | |
323 */ | |
324 if(!finish_searching) | |
325 return 1; | |
326 } | |
327 if(_validate_focus(box->items[z].hwnd)) | |
328 { | |
329 /* Start is 3 when we are looking for the | |
330 * first valid item in the layout. | |
331 */ | |
332 if(start == 3) | |
333 { | |
334 if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) | |
335 { | |
336 WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); | |
337 return 1; | |
338 } | |
339 } | |
340 | |
341 if(!firsthwnd) | |
342 firsthwnd = box->items[z].hwnd; | |
343 | |
344 lasthwnd = box->items[z].hwnd; | |
345 } | |
346 else | |
347 { | |
348 char tmpbuf[100] = ""; | |
349 | |
350 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | |
351 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | |
442 { | 352 { |
443 Box *notebox; | 353 Box *notebox; |
444 | 354 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, |
445 if(array[pageid]->hwnd) | 355 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); |
356 | |
357 if(page) | |
446 { | 358 { |
447 notebox = (Box *)GetWindowLong(array[pageid]->hwnd, GWL_USERDATA); | 359 notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); |
448 | 360 |
449 if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem)) | 361 if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem)) |
450 return 1; | 362 return 1; |
451 } | 363 } |
452 } | 364 } |
453 } | 365 } |
454 } | 366 } |
455 } | 367 } |
456 } | 368 } |
369 else | |
370 { | |
371 for(z=box->count-1;z>-1;z--) | |
372 { | |
373 if(box->items[z].type == TYPEBOX) | |
374 { | |
375 Box *thisbox = WinQueryWindowPtr(box->items[z].hwnd, QWP_USER); | |
376 | |
377 if(thisbox && _focus_check_box(thisbox, handle, start == 3 ? 3 : 0, defaultitem)) | |
378 return 1; | |
379 } | |
380 else | |
381 { | |
382 if(box->items[z].hwnd == handle) | |
383 { | |
384 if(lasthwnd == handle && firsthwnd) | |
385 WinSetFocus(HWND_DESKTOP, firsthwnd); | |
386 else if(lasthwnd == handle && !firsthwnd) | |
387 finish_searching = 1; | |
388 else | |
389 WinSetFocus(HWND_DESKTOP, lasthwnd); | |
390 | |
391 /* If we aren't looking for the last handle, | |
392 * return immediately. | |
393 */ | |
394 if(!finish_searching) | |
395 return 1; | |
396 } | |
397 if(_validate_focus(box->items[z].hwnd)) | |
398 { | |
399 /* Start is 3 when we are looking for the | |
400 * first valid item in the layout. | |
401 */ | |
402 if(start == 3) | |
403 { | |
404 if(!defaultitem || (defaultitem && defaultitem == box->items[z].hwnd)) | |
405 { | |
406 WinSetFocus(HWND_DESKTOP, box->items[z].hwnd); | |
407 return 1; | |
408 } | |
409 } | |
410 | |
411 if(!firsthwnd) | |
412 firsthwnd = box->items[z].hwnd; | |
413 | |
414 lasthwnd = box->items[z].hwnd; | |
415 } | |
416 else | |
417 { | |
418 char tmpbuf[100] = ""; | |
419 | |
420 WinQueryClassName(box->items[z].hwnd, 99, tmpbuf); | |
421 if(strncmp(tmpbuf, "#40", 3)==0) /* Notebook */ | |
422 { | |
423 Box *notebox; | |
424 HWND page = (HWND)WinSendMsg(box->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, | |
425 (MPARAM)dw_notebook_page_query(box->items[z].hwnd), 0); | |
426 | |
427 if(page) | |
428 { | |
429 notebox = (Box *)WinQueryWindowPtr(page, QWP_USER); | |
430 | |
431 if(notebox && _focus_check_box(notebox, handle, start == 3 ? 3 : 0, defaultitem)) | |
432 return 1; | |
433 } | |
434 } | |
435 } | |
436 } | |
437 } | |
438 } | |
457 return 0; | 439 return 0; |
458 } | 440 } |
459 | 441 |
460 /* This function finds the first widget in the | 442 /* This function finds the first widget in the |
461 * layout and moves the current focus to it. | 443 * layout and moves the current focus to it. |
462 */ | 444 */ |
463 void _initial_focus(HWND handle) | 445 int _initial_focus(HWND handle) |
464 { | 446 { |
465 Box *thisbox; | 447 Box *thisbox = NULL; |
466 char tmpbuf[100]; | 448 HWND box; |
467 | 449 |
468 if(!handle) | 450 box = WinWindowFromID(handle, FID_CLIENT); |
469 return; | 451 if(box) |
470 | 452 thisbox = WinQueryWindowPtr(box, QWP_USER); |
471 GetClassName(handle, tmpbuf, 99); | 453 else |
472 | 454 return 1; |
473 if(strnicmp(tmpbuf, ClassName, strlen(ClassName))!=0) | |
474 return; | |
475 | |
476 | |
477 if(handle) | |
478 thisbox = (Box *)GetWindowLong(handle, GWL_USERDATA); | |
479 | 455 |
480 if(thisbox) | 456 if(thisbox) |
481 { | |
482 _focus_check_box(thisbox, handle, 3, thisbox->defaultitem); | 457 _focus_check_box(thisbox, handle, 3, thisbox->defaultitem); |
483 } | 458 return 0; |
484 } | 459 } |
485 | 460 |
486 /* This function finds the current widget in the | 461 /* This function finds the current widget in the |
487 * layout and moves the current focus to the next item. | 462 * layout and moves the current focus to the next item. |
488 */ | 463 */ |
489 void _shift_focus(HWND handle) | 464 void _shift_focus(HWND handle) |
490 { | 465 { |
491 Box *thisbox; | 466 Box *thisbox; |
492 | 467 HWND box, lastbox = WinQueryWindow(handle, QW_PARENT); |
493 HWND box, lastbox = GetParent(handle); | |
494 | 468 |
495 /* Find the toplevel window */ | 469 /* Find the toplevel window */ |
496 while((box = GetParent(lastbox))) | 470 while((box = WinQueryWindow(lastbox, QW_PARENT)) > 0x80000001) |
497 { | 471 { |
498 lastbox = box; | 472 lastbox = box; |
499 } | 473 } |
500 | 474 |
501 thisbox = (Box *)GetWindowLong(lastbox, GWL_USERDATA); | 475 box = WinWindowFromID(lastbox, FID_CLIENT); |
476 if(box) | |
477 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
478 else | |
479 thisbox = WinQueryWindowPtr(lastbox, QWP_USER); | |
480 | |
502 if(thisbox) | 481 if(thisbox) |
503 { | 482 { |
504 if(_focus_check_box(thisbox, handle, 1, 0) == 0) | 483 if(_focus_check_box(thisbox, handle, 1, 0) == 0) |
505 _focus_check_box(thisbox, handle, 2, 0); | 484 _focus_check_box(thisbox, handle, 2, 0); |
506 } | 485 } |
510 * Resizes window to the exact same size to trigger | 489 * Resizes window to the exact same size to trigger |
511 * recalculation of frame. | 490 * recalculation of frame. |
512 */ | 491 */ |
513 void _ResetWindow(HWND hwndFrame) | 492 void _ResetWindow(HWND hwndFrame) |
514 { | 493 { |
515 RECT rcl; | 494 SWP swp; |
516 | 495 |
517 GetWindowRect(hwndFrame, &rcl); | 496 WinQueryWindowPos(hwndFrame, &swp); |
518 SetWindowPos(hwndFrame, HWND_TOP, 0, 0, rcl.right - rcl.left, | 497 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy-1, SWP_SIZE); |
519 rcl.bottom - rcl.top - 1, SWP_NOMOVE | SWP_NOZORDER); | 498 WinSetWindowPos(hwndFrame, HWND_TOP, 0, 0, swp.cx, swp.cy, SWP_SIZE); |
520 SetWindowPos(hwndFrame, HWND_TOP, 0, 0, rcl.right - rcl.left, | 499 } |
521 rcl.bottom - rcl.top, SWP_NOMOVE | SWP_NOZORDER); | 500 |
522 } | 501 /* This function will recursively search a box and add up the total height of it */ |
502 void _count_size(HWND box, int type, int *xsize, int *xorigsize) | |
503 { | |
504 int size = 0, origsize = 0, z; | |
505 Box *tmp = WinQueryWindowPtr(box, QWP_USER); | |
506 | |
507 if(!tmp) | |
508 { | |
509 *xsize = *xorigsize = 0; | |
510 return; | |
511 } | |
512 | |
513 if(type == tmp->type) | |
514 { | |
515 /* If the box is going in the direction we want, then we | |
516 * return the entire sum of the items. | |
517 */ | |
518 for(z=0;z<tmp->count;z++) | |
519 { | |
520 if(tmp->items[z].type == TYPEBOX) | |
521 { | |
522 int s, os; | |
523 | |
524 _count_size(tmp->items[z].hwnd, type, &s, &os); | |
525 size += s; | |
526 origsize += os; | |
527 } | |
528 else | |
529 { | |
530 size += (type == BOXHORZ ? tmp->items[z].width : tmp->items[z].height); | |
531 origsize += (type == BOXHORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); | |
532 } | |
533 } | |
534 } | |
535 else | |
536 { | |
537 /* If the box is not going in the direction we want, then we only | |
538 * want to return the maximum value. | |
539 */ | |
540 int tmpsize = 0, tmporigsize = 0; | |
541 | |
542 for(z=0;z<tmp->count;z++) | |
543 { | |
544 if(tmp->items[z].type == TYPEBOX) | |
545 _count_size(tmp->items[z].hwnd, type, &tmpsize, &tmporigsize); | |
546 else | |
547 { | |
548 tmpsize = (type == BOXHORZ ? tmp->items[z].width : tmp->items[z].height); | |
549 tmporigsize = (type == BOXHORZ ? tmp->items[z].origwidth : tmp->items[z].origheight); | |
550 } | |
551 | |
552 if(tmpsize > size) | |
553 size = tmpsize; | |
554 } | |
555 } | |
556 | |
557 *xsize = size; | |
558 *xorigsize = origsize; | |
559 } | |
560 | |
523 | 561 |
524 /* Function: TrackRectangle | 562 /* Function: TrackRectangle |
525 * Abstract: Tracks given rectangle. | 563 * Abstract: Tracks given rectangle. |
526 * | 564 * |
527 * If rclBounds is NULL, then track rectangle on entire desktop. | 565 * If rclBounds is NULL, then track rectangle on entire desktop. |
529 * desktop. | 567 * desktop. |
530 */ | 568 */ |
531 | 569 |
532 BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds) | 570 BOOL _TrackRectangle(HWND hwndBase, RECTL* rclTrack, RECTL* rclBounds) |
533 { | 571 { |
534 ULONG rc = 0; | |
535 #if 0 | |
536 TRACKINFO track; | 572 TRACKINFO track; |
573 APIRET rc; | |
537 | 574 |
538 track.cxBorder = 1; | 575 track.cxBorder = 1; |
539 track.cyBorder = 1; | 576 track.cyBorder = 1; |
540 track.cxGrid = 1; | 577 track.cxGrid = 1; |
541 track.cyGrid = 1; | 578 track.cyGrid = 1; |
557 track.rclBoundary.xLeft = -3000; | 594 track.rclBoundary.xLeft = -3000; |
558 } | 595 } |
559 | 596 |
560 track.rclTrack = *rclTrack; | 597 track.rclTrack = *rclTrack; |
561 | 598 |
562 MapWindowPoints(hwndBase, | 599 WinMapWindowPoints(hwndBase, |
563 HWND_DESKTOP, | 600 HWND_DESKTOP, |
564 (PPOINT)&track.rclTrack, | 601 (PPOINTL)&track.rclTrack, |
565 2); | 602 2); |
566 | 603 |
567 track.ptlMinTrackSize.x = track.rclTrack.xRight | 604 track.ptlMinTrackSize.x = track.rclTrack.xRight |
568 - track.rclTrack.xLeft; | 605 - track.rclTrack.xLeft; |
569 track.ptlMinTrackSize.y = track.rclTrack.yTop | 606 track.ptlMinTrackSize.y = track.rclTrack.yTop |
570 - track.rclTrack.yBottom; | 607 - track.rclTrack.yBottom; |
578 rc = WinTrackRect(HWND_DESKTOP, 0, &track); | 615 rc = WinTrackRect(HWND_DESKTOP, 0, &track); |
579 | 616 |
580 if(rc) | 617 if(rc) |
581 *rclTrack = track.rclTrack; | 618 *rclTrack = track.rclTrack; |
582 | 619 |
583 #endif | |
584 return rc; | 620 return rc; |
585 } | 621 } |
586 | 622 |
587 /* This function calculates how much space the widgets and boxes require | 623 /* This function calculates how much space the widgets and boxes require |
588 * and does expansion as necessary. | 624 * and does expansion as necessary. |
603 for(z=0;z<thisbox->count;z++) | 639 for(z=0;z<thisbox->count;z++) |
604 { | 640 { |
605 if(thisbox->items[z].type == TYPEBOX) | 641 if(thisbox->items[z].type == TYPEBOX) |
606 { | 642 { |
607 int initialx, initialy; | 643 int initialx, initialy; |
608 Box *tmp = (Box *)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA); | 644 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); |
609 | 645 |
610 initialx = x - (*usedx); | 646 initialx = x - (*usedx); |
611 initialy = y - (*usedy); | 647 initialy = y - (*usedy); |
612 | 648 |
613 if(tmp) | 649 if(tmp) |
649 fprintf(f, "FARK! depth %d\r\nwidth = %d, height = %d, nux = %d, nuy = %d, upx = %d, upy = %d xratio = %f, yratio = %f\r\n\r\n", | 685 fprintf(f, "FARK! depth %d\r\nwidth = %d, height = %d, nux = %d, nuy = %d, upx = %d, upy = %d xratio = %f, yratio = %f\r\n\r\n", |
650 *depth, thisbox->items[z].width, thisbox->items[z].height, nux, nuy, tmp->upx, tmp->upy, tmp->xratio, tmp->yratio); | 686 *depth, thisbox->items[z].width, thisbox->items[z].height, nux, nuy, tmp->upx, tmp->upy, tmp->xratio, tmp->yratio); |
651 reopen(); | 687 reopen(); |
652 } | 688 } |
653 #endif | 689 #endif |
690 | |
654 if(thisbox->type == BOXVERT) | 691 if(thisbox->type == BOXVERT) |
655 { | 692 { |
656 if((thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))!=0) | 693 if((thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))!=0) |
657 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(tmp->pad*2))))/((float)(thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))); | 694 tmp->xratio = ((float)((thisbox->items[z].width * thisbox->xratio)-((thisbox->items[z].pad*2)+(tmp->pad*2))))/((float)(thisbox->items[z].width-((thisbox->items[z].pad*2)+(tmp->pad*2)))); |
658 } | 695 } |
720 else | 757 else |
721 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy)); | 758 thisbox->items[z].yratio = ((float)((thisbox->height * thisbox->parentyratio)-thisbox->upy))/((float)(thisbox->minheight-thisbox->upy)); |
722 | 759 |
723 if(thisbox->items[z].type == TYPEBOX) | 760 if(thisbox->items[z].type == TYPEBOX) |
724 { | 761 { |
725 Box *tmp = (Box *)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA); | 762 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); |
726 | 763 |
727 if(tmp) | 764 if(tmp) |
728 { | 765 { |
729 tmp->parentxratio = thisbox->items[z].xratio; | 766 tmp->parentxratio = thisbox->items[z].xratio; |
730 tmp->parentyratio = thisbox->items[z].yratio; | 767 tmp->parentyratio = thisbox->items[z].yratio; |
832 if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == BOXHORZ) | 869 if(thisbox->items[z].vsize == SIZEEXPAND && thisbox->type == BOXHORZ) |
833 thisbox->items[z].height = uymax-(thisbox->items[z].pad*2); | 870 thisbox->items[z].height = uymax-(thisbox->items[z].pad*2); |
834 /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */ | 871 /* Run this code segment again to finalize the sized after setting uxmax/uymax values. */ |
835 if(thisbox->items[z].type == TYPEBOX) | 872 if(thisbox->items[z].type == TYPEBOX) |
836 { | 873 { |
837 Box *tmp = (Box *)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA); | 874 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); |
838 | 875 |
839 if(tmp) | 876 if(tmp) |
840 { | 877 { |
841 if(*depth > 0) | 878 if(*depth > 0) |
842 { | 879 { |
894 if(thisbox->items[z].vsize != SIZEEXPAND) | 931 if(thisbox->items[z].vsize != SIZEEXPAND) |
895 vectory = 0; | 932 vectory = 0; |
896 if(thisbox->items[z].hsize != SIZEEXPAND) | 933 if(thisbox->items[z].hsize != SIZEEXPAND) |
897 vectorx = 0; | 934 vectorx = 0; |
898 | 935 |
899 GetClassName(handle, tmpbuf, 99); | 936 WinQueryClassName(handle, 99, tmpbuf); |
900 | 937 |
901 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | 938 if(strncmp(tmpbuf, "#2", 3)==0) |
902 { | 939 { |
903 /* Handle special case Combobox */ | 940 /* Make the combobox big enough to drop down. :) */ |
904 MoveWindow(handle, currentx + pad, currenty + pad, | 941 WinSetWindowPos(handle, HWND_TOP, currentx + pad, (currenty + pad) - 100, |
905 width + vectorx, (height + vectory) + 400, TRUE); | 942 width + vectorx, (height + vectory) + 100, SWP_MOVE | SWP_SIZE | SWP_ZORDER); |
906 } | 943 } |
907 else if(strnicmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) | 944 else if(strncmp(tmpbuf, "#6", 3)==0) |
908 { | 945 { |
909 /* Handle special case Spinbutton */ | 946 /* Entryfields on OS/2 have a thick border that isn't on Windows and GTK */ |
910 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | 947 WinSetWindowPos(handle, HWND_TOP, (currentx + pad) + 3, (currenty + pad) + 3, |
911 | 948 (width + vectorx) - 6, (height + vectory) - 6, SWP_MOVE | SWP_SIZE | SWP_ZORDER); |
912 MoveWindow(handle, currentx + pad + ((width + vectorx) - 20), currenty + pad, | |
913 20, height + vectory, TRUE); | |
914 | |
915 if(cinfo) | |
916 { | |
917 MoveWindow(cinfo->buddy, currentx + pad, currenty + pad, | |
918 (width + vectorx) - 20, height + vectory, TRUE); | |
919 } | |
920 } | 949 } |
921 else | 950 else |
922 { | 951 { |
923 /* Everything else */ | 952 WinSetWindowPos(handle, HWND_TOP, currentx + pad, currenty + pad, |
924 MoveWindow(handle, currentx + pad, currenty + pad, | 953 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE | SWP_ZORDER); |
925 width + vectorx, height + vectory, TRUE); | |
926 if(thisbox->items[z].type == TYPEBOX) | 954 if(thisbox->items[z].type == TYPEBOX) |
927 { | 955 { |
928 Box *boxinfo = (Box *)GetWindowLong(handle, GWL_USERDATA); | 956 Box *boxinfo = WinQueryWindowPtr(handle, QWP_USER); |
929 | 957 |
930 if(boxinfo && boxinfo->grouphwnd) | 958 if(boxinfo && boxinfo->grouphwnd) |
931 MoveWindow(boxinfo->grouphwnd, 0, 0, | 959 WinSetWindowPos(boxinfo->grouphwnd, HWND_TOP, 0, 0, |
932 width + vectorx, height + vectory, TRUE); | 960 width + vectorx, height + vectory, SWP_MOVE | SWP_SIZE); |
933 | 961 |
934 } | 962 } |
935 } | 963 |
936 | |
937 /* Notebook dialog requires additional processing */ | |
938 if(strncmp(tmpbuf, WC_TABCONTROL, strlen(WC_TABCONTROL))==0) | |
939 { | |
940 RECT rect; | |
941 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | |
942 int pageid = TabCtrl_GetCurSel(handle); | |
943 | |
944 if(pageid > -1 && array && array[pageid]) | |
945 { | |
946 GetClientRect(handle,&rect); | |
947 TabCtrl_AdjustRect(handle,FALSE,&rect); | |
948 MoveWindow(array[pageid]->hwnd, rect.left, rect.top, | |
949 rect.right - rect.left, rect.bottom-rect.top, TRUE); | |
950 } | |
951 } | 964 } |
952 | 965 |
953 #ifdef DWDEBUG | 966 #ifdef DWDEBUG |
954 fprintf(f, "Window Pos depth %d\r\ncurrentx = %d, currenty = %d, pad = %d, width = %d, height = %d, vectorx = %d, vectory = %d, Box type = %s\r\n\r\n", | 967 fprintf(f, "Window Pos depth %d\r\ncurrentx = %d, currenty = %d, pad = %d, width = %d, height = %d, vectorx = %d, vectory = %d, Box type = %s\r\n\r\n", |
955 *depth, currentx, currenty, pad, width, height, vectorx, vectory,thisbox->type == BOXHORZ ? "Horizontal" : "Vertical"); | 968 *depth, currentx, currenty, pad, width, height, vectorx, vectory,thisbox->type == BOXHORZ ? "Horizontal" : "Vertical"); |
970 { | 983 { |
971 if(x != 0 && y != 0) | 984 if(x != 0 && y != 0) |
972 { | 985 { |
973 if(thisbox) | 986 if(thisbox) |
974 { | 987 { |
975 int usedx = 0, usedy = 0, depth = 0, usedpadx = 0, usedpady = 0; | 988 int usedx = 0, usedy = 0, usedpadx = 0, usedpady = 0, depth = 0; |
976 | 989 |
977 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); | 990 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 1, &usedpadx, &usedpady); |
978 | 991 |
979 if(usedx-usedpadx == 0 || usedy-usedpady == 0) | 992 if(usedx-usedpadx == 0 || usedy-usedpady == 0) |
980 return; | 993 return; |
986 fprintf(f, "WM_SIZE Resize Box Pass 1\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d xratio = %f, yratio = %f\r\n\r\n", | 999 fprintf(f, "WM_SIZE Resize Box Pass 1\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d xratio = %f, yratio = %f\r\n\r\n", |
987 x, y, usedx, usedy, usedpadx, usedpady, thisbox->xratio, thisbox->yratio); | 1000 x, y, usedx, usedy, usedpadx, usedpady, thisbox->xratio, thisbox->yratio); |
988 reopen(); | 1001 reopen(); |
989 #endif | 1002 #endif |
990 | 1003 |
991 usedpadx = usedpady = usedx = usedy = depth = 0; | 1004 usedx = usedy = usedpadx = usedpady = depth = 0; |
992 | 1005 |
993 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady); | 1006 _resize_box(thisbox, &depth, x, y, &usedx, &usedy, 2, &usedpadx, &usedpady); |
994 | |
995 #ifdef DWDEBUG | 1007 #ifdef DWDEBUG |
996 fprintf(f, "WM_SIZE Resize Box Pass 2\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d\r\n", | 1008 fprintf(f, "WM_SIZE Resize Box Pass 2\r\nx = %d, y = %d, usedx = %d, usedy = %d, usedpadx = %d, usedpady = %d\r\n", |
997 x, y, usedx, usedy, usedpadx, usedpady); | 1009 x, y, usedx, usedy, usedpadx, usedpady); |
998 reopen(); | 1010 reopen(); |
999 #endif | 1011 #endif |
1000 } | 1012 } |
1001 } | 1013 } |
1002 } | 1014 } |
1003 | 1015 |
1004 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ | 1016 /* This procedure handles WM_QUERYTRACKINFO requests from the frame */ |
1005 BOOL CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | 1017 MRESULT EXPENTRY _sizeproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
1006 { | 1018 { |
1007 int result = -1; | 1019 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); |
1008 static int command_active = 0; | 1020 |
1009 #ifndef NO_SIGNALS | 1021 switch(msg) |
1010 SignalHandler *tmp = Root; | 1022 { |
1011 #endif | 1023 case WM_QUERYTRACKINFO: |
1012 void (* windowfunc)(PVOID); | |
1013 ULONG origmsg = msg; | |
1014 | |
1015 if(msg == WM_RBUTTONDOWN || msg == WM_MBUTTONDOWN) | |
1016 msg = WM_LBUTTONDOWN; | |
1017 if(msg == WM_RBUTTONUP || msg == WM_MBUTTONUP) | |
1018 msg = WM_LBUTTONUP; | |
1019 | |
1020 if(filterfunc) | |
1021 result = filterfunc(hWnd, msg, mp1, mp2); | |
1022 | |
1023 #ifndef NO_SIGNALS | |
1024 if(result == -1) | |
1025 { | |
1026 /* Avoid infinite recursion */ | |
1027 command_active = 1; | |
1028 | |
1029 /* Find any callbacks for this function */ | |
1030 while(tmp) | |
1031 { | 1024 { |
1032 if(tmp->message == msg || msg == WM_COMMAND || msg == WM_NOTIFY || tmp->message == WM_USER+1) | 1025 if(blah && *blah) |
1033 { | 1026 { |
1034 switch(msg) | 1027 PTRACKINFO ptInfo; |
1035 { | 1028 int res; |
1036 case WM_SETFOCUS: | 1029 PFNWP myfunc = *blah; |
1037 { | 1030 res = (int)myfunc(hWnd, msg, mp1, mp2); |
1038 int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; | 1031 |
1039 | 1032 ptInfo = (PTRACKINFO)(mp2); |
1040 if(hWnd == tmp->window) | 1033 |
1041 { | 1034 ptInfo->ptlMinTrackSize.y = 8; |
1042 result = setfocusfunc(tmp->window, tmp->data); | 1035 ptInfo->ptlMinTrackSize.x = 8; |
1043 tmp = NULL; | 1036 |
1044 } | 1037 return (MRESULT)res; |
1045 } | |
1046 break; | |
1047 case WM_SIZE: | |
1048 { | |
1049 int (*sizefunc)(HWND, int, int, void *) = tmp->signalfunction; | |
1050 | |
1051 if(hWnd == tmp->window) | |
1052 { | |
1053 result = sizefunc(tmp->window, LOWORD(mp2), HIWORD(mp2), tmp->data); | |
1054 tmp = NULL; | |
1055 } | |
1056 } | |
1057 break; | |
1058 case WM_LBUTTONDOWN: | |
1059 { | |
1060 POINTS pts = MAKEPOINTS(mp2); | |
1061 int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1062 | |
1063 if(hWnd == tmp->window) | |
1064 { | |
1065 int button; | |
1066 | |
1067 switch(origmsg) | |
1068 { | |
1069 case WM_LBUTTONDOWN: | |
1070 button = 1; | |
1071 break; | |
1072 case WM_RBUTTONDOWN: | |
1073 button = 2; | |
1074 break; | |
1075 case WM_MBUTTONDOWN: | |
1076 button = 3; | |
1077 break; | |
1078 } | |
1079 result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data); | |
1080 tmp = NULL; | |
1081 } | |
1082 } | |
1083 break; | |
1084 case WM_LBUTTONUP: | |
1085 { | |
1086 POINTS pts = MAKEPOINTS(mp2); | |
1087 int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1088 | |
1089 if(hWnd == tmp->window) | |
1090 { | |
1091 int button; | |
1092 | |
1093 switch(origmsg) | |
1094 { | |
1095 case WM_LBUTTONUP: | |
1096 button = 1; | |
1097 break; | |
1098 case WM_RBUTTONUP: | |
1099 button = 2; | |
1100 break; | |
1101 case WM_MBUTTONUP: | |
1102 button = 3; | |
1103 break; | |
1104 } | |
1105 result = buttonfunc(tmp->window, pts.x, pts.y, button, tmp->data); | |
1106 tmp = NULL; | |
1107 } | |
1108 } | |
1109 break; | |
1110 case WM_MOUSEMOVE: | |
1111 { | |
1112 POINTS pts = MAKEPOINTS(mp2); | |
1113 int (*motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1114 | |
1115 if(hWnd == tmp->window) | |
1116 { | |
1117 int keys = 0; | |
1118 | |
1119 if (mp1 & MK_LBUTTON) | |
1120 keys = DW_BUTTON1_MASK; | |
1121 if (mp1 & MK_RBUTTON) | |
1122 keys |= DW_BUTTON2_MASK; | |
1123 if (mp1 & MK_MBUTTON) | |
1124 keys |= DW_BUTTON3_MASK; | |
1125 | |
1126 result = motionfunc(tmp->window, pts.x, pts.y, keys, tmp->data); | |
1127 tmp = NULL; | |
1128 } | |
1129 } | |
1130 break; | |
1131 case WM_CHAR: | |
1132 { | |
1133 int (*keypressfunc)(HWND, int, void *) = tmp->signalfunction; | |
1134 | |
1135 if(hWnd == tmp->window) | |
1136 { | |
1137 result = keypressfunc(tmp->window, LOWORD(mp2), tmp->data); | |
1138 tmp = NULL; | |
1139 } | |
1140 } | |
1141 break; | |
1142 case WM_CLOSE: | |
1143 { | |
1144 int (*closefunc)(HWND, void *) = tmp->signalfunction; | |
1145 | |
1146 if(hWnd == tmp->window) | |
1147 { | |
1148 result = closefunc(tmp->window, tmp->data); | |
1149 tmp = NULL; | |
1150 } | |
1151 } | |
1152 break; | |
1153 case WM_PAINT: | |
1154 { | |
1155 PAINTSTRUCT ps; | |
1156 DWExpose exp; | |
1157 int (*exposefunc)(HWND, DWExpose *, void *) = tmp->signalfunction; | |
1158 | |
1159 if(hWnd == tmp->window) | |
1160 { | |
1161 BeginPaint(hWnd, &ps); | |
1162 exp.x = ps.rcPaint.left; | |
1163 exp.y = ps.rcPaint.top; | |
1164 exp.width = ps.rcPaint.right - ps.rcPaint.left; | |
1165 exp.height = ps.rcPaint.bottom - ps.rcPaint.top; | |
1166 result = exposefunc(hWnd, &exp, tmp->data); | |
1167 EndPaint(hWnd, &ps); | |
1168 } | |
1169 } | |
1170 break; | |
1171 case WM_NOTIFY: | |
1172 { | |
1173 if(tmp->message == TVN_SELCHANGED || tmp->message == NM_RCLICK) | |
1174 { | |
1175 NMTREEVIEW FAR *tem=(NMTREEVIEW FAR *)mp2; | |
1176 char tmpbuf[100]; | |
1177 | |
1178 GetClassName(tem->hdr.hwndFrom, tmpbuf, 99); | |
1179 | |
1180 if(strnicmp(tmpbuf, WC_TREEVIEW, strlen(WC_TREEVIEW))==0) | |
1181 { | |
1182 if(tem->hdr.code == TVN_SELCHANGED && tmp->message == TVN_SELCHANGED) | |
1183 { | |
1184 if(tmp->window == tem->hdr.hwndFrom) | |
1185 { | |
1186 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = tmp->signalfunction; | |
1187 TVITEM tvi; | |
1188 void **ptrs; | |
1189 | |
1190 tvi.mask = TVIF_HANDLE; | |
1191 tvi.hItem = tem->itemNew.hItem; | |
1192 | |
1193 TreeView_GetItem(tmp->window, &tvi); | |
1194 | |
1195 ptrs = (void **)tvi.lParam; | |
1196 if(ptrs) | |
1197 result = treeselectfunc(tmp->window, (HWND)tem->itemNew.hItem, (char *)ptrs[0], (void *)ptrs[1], tmp->data); | |
1198 | |
1199 tmp = NULL; | |
1200 } | |
1201 } | |
1202 else if(tem->hdr.code == NM_RCLICK && tmp->message == NM_RCLICK) | |
1203 { | |
1204 if(tmp->window == tem->hdr.hwndFrom) | |
1205 { | |
1206 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = tmp->signalfunction; | |
1207 HTREEITEM hti; | |
1208 TVITEM tvi; | |
1209 TVHITTESTINFO thi; | |
1210 void **ptrs = NULL; | |
1211 LONG x, y; | |
1212 | |
1213 dw_pointer_query_pos(&x, &y); | |
1214 | |
1215 thi.pt.x = x; | |
1216 thi.pt.y = y; | |
1217 | |
1218 MapWindowPoints(HWND_DESKTOP, tmp->window, &thi.pt, 1); | |
1219 | |
1220 hti = TreeView_HitTest(tmp->window, &thi); | |
1221 | |
1222 if(hti) | |
1223 { | |
1224 tvi.mask = TVIF_HANDLE; | |
1225 tvi.hItem = hti; | |
1226 | |
1227 TreeView_GetItem(tmp->window, &tvi); | |
1228 dw_tree_item_select(tmp->window, (HWND)hti); | |
1229 | |
1230 ptrs = (void **)tvi.lParam; | |
1231 | |
1232 } | |
1233 containercontextfunc(tmp->window, ptrs ? (char *)ptrs[0] : NULL, x, y, tmp->data, ptrs ? ptrs[1] : NULL); | |
1234 tmp = NULL; | |
1235 } | |
1236 } | |
1237 } | |
1238 } | |
1239 } | |
1240 break; | |
1241 case WM_COMMAND: | |
1242 { | |
1243 int (*clickfunc)(HWND, void *) = tmp->signalfunction; | |
1244 HWND command; | |
1245 ULONG passthru = (ULONG)LOWORD(mp1); | |
1246 ULONG message = HIWORD(mp1); | |
1247 | |
1248 command = (HWND)passthru; | |
1249 | |
1250 if(message == LBN_SELCHANGE || message == CBN_SELCHANGE) | |
1251 { | |
1252 int (*listboxselectfunc)(HWND, int, void *) = tmp->signalfunction; | |
1253 | |
1254 if(tmp->message == LBN_SELCHANGE && tmp->window == (HWND)mp2) | |
1255 { | |
1256 result = listboxselectfunc(tmp->window, dw_listbox_selected(tmp->window), tmp->data); | |
1257 tmp = NULL; | |
1258 } | |
1259 } /* Make sure it's the right window, and the right ID */ | |
1260 else if(tmp->window < (HWND)65536 && command == tmp->window) | |
1261 { | |
1262 result = clickfunc(tmp->window, tmp->data); | |
1263 tmp = NULL; | |
1264 } | |
1265 } | |
1266 break; | |
1267 } | |
1268 } | |
1269 if(tmp) | |
1270 tmp = tmp->next; | |
1271 } | |
1272 command_active = 0; | |
1273 } | |
1274 #endif | |
1275 | |
1276 /* Now that any handlers are done... do normal processing */ | |
1277 switch( msg ) | |
1278 { | |
1279 case WM_PAINT: | |
1280 { | |
1281 PAINTSTRUCT ps; | |
1282 | |
1283 BeginPaint(hWnd, &ps); | |
1284 EndPaint(hWnd, &ps); | |
1285 } | |
1286 break; | |
1287 case WM_SIZE: | |
1288 { | |
1289 static int lastx = -1, lasty = -1; | |
1290 static HWND lasthwnd = 0; | |
1291 | |
1292 if(lastx != LOWORD(mp2) || lasty != HIWORD(mp2) || lasthwnd != hWnd) | |
1293 { | |
1294 Box *mybox = (Box *)GetWindowLong(hWnd, GWL_USERDATA); | |
1295 | |
1296 if(mybox && mybox->count) | |
1297 { | |
1298 lastx = LOWORD(mp2); | |
1299 lasty = HIWORD(mp2); | |
1300 lasthwnd = hWnd; | |
1301 | |
1302 ShowWindow(mybox->items[0].hwnd, SW_HIDE); | |
1303 _do_resize(mybox,LOWORD(mp2),HIWORD(mp2)); | |
1304 ShowWindow(mybox->items[0].hwnd, SW_SHOW); | |
1305 return 0; | |
1306 } | |
1307 } | 1038 } |
1308 } | 1039 } |
1309 break; | 1040 } |
1310 case WM_CHAR: | 1041 if(blah && *blah) |
1311 if(LOWORD(mp1) == '\t') | 1042 { |
1043 PFNWP myfunc = *blah; | |
1044 return myfunc(hWnd, msg, mp1, mp2); | |
1045 } | |
1046 | |
1047 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1048 } | |
1049 | |
1050 void _Top(HPS hpsPaint, RECTL rclPaint) | |
1051 { | |
1052 POINTL ptl1, ptl2; | |
1053 | |
1054 ptl1.x = rclPaint.xLeft; | |
1055 ptl2.y = ptl1.y = rclPaint.yTop - 1; | |
1056 ptl2.x = rclPaint.xRight - 1; | |
1057 GpiMove(hpsPaint, &ptl1); | |
1058 GpiLine(hpsPaint, &ptl2); | |
1059 } | |
1060 | |
1061 /* Left hits the bottom */ | |
1062 void _Left(HPS hpsPaint, RECTL rclPaint) | |
1063 { | |
1064 POINTL ptl1, ptl2; | |
1065 | |
1066 ptl2.x = ptl1.x = rclPaint.xLeft; | |
1067 ptl1.y = rclPaint.yTop - 1; | |
1068 ptl2.y = rclPaint.yBottom; | |
1069 GpiMove(hpsPaint, &ptl1); | |
1070 GpiLine(hpsPaint, &ptl2); | |
1071 } | |
1072 | |
1073 void _Bottom(HPS hpsPaint, RECTL rclPaint) | |
1074 { | |
1075 POINTL ptl1, ptl2; | |
1076 | |
1077 ptl1.x = rclPaint.xRight - 1; | |
1078 ptl1.y = ptl2.y = rclPaint.yBottom; | |
1079 ptl2.x = rclPaint.xLeft; | |
1080 GpiMove(hpsPaint, &ptl1); | |
1081 GpiLine(hpsPaint, &ptl2); | |
1082 } | |
1083 | |
1084 /* Right hits the top */ | |
1085 void _Right(HPS hpsPaint, RECTL rclPaint) | |
1086 { | |
1087 POINTL ptl1, ptl2; | |
1088 | |
1089 ptl2.x = ptl1.x = rclPaint.xRight - 1; | |
1090 ptl1.y = rclPaint.yBottom + 1; | |
1091 ptl2.y = rclPaint.yTop - 1; | |
1092 GpiMove(hpsPaint, &ptl1); | |
1093 GpiLine(hpsPaint, &ptl2); | |
1094 } | |
1095 | |
1096 /* This procedure handles drawing of a status border */ | |
1097 MRESULT EXPENTRY _statusproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1098 { | |
1099 PFNWP *blah = WinQueryWindowPtr(hWnd, QWP_USER); | |
1100 | |
1101 if(blah && *blah) | |
1102 { | |
1103 PFNWP myfunc = *blah; | |
1104 | |
1105 switch(msg) | |
1312 { | 1106 { |
1313 _shift_focus(hWnd); | 1107 case WM_PAINT: |
1314 return TRUE; | |
1315 } | |
1316 break; | |
1317 case WM_USER: | |
1318 windowfunc = (void *)mp1; | |
1319 | |
1320 if(windowfunc) | |
1321 windowfunc((void *)mp2); | |
1322 break; | |
1323 case WM_NOTIFY: | |
1324 { | |
1325 NMHDR FAR *tem=(NMHDR FAR *)mp2; | |
1326 | |
1327 if(tem->code == TCN_SELCHANGING) | |
1328 { | 1108 { |
1329 int num=TabCtrl_GetCurSel(tem->hwndFrom); | 1109 HPS hpsPaint; |
1330 NotebookPage **array = (NotebookPage **)GetWindowLong(tem->hwndFrom, GWL_USERDATA); | 1110 RECTL rclPaint; |
1331 | 1111 char buf[1024]; |
1332 if(num > -1 && array && array[num]) | 1112 |
1333 SetParent(array[num]->hwnd, DW_HWND_OBJECT); | 1113 hpsPaint = WinBeginPaint(hWnd, 0, 0); |
1334 | 1114 WinQueryWindowRect(hWnd, &rclPaint); |
1335 } | 1115 WinFillRect(hpsPaint, &rclPaint, CLR_PALEGRAY); |
1336 else if(tem->code == TCN_SELCHANGE) | 1116 |
1337 { | 1117 GpiSetColor(hpsPaint, CLR_DARKGRAY); |
1338 int num=TabCtrl_GetCurSel(tem->hwndFrom); | 1118 _Top(hpsPaint, rclPaint); |
1339 NotebookPage **array = (NotebookPage **)GetWindowLong(tem->hwndFrom, GWL_USERDATA); | 1119 _Left(hpsPaint, rclPaint); |
1340 | 1120 |
1341 if(num > -1 && array && array[num]) | 1121 GpiSetColor(hpsPaint, CLR_WHITE); |
1342 SetParent(array[num]->hwnd, tem->hwndFrom); | 1122 _Right(hpsPaint, rclPaint); |
1343 | 1123 _Bottom(hpsPaint, rclPaint); |
1344 _resize_notebook_page(tem->hwndFrom, num); | 1124 |
1125 WinQueryWindowText(hWnd, 1024, buf); | |
1126 rclPaint.xLeft += 3; | |
1127 rclPaint.xRight--; | |
1128 rclPaint.yTop--; | |
1129 rclPaint.yBottom++; | |
1130 | |
1131 GpiSetColor(hpsPaint, CLR_BLACK); | |
1132 WinDrawText(hpsPaint, -1, buf, &rclPaint, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); | |
1133 WinEndPaint(hpsPaint); | |
1134 | |
1135 return (MRESULT)TRUE; | |
1345 } | 1136 } |
1346 } | 1137 } |
1347 break; | 1138 return myfunc(hWnd, msg, mp1, mp2); |
1348 case WM_GETMINMAXINFO: | 1139 } |
1140 | |
1141 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1142 } | |
1143 | |
1144 /* This procedure handles drawing of a percent bar */ | |
1145 MRESULT EXPENTRY _percentproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1146 { | |
1147 PercentBar *blah = (PercentBar *)WinQueryWindowPtr(hWnd, QWP_USER); | |
1148 | |
1149 if(blah) | |
1150 { | |
1151 PFNWP myfunc = blah->oldproc; | |
1152 | |
1153 switch(msg) | |
1349 { | 1154 { |
1350 MINMAXINFO *info = (MINMAXINFO *)mp2; | 1155 case WM_PAINT: |
1351 info->ptMinTrackSize.x = 8; | 1156 { |
1352 info->ptMinTrackSize.y = 8; | 1157 HPS hpsPaint; |
1353 return 0; | 1158 RECTL rclPaint, rclBar; |
1159 | |
1160 hpsPaint = WinBeginPaint(hWnd, 0, 0); | |
1161 WinQueryWindowRect(hWnd, &rclPaint); | |
1162 | |
1163 /* Draw outer border */ | |
1164 rclBar = rclPaint; | |
1165 GpiSetColor(hpsPaint, CLR_PALEGRAY); | |
1166 _Top(hpsPaint, rclBar); | |
1167 _Bottom(hpsPaint, rclBar); | |
1168 rclBar.yTop--; | |
1169 GpiSetColor(hpsPaint, CLR_WHITE); | |
1170 _Right(hpsPaint, rclBar); | |
1171 rclBar.yBottom++; | |
1172 GpiSetColor(hpsPaint, CLR_DARKGRAY); | |
1173 _Left(hpsPaint, rclBar); | |
1174 | |
1175 /* Draw inner border */ | |
1176 rclBar.xLeft++; | |
1177 rclBar.xRight--; | |
1178 GpiSetColor(hpsPaint, CLR_DARKGRAY); | |
1179 _Left(hpsPaint, rclBar); | |
1180 _Top(hpsPaint, rclBar); | |
1181 GpiSetColor(hpsPaint, CLR_WHITE); | |
1182 _Bottom(hpsPaint, rclBar); | |
1183 _Right(hpsPaint, rclBar); | |
1184 | |
1185 /* Draw bar border */ | |
1186 rclBar.xLeft++; | |
1187 rclBar.xRight--; | |
1188 rclBar.yBottom++; | |
1189 rclBar.yTop--; | |
1190 GpiSetColor(hpsPaint, CLR_DARKGRAY); | |
1191 _Left(hpsPaint, rclBar); | |
1192 _Top(hpsPaint, rclBar); | |
1193 _Bottom(hpsPaint, rclBar); | |
1194 _Right(hpsPaint, rclBar); | |
1195 | |
1196 if(blah->pos) | |
1197 { | |
1198 rclBar.xRight = 3 + blah->pos; | |
1199 _Right(hpsPaint, rclBar); | |
1200 | |
1201 /* Draw Bar itself */ | |
1202 rclBar.xLeft = rclPaint.xLeft + 3; | |
1203 rclBar.xRight = rclPaint.xLeft + 2 + blah->pos; | |
1204 rclBar.yTop = rclPaint.yTop - 3; | |
1205 rclBar.yBottom = rclPaint.yBottom + 3; | |
1206 | |
1207 WinFillRect(hpsPaint, &rclBar, CLR_DARKBLUE); | |
1208 } | |
1209 | |
1210 /* Draw the background */ | |
1211 rclBar.xLeft = rclPaint.xLeft + 3 + blah->pos; | |
1212 rclBar.xRight = rclPaint.xRight - 3; | |
1213 rclBar.yTop = rclPaint.yTop - 3; | |
1214 rclBar.yBottom = rclPaint.yBottom + 3; | |
1215 | |
1216 WinFillRect(hpsPaint, &rclBar, CLR_PALEGRAY); | |
1217 | |
1218 WinEndPaint(hpsPaint); | |
1219 | |
1220 return (MRESULT)TRUE; | |
1221 } | |
1354 } | 1222 } |
1355 break; | 1223 return myfunc(hWnd, msg, mp1, mp2); |
1356 case WM_DESTROY: | 1224 } |
1357 /* Free memory before destroying */ | 1225 |
1358 _free_window_memory(hWnd, 0); | 1226 return WinDefWindowProc(hWnd, msg, mp1, mp2); |
1359 EnumChildWindows(hWnd, _free_window_memory, 0); | |
1360 break; | |
1361 case WM_CTLCOLORSTATIC: | |
1362 case WM_CTLCOLORLISTBOX: | |
1363 case WM_CTLCOLORBTN: | |
1364 case WM_CTLCOLOREDIT: | |
1365 case WM_CTLCOLORMSGBOX: | |
1366 case WM_CTLCOLORSCROLLBAR: | |
1367 case WM_CTLCOLORDLG: | |
1368 { | |
1369 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong((HWND)mp2, GWL_USERDATA); | |
1370 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1) | |
1371 { | |
1372 if(thiscinfo->fore > -1 && thiscinfo->back > -1 && | |
1373 thiscinfo->fore < 18 && thiscinfo->back < 18) | |
1374 { | |
1375 SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore], | |
1376 _green[thiscinfo->fore], | |
1377 _blue[thiscinfo->fore])); | |
1378 SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back], | |
1379 _green[thiscinfo->back], | |
1380 _blue[thiscinfo->back])); | |
1381 DeleteObject(thiscinfo->hbrush); | |
1382 thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back], | |
1383 _green[thiscinfo->back], | |
1384 _blue[thiscinfo->back])); | |
1385 SelectObject((HDC)mp1, thiscinfo->hbrush); | |
1386 return (LONG)thiscinfo->hbrush; | |
1387 } | |
1388 if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR) | |
1389 { | |
1390 SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore), | |
1391 DW_GREEN_VALUE(thiscinfo->fore), | |
1392 DW_BLUE_VALUE(thiscinfo->fore))); | |
1393 SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back), | |
1394 DW_GREEN_VALUE(thiscinfo->back), | |
1395 DW_BLUE_VALUE(thiscinfo->back))); | |
1396 DeleteObject(thiscinfo->hbrush); | |
1397 thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back), | |
1398 DW_GREEN_VALUE(thiscinfo->back), | |
1399 DW_BLUE_VALUE(thiscinfo->back))); | |
1400 SelectObject((HDC)mp1, thiscinfo->hbrush); | |
1401 return (LONG)thiscinfo->hbrush; | |
1402 } | |
1403 } | |
1404 | |
1405 } | |
1406 break; | |
1407 } | |
1408 if(result != -1) | |
1409 return result; | |
1410 else | |
1411 return DefWindowProc(hWnd, msg, mp1, mp2); | |
1412 } | |
1413 | |
1414 BOOL CALLBACK _framewndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | |
1415 { | |
1416 switch( msg ) | |
1417 { | |
1418 case WM_LBUTTONDOWN: | |
1419 case WM_MBUTTONDOWN: | |
1420 case WM_RBUTTONDOWN: | |
1421 SetActiveWindow(hWnd); | |
1422 break; | |
1423 case WM_COMMAND: | |
1424 case WM_NOTIFY: | |
1425 _wndproc(hWnd, msg, mp1, mp2); | |
1426 break; | |
1427 #if 0 | |
1428 case WM_ERASEBKGND: | |
1429 { | |
1430 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong(hWnd, GWL_USERDATA); | |
1431 | |
1432 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1) | |
1433 return FALSE; | |
1434 } | |
1435 break; | |
1436 #endif | |
1437 case WM_PAINT: | |
1438 { | |
1439 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong(hWnd, GWL_USERDATA); | |
1440 | |
1441 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1) | |
1442 { | |
1443 PAINTSTRUCT ps; | |
1444 HDC hdcPaint = BeginPaint(hWnd, &ps); | |
1445 int success = FALSE; | |
1446 | |
1447 if(thiscinfo->fore > -1 && thiscinfo->back > -1 && | |
1448 thiscinfo->fore < 18 && thiscinfo->back < 18) | |
1449 { | |
1450 SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore], | |
1451 _green[thiscinfo->fore], | |
1452 _blue[thiscinfo->fore])); | |
1453 SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back], | |
1454 _green[thiscinfo->back], | |
1455 _blue[thiscinfo->back])); | |
1456 DeleteObject(thiscinfo->hbrush); | |
1457 thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back], | |
1458 _green[thiscinfo->back], | |
1459 _blue[thiscinfo->back])); | |
1460 SelectObject(hdcPaint, thiscinfo->hbrush); | |
1461 Rectangle(hdcPaint, ps.rcPaint.left - 1, ps.rcPaint.top - 1, ps.rcPaint.right + 1, ps.rcPaint.bottom + 1); | |
1462 success = TRUE; | |
1463 } | |
1464 if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR) | |
1465 { | |
1466 SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore), | |
1467 DW_GREEN_VALUE(thiscinfo->fore), | |
1468 DW_BLUE_VALUE(thiscinfo->fore))); | |
1469 SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back), | |
1470 DW_GREEN_VALUE(thiscinfo->back), | |
1471 DW_BLUE_VALUE(thiscinfo->back))); | |
1472 DeleteObject(thiscinfo->hbrush); | |
1473 thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back), | |
1474 DW_GREEN_VALUE(thiscinfo->back), | |
1475 DW_BLUE_VALUE(thiscinfo->back))); | |
1476 SelectObject(hdcPaint, thiscinfo->hbrush); | |
1477 Rectangle(hdcPaint, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom); | |
1478 success = TRUE; | |
1479 } | |
1480 | |
1481 EndPaint(hWnd, &ps); | |
1482 if(success) | |
1483 return FALSE; | |
1484 } | |
1485 | |
1486 } | |
1487 break; | |
1488 } | |
1489 return DefWindowProc(hWnd, msg, mp1, mp2); | |
1490 } | |
1491 | |
1492 BOOL CALLBACK _rendwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | |
1493 { | |
1494 switch( msg ) | |
1495 { | |
1496 case WM_LBUTTONDOWN: | |
1497 case WM_MBUTTONDOWN: | |
1498 case WM_RBUTTONDOWN: | |
1499 SetActiveWindow(hWnd); | |
1500 _wndproc(hWnd, msg, mp1, mp2); | |
1501 break; | |
1502 case WM_LBUTTONUP: | |
1503 case WM_MBUTTONUP: | |
1504 case WM_RBUTTONUP: | |
1505 case WM_MOUSEMOVE: | |
1506 case WM_PAINT: | |
1507 case WM_SIZE: | |
1508 case WM_COMMAND: | |
1509 _wndproc(hWnd, msg, mp1, mp2); | |
1510 break; | |
1511 } | |
1512 return DefWindowProc(hWnd, msg, mp1, mp2); | |
1513 } | |
1514 | |
1515 BOOL CALLBACK _spinnerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | |
1516 { | |
1517 ColorInfo *cinfo; | |
1518 | |
1519 cinfo = (ColorInfo *)GetWindowLong(hWnd, GWL_USERDATA); | |
1520 | |
1521 if(cinfo) | |
1522 { | |
1523 switch( msg ) | |
1524 { | |
1525 case WM_LBUTTONDOWN: | |
1526 case WM_MBUTTONDOWN: | |
1527 case WM_RBUTTONDOWN: | |
1528 case WM_CHAR: | |
1529 { | |
1530 BOOL ret; | |
1531 | |
1532 if(!cinfo || !cinfo->pOldProc) | |
1533 ret = DefWindowProc(hWnd, msg, mp1, mp2); | |
1534 ret = CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2); | |
1535 | |
1536 /* Tell the edit control that a buttonpress has | |
1537 * occured and to update it's window title. | |
1538 */ | |
1539 if(cinfo->buddy) | |
1540 SendMessage(cinfo->buddy, WM_USER+10, 0, 0); | |
1541 | |
1542 return ret; | |
1543 } | |
1544 break; | |
1545 case WM_USER+10: | |
1546 { | |
1547 if(cinfo->buddy) | |
1548 { | |
1549 char tempbuf[100] = ""; | |
1550 long position; | |
1551 | |
1552 GetWindowText(cinfo->buddy, tempbuf, 99); | |
1553 | |
1554 position = atol(tempbuf); | |
1555 | |
1556 if(IS_WIN98PLUS) | |
1557 SendMessage(hWnd, UDM_SETPOS32, 0, (LPARAM)position); | |
1558 else | |
1559 SendMessage(hWnd, UDM_SETPOS, 0, (LPARAM)MAKELONG((short)position, 0)); | |
1560 } | |
1561 } | |
1562 break; | |
1563 } | |
1564 } | |
1565 | |
1566 if(!cinfo || !cinfo->pOldProc) | |
1567 return DefWindowProc(hWnd, msg, mp1, mp2); | |
1568 return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2); | |
1569 } | 1227 } |
1570 | 1228 |
1571 void _click_default(HWND handle) | 1229 void _click_default(HWND handle) |
1572 { | 1230 { |
1573 char tmpbuf[100]; | 1231 char tmpbuf[100]; |
1574 | 1232 |
1575 GetClassName(handle, tmpbuf, 99); | 1233 WinQueryClassName(handle, 99, tmpbuf); |
1576 | 1234 |
1577 /* These are the window classes which can | 1235 /* These are the window classes which can |
1578 * obtain input focus. | 1236 * obtain input focus. |
1579 */ | 1237 */ |
1580 if(strnicmp(tmpbuf, BUTTONCLASSNAME, strlen(BUTTONCLASSNAME))==0) | 1238 if(strncmp(tmpbuf, "#3", 3)==0) |
1581 { | 1239 { |
1582 /* Generate click on default item */ | 1240 /* Generate click on default item */ |
1583 SignalHandler *tmp = Root; | 1241 SignalHandler *tmp = Root; |
1584 | 1242 |
1585 /* Find any callbacks for this function */ | 1243 /* Find any callbacks for this function */ |
1586 while(tmp) | 1244 while(tmp) |
1587 { | 1245 { |
1588 if(tmp->message == WM_COMMAND) | 1246 if(tmp->message == WM_COMMAND) |
1589 { | 1247 { |
1590 int (*clickfunc)(HWND, void *) = tmp->signalfunction; | 1248 int (*clickfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; |
1591 | 1249 |
1592 /* Make sure it's the right window, and the right ID */ | 1250 /* Make sure it's the right window, and the right ID */ |
1593 if(tmp->window == handle) | 1251 if(tmp->window == handle) |
1594 { | 1252 { |
1595 clickfunc(tmp->window, tmp->data); | 1253 clickfunc(tmp->window, tmp->data); |
1599 if(tmp) | 1257 if(tmp) |
1600 tmp= tmp->next; | 1258 tmp= tmp->next; |
1601 } | 1259 } |
1602 } | 1260 } |
1603 else | 1261 else |
1604 SetFocus(handle); | 1262 WinSetFocus(HWND_DESKTOP, handle); |
1605 } | 1263 } |
1606 | 1264 |
1607 BOOL CALLBACK _colorwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | 1265 MRESULT EXPENTRY _comboentryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
1608 { | 1266 { |
1609 ColorInfo *cinfo; | 1267 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); |
1610 char tmpbuf[100]; | 1268 |
1611 WNDPROC pOldProc = 0; | 1269 switch(msg) |
1612 | 1270 { |
1613 cinfo = (ColorInfo *)GetWindowLong(hWnd, GWL_USERDATA); | 1271 case WM_SETFOCUS: |
1614 | 1272 _run_event(hWnd, msg, mp1, mp2); |
1615 GetClassName(hWnd, tmpbuf, 99); | 1273 break; |
1616 if(strcmp(tmpbuf, FRAMECLASSNAME) == 0) | 1274 } |
1617 cinfo = &(((Box *)cinfo)->cinfo); | 1275 |
1618 | 1276 if(blah && blah->oldproc) |
1619 if(cinfo) | 1277 return blah->oldproc(hWnd, msg, mp1, mp2); |
1620 { | 1278 |
1621 pOldProc = cinfo->pOldProc; | 1279 return WinDefWindowProc(hWnd, msg, mp1, mp2); |
1622 | 1280 } |
1623 switch( msg ) | 1281 |
1282 /* Originally just intended for entryfields, it now serves as a generic | |
1283 * procedure for handling TAB presses to change input focus on controls. | |
1284 */ | |
1285 MRESULT EXPENTRY _entryproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1286 { | |
1287 WindowData *blah = (WindowData *)WinQueryWindowPtr(hWnd, QWP_USER); | |
1288 PFNWP oldproc = 0; | |
1289 | |
1290 if(blah) | |
1291 oldproc = blah->oldproc; | |
1292 | |
1293 switch(msg) | |
1294 { | |
1295 case WM_BUTTON1DOWN: | |
1296 case WM_BUTTON2DOWN: | |
1297 case WM_BUTTON3DOWN: | |
1624 { | 1298 { |
1625 case WM_SETFOCUS: | 1299 char tmpbuf[100]; |
1626 if(cinfo->combo) | 1300 |
1627 _wndproc(cinfo->combo, msg, mp1, mp2); | 1301 WinQueryClassName(hWnd, 99, tmpbuf); |
1628 else | 1302 |
1629 _wndproc(hWnd, msg, mp1, mp2); | 1303 if(strncmp(tmpbuf, "#32", 3)==0) |
1630 break; | 1304 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); |
1631 case WM_CHAR: | 1305 } |
1632 if(LOWORD(mp1) == '\t') | 1306 break; |
1307 case WM_SETFOCUS: | |
1308 _run_event(hWnd, msg, mp1, mp2); | |
1309 break; | |
1310 case WM_CHAR: | |
1311 if(SHORT1FROMMP(mp2) == '\t') | |
1312 { | |
1313 _shift_focus(hWnd); | |
1314 return FALSE; | |
1315 } | |
1316 else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) | |
1317 _click_default(blah->clickdefault); | |
1318 | |
1319 break; | |
1320 } | |
1321 | |
1322 if(oldproc) | |
1323 return oldproc(hWnd, msg, mp1, mp2); | |
1324 | |
1325 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1326 } | |
1327 | |
1328 /* Handle correct painting of a combobox with the WS_CLIPCHILDREN | |
1329 * flag enabled, and also handle TABs to switch input focus. | |
1330 */ | |
1331 MRESULT EXPENTRY _comboproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1332 { | |
1333 WindowData *blah = WinQueryWindowPtr(hWnd, QWP_USER); | |
1334 PFNWP oldproc = 0; | |
1335 | |
1336 if(blah) | |
1337 oldproc = blah->oldproc; | |
1338 | |
1339 switch(msg) | |
1340 { | |
1341 case WM_CHAR: | |
1342 if(SHORT1FROMMP(mp2) == '\t') | |
1343 { | |
1344 _shift_focus(hWnd); | |
1345 return FALSE; | |
1346 } | |
1347 else if(SHORT1FROMMP(mp2) == '\r' && blah && blah->clickdefault) | |
1348 _click_default(blah->clickdefault); | |
1349 break; | |
1350 case WM_BUTTON1DOWN: | |
1351 case WM_BUTTON2DOWN: | |
1352 case WM_BUTTON3DOWN: | |
1353 _run_event(hWnd, WM_SETFOCUS, (MPARAM)FALSE, (MPARAM)TRUE); | |
1354 break; | |
1355 case WM_SETFOCUS: | |
1356 _run_event(hWnd, msg, mp1, mp2); | |
1357 break; | |
1358 case WM_PAINT: | |
1359 { | |
1360 HWND parent = WinQueryWindow(hWnd, QW_PARENT); | |
1361 ULONG bcol, av[32]; | |
1362 HPS hpsPaint; | |
1363 POINTL ptl; /* Add 6 because it has a thick border like the entryfield */ | |
1364 unsigned long width, height, thumbheight = WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW) + 6; | |
1365 | |
1366 WinQueryPresParam(parent, PP_BACKGROUNDCOLORINDEX, 0, &bcol, sizeof(ULONG), &av, QPF_ID1COLORINDEX | QPF_NOINHERIT); | |
1367 dw_window_get_pos_size(hWnd, 0, 0, &width, &height); | |
1368 | |
1369 hpsPaint = WinGetPS(hWnd); | |
1370 GpiSetColor(hpsPaint, CLR_PALEGRAY); | |
1371 | |
1372 ptl.x = 0; | |
1373 ptl.y = 0; | |
1374 GpiMove(hpsPaint, &ptl); | |
1375 | |
1376 ptl.x = width; | |
1377 ptl.y = height - thumbheight; | |
1378 GpiBox(hpsPaint, DRO_FILL, &ptl, 0, 0); | |
1379 | |
1380 WinReleasePS(hpsPaint); | |
1381 } | |
1382 break; | |
1383 } | |
1384 if(oldproc) | |
1385 return oldproc(hWnd, msg, mp1, mp2); | |
1386 | |
1387 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1388 } | |
1389 | |
1390 void _GetPPFont(HWND hwnd, char *buff) | |
1391 { | |
1392 ULONG AttrFound; | |
1393 BYTE AttrValue[128]; | |
1394 ULONG cbRetLen; | |
1395 | |
1396 cbRetLen = WinQueryPresParam(hwnd, | |
1397 PP_FONTNAMESIZE, | |
1398 0, | |
1399 &AttrFound, | |
1400 sizeof(AttrValue), | |
1401 &AttrValue, | |
1402 QPF_NOINHERIT); | |
1403 | |
1404 if(PP_FONTNAMESIZE == AttrFound && cbRetLen) | |
1405 { | |
1406 memcpy(buff, AttrValue, cbRetLen); | |
1407 } | |
1408 } | |
1409 | |
1410 /* Returns height of specified window. */ | |
1411 int _get_height(HWND handle) | |
1412 { | |
1413 unsigned long height; | |
1414 dw_window_get_pos_size(handle, NULL, NULL, NULL, &height); | |
1415 return (int)height; | |
1416 } | |
1417 | |
1418 /* Find the height of the frame a desktop style window is sitting on */ | |
1419 int _get_frame_height(HWND handle) | |
1420 { | |
1421 while(handle) | |
1422 { | |
1423 HWND client; | |
1424 if((client = WinWindowFromID(handle, FID_CLIENT)) != NULLHANDLE) | |
1425 { | |
1426 return _get_height(WinQueryWindow(handle, QW_PARENT)); | |
1427 } | |
1428 handle = WinQueryWindow(handle, QW_PARENT); | |
1429 } | |
1430 return dw_screen_height(); | |
1431 } | |
1432 | |
1433 #ifndef NO_SIGNALS | |
1434 MRESULT EXPENTRY _run_event(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1435 { | |
1436 int result = -1; | |
1437 SignalHandler *tmp = Root; | |
1438 ULONG origmsg = msg; | |
1439 | |
1440 if(msg == WM_BUTTON2DOWN || msg == WM_BUTTON3DOWN) | |
1441 msg = WM_BUTTON1DOWN; | |
1442 if(msg == WM_BUTTON2UP || msg == WM_BUTTON3UP) | |
1443 msg = WM_BUTTON1UP; | |
1444 | |
1445 /* Find any callbacks for this function */ | |
1446 while(tmp) | |
1447 { | |
1448 if(tmp->message == msg || msg == WM_CONTROL || tmp->message == WM_USER+1) | |
1449 { | |
1450 switch(msg) | |
1633 { | 1451 { |
1634 if(cinfo->combo) | 1452 case WM_SETFOCUS: |
1635 _shift_focus(cinfo->combo); | 1453 { |
1636 else if(cinfo->buddy) | 1454 if((mp2 && tmp->message == WM_SETFOCUS) || (!mp2 && tmp->message == WM_USER+1)) |
1637 _shift_focus(cinfo->buddy); | 1455 { |
1638 else | 1456 int (*setfocusfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; |
1639 _shift_focus(hWnd); | 1457 |
1640 return FALSE; | 1458 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) |
1459 { | |
1460 result = setfocusfunc(tmp->window, tmp->data); | |
1461 tmp = NULL; | |
1462 } | |
1463 } | |
1464 } | |
1465 break; | |
1466 case WM_SIZE: | |
1467 { | |
1468 int (*sizefunc)(HWND, int, int, void *) = (int (*)(HWND, int, int, void *))tmp->signalfunction; | |
1469 | |
1470 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd) | |
1471 { | |
1472 result = sizefunc(tmp->window, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), tmp->data); | |
1473 tmp = NULL; | |
1474 } | |
1475 } | |
1476 break; | |
1477 case WM_BUTTON1DOWN: | |
1478 { | |
1479 POINTS pts = (*((POINTS*)&mp1)); | |
1480 int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1481 | |
1482 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) | |
1483 { | |
1484 int button = 0; | |
1485 | |
1486 switch(origmsg) | |
1487 { | |
1488 case WM_BUTTON1DOWN: | |
1489 button = 1; | |
1490 break; | |
1491 case WM_BUTTON2DOWN: | |
1492 button = 2; | |
1493 break; | |
1494 case WM_BUTTON3DOWN: | |
1495 button = 3; | |
1496 break; | |
1497 } | |
1498 | |
1499 result = buttonfunc(tmp->window, pts.x, _get_frame_height(tmp->window) - pts.y, button, tmp->data); | |
1500 tmp = NULL; | |
1501 } | |
1502 } | |
1503 break; | |
1504 case WM_BUTTON1UP: | |
1505 { | |
1506 POINTS pts = (*((POINTS*)&mp1)); | |
1507 int (*buttonfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1508 | |
1509 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) | |
1510 { | |
1511 int button = 0; | |
1512 | |
1513 switch(origmsg) | |
1514 { | |
1515 case WM_BUTTON1UP: | |
1516 button = 1; | |
1517 break; | |
1518 case WM_BUTTON2UP: | |
1519 button = 2; | |
1520 break; | |
1521 case WM_BUTTON3UP: | |
1522 button = 3; | |
1523 break; | |
1524 } | |
1525 | |
1526 result = buttonfunc(tmp->window, pts.x, WinQueryWindow(tmp->window, QW_PARENT) == HWND_DESKTOP ? dw_screen_height() - pts.y : _get_height(tmp->window) - pts.y, button, tmp->data); | |
1527 tmp = NULL; | |
1528 } | |
1529 } | |
1530 break; | |
1531 case WM_MOUSEMOVE: | |
1532 { | |
1533 int (*motionfunc)(HWND, int, int, int, void *) = (int (*)(HWND, int, int, int, void *))tmp->signalfunction; | |
1534 | |
1535 if(hWnd == tmp->window || WinWindowFromID(tmp->window, FID_CLIENT) == hWnd || WinQueryCapture(HWND_DESKTOP) == tmp->window) | |
1536 { | |
1537 int keys = 0; | |
1538 SHORT x = SHORT1FROMMP(mp1), y = SHORT2FROMMP(mp1); | |
1539 | |
1540 if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000) | |
1541 keys = DW_BUTTON1_MASK; | |
1542 if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) | |
1543 keys |= DW_BUTTON2_MASK; | |
1544 if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) | |
1545 keys |= DW_BUTTON3_MASK; | |
1546 | |
1547 result = motionfunc(tmp->window, x, _get_frame_height(tmp->window) - y, keys, tmp->data); | |
1548 tmp = NULL; | |
1549 } | |
1550 } | |
1551 break; | |
1552 case WM_CHAR: | |
1553 { | |
1554 int (*keypressfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; | |
1555 | |
1556 if(hWnd == tmp->window) | |
1557 { | |
1558 result = keypressfunc(tmp->window, SHORT1FROMMP(mp2), tmp->data); | |
1559 tmp = NULL; | |
1560 } | |
1561 } | |
1562 break; | |
1563 case WM_CLOSE: | |
1564 { | |
1565 int (*closefunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; | |
1566 | |
1567 if(hWnd == tmp->window || hWnd == WinWindowFromID(tmp->window, FID_CLIENT)) | |
1568 { | |
1569 result = closefunc(tmp->window, tmp->data); | |
1570 if(result) | |
1571 result = FALSE; | |
1572 tmp = NULL; | |
1573 } | |
1574 } | |
1575 break; | |
1576 case WM_PAINT: | |
1577 { | |
1578 HPS hps; | |
1579 DWExpose exp; | |
1580 int (*exposefunc)(HWND, DWExpose *, void *) = (int (*)(HWND, DWExpose *, void *))tmp->signalfunction; | |
1581 RECTL rc; | |
1582 | |
1583 if(hWnd == tmp->window) | |
1584 { | |
1585 int height = _get_height(hWnd); | |
1586 | |
1587 hps = WinBeginPaint(hWnd, 0L, &rc); | |
1588 exp.x = rc.xLeft; | |
1589 exp.y = height - rc.yTop - 1; | |
1590 exp.width = rc.xRight - rc. xLeft; | |
1591 exp.height = rc.yTop - rc.yBottom; | |
1592 result = exposefunc(hWnd, &exp, tmp->data); | |
1593 WinEndPaint(hps); | |
1594 } | |
1595 } | |
1596 break; | |
1597 case WM_COMMAND: | |
1598 { | |
1599 int (*clickfunc)(HWND, void *) = (int (*)(HWND, void *))tmp->signalfunction; | |
1600 ULONG command = COMMANDMSG(&msg)->cmd; | |
1601 | |
1602 if(tmp->window < 65536 && command == tmp->window) | |
1603 { | |
1604 result = clickfunc(tmp->window, tmp->data); | |
1605 tmp = NULL; | |
1606 } | |
1607 } | |
1608 break; | |
1609 case WM_CONTROL: | |
1610 if(tmp->message == SHORT2FROMMP(mp1)) | |
1611 { | |
1612 switch(SHORT2FROMMP(mp1)) | |
1613 { | |
1614 case CN_ENTER: | |
1615 { | |
1616 int (*containerselectfunc)(HWND, char *, void *) = (int (*)(HWND, char *, void *))tmp->signalfunction; | |
1617 int id = SHORT1FROMMP(mp1); | |
1618 HWND conthwnd = dw_window_from_id(hWnd, id); | |
1619 char *text = NULL; | |
1620 | |
1621 if(mp2) | |
1622 { | |
1623 PRECORDCORE pre; | |
1624 | |
1625 pre = ((PNOTIFYRECORDENTER)mp2)->pRecord; | |
1626 if(pre) | |
1627 text = pre->pszIcon; | |
1628 } | |
1629 | |
1630 if(tmp->window == conthwnd) | |
1631 { | |
1632 result = containerselectfunc(tmp->window, text, tmp->data); | |
1633 tmp = NULL; | |
1634 } | |
1635 } | |
1636 break; | |
1637 case CN_CONTEXTMENU: | |
1638 { | |
1639 int (*containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (*)(HWND, char *, int, int, void *, void *))tmp->signalfunction; | |
1640 int id = SHORT1FROMMP(mp1); | |
1641 HWND conthwnd = dw_window_from_id(hWnd, id); | |
1642 char *text = NULL; | |
1643 void *user = NULL; | |
1644 LONG x,y; | |
1645 | |
1646 if(mp2) | |
1647 { | |
1648 PCNRITEM pci; | |
1649 | |
1650 pci = (PCNRITEM)mp2; | |
1651 | |
1652 text = pci->rc.pszIcon; | |
1653 user = pci->user; | |
1654 } | |
1655 | |
1656 dw_pointer_query_pos(&x, &y); | |
1657 | |
1658 if(tmp->window == conthwnd) | |
1659 { | |
1660 if(mp2) | |
1661 { | |
1662 NOTIFYRECORDEMPHASIS pre; | |
1663 | |
1664 dw_tree_item_select(tmp->window, (HWND)mp2); | |
1665 pre.pRecord = mp2; | |
1666 pre.fEmphasisMask = CRA_CURSORED; | |
1667 pre.hwndCnr = tmp->window; | |
1668 _run_event(hWnd, WM_CONTROL, MPFROM2SHORT(0, CN_EMPHASIS), (MPARAM)&pre); | |
1669 pre.pRecord->flRecordAttr |= CRA_CURSORED; | |
1670 } | |
1671 result = containercontextfunc(tmp->window, text, x, y, tmp->data, user); | |
1672 tmp = NULL; | |
1673 } | |
1674 } | |
1675 break; | |
1676 case CN_EMPHASIS: | |
1677 { | |
1678 PNOTIFYRECORDEMPHASIS pre = (PNOTIFYRECORDEMPHASIS)mp2; | |
1679 static int emph_recurse = 0; | |
1680 | |
1681 if(!emph_recurse) | |
1682 { | |
1683 emph_recurse = 1; | |
1684 | |
1685 if(mp2) | |
1686 { | |
1687 if(tmp->window == pre->hwndCnr) | |
1688 { | |
1689 PCNRITEM pci = (PCNRITEM)pre->pRecord; | |
1690 | |
1691 if(pci && pre->fEmphasisMask & CRA_CURSORED && (pci->rc.flRecordAttr & CRA_CURSORED)) | |
1692 { | |
1693 int (*treeselectfunc)(HWND, HWND, char *, void *, void *) = (int (*)(HWND, HWND, char *, void *, void *))tmp->signalfunction; | |
1694 | |
1695 if(lasthcnr == tmp->window && lastitem == (HWND)pci) | |
1696 { | |
1697 lasthcnr = 0; | |
1698 lastitem = 0; | |
1699 } | |
1700 else | |
1701 { | |
1702 lasthcnr = tmp->window; | |
1703 lastitem = (HWND)pci; | |
1704 result = treeselectfunc(tmp->window, (HWND)pci, pci->rc.pszIcon, pci->user, tmp->data); | |
1705 } | |
1706 tmp = NULL; | |
1707 } | |
1708 } | |
1709 } | |
1710 emph_recurse = 0; | |
1711 } | |
1712 } | |
1713 break; | |
1714 case LN_SELECT: | |
1715 { | |
1716 int (*listboxselectfunc)(HWND, int, void *) = (int (*)(HWND, int, void *))tmp->signalfunction; | |
1717 int id = SHORT1FROMMP(mp1); | |
1718 HWND conthwnd = dw_window_from_id(hWnd, id); | |
1719 static int _recursing = 0; | |
1720 | |
1721 if(_recursing == 0 && (tmp->window == conthwnd || (!id && tmp->window == (HWND)mp2))) | |
1722 { | |
1723 char buf1[500], classbuf[100]; | |
1724 unsigned int index = dw_listbox_selected(tmp->window); | |
1725 | |
1726 dw_listbox_query_text(tmp->window, index, buf1, 500); | |
1727 | |
1728 WinQueryClassName(tmp->window, 99, classbuf); | |
1729 | |
1730 _recursing = 1; | |
1731 | |
1732 if(id && strncmp(classbuf, "#2", 3)==0) | |
1733 { | |
1734 char *buf2; | |
1735 | |
1736 buf2 = dw_window_get_text(tmp->window); | |
1737 | |
1738 /* This is to make sure the listboxselect function doesn't | |
1739 * get called if the user is modifying the entry text. | |
1740 */ | |
1741 if(buf2 && *buf2 && *buf1 && strncmp(buf1, buf2, 500) == 0) | |
1742 result = listboxselectfunc(tmp->window, index, tmp->data); | |
1743 | |
1744 if(buf2) | |
1745 free(buf2); | |
1746 } | |
1747 else | |
1748 result = listboxselectfunc(tmp->window, index, tmp->data); | |
1749 | |
1750 _recursing = 0; | |
1751 tmp = NULL; | |
1752 } | |
1753 } | |
1754 break; | |
1755 } | |
1756 } | |
1757 break; | |
1641 } | 1758 } |
1642 else if(LOWORD(mp1) == '\r') | 1759 } |
1760 | |
1761 if(tmp) | |
1762 tmp = tmp->next; | |
1763 | |
1764 } | |
1765 | |
1766 return (MRESULT)result; | |
1767 } | |
1768 #endif | |
1769 | |
1770 /* Handles control messages sent to the box (owner). */ | |
1771 MRESULT EXPENTRY _controlproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1772 { | |
1773 Box *blah = WinQueryWindowPtr(hWnd, QWP_USER); | |
1774 | |
1775 #ifndef NO_SIGNALS | |
1776 switch(msg) | |
1777 { | |
1778 case WM_CONTROL: | |
1779 _run_event(hWnd, msg, mp1, mp2); | |
1780 break; | |
1781 } | |
1782 #endif | |
1783 if(blah && blah->oldproc) | |
1784 { | |
1785 return blah->oldproc(hWnd, msg, mp1, mp2); | |
1786 } | |
1787 | |
1788 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1789 } | |
1790 | |
1791 /* The main window procedure for Dynamic Windows, all the resizing code is done here. */ | |
1792 MRESULT EXPENTRY _wndproc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) | |
1793 { | |
1794 int result = -1; | |
1795 static int command_active = 0; | |
1796 void (* windowfunc)(PVOID) = 0L; | |
1797 | |
1798 if(filterfunc) | |
1799 result = filterfunc(hWnd, msg, mp1, mp2); | |
1800 | |
1801 #ifndef NO_SIGNALS | |
1802 if(result == -1 && !command_active) | |
1803 { | |
1804 /* Make sure we don't end up in infinite recursion */ | |
1805 command_active = 1; | |
1806 | |
1807 result = (int)_run_event(hWnd, msg, mp1, mp2); | |
1808 | |
1809 command_active = 0; | |
1810 } | |
1811 #endif | |
1812 | |
1813 /* Now that any handlers are done... do normal processing */ | |
1814 switch( msg ) | |
1815 { | |
1816 case WM_ERASEBACKGROUND: | |
1817 return 0; | |
1818 | |
1819 case WM_PAINT: | |
1820 { | |
1821 HPS hps; | |
1822 RECTL rc; | |
1823 | |
1824 hps = WinBeginPaint( hWnd, 0L, &rc ); | |
1825 WinEndPaint( hps ); | |
1826 break; | |
1827 } | |
1828 | |
1829 case WM_SIZE: | |
1830 { | |
1831 Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); | |
1832 | |
1833 if(!SHORT1FROMMP(mp2) && !SHORT2FROMMP(mp2)) | |
1834 return (MPARAM)TRUE; | |
1835 | |
1836 if(mybox && mybox->flags != DW_MINIMIZED) | |
1643 { | 1837 { |
1644 if(cinfo->clickdefault) | 1838 /* Hide the window when recalculating to reduce |
1645 _click_default(cinfo->clickdefault); | 1839 * CPU load. |
1646 | 1840 */ |
1841 WinShowWindow(hWnd, FALSE); | |
1842 | |
1843 _do_resize(mybox, SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); | |
1844 | |
1845 WinShowWindow(hWnd, TRUE); | |
1647 } | 1846 } |
1648 | 1847 } |
1649 /* Tell the spinner control that a keypress has | 1848 break; |
1650 * occured and to update it's internal value. | 1849 case WM_MINMAXFRAME: |
1651 */ | 1850 { |
1652 if(cinfo->buddy && !cinfo->combo) | 1851 Box *mybox = (Box *)WinQueryWindowPtr(hWnd, QWP_USER); |
1852 SWP *swp = (SWP *)mp1; | |
1853 | |
1854 if(mybox && (swp->fl & SWP_MINIMIZE)) | |
1855 mybox->flags = DW_MINIMIZED; | |
1856 | |
1857 if(mybox && (swp->fl & SWP_RESTORE)) | |
1653 { | 1858 { |
1654 if(IsWinNT()) | 1859 if(!mybox->titlebar && mybox->hwndtitle) |
1655 PostMessage(cinfo->buddy, WM_USER+10, 0, 0); | 1860 WinSetParent(mybox->hwndtitle, HWND_OBJECT, FALSE); |
1656 else | 1861 mybox->flags = 0; |
1657 SendMessage(cinfo->buddy, WM_USER+10, 0, 0); | |
1658 } | 1862 } |
1659 break; | 1863 |
1660 case WM_USER+10: | 1864 if(mybox && (swp->fl & SWP_MAXIMIZE)) |
1661 { | 1865 { |
1662 if(cinfo->buddy) | 1866 int z; |
1867 SWP swp2; | |
1868 | |
1869 WinQueryWindowPos(swp->hwnd, &swp2); | |
1870 | |
1871 if(swp2.cx == swp->cx && swp2.cy == swp->cy) | |
1872 return FALSE; | |
1873 | |
1874 mybox->flags = 0; | |
1875 | |
1876 /* Hide the window when recalculating to reduce | |
1877 * CPU load. | |
1878 */ | |
1879 WinShowWindow(hWnd, FALSE); | |
1880 | |
1881 _do_resize(mybox, swp->cx, swp->cy); | |
1882 | |
1883 if(mybox->count == 1 && mybox->items[0].type == TYPEBOX) | |
1663 { | 1884 { |
1664 long val, position; | 1885 mybox = (Box *)WinQueryWindowPtr(mybox->items[0].hwnd, QWP_USER); |
1665 char tmpbuf[100] = ""; | 1886 |
1666 | 1887 for(z=0;z<mybox->count;z++) |
1667 GetWindowText(cinfo->buddy, tmpbuf, 99); | |
1668 | |
1669 position = atol(tmpbuf); | |
1670 | |
1671 if(IS_WIN98PLUS) | |
1672 val = (long)SendMessage(cinfo->buddy, UDM_GETPOS32, 0, 0); | |
1673 else | |
1674 val = (long)SendMessage(cinfo->buddy, UDM_GETPOS, 0, 0); | |
1675 | |
1676 if(val != position) | |
1677 { | 1888 { |
1678 sprintf(tmpbuf, "%d", val); | 1889 char tmpbuf[100]; |
1679 SetWindowText(hWnd, tmpbuf); | 1890 |
1891 WinQueryClassName(mybox->items[z].hwnd, 99, tmpbuf); | |
1892 | |
1893 /* If we have a notebook we resize the page again. */ | |
1894 if(strncmp(tmpbuf, "#40", 3)==0) | |
1895 { | |
1896 unsigned long x, y, width, height; | |
1897 int page = dw_notebook_page_query(mybox->items[z].hwnd); | |
1898 HWND pagehwnd = (HWND)WinSendMsg(mybox->items[z].hwnd, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(page), 0); | |
1899 RECTL rc; | |
1900 | |
1901 Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); | |
1902 if(pagebox) | |
1903 { | |
1904 dw_window_get_pos_size(mybox->items[z].hwnd, &x, &y, &width, &height); | |
1905 | |
1906 rc.xLeft = x; | |
1907 rc.yBottom = y; | |
1908 rc.xRight = x + width; | |
1909 rc.yTop = y + height; | |
1910 | |
1911 WinSendMsg(mybox->items[z].hwnd, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); | |
1912 | |
1913 _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); | |
1914 } | |
1915 | |
1916 } | |
1680 } | 1917 } |
1918 | |
1919 } | |
1920 | |
1921 WinShowWindow(hWnd, TRUE); | |
1922 } | |
1923 } | |
1924 break; | |
1925 case WM_CONTROL: | |
1926 switch(SHORT2FROMMP(mp1)) | |
1927 { | |
1928 case BKN_PAGESELECTEDPENDING: | |
1929 { | |
1930 PAGESELECTNOTIFY *psn = (PAGESELECTNOTIFY *)mp2; | |
1931 HWND pagehwnd = (HWND)WinSendMsg(psn->hwndBook, BKM_QUERYPAGEWINDOWHWND, MPFROMLONG(psn->ulPageIdNew), 0); | |
1932 Box *pagebox = (Box *)WinQueryWindowPtr(pagehwnd, QWP_USER); | |
1933 unsigned long x, y, width, height; | |
1934 RECTL rc; | |
1935 | |
1936 if(pagebox && psn->ulPageIdNew != psn->ulPageIdCur) | |
1937 { | |
1938 dw_window_get_pos_size(psn->hwndBook, &x, &y, &width, &height); | |
1939 | |
1940 rc.xLeft = x; | |
1941 rc.yBottom = y; | |
1942 rc.xRight = x + width; | |
1943 rc.yTop = y + height; | |
1944 | |
1945 WinSendMsg(psn->hwndBook, BKM_CALCPAGERECT, (MPARAM)&rc, (MPARAM)TRUE); | |
1946 | |
1947 _do_resize(pagebox, rc.xRight - rc.xLeft, rc.yTop - rc.yBottom); | |
1681 } | 1948 } |
1682 } | 1949 } |
1683 break; | 1950 break; |
1684 case WM_KEYUP: | |
1685 { | |
1686 if(mp1 == VK_UP || mp1 == VK_DOWN) | |
1687 { | |
1688 if(cinfo->buddy) | |
1689 PostMessage(hWnd, WM_USER+10, 0, 0); | |
1690 } | |
1691 } | |
1692 break; | |
1693 case WM_CTLCOLORSTATIC: | |
1694 case WM_CTLCOLORLISTBOX: | |
1695 case WM_CTLCOLORBTN: | |
1696 case WM_CTLCOLOREDIT: | |
1697 case WM_CTLCOLORMSGBOX: | |
1698 case WM_CTLCOLORSCROLLBAR: | |
1699 case WM_CTLCOLORDLG: | |
1700 { | |
1701 ColorInfo *thiscinfo = (ColorInfo *)GetWindowLong((HWND)mp2, GWL_USERDATA); | |
1702 if(thiscinfo && thiscinfo->fore != -1 && thiscinfo->back != -1) | |
1703 { | |
1704 if(thiscinfo->fore > -1 && thiscinfo->back > -1 && | |
1705 thiscinfo->fore < 18 && thiscinfo->back < 18) | |
1706 { | |
1707 SetTextColor((HDC)mp1, RGB(_red[thiscinfo->fore], | |
1708 _green[thiscinfo->fore], | |
1709 _blue[thiscinfo->fore])); | |
1710 SetBkColor((HDC)mp1, RGB(_red[thiscinfo->back], | |
1711 _green[thiscinfo->back], | |
1712 _blue[thiscinfo->back])); | |
1713 DeleteObject(thiscinfo->hbrush); | |
1714 thiscinfo->hbrush = CreateSolidBrush(RGB(_red[thiscinfo->back], | |
1715 _green[thiscinfo->back], | |
1716 _blue[thiscinfo->back])); | |
1717 SelectObject((HDC)mp1, thiscinfo->hbrush); | |
1718 return (LONG)thiscinfo->hbrush; | |
1719 } | |
1720 if((thiscinfo->fore & DW_RGB_COLOR) == DW_RGB_COLOR && (thiscinfo->back & DW_RGB_COLOR) == DW_RGB_COLOR) | |
1721 { | |
1722 SetTextColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->fore), | |
1723 DW_GREEN_VALUE(thiscinfo->fore), | |
1724 DW_BLUE_VALUE(thiscinfo->fore))); | |
1725 SetBkColor((HDC)mp1, RGB(DW_RED_VALUE(thiscinfo->back), | |
1726 DW_GREEN_VALUE(thiscinfo->back), | |
1727 DW_BLUE_VALUE(thiscinfo->back))); | |
1728 DeleteObject(thiscinfo->hbrush); | |
1729 thiscinfo->hbrush = CreateSolidBrush(RGB(DW_RED_VALUE(thiscinfo->back), | |
1730 DW_GREEN_VALUE(thiscinfo->back), | |
1731 DW_BLUE_VALUE(thiscinfo->back))); | |
1732 SelectObject((HDC)mp1, thiscinfo->hbrush); | |
1733 return (LONG)thiscinfo->hbrush; | |
1734 } | |
1735 } | |
1736 | |
1737 } | |
1738 break; | |
1739 } | |
1740 } | |
1741 | |
1742 if(!pOldProc) | |
1743 return DefWindowProc(hWnd, msg, mp1, mp2); | |
1744 return CallWindowProc(pOldProc, hWnd, msg, mp1, mp2); | |
1745 } | |
1746 | |
1747 BOOL CALLBACK _containerwndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2) | |
1748 { | |
1749 ContainerInfo *cinfo; | |
1750 | |
1751 cinfo = (ContainerInfo *)GetWindowLong(hWnd, GWL_USERDATA); | |
1752 | |
1753 switch( msg ) | |
1754 { | |
1755 case WM_COMMAND: | |
1756 case WM_NOTIFY: | |
1757 _wndproc(hWnd, msg, mp1, mp2); | |
1758 break; | |
1759 #ifndef NO_SIGNALS | |
1760 case WM_LBUTTONDBLCLK: | |
1761 case WM_CHAR: | |
1762 { | |
1763 LV_ITEM lvi; | |
1764 int iItem; | |
1765 | |
1766 if(LOWORD(mp1) == '\t') | |
1767 { | |
1768 _shift_focus(hWnd); | |
1769 return FALSE; | |
1770 } | |
1771 | |
1772 if(msg == WM_CHAR && (char)mp1 != '\r') | |
1773 break; | |
1774 | |
1775 iItem = ListView_GetNextItem(hWnd, -1, LVNI_FOCUSED); | |
1776 | |
1777 if(iItem > -1) | |
1778 { | |
1779 lvi.iItem = iItem; | |
1780 lvi.mask = LVIF_PARAM; | |
1781 | |
1782 ListView_GetItem(hWnd, &lvi); | |
1783 } | |
1784 else | |
1785 lvi.lParam = (LPARAM)NULL; | |
1786 | |
1787 { | |
1788 SignalHandler *tmp = Root; | |
1789 | |
1790 while(tmp) | |
1791 { | |
1792 if(tmp->message == NM_DBLCLK && tmp->window == hWnd) | |
1793 { | |
1794 int (*containerselectfunc)(HWND, char *, void *) = tmp->signalfunction; | |
1795 | |
1796 /* Seems to be having lParam as 1 which really sucks */ | |
1797 if(lvi.lParam < 100) | |
1798 lvi.lParam = 0; | |
1799 | |
1800 containerselectfunc(tmp->window, (char *)lvi.lParam, tmp->data); | |
1801 tmp = NULL; | |
1802 } | |
1803 if(tmp) | |
1804 tmp = tmp->next; | |
1805 } | |
1806 } | |
1807 } | 1951 } |
1808 break; | 1952 break; |
1809 case WM_CONTEXTMENU: | 1953 case WM_CLOSE: |
1954 if(result == -1) | |
1810 { | 1955 { |
1811 SignalHandler *tmp = Root; | 1956 dw_window_destroy(WinQueryWindow(hWnd, QW_PARENT)); |
1812 | 1957 return (MRESULT)TRUE; |
1813 while(tmp) | |
1814 { | |
1815 if(tmp->message == NM_RCLICK && tmp->window == hWnd) | |
1816 { | |
1817 int (*containercontextfunc)(HWND, char *, int, int, void *) = tmp->signalfunction; | |
1818 LONG x,y; | |
1819 LV_ITEM lvi; | |
1820 int iItem; | |
1821 LVHITTESTINFO lhi; | |
1822 | |
1823 dw_pointer_query_pos(&x, &y); | |
1824 | |
1825 lhi.pt.x = x; | |
1826 lhi.pt.y = y; | |
1827 | |
1828 MapWindowPoints(HWND_DESKTOP, tmp->window, &lhi.pt, 1); | |
1829 | |
1830 iItem = ListView_HitTest(tmp->window, &lhi); | |
1831 | |
1832 if(iItem > -1) | |
1833 { | |
1834 lvi.iItem = iItem; | |
1835 lvi.mask = LVIF_PARAM; | |
1836 | |
1837 ListView_GetItem(tmp->window, &lvi); | |
1838 ListView_SetSelectionMark(tmp->window, iItem); | |
1839 } | |
1840 else | |
1841 lvi.lParam = (LPARAM)NULL; | |
1842 | |
1843 /* Seems to be having lParam as 1 which really sucks */ | |
1844 if(lvi.lParam < 100) | |
1845 lvi.lParam = 0; | |
1846 | |
1847 containercontextfunc(tmp->window, (char *)lvi.lParam, x, y, tmp->data); | |
1848 tmp = NULL; | |
1849 } | |
1850 if(tmp) | |
1851 tmp = tmp->next; | |
1852 } | |
1853 } | 1958 } |
1854 break; | 1959 break; |
1855 #else | 1960 case WM_USER: |
1961 windowfunc = (void (*)(void *))mp1; | |
1962 | |
1963 if(windowfunc) | |
1964 windowfunc((void *)mp2); | |
1965 break; | |
1856 case WM_CHAR: | 1966 case WM_CHAR: |
1857 if(LOWORD(mp1) == '\t') | 1967 if(SHORT1FROMMP(mp2) == '\t') |
1858 { | 1968 { |
1859 _shift_focus(hWnd); | 1969 _shift_focus(hWnd); |
1860 return FALSE; | 1970 return FALSE; |
1861 } | 1971 } |
1862 break; | 1972 break; |
1863 #endif | 1973 case WM_DESTROY: |
1864 } | 1974 /* Free memory before destroying */ |
1865 | 1975 _free_window_memory(hWnd); |
1866 if(!cinfo || !cinfo->pOldProc) | 1976 break; |
1867 return DefWindowProc(hWnd, msg, mp1, mp2); | 1977 } |
1868 return CallWindowProc(cinfo->pOldProc, hWnd, msg, mp1, mp2); | 1978 if(result != -1) |
1979 return (MRESULT)result; | |
1980 else | |
1981 return WinDefWindowProc(hWnd, msg, mp1, mp2); | |
1869 } | 1982 } |
1870 | 1983 |
1871 void _changebox(Box *thisbox, int percent, int type) | 1984 void _changebox(Box *thisbox, int percent, int type) |
1872 { | 1985 { |
1873 int z; | 1986 int z; |
1874 | 1987 |
1875 for(z=0;z<thisbox->count;z++) | 1988 for(z=0;z<thisbox->count;z++) |
1876 { | 1989 { |
1877 if(thisbox->items[z].type == TYPEBOX) | 1990 if(thisbox->items[z].type == TYPEBOX) |
1878 { | 1991 { |
1879 Box *tmp = (Box*)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA); | 1992 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); |
1880 _changebox(tmp, percent, type); | 1993 _changebox(tmp, percent, type); |
1881 } | 1994 } |
1882 else | 1995 else |
1883 { | 1996 { |
1884 if(type == BOXHORZ) | 1997 if(type == BOXHORZ) |
1894 } | 2007 } |
1895 } | 2008 } |
1896 } | 2009 } |
1897 | 2010 |
1898 /* This handles any activity on the splitbars (sizers) */ | 2011 /* This handles any activity on the splitbars (sizers) */ |
1899 BOOL CALLBACK _splitwndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2) | 2012 MRESULT EXPENTRY _splitwndproc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
1900 { | 2013 { |
1901 HWND hwndFrame = 0; | 2014 HWND hwndFrame = 0; |
1902 Box *thisbox = 0; | 2015 Box *thisbox = 0; |
1903 | 2016 |
1904 hwndFrame = GetParent(hwnd); | 2017 hwndFrame = WinQueryWindow(hwnd, QW_PARENT); |
1905 if(hwndFrame) | 2018 if(hwndFrame) |
1906 thisbox = (Box *)GetWindowLong(hwndFrame, GWL_USERDATA); | 2019 thisbox = WinQueryWindowPtr(hwndFrame, QWL_USER); |
1907 | 2020 |
1908 switch (msg) | 2021 switch (msg) |
1909 { | 2022 { |
1910 case WM_ACTIVATE: | 2023 case WM_ACTIVATE: |
1911 case WM_SETFOCUS: | 2024 case WM_SETFOCUS: |
1912 return FALSE; | 2025 return (MRESULT)(FALSE); |
1913 | 2026 |
1914 case WM_PAINT: | 2027 case WM_PAINT: |
1915 { | 2028 { |
1916 HDC hdcPaint; | 2029 HPS hpsPaint; |
1917 PAINTSTRUCT ps; | 2030 RECTL rclPaint; |
1918 POINT ptlStart[SPLITBAR_WIDTH]; | 2031 POINTL ptlStart[SPLITBAR_WIDTH]; |
1919 POINT ptlEnd[SPLITBAR_WIDTH]; | 2032 POINTL ptlEnd[SPLITBAR_WIDTH]; |
1920 RECT rcPaint; | |
1921 USHORT i; | 2033 USHORT i; |
1922 | 2034 |
1923 hdcPaint = BeginPaint(hwnd, &ps); | 2035 hpsPaint = WinBeginPaint(hwnd, 0, 0); |
1924 GetWindowRect(hwnd, &rcPaint); | 2036 WinQueryWindowRect(hwnd, &rclPaint); |
1925 | 2037 |
1926 if(thisbox->type == BOXHORZ) | 2038 if(thisbox->type == BOXHORZ) |
1927 { | 2039 { |
1928 for(i = 0; i < SPLITBAR_WIDTH; i++) | 2040 for(i = 0; i < SPLITBAR_WIDTH; i++) |
1929 { | 2041 { |
1930 ptlStart[i].x = i; | 2042 ptlStart[i].x = rclPaint.xLeft + i; |
1931 ptlStart[i].y = 0; | 2043 ptlStart[i].y = rclPaint.yTop; |
1932 | 2044 |
1933 ptlEnd[i].x = i; | 2045 ptlEnd[i].x = rclPaint.xLeft + i; |
1934 ptlEnd[i].y = rcPaint.bottom - rcPaint.top; | 2046 ptlEnd[i].y = rclPaint.yBottom; |
1935 } | 2047 } |
1936 } | 2048 } |
1937 else | 2049 else |
1938 { | 2050 { |
1939 for(i = 0; i < SPLITBAR_WIDTH; i++) | 2051 for(i = 0; i < SPLITBAR_WIDTH; i++) |
1940 { | 2052 { |
1941 ptlStart[i].x = 0; | 2053 ptlStart[i].x = rclPaint.xLeft; |
1942 ptlStart[i].y = i; | 2054 ptlStart[i].y = rclPaint.yBottom + i; |
1943 | 2055 |
1944 ptlEnd[i].x = rcPaint.right - rcPaint.left; | 2056 ptlEnd[i].x = rclPaint.xRight; |
1945 ptlEnd[i].y = i; | 2057 ptlEnd[i].y = rclPaint.yBottom + i; |
1946 } | 2058 } |
1947 } | 2059 } |
1948 | 2060 |
1949 for(i = 0; i < SPLITBAR_WIDTH; i++) | 2061 for(i = 0; i < SPLITBAR_WIDTH; i++) |
1950 { | 2062 { |
1951 HPEN hPen; | 2063 GpiSetColor( hpsPaint, lColor[i]); |
1952 HPEN hOldPen; | 2064 GpiMove(hpsPaint, &ptlStart[i]); |
1953 | 2065 GpiLine(hpsPaint, &ptlEnd[i]); |
1954 hPen = CreatePen(PS_SOLID, 1, RGB (_red[lColor[i]], _green[lColor[i]], _blue[lColor[i]])); | |
1955 hOldPen = (HPEN)SelectObject(hdcPaint, hPen); | |
1956 MoveToEx(hdcPaint, ptlStart[i].x, ptlStart[i].y, NULL); | |
1957 LineTo(hdcPaint, ptlEnd[i].x, ptlEnd[i].y); | |
1958 SelectObject(hdcPaint, hOldPen); | |
1959 DeleteObject(hPen); | |
1960 } | 2066 } |
1961 EndPaint(hwnd, &ps); | 2067 WinEndPaint(hpsPaint); |
1962 } | 2068 } |
1963 return FALSE; | 2069 return MRFROMSHORT(FALSE); |
2070 | |
1964 case WM_MOUSEMOVE: | 2071 case WM_MOUSEMOVE: |
1965 { | 2072 { |
1966 if(thisbox->type == BOXHORZ) | 2073 if(thisbox->type == BOXHORZ) |
1967 SetCursor(LoadCursor(NULL, IDC_SIZEWE)); | 2074 WinSetPointer(HWND_DESKTOP, |
2075 WinQuerySysPointer(HWND_DESKTOP, | |
2076 SPTR_SIZEWE, | |
2077 FALSE)); | |
1968 else | 2078 else |
1969 SetCursor(LoadCursor(NULL, IDC_SIZENS)); | 2079 WinSetPointer(HWND_DESKTOP, |
2080 WinQuerySysPointer(HWND_DESKTOP, | |
2081 SPTR_SIZENS, | |
2082 FALSE)); | |
1970 } | 2083 } |
1971 return FALSE; | 2084 return MRFROMSHORT(FALSE); |
1972 #if 0 | |
1973 case WM_BUTTON1DOWN: | 2085 case WM_BUTTON1DOWN: |
1974 { | 2086 { |
1975 ULONG rc; | 2087 APIRET rc; |
1976 RECTL rclFrame; | 2088 RECTL rclFrame; |
1977 RECTL rclBounds; | 2089 RECTL rclBounds; |
1978 RECTL rclStart; | 2090 RECTL rclStart; |
1979 USHORT startSize, orig, actual; | 2091 USHORT startSize, orig, actual; |
1980 | 2092 |
1981 GetWindowRect(hwnd, &rclFrame); | 2093 WinQueryWindowRect(hwnd, &rclFrame); |
1982 GetWindowRect(hwnd, &rclStart); | 2094 WinQueryWindowRect(hwnd, &rclStart); |
1983 | 2095 |
1984 GetWindowRect(hwndFrame, &rclBounds); | 2096 WinQueryWindowRect(hwndFrame, &rclBounds); |
1985 | 2097 |
1986 WinMapWindowPoints(hwndFrame, HWND_DESKTOP, | 2098 WinMapWindowPoints(hwndFrame, HWND_DESKTOP, |
1987 (PPOINTL)&rclBounds, 2); | 2099 (PPOINTL)&rclBounds, 2); |
1988 WinMapWindowPoints(hwnd, HWND_DESKTOP, | 2100 WinMapWindowPoints(hwnd, HWND_DESKTOP, |
1989 (PPOINTL)&rclStart, 2); | 2101 (PPOINTL)&rclStart, 2); |
1990 | 2102 |
1991 if(thisbox->type == BOXHORZ) | |
1992 { | 2103 { |
1993 orig = thisbox->items[0].origwidth; | 2104 int z, pastsplitbar = FALSE, found = FALSE; |
1994 actual = thisbox->items[0].width; | 2105 orig = actual = 0; |
1995 | 2106 |
1996 startSize = (rclStart.xLeft - rclBounds.xLeft) | 2107 for(z=0;z<thisbox->count;z++) |
1997 * (((float)orig)/((float)actual)); | 2108 { |
1998 } | 2109 if(thisbox->items[z].hwnd == hwnd) |
1999 else | 2110 pastsplitbar = TRUE; |
2000 { | 2111 else |
2001 orig = thisbox->items[0].origheight; | 2112 { |
2002 actual = thisbox->items[0].height; | 2113 if(thisbox->type == BOXHORZ) |
2003 | 2114 { |
2004 startSize = (rclStart.yBottom - rclBounds.yBottom) | 2115 int tmpwidth, tmporigwidth; |
2005 * (((float)actual)/((float)orig)); | 2116 |
2117 if(thisbox->items[z].type == TYPEBOX) | |
2118 _count_size(thisbox->items[z].hwnd, BOXHORZ, &tmpwidth, &tmporigwidth); | |
2119 else | |
2120 { | |
2121 tmpwidth = thisbox->items[z].width; | |
2122 tmporigwidth = thisbox->items[z].origwidth; | |
2123 } | |
2124 | |
2125 if(thisbox->items[z].hsize != SIZESTATIC && tmpwidth > actual && tmporigwidth) | |
2126 { | |
2127 found = pastsplitbar; | |
2128 orig = tmporigwidth; | |
2129 actual = tmpwidth; | |
2130 } | |
2131 } | |
2132 else | |
2133 { | |
2134 int tmpheight, tmporigheight; | |
2135 | |
2136 if(thisbox->items[z].type == TYPEBOX) | |
2137 _count_size(thisbox->items[z].hwnd, BOXVERT, &tmpheight, &tmporigheight); | |
2138 else | |
2139 { | |
2140 tmpheight = thisbox->items[z].height; | |
2141 tmporigheight = thisbox->items[z].origheight; | |
2142 } | |
2143 | |
2144 if(thisbox->items[z].vsize != SIZESTATIC && tmpheight > actual && tmporigheight) | |
2145 { | |
2146 found = pastsplitbar; | |
2147 orig = tmporigheight; | |
2148 actual = tmpheight; | |
2149 } | |
2150 } | |
2151 } | |
2152 } | |
2153 | |
2154 /* If we couldn't determine a valid scale... then abort */ | |
2155 if(!orig || !actual) | |
2156 return MRFROMSHORT(FALSE); | |
2157 | |
2158 if(thisbox->type == BOXHORZ) | |
2159 { | |
2160 if(found) | |
2161 startSize = (rclStart.xLeft - rclBounds.xLeft) | |
2162 * (((float)actual)/((float)orig)); | |
2163 else | |
2164 startSize = (rclStart.xLeft - rclBounds.xLeft) | |
2165 * (((float)orig)/((float)actual)); | |
2166 } | |
2167 else | |
2168 { | |
2169 if(found) | |
2170 startSize = (rclStart.yBottom - rclBounds.yBottom) | |
2171 * (((float)actual)/((float)orig)); | |
2172 else | |
2173 startSize = (rclStart.yBottom - rclBounds.yBottom) | |
2174 * (((float)orig)/((float)actual)); | |
2175 } | |
2006 } | 2176 } |
2007 | 2177 |
2008 rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds); | 2178 rc = _TrackRectangle(hwnd, &rclFrame, &rclBounds); |
2009 | 2179 |
2010 if(rc == TRUE) | 2180 if(rc == TRUE) |
2011 { | 2181 { |
2012 USHORT usNewRB; | 2182 USHORT usNewRB; |
2013 USHORT usSize; | |
2014 USHORT percent; | 2183 USHORT percent; |
2015 int z; | 2184 int z; |
2016 | 2185 |
2017 if(thisbox->type == BOXHORZ) | 2186 if(thisbox->type == BOXHORZ) |
2018 { | 2187 { |
2019 usNewRB = rclFrame.xLeft | 2188 usNewRB = rclFrame.xLeft |
2020 - rclBounds.xLeft; | |
2021 usSize = rclBounds.xRight | |
2022 - rclBounds.xLeft; | 2189 - rclBounds.xLeft; |
2023 } | 2190 } |
2024 else | 2191 else |
2025 { | 2192 { |
2026 usNewRB = rclFrame.yBottom | 2193 usNewRB = rclFrame.yBottom |
2027 - rclBounds.yBottom; | 2194 - rclBounds.yBottom; |
2028 usSize = rclBounds.yTop | |
2029 - rclBounds.yBottom; | |
2030 } | 2195 } |
2196 | |
2197 /* We don't want the item to disappear completely */ | |
2198 if(!usNewRB) | |
2199 usNewRB++; | |
2200 | |
2201 if(!startSize) | |
2202 startSize++; | |
2031 | 2203 |
2032 percent = (usNewRB*100)/startSize; | 2204 percent = (usNewRB*100)/startSize; |
2033 | 2205 |
2034 for(z=0;z<thisbox->count;z++) | 2206 for(z=0;z<thisbox->count;z++) |
2035 { | 2207 { |
2036 if(thisbox->items[z].type == TYPEBOX) | 2208 if(thisbox->items[z].type == TYPEBOX) |
2037 { | 2209 { |
2038 Box *tmp = (Box *)GetWindowLong(thisbox->items[z].hwnd, GWL_USERDATA); | 2210 Box *tmp = WinQueryWindowPtr(thisbox->items[z].hwnd, QWP_USER); |
2039 _changebox(tmp, percent, thisbox->type); | 2211 |
2212 if(tmp) | |
2213 _changebox(tmp, percent, thisbox->type); | |
2040 } | 2214 } |
2041 else | 2215 else |
2042 { | 2216 { |
2043 if(thisbox->items[z].hwnd == hwnd) | 2217 if(thisbox->items[z].hwnd == hwnd) |
2044 percent = (startSize*100)/usNewRB; | 2218 percent = (startSize*100)/usNewRB; |
2054 thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0))); | 2228 thisbox->items[z].height = (int)(((float)thisbox->items[z].origheight) * (((float)percent)/((float)100.0))); |
2055 } | 2229 } |
2056 } | 2230 } |
2057 } | 2231 } |
2058 | 2232 |
2059 _ResetWindow(GetWindow(hwnd, GW_OWNER)); | 2233 _ResetWindow(WinQueryWindow(hwnd, QW_OWNER)); |
2060 } | 2234 } |
2061 } | 2235 } |
2062 return MRFROMSHORT(FALSE); | 2236 return MRFROMSHORT(FALSE); |
2063 #endif | 2237 } |
2064 } | 2238 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2065 return DefWindowProc(hwnd, msg, mp1, mp2); | 2239 } |
2066 } | 2240 |
2067 | 2241 /* Function: BubbleProc |
2068 /* This handles drawing the status text areas */ | 2242 * Abstract: Subclass procedure for bubble help |
2069 BOOL CALLBACK _statuswndproc(HWND hwnd, UINT msg, WPARAM mp1, LPARAM mp2) | 2243 */ |
2070 { | 2244 MRESULT EXPENTRY _BubbleProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
2071 switch (msg) | 2245 { |
2072 { | 2246 MRESULT res; |
2073 case WM_SETTEXT: | 2247 PFNWP proc = (PFNWP)WinQueryWindowPtr(hwnd, QWL_USER); |
2074 { | 2248 |
2075 /* Make sure the control redraws when there is a text change */ | 2249 if(proc) |
2076 int ret = (int)DefWindowProc(hwnd, msg, mp1, mp2); | 2250 res = proc(hwnd, msg, mp1, mp2); |
2077 | 2251 else |
2078 InvalidateRgn(hwnd, NULL, TRUE); | 2252 res = WinDefWindowProc(hwnd, msg, mp1, mp2); |
2079 return ret; | 2253 |
2080 } | 2254 if(msg == WM_PAINT) |
2081 case WM_PAINT: | 2255 { |
2082 { | 2256 POINTL ptl; |
2083 HDC hdcPaint; | 2257 HPS hpsTemp; |
2084 PAINTSTRUCT ps; | 2258 RECTL rcl; |
2085 RECT rc; | 2259 int height, width; |
2086 HFONT hFont; | 2260 |
2087 HBRUSH oldBrush; | 2261 WinQueryWindowRect(hwnd, &rcl); |
2088 HPEN oldPen; | 2262 height = rcl.yTop - rcl.yBottom - 1; |
2089 unsigned long cx, cy; | 2263 width = rcl.xRight - rcl.xLeft - 1; |
2090 int threadid = dw_thread_id(); | 2264 |
2091 char tempbuf[1024] = ""; | 2265 /* Draw a border around the bubble help */ |
2092 | 2266 hpsTemp = WinGetPS(hwnd); |
2093 if(threadid < 0 || threadid >= THREAD_LIMIT) | 2267 GpiSetColor(hpsTemp, DW_CLR_BLACK); |
2094 threadid = 0; | 2268 ptl.x = ptl.y = 0; |
2095 | 2269 GpiMove(hpsTemp, &ptl); |
2096 hdcPaint = BeginPaint(hwnd, &ps); | 2270 ptl.x = 0; |
2097 EndPaint(hwnd, &ps); | 2271 ptl.y = height; |
2098 | 2272 GpiLine(hpsTemp, &ptl); |
2099 hdcPaint = GetDC(hwnd); | 2273 ptl.x = ptl.y = 0; |
2100 | 2274 GpiMove(hpsTemp, &ptl); |
2101 oldBrush = _hBrush[threadid]; | 2275 ptl.y = 0; |
2102 oldPen = _hPen[threadid]; | 2276 ptl.x = width; |
2103 | 2277 GpiLine(hpsTemp, &ptl); |
2104 dw_window_get_pos_size(hwnd, NULL, NULL, &cx, &cy); | 2278 ptl.x = width; |
2105 | 2279 ptl.y = height; |
2106 | 2280 GpiMove(hpsTemp, &ptl); |
2107 _hBrush[threadid] = CreateSolidBrush(GetSysColor(COLOR_3DFACE)); | 2281 ptl.x = 0; |
2108 | 2282 ptl.y = height; |
2109 dw_draw_rect(hwnd, 0, TRUE, 0, 0, cx, cy); | 2283 GpiLine(hpsTemp, &ptl); |
2110 | 2284 ptl.x = width; |
2111 _hPen[threadid] = CreatePen(PS_SOLID, 1, RGB(_red[DW_CLR_DARKGRAY], | 2285 ptl.y = height; |
2112 _green[DW_CLR_DARKGRAY], | 2286 GpiMove(hpsTemp, &ptl); |
2113 _blue[DW_CLR_DARKGRAY])); | 2287 ptl.y = 0; |
2114 | 2288 ptl.x = width; |
2115 dw_draw_line(hwnd, 0, 0, 0, cx, 0); | 2289 GpiLine(hpsTemp, &ptl); |
2116 dw_draw_line(hwnd, 0, 0, 0, 0, cy); | 2290 WinReleasePS(hpsTemp); |
2117 | 2291 } |
2118 DeleteObject(_hPen[threadid]); | 2292 return res; |
2119 | 2293 } |
2120 _hPen[threadid] = GetStockObject(WHITE_PEN); | 2294 |
2121 | 2295 /* Function: BtProc |
2122 dw_draw_line(hwnd, 0, cx - 1, cy - 1, cx - 1, 0); | |
2123 dw_draw_line(hwnd, 0, cx - 1, cy - 1, 0, cy - 1); | |
2124 | |
2125 rc.left = 3; | |
2126 rc.top = 1; | |
2127 rc.bottom = cy - 1; | |
2128 rc.right = cx - 1; | |
2129 | |
2130 GetWindowText(hwnd, tempbuf, 1024); | |
2131 | |
2132 hFont = (HFONT)SelectObject(hdcPaint, GetStockObject(DEFAULT_GUI_FONT)); | |
2133 | |
2134 SetTextColor(hdcPaint, RGB(0,0,0)); | |
2135 SetBkMode(hdcPaint, TRANSPARENT); | |
2136 | |
2137 ExtTextOut(hdcPaint, 3, 1, ETO_CLIPPED, &rc, tempbuf, strlen(tempbuf), NULL); | |
2138 | |
2139 SelectObject(hdcPaint, hFont); | |
2140 | |
2141 DeleteObject(_hBrush[threadid]); | |
2142 _hBrush[threadid] = oldBrush; | |
2143 _hPen[threadid] = oldPen; | |
2144 ReleaseDC(hwnd, hdcPaint); | |
2145 } | |
2146 return FALSE; | |
2147 } | |
2148 return DefWindowProc(hwnd, msg, mp1, mp2); | |
2149 } | |
2150 | |
2151 /* Function: _BtProc | |
2152 * Abstract: Subclass procedure for buttons | 2296 * Abstract: Subclass procedure for buttons |
2153 */ | 2297 */ |
2154 | 2298 |
2155 BOOL CALLBACK _BtProc(HWND hwnd, ULONG msg, WPARAM mp1, LPARAM mp2) | 2299 MRESULT EXPENTRY _BtProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
2156 { | 2300 { |
2157 BubbleButton *bubble; | 2301 BubbleButton *bubble; |
2158 static int bMouseOver = 0; | 2302 PFNWP oldproc; |
2159 POINT point; | 2303 |
2160 RECT rect; | 2304 bubble = (BubbleButton *)WinQueryWindowPtr(hwnd, QWL_USER); |
2161 WNDPROC pOldProc; | |
2162 | |
2163 bubble = (BubbleButton *)GetWindowLong(hwnd, GWL_USERDATA); | |
2164 | 2305 |
2165 if(!bubble) | 2306 if(!bubble) |
2166 return DefWindowProc(hwnd, msg, mp1, mp2); | 2307 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2167 | 2308 |
2168 /* We must save a pointer to the old | 2309 oldproc = bubble->pOldProc; |
2169 * window procedure because if a signal | |
2170 * handler attached here destroys this | |
2171 * window it will then be invalid. | |
2172 */ | |
2173 pOldProc = bubble->pOldProc; | |
2174 | 2310 |
2175 switch(msg) | 2311 switch(msg) |
2176 { | 2312 { |
2177 #ifndef NO_SIGNALS | 2313 #ifndef NO_SIGNALS |
2178 case WM_SETFOCUS: | 2314 case WM_SETFOCUS: |
2179 _wndproc(hwnd, msg, mp1, mp2); | 2315 if(mp2) |
2316 _run_event(hwnd, msg, mp1, mp2); | |
2317 else | |
2318 WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); | |
2180 break; | 2319 break; |
2181 case WM_LBUTTONUP: | 2320 case WM_BUTTON1UP: |
2182 { | 2321 { |
2183 SignalHandler *tmp = Root; | 2322 SignalHandler *tmp = Root; |
2184 | 2323 |
2185 /* Find any callbacks for this function */ | 2324 if(WinIsWindowEnabled(hwnd)) |
2186 while(tmp) | |
2187 { | 2325 { |
2188 if(tmp->message == WM_COMMAND) | 2326 /* Find any callbacks for this function */ |
2327 while(tmp) | |
2189 { | 2328 { |
2190 int (*clickfunc)(HWND, void *) = tmp->signalfunction; | 2329 if(tmp->message == WM_COMMAND) |
2191 | |
2192 /* Make sure it's the right window, and the right ID */ | |
2193 if(tmp->window == hwnd) | |
2194 { | 2330 { |
2195 clickfunc(tmp->window, tmp->data); | 2331 /* Make sure it's the right window, and the right ID */ |
2196 tmp = NULL; | 2332 if(tmp->window == hwnd) |
2333 { | |
2334 /* Due to the fact that if we run the function | |
2335 * here, finishing actions on the button will occur | |
2336 * after we run the signal handler. So we post the | |
2337 * message so the button can finish what it needs to | |
2338 * do before we run our handler. | |
2339 */ | |
2340 WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); | |
2341 tmp = NULL; | |
2342 } | |
2197 } | 2343 } |
2344 if(tmp) | |
2345 tmp= tmp->next; | |
2198 } | 2346 } |
2199 if(tmp) | |
2200 tmp= tmp->next; | |
2201 } | 2347 } |
2202 } | 2348 } |
2203 break; | 2349 break; |
2350 case WM_USER: | |
2351 { | |
2352 SignalHandler *tmp = (SignalHandler *)mp1; | |
2353 int (*clickfunc)(HWND, void *) = NULL; | |
2354 | |
2355 if(tmp) | |
2356 { | |
2357 clickfunc = (int (*)(HWND, void *))tmp->signalfunction; | |
2358 | |
2359 clickfunc(tmp->window, tmp->data); | |
2360 } | |
2361 } | |
2362 break; | |
2204 #endif | 2363 #endif |
2205 case WM_CHAR: | 2364 case WM_CHAR: |
2206 { | 2365 { |
2207 #ifndef NO_SIGNALS | 2366 #ifndef NO_SIGNALS |
2208 /* A button press should also occur for an ENTER or SPACE press | 2367 /* A button press should also occur for an ENTER or SPACE press |
2209 * while the button has the active input focus. | 2368 * while the button has the active input focus. |
2210 */ | 2369 */ |
2211 if(LOWORD(mp1) == '\r' || LOWORD(mp1) == ' ') | 2370 if(SHORT1FROMMP(mp2) == '\r' || SHORT1FROMMP(mp2) == ' ') |
2212 { | 2371 { |
2213 SignalHandler *tmp = Root; | 2372 SignalHandler *tmp = Root; |
2214 | 2373 |
2215 /* Find any callbacks for this function */ | 2374 /* Find any callbacks for this function */ |
2216 while(tmp) | 2375 while(tmp) |
2217 { | 2376 { |
2218 if(tmp->message == WM_COMMAND) | 2377 if(tmp->message == WM_COMMAND) |
2219 { | 2378 { |
2220 int (*clickfunc)(HWND, void *) = tmp->signalfunction; | |
2221 | |
2222 /* Make sure it's the right window, and the right ID */ | 2379 /* Make sure it's the right window, and the right ID */ |
2223 if(tmp->window == hwnd) | 2380 if(tmp->window == hwnd) |
2224 { | 2381 { |
2225 clickfunc(tmp->window, tmp->data); | 2382 WinPostMsg(hwnd, WM_USER, (MPARAM)tmp, 0); |
2226 tmp = NULL; | 2383 tmp = NULL; |
2227 } | 2384 } |
2228 } | 2385 } |
2229 if(tmp) | 2386 if(tmp) |
2230 tmp= tmp->next; | 2387 tmp= tmp->next; |
2231 } | 2388 } |
2232 } | 2389 } |
2233 #endif | 2390 #endif |
2234 if(LOWORD(mp1) == '\t') | 2391 if(SHORT1FROMMP(mp2) == '\t') |
2235 { | 2392 { |
2236 _shift_focus(hwnd); | 2393 _shift_focus(hwnd); |
2394 WinSendMsg(hwnd, BM_SETDEFAULT, 0, 0); | |
2237 return FALSE; | 2395 return FALSE; |
2238 } | 2396 } |
2239 } | 2397 } |
2240 break; | 2398 break; |
2241 case WM_TIMER: | 2399 case 0x041f: |
2242 if (hwndBubble) | 2400 if (hwndBubble) |
2243 { | 2401 { |
2244 DestroyWindow(hwndBubble); | 2402 WinDestroyWindow(hwndBubble); |
2245 hwndBubble = 0; | 2403 hwndBubble = 0; |
2246 KillTimer(hwnd, 1); | |
2247 } | 2404 } |
2248 break; | 2405 break; |
2249 | 2406 |
2250 case WM_MOUSEMOVE: | 2407 case 0x041e: |
2251 GetCursorPos(&point); | 2408 |
2252 GetWindowRect(hwnd, &rect); | 2409 if(!*bubble->bubbletext) |
2253 | 2410 break; |
2254 if(PtInRect(&rect, point)) | 2411 |
2412 | |
2413 if(hwndBubble) | |
2255 { | 2414 { |
2256 if(hwnd != GetCapture()) | 2415 WinDestroyWindow(hwndBubble); |
2257 { | 2416 hwndBubble = 0; |
2258 SetCapture(hwnd); | |
2259 } | |
2260 if(!bMouseOver) | |
2261 { | |
2262 bMouseOver = 1; | |
2263 if(!*bubble->bubbletext) | |
2264 break; | |
2265 | |
2266 if(hwndBubble) | |
2267 { | |
2268 DestroyWindow(hwndBubble); | |
2269 hwndBubble = 0; | |
2270 KillTimer(hwndBubbleLast, 1); | |
2271 } | |
2272 | |
2273 if(!hwndBubble) | |
2274 { | |
2275 POINTL ptlWork = {0,0}; | |
2276 ULONG ulColor = DW_CLR_YELLOW; | |
2277 SIZE size; | |
2278 HDC hdc; | |
2279 RECT rect; | |
2280 void *oldproc; | |
2281 | |
2282 /* Use the WS_EX_TOOLWINDOW extended style | |
2283 * so the window doesn't get listed in the | |
2284 * taskbar. | |
2285 */ | |
2286 hwndBubble = CreateWindowEx(WS_EX_TOOLWINDOW, | |
2287 STATICCLASSNAME, | |
2288 bubble->bubbletext, | |
2289 BS_TEXT | WS_POPUP | | |
2290 WS_BORDER | | |
2291 SS_CENTER, | |
2292 0,0,50,20, | |
2293 HWND_DESKTOP, | |
2294 NULL, | |
2295 NULL, | |
2296 NULL); | |
2297 | |
2298 dw_window_set_font(hwndBubble, DefaultFont); | |
2299 dw_window_set_color(hwndBubble, DW_CLR_BLACK, DW_CLR_YELLOW); | |
2300 | |
2301 hwndBubbleLast = hwnd; | |
2302 | |
2303 SetTimer(hwnd, 1, 3000, NULL); | |
2304 | |
2305 hdc = GetDC(hwndBubble); | |
2306 | |
2307 GetTextExtentPoint(hdc, bubble->bubbletext, strlen(bubble->bubbletext), &size); | |
2308 | |
2309 MapWindowPoints(hwnd, HWND_DESKTOP, (LPPOINT)&ptlWork, 1); | |
2310 | |
2311 GetWindowRect(hwnd, &rect); | |
2312 | |
2313 SetWindowPos(hwndBubble, | |
2314 HWND_TOP, | |
2315 ptlWork.x, | |
2316 ptlWork.y + (rect.bottom-rect.top) + 1, | |
2317 size.cx + 2, | |
2318 size.cy + 2, | |
2319 SWP_NOACTIVATE | SWP_SHOWWINDOW); | |
2320 | |
2321 ReleaseDC(hwndBubble, hdc); | |
2322 } | |
2323 } | |
2324 } | 2417 } |
2325 else{ | 2418 |
2326 /* Calling ReleaseCapture in Win95 also causes WM_CAPTURECHANGED | 2419 if(!hwndBubble) |
2327 * to be sent. Be sure to account for that. | 2420 { |
2328 */ | 2421 HPS hpsTemp = 0; |
2329 ReleaseCapture(); | 2422 LONG lHight; |
2330 | 2423 LONG lWidth; |
2331 if(bMouseOver) | 2424 POINTL txtPointl[TXTBOX_COUNT]; |
2332 { | 2425 POINTL ptlWork = {0,0}; |
2333 bMouseOver = 0; | 2426 ULONG ulColor = DW_CLR_YELLOW; |
2334 DestroyWindow(hwndBubble); | 2427 void *blah; |
2335 hwndBubble = 0; | 2428 |
2336 KillTimer(hwndBubbleLast, 1); | 2429 hwndBubbleLast = hwnd; |
2337 } | 2430 hwndBubble = WinCreateWindow(HWND_DESKTOP, |
2431 WC_STATIC, | |
2432 "", | |
2433 SS_TEXT | | |
2434 DT_CENTER | | |
2435 DT_VCENTER, | |
2436 0,0,0,0, | |
2437 HWND_DESKTOP, | |
2438 HWND_TOP, | |
2439 0, | |
2440 NULL, | |
2441 NULL); | |
2442 | |
2443 WinSetPresParam(hwndBubble, | |
2444 PP_FONTNAMESIZE, | |
2445 sizeof(DefaultFont), | |
2446 DefaultFont); | |
2447 | |
2448 | |
2449 WinSetPresParam(hwndBubble, | |
2450 PP_BACKGROUNDCOLORINDEX, | |
2451 sizeof(ulColor), | |
2452 &ulColor); | |
2453 | |
2454 WinSetWindowText(hwndBubble, | |
2455 bubble->bubbletext); | |
2456 | |
2457 WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptlWork, 1); | |
2458 | |
2459 hpsTemp = WinGetPS(hwndBubble); | |
2460 GpiQueryTextBox(hpsTemp, | |
2461 strlen(bubble->bubbletext), | |
2462 bubble->bubbletext, | |
2463 TXTBOX_COUNT, | |
2464 txtPointl); | |
2465 WinReleasePS(hpsTemp); | |
2466 | |
2467 lWidth = txtPointl[TXTBOX_TOPRIGHT].x - | |
2468 txtPointl[TXTBOX_TOPLEFT ].x + 8; | |
2469 | |
2470 lHight = txtPointl[TXTBOX_TOPLEFT].y - | |
2471 txtPointl[TXTBOX_BOTTOMLEFT].y + 8; | |
2472 | |
2473 ptlWork.y -= lHight; | |
2474 | |
2475 blah = (void *)WinSubclassWindow(hwndBubble, _BubbleProc); | |
2476 | |
2477 if(blah) | |
2478 WinSetWindowPtr(hwndBubble, QWP_USER, blah); | |
2479 | |
2480 WinSetWindowPos(hwndBubble, | |
2481 HWND_TOP, | |
2482 ptlWork.x, | |
2483 ptlWork.y, | |
2484 lWidth, | |
2485 lHight, | |
2486 SWP_SIZE | SWP_MOVE | SWP_SHOW); | |
2338 } | 2487 } |
2339 break; | 2488 break; |
2340 case WM_CAPTURECHANGED: | 2489 } |
2341 /* This message means we are losing the capture for some reason | 2490 |
2342 * Either because we intentionally lost it or another window | 2491 if(!oldproc) |
2343 * stole it | 2492 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2344 */ | 2493 return oldproc(hwnd, msg, mp1, mp2); |
2345 if(bMouseOver) | 2494 } |
2346 { | 2495 |
2347 bMouseOver = 0; | 2496 MRESULT EXPENTRY _RendProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
2348 DestroyWindow(hwndBubble); | 2497 { |
2349 hwndBubble = 0; | 2498 int res = 0; |
2350 KillTimer(hwndBubbleLast, 1); | 2499 #ifndef NO_SIGNALS |
2351 } | 2500 res = (int)_run_event(hwnd, msg, mp1, mp2); |
2352 break; | 2501 #endif |
2353 } | 2502 switch(msg) |
2354 | 2503 { |
2355 if(!pOldProc) | 2504 case WM_BUTTON1DOWN: |
2356 return DefWindowProc(hwnd, msg, mp1, mp2); | 2505 case WM_BUTTON2DOWN: |
2357 return CallWindowProc(pOldProc, hwnd, msg, mp1, mp2); | 2506 case WM_BUTTON3DOWN: |
2358 } | 2507 if(!res) |
2359 | 2508 WinSetFocus(HWND_DESKTOP, hwnd); |
2360 /* This function recalculates a notebook page for example | 2509 return (MPARAM)TRUE; |
2361 * during switching of notebook pages. | 2510 } |
2362 */ | 2511 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2363 void _resize_notebook_page(HWND handle, int pageid) | 2512 } |
2364 { | 2513 |
2365 RECT rect; | 2514 MRESULT EXPENTRY _TreeProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) |
2366 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | 2515 { |
2367 | 2516 Box *blah = WinQueryWindowPtr(hwnd, QWP_USER); |
2368 if(array && array[pageid]) | 2517 |
2369 { | 2518 #ifndef NO_SIGNALS |
2370 Box *box = (Box *)GetWindowLong(array[pageid]->hwnd, GWL_USERDATA); | 2519 _run_event(hwnd, msg, mp1, mp2); |
2371 | 2520 #endif |
2372 GetClientRect(handle,&rect); | 2521 if(blah && blah->oldproc) |
2373 TabCtrl_AdjustRect(handle,FALSE,&rect); | 2522 return blah->oldproc(hwnd, msg, mp1, mp2); |
2374 MoveWindow(array[pageid]->hwnd, rect.left, rect.top, | 2523 return WinDefWindowProc(hwnd, msg, mp1, mp2); |
2375 rect.right - rect.left, rect.bottom-rect.top, TRUE); | |
2376 if(box && box->count) | |
2377 { | |
2378 ShowWindow(box->items[0].hwnd, SW_HIDE); | |
2379 _do_resize(box, rect.right - rect.left, rect.bottom - rect.top); | |
2380 ShowWindow(box->items[0].hwnd, SW_SHOW); | |
2381 } | |
2382 | |
2383 ShowWindow(array[pageid]->hwnd, SW_SHOWNORMAL); | |
2384 } | |
2385 } | 2524 } |
2386 | 2525 |
2387 /* | 2526 /* |
2388 * Initializes the Dynamic Windows engine. | 2527 * Initializes the Dynamic Windows engine. |
2389 * Parameters: | 2528 * Parameters: |
2390 * newthread: True if this is the only thread. | 2529 * newthread: True if this is the only thread. |
2391 * False if there is already a message loop running. | 2530 * False if there is already a message loop running. |
2392 */ | 2531 */ |
2393 int dw_init(int newthread, int argc, char *argv[]) | 2532 int dw_init(int newthread, int argc, char *argv[]) |
2394 { | 2533 { |
2395 WNDCLASS wc; | 2534 APIRET rc; |
2396 int z; | 2535 |
2397 INITCOMMONCONTROLSEX icc; | 2536 if(newthread) |
2398 | 2537 { |
2399 icc.dwSize = sizeof(INITCOMMONCONTROLSEX); | 2538 dwhab = WinInitialize(0); |
2400 icc.dwICC = ICC_WIN95_CLASSES; | 2539 dwhmq = WinCreateMsgQueue(dwhab, 0); |
2401 | 2540 } |
2402 InitCommonControlsEx(&icc); | 2541 |
2403 | 2542 rc = WinRegisterClass(dwhab, ClassName, _wndproc, CS_SIZEREDRAW | CS_CLIPCHILDREN, 32); |
2404 memset(lookup, 0, sizeof(HICON) * ICON_INDEX_LIMIT); | 2543 rc = WinRegisterClass(dwhab, SplitbarClassName, _splitwndproc, 0L, 32); |
2405 | 2544 |
2406 /* Register the generic Dynamic Windows class */ | 2545 /* Get the OS/2 version. */ |
2407 memset(&wc, 0, sizeof(WNDCLASS)); | 2546 DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG)); |
2408 wc.style = CS_DBLCLKS; | |
2409 wc.lpfnWndProc = (WNDPROC)_wndproc; | |
2410 wc.cbClsExtra = 0; | |
2411 wc.cbWndExtra = 32; | |
2412 wc.hbrBackground = NULL; | |
2413 wc.lpszMenuName = NULL; | |
2414 wc.lpszClassName = ClassName; | |
2415 | |
2416 RegisterClass(&wc); | |
2417 | |
2418 /* Register the splitbar control */ | |
2419 memset(&wc, 0, sizeof(WNDCLASS)); | |
2420 wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; | |
2421 wc.lpfnWndProc = (WNDPROC)_splitwndproc; | |
2422 wc.cbClsExtra = 0; | |
2423 wc.cbWndExtra = 0; | |
2424 wc.hbrBackground = NULL; | |
2425 wc.lpszMenuName = NULL; | |
2426 wc.lpszClassName = SplitbarClassName; | |
2427 | |
2428 RegisterClass(&wc); | |
2429 | |
2430 /* Register a frame control like on OS/2 */ | |
2431 memset(&wc, 0, sizeof(WNDCLASS)); | |
2432 wc.style = CS_DBLCLKS; | |
2433 wc.lpfnWndProc = (WNDPROC)_framewndproc; | |
2434 wc.cbClsExtra = 0; | |
2435 wc.cbWndExtra = 32; | |
2436 wc.hbrBackground = (HBRUSH)COLOR_WINDOW; | |
2437 wc.hCursor = LoadCursor(NULL, IDC_ARROW); | |
2438 wc.lpszMenuName = NULL; | |
2439 wc.lpszClassName = FRAMECLASSNAME; | |
2440 | |
2441 RegisterClass(&wc); | |
2442 | |
2443 /* Create a set of brushes using the default OS/2 and DOS colors */ | |
2444 for(z=0;z<18;z++) | |
2445 _colors[z] = CreateSolidBrush(RGB(_red[z],_green[z],_blue[z])); | |
2446 | |
2447 /* Register an Object Windows class like OS/2 and Win2k+ | |
2448 * so similar functionality can be used on earlier releases | |
2449 * of Windows. | |
2450 */ | |
2451 memset(&wc, 0, sizeof(WNDCLASS)); | |
2452 wc.style = 0; | |
2453 wc.lpfnWndProc = (WNDPROC)_wndproc; | |
2454 wc.cbClsExtra = 0; | |
2455 wc.cbWndExtra = 0; | |
2456 wc.hbrBackground = NULL; | |
2457 wc.hCursor = LoadCursor(NULL, IDC_ARROW); | |
2458 wc.lpszMenuName = NULL; | |
2459 wc.lpszClassName = ObjectClassName; | |
2460 | |
2461 RegisterClass(&wc); | |
2462 | |
2463 /* Since Windows 95/98/NT don't have a HWND_OBJECT class | |
2464 * also known as a input only window, I will create a | |
2465 * temporary window that isn't visible and really does nothing | |
2466 * except temporarily hold the child windows before they are | |
2467 * packed into their correct parent. | |
2468 */ | |
2469 | |
2470 DW_HWND_OBJECT = CreateWindow(ObjectClassName, "", 0, 0, 0, | |
2471 0, 0, HWND_DESKTOP, NULL, NULL, NULL); | |
2472 | |
2473 if(!DW_HWND_OBJECT) | |
2474 { | |
2475 dw_messagebox("Dynamic Windows", "Could not initialize the object window. error code %d", GetLastError()); | |
2476 exit(1); | |
2477 } | |
2478 | 2547 |
2479 #ifdef DWDEBUG | 2548 #ifdef DWDEBUG |
2480 f = fopen("dw.log", "wt"); | 2549 f = fopen("dw.log", "w"); |
2481 #endif | 2550 #endif |
2482 /* We need the version to check capability like up-down controls */ | 2551 return rc; |
2483 dwVersion = GetVersion(); | |
2484 | |
2485 for(z=0;z<THREAD_LIMIT;z++) | |
2486 { | |
2487 _foreground[z] = RGB(128,128,128); | |
2488 _background[z] = 0; | |
2489 _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]); | |
2490 _hBrush[z] = CreateSolidBrush(_foreground[z]); | |
2491 } | |
2492 | |
2493 #if 0 | |
2494 { | |
2495 DWORD dwResult = GetSysColor(COLOR_3DFACE); | |
2496 | |
2497 dw_messagebox("DW", | |
2498 "Window color: {%x, %x, %x}", | |
2499 GetRValue(dwResult), | |
2500 GetGValue(dwResult), | |
2501 GetBValue(dwResult)); | |
2502 } | |
2503 #endif | |
2504 return 0; | |
2505 } | 2552 } |
2506 | 2553 |
2507 /* | 2554 /* |
2508 * Runs a message loop for Dynamic Windows. | 2555 * Runs a message loop for Dynamic Windows. |
2509 * Parameters: | 2556 * Parameters: |
2511 * or NULL if this DW is handling the message loop. | 2558 * or NULL if this DW is handling the message loop. |
2512 * func: Function pointer to the message filter function. | 2559 * func: Function pointer to the message filter function. |
2513 */ | 2560 */ |
2514 void dw_main(HAB currenthab, void *func) | 2561 void dw_main(HAB currenthab, void *func) |
2515 { | 2562 { |
2516 MSG msg; | 2563 QMSG qmsg; |
2564 HAB habtouse; | |
2565 | |
2566 if(!currenthab) | |
2567 habtouse = dwhab; | |
2568 else | |
2569 habtouse = currenthab; | |
2517 | 2570 |
2518 /* Setup the filter function */ | 2571 /* Setup the filter function */ |
2519 filterfunc = func; | 2572 filterfunc = (int (* EXPENTRY)(HWND, ULONG, MPARAM, MPARAM))func; |
2520 | 2573 |
2521 while (GetMessage(&msg, NULL, 0, 0)) | 2574 _dwtid = dw_thread_id(); |
2522 { | 2575 |
2523 TranslateMessage(&msg); | 2576 while (WinGetMsg(habtouse, &qmsg, 0, 0, 0)) |
2524 DispatchMessage(&msg); | 2577 WinDispatchMsg(habtouse, &qmsg); |
2525 } | |
2526 | 2578 |
2527 #ifdef DWDEBUG | 2579 #ifdef DWDEBUG |
2528 fclose(f); | 2580 fclose(f); |
2529 #endif | 2581 #endif |
2582 | |
2583 if(!currenthab) | |
2584 { | |
2585 WinDestroyMsgQueue(dwhmq); | |
2586 WinTerminate(dwhab); | |
2587 } | |
2530 } | 2588 } |
2531 | 2589 |
2532 /* | 2590 /* |
2533 * Runs a message loop for Dynamic Windows, for a period of seconds. | 2591 * Runs a message loop for Dynamic Windows, for a period of seconds. |
2534 * Parameters: | 2592 * Parameters: |
2535 * seconds: Number of seconds to run the loop for. | 2593 * seconds: Number of seconds to run the loop for. |
2536 */ | 2594 */ |
2537 void dw_main_sleep(int seconds) | 2595 void dw_main_sleep(int seconds) |
2538 { | 2596 { |
2539 MSG msg; | 2597 QMSG qmsg; |
2540 time_t start = time(NULL); | 2598 time_t start = time(NULL); |
2541 | 2599 |
2542 while(time(NULL) - start <= seconds) | 2600 while(time(NULL) - start <= seconds) |
2543 { | 2601 { |
2544 if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) | 2602 if(WinPeekMsg(dwhab, &qmsg, 0, 0, 0, PM_NOREMOVE)) |
2545 { | 2603 { |
2546 GetMessage(&msg, NULL, 0, 0); | 2604 WinGetMsg(dwhab, &qmsg, 0, 0, 0); |
2547 TranslateMessage(&msg); | 2605 WinDispatchMsg(dwhab, &qmsg); |
2548 DispatchMessage(&msg); | |
2549 } | 2606 } |
2550 else | 2607 else |
2551 Sleep(1); | 2608 DosSleep(1); |
2552 } | 2609 } |
2553 } | 2610 } |
2554 | 2611 |
2555 /* | 2612 /* |
2556 * Free's memory allocated by dynamic windows. | 2613 * Free's memory allocated by dynamic windows. |
2602 * Parameters: | 2659 * Parameters: |
2603 * dialog: Pointer to a dialog struct aquired by dw_dialog_new). | 2660 * dialog: Pointer to a dialog struct aquired by dw_dialog_new). |
2604 */ | 2661 */ |
2605 void *dw_dialog_wait(DWDialog *dialog) | 2662 void *dw_dialog_wait(DWDialog *dialog) |
2606 { | 2663 { |
2607 MSG msg; | 2664 QMSG qmsg; |
2608 void *tmp; | 2665 void *tmp; |
2609 | 2666 |
2610 while (GetMessage(&msg,NULL,0,0)) | 2667 while (WinGetMsg(dwhab, &qmsg, 0, 0, 0)) |
2611 { | 2668 { |
2612 TranslateMessage(&msg); | 2669 WinDispatchMsg(dwhab, &qmsg); |
2613 DispatchMessage(&msg); | |
2614 if(dialog->done) | 2670 if(dialog->done) |
2615 break; | 2671 break; |
2616 } | 2672 } |
2617 dw_event_close(&dialog->eve); | 2673 dw_event_close(&dialog->eve); |
2618 tmp = dialog->result; | 2674 tmp = dialog->result; |
2619 free(dialog); | 2675 free(dialog); |
2620 return tmp; | 2676 return tmp; |
2621 } | 2677 } |
2622 | 2678 |
2679 | |
2623 /* | 2680 /* |
2624 * Displays a Message Box with given text and title.. | 2681 * Displays a Message Box with given text and title.. |
2625 * Parameters: | 2682 * Parameters: |
2626 * title: The title of the message box. | 2683 * title: The title of the message box. |
2627 * format: printf style format string. | 2684 * format: printf style format string. |
2628 * ...: Additional variables for use in the format. | 2685 * ...: Additional variables for use in the format. |
2629 */ | 2686 */ |
2630 int dw_messagebox(char *title, char *format, ...) | 2687 int dw_messagebox(char *title, char *format, ...) |
2631 { | 2688 { |
2632 va_list args; | 2689 va_list args; |
2633 char outbuf[256]; | 2690 char outbuf[1024]; |
2634 | 2691 |
2635 va_start(args, format); | 2692 va_start(args, format); |
2636 vsprintf(outbuf, format, args); | 2693 vsprintf(outbuf, format, args); |
2637 va_end(args); | 2694 va_end(args); |
2638 | 2695 |
2639 MessageBox(HWND_DESKTOP, outbuf, title, MB_OK); | 2696 WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, outbuf, title, 0, MB_OK | MB_INFORMATION | MB_MOVEABLE); |
2640 | 2697 |
2641 return strlen(outbuf); | 2698 return strlen(outbuf); |
2642 } | 2699 } |
2643 | 2700 |
2644 /* | 2701 /* |
2649 * Returns: | 2706 * Returns: |
2650 * True if YES False of NO. | 2707 * True if YES False of NO. |
2651 */ | 2708 */ |
2652 int dw_yesno(char *title, char *text) | 2709 int dw_yesno(char *title, char *text) |
2653 { | 2710 { |
2654 if(MessageBox(HWND_DESKTOP, text, title, MB_YESNO) == IDYES) | 2711 if(WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text, title, 0, MB_YESNO | MB_INFORMATION | MB_MOVEABLE | MB_SYSTEMMODAL)==MBID_YES) |
2655 return TRUE; | 2712 return TRUE; |
2656 return FALSE; | 2713 return FALSE; |
2657 } | 2714 } |
2658 | 2715 |
2659 /* | 2716 /* |
2717 * Makes the window topmost. | |
2718 * Parameters: | |
2719 * handle: The window handle to make topmost. | |
2720 */ | |
2721 int dw_window_raise(HWND handle) | |
2722 { | |
2723 return WinSetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER); | |
2724 } | |
2725 | |
2726 /* | |
2727 * Makes the window bottommost. | |
2728 * Parameters: | |
2729 * handle: The window handle to make bottommost. | |
2730 */ | |
2731 int dw_window_lower(HWND handle) | |
2732 { | |
2733 return WinSetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER); | |
2734 } | |
2735 | |
2736 /* | |
2737 * Makes the window visible. | |
2738 * Parameters: | |
2739 * handle: The window handle to make visible. | |
2740 */ | |
2741 int dw_window_show(HWND handle) | |
2742 { | |
2743 int rc = WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_SHOW); | |
2744 HSWITCH hswitch; | |
2745 SWCNTRL swcntrl; | |
2746 | |
2747 _fix_button_owner(handle, 0); | |
2748 WinSetFocus(HWND_DESKTOP, handle); | |
2749 _initial_focus(handle); | |
2750 | |
2751 /* If this window has a switch list entry make sure it is visible */ | |
2752 hswitch = WinQuerySwitchHandle(handle, 0); | |
2753 if(hswitch) | |
2754 { | |
2755 WinQuerySwitchEntry(hswitch, &swcntrl); | |
2756 swcntrl.uchVisibility = SWL_VISIBLE; | |
2757 WinChangeSwitchEntry(hswitch, &swcntrl); | |
2758 } | |
2759 return rc; | |
2760 | |
2761 } | |
2762 | |
2763 /* | |
2660 * Minimizes or Iconifies a top-level window. | 2764 * Minimizes or Iconifies a top-level window. |
2661 * Parameters: | 2765 * Parameters: |
2662 * handle: The window handle to minimize. | 2766 * handle: The window handle to minimize. |
2663 */ | 2767 */ |
2664 int dw_window_minimize(HWND handle) | 2768 int dw_window_minimize(HWND handle) |
2665 { | 2769 { |
2666 return ShowWindow(handle, SW_MINIMIZE); | 2770 HWND hwndclient = WinWindowFromID(handle, FID_CLIENT); |
2667 } | 2771 |
2668 | 2772 if(hwndclient) |
2669 /* | 2773 { |
2670 * Makes the window topmost. | 2774 Box *box = (Box *)WinQueryWindowPtr(hwndclient, QWP_USER); |
2671 * Parameters: | 2775 |
2672 * handle: The window handle to make topmost. | 2776 if(box) |
2673 */ | 2777 { |
2674 int dw_window_raise(HWND handle) | 2778 if(!box->titlebar && box->hwndtitle) |
2675 { | 2779 WinSetParent(box->hwndtitle, handle, FALSE); |
2676 return SetWindowPos(handle, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | 2780 } |
2677 } | 2781 } |
2678 | 2782 |
2679 /* | 2783 return WinSetWindowPos(handle, NULLHANDLE, 0, 0, 0, 0, SWP_MINIMIZE); |
2680 * Makes the window bottommost. | 2784 } |
2681 * Parameters: | 2785 |
2682 * handle: The window handle to make bottommost. | 2786 /* |
2683 */ | 2787 * Makes the window invisible. |
2684 int dw_window_lower(HWND handle) | |
2685 { | |
2686 return SetWindowPos(handle, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | |
2687 } | |
2688 | |
2689 /* | |
2690 * Makes the window visible. | |
2691 * Parameters: | 2788 * Parameters: |
2692 * handle: The window handle to make visible. | 2789 * handle: The window handle to make visible. |
2693 */ | 2790 */ |
2694 int dw_window_show(HWND handle) | |
2695 { | |
2696 int rc = ShowWindow(handle, SW_SHOW); | |
2697 SetFocus(handle); | |
2698 _initial_focus(handle); | |
2699 return rc; | |
2700 } | |
2701 | |
2702 /* | |
2703 * Makes the window invisible. | |
2704 * Parameters: | |
2705 * handle: The window handle to make visible. | |
2706 */ | |
2707 int dw_window_hide(HWND handle) | 2791 int dw_window_hide(HWND handle) |
2708 { | 2792 { |
2709 return ShowWindow(handle, SW_HIDE); | 2793 HSWITCH hswitch; |
2794 SWCNTRL swcntrl; | |
2795 | |
2796 /* If this window has a switch list entry make sure it is invisible */ | |
2797 hswitch = WinQuerySwitchHandle(handle, 0); | |
2798 if(hswitch) | |
2799 { | |
2800 WinQuerySwitchEntry(hswitch, &swcntrl); | |
2801 swcntrl.uchVisibility = SWL_INVISIBLE; | |
2802 WinChangeSwitchEntry(hswitch, &swcntrl); | |
2803 } | |
2804 return WinShowWindow(handle, FALSE); | |
2710 } | 2805 } |
2711 | 2806 |
2712 /* | 2807 /* |
2713 * Destroys a window and all of it's children. | 2808 * Destroys a window and all of it's children. |
2714 * Parameters: | 2809 * Parameters: |
2715 * handle: The window handle to destroy. | 2810 * handle: The window handle to destroy. |
2716 */ | 2811 */ |
2717 int dw_window_destroy(HWND handle) | 2812 int dw_window_destroy(HWND handle) |
2718 { | 2813 { |
2719 HWND parent = GetParent(handle); | 2814 HWND parent = WinQueryWindow(handle, QW_PARENT); |
2720 Box *thisbox = (Box *)GetWindowLong(parent, GWL_USERDATA); | 2815 Box *thisbox = WinQueryWindowPtr(parent, QWP_USER); |
2816 | |
2817 if(!handle) | |
2818 return -1; | |
2721 | 2819 |
2722 if(parent != HWND_DESKTOP && thisbox && thisbox->count) | 2820 if(parent != HWND_DESKTOP && thisbox && thisbox->count) |
2723 { | 2821 { |
2724 int z, index = -1; | 2822 int z, index = -1; |
2725 Item *tmpitem, *thisitem = thisbox->items; | 2823 Item *tmpitem, *thisitem = thisbox->items; |
2747 | 2845 |
2748 thisbox->items = tmpitem; | 2846 thisbox->items = tmpitem; |
2749 free(thisitem); | 2847 free(thisitem); |
2750 thisbox->count--; | 2848 thisbox->count--; |
2751 } | 2849 } |
2752 return DestroyWindow(handle); | 2850 _disconnect_windows(handle); |
2851 return WinDestroyWindow(handle); | |
2753 } | 2852 } |
2754 | 2853 |
2755 /* Causes entire window to be invalidated and redrawn. | 2854 /* Causes entire window to be invalidated and redrawn. |
2756 * Parameters: | 2855 * Parameters: |
2757 * handle: Toplevel window handle to be redrawn. | 2856 * handle: Toplevel window handle to be redrawn. |
2758 */ | 2857 */ |
2759 void dw_window_redraw(HWND handle) | 2858 void dw_window_redraw(HWND handle) |
2760 { | 2859 { |
2761 Box *mybox = (Box *)GetWindowLong(handle, GWL_USERDATA); | 2860 HWND window = WinWindowFromID(handle, FID_CLIENT); |
2762 | 2861 Box *mybox = (Box *)WinQueryWindowPtr(window, QWP_USER); |
2763 if(mybox) | 2862 |
2764 { | 2863 if(window && mybox) |
2765 RECT rect; | 2864 { |
2766 | 2865 unsigned long width, height; |
2767 GetClientRect(handle, &rect); | 2866 |
2768 | 2867 dw_window_get_pos_size(window, NULL, NULL, &width, &height); |
2769 ShowWindow(mybox->items[0].hwnd, SW_HIDE); | 2868 |
2770 _do_resize(mybox, rect.right - rect.left, rect.bottom - rect.top); | 2869 WinShowWindow(mybox->items[0].hwnd, FALSE); |
2771 ShowWindow(mybox->items[0].hwnd, SW_SHOW); | 2870 _do_resize(mybox, width, height); |
2871 WinShowWindow(mybox->items[0].hwnd, TRUE); | |
2772 } | 2872 } |
2773 } | 2873 } |
2774 | 2874 |
2775 /* | 2875 /* |
2776 * Changes a window's parent to newparent. | 2876 * Changes a window's parent to newparent. |
2778 * handle: The window handle to destroy. | 2878 * handle: The window handle to destroy. |
2779 * newparent: The window's new parent window. | 2879 * newparent: The window's new parent window. |
2780 */ | 2880 */ |
2781 void dw_window_reparent(HWND handle, HWND newparent) | 2881 void dw_window_reparent(HWND handle, HWND newparent) |
2782 { | 2882 { |
2783 SetParent(handle, newparent); | 2883 HWND blah = WinWindowFromID(newparent, FID_CLIENT); |
2784 } | 2884 WinSetParent(handle, blah ? blah : newparent, TRUE); |
2785 | |
2786 HFONT _aquire_font(char *fontname) | |
2787 { | |
2788 HFONT hfont; | |
2789 int z, size = 9; | |
2790 LOGFONT lf; | |
2791 | |
2792 if(fontname == DefaultFont) | |
2793 hfont = GetStockObject(DEFAULT_GUI_FONT); | |
2794 else | |
2795 { | |
2796 for(z=0;z<strlen(fontname);z++) | |
2797 { | |
2798 if(fontname[z]=='.') | |
2799 break; | |
2800 } | |
2801 size = atoi(fontname) + 5; | |
2802 | |
2803 lf.lfHeight = size; | |
2804 lf.lfWidth = 0; | |
2805 lf.lfEscapement = 0; | |
2806 lf.lfOrientation = 0; | |
2807 lf.lfItalic = 0; | |
2808 lf.lfUnderline = 0; | |
2809 lf.lfStrikeOut = 0; | |
2810 lf.lfWeight = FW_NORMAL; | |
2811 lf.lfCharSet = DEFAULT_CHARSET; | |
2812 lf.lfOutPrecision = 0; | |
2813 lf.lfClipPrecision = 0; | |
2814 lf.lfQuality = DEFAULT_QUALITY; | |
2815 lf.lfPitchAndFamily = DEFAULT_PITCH | FW_DONTCARE; | |
2816 strcpy(lf.lfFaceName, &fontname[z+1]); | |
2817 | |
2818 hfont = CreateFontIndirect(&lf); | |
2819 } | |
2820 return hfont; | |
2821 } | 2885 } |
2822 | 2886 |
2823 /* | 2887 /* |
2824 * Sets the font used by a specified window (widget) handle. | 2888 * Sets the font used by a specified window (widget) handle. |
2825 * Parameters: | 2889 * Parameters: |
2826 * handle: The window (widget) handle. | 2890 * handle: The window (widget) handle. |
2827 * fontname: Name and size of the font in the form "size.fontname" | 2891 * fontname: Name and size of the font in the form "size.fontname" |
2828 */ | 2892 */ |
2829 int dw_window_set_font(HWND handle, char *fontname) | 2893 int dw_window_set_font(HWND handle, char *fontname) |
2830 { | 2894 { |
2831 HFONT hfont = _aquire_font(fontname); | 2895 return WinSetPresParam(handle, PP_FONTNAMESIZE, strlen(fontname)+1, fontname); |
2832 ColorInfo *cinfo; | |
2833 | |
2834 cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | |
2835 | |
2836 if(fontname) | |
2837 { | |
2838 if(cinfo) | |
2839 { | |
2840 strcpy(cinfo->fontname, fontname); | |
2841 } | |
2842 else | |
2843 { | |
2844 cinfo = calloc(1, sizeof(ColorInfo)); | |
2845 cinfo->fore = cinfo->back = -1; | |
2846 cinfo->buddy = 0; | |
2847 | |
2848 strcpy(cinfo->fontname, fontname); | |
2849 | |
2850 cinfo->pOldProc = SubclassWindow(handle, _colorwndproc); | |
2851 SetWindowLong(handle, GWL_USERDATA, (ULONG)cinfo); | |
2852 } | |
2853 } | |
2854 SendMessage(handle, WM_SETFONT, (WPARAM)hfont, FALSE); | |
2855 return 0; | |
2856 } | 2896 } |
2857 | 2897 |
2858 /* | 2898 /* |
2859 * Sets the colors used by a specified window (widget) handle. | 2899 * Sets the colors used by a specified window (widget) handle. |
2860 * Parameters: | 2900 * Parameters: |
2861 * handle: The window (widget) handle. | 2901 * handle: The window (widget) handle. |
2862 * fore: Foreground color in RGB format. | 2902 * fore: Foreground color in DW_RGB format or a default color index. |
2863 * back: Background color in RGB format. | 2903 * back: Background color in DW_RGB format or a default color index. |
2864 */ | 2904 */ |
2865 int dw_window_set_color(HWND handle, ULONG fore, ULONG back) | 2905 int dw_window_set_color(HWND handle, ULONG fore, ULONG back) |
2866 { | 2906 { |
2867 ColorInfo *cinfo; | 2907 if((fore & DW_RGB_COLOR) == DW_RGB_COLOR) |
2868 char tmpbuf[100]; | 2908 { |
2869 | 2909 RGB2 rgb2; |
2870 cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | 2910 |
2871 | 2911 rgb2.bBlue = DW_BLUE_VALUE(fore); |
2872 GetClassName(handle, tmpbuf, 99); | 2912 rgb2.bGreen = DW_GREEN_VALUE(fore); |
2873 | 2913 rgb2.bRed = DW_RED_VALUE(fore); |
2874 if(strnicmp(tmpbuf, WC_LISTVIEW, strlen(WC_LISTVIEW))==0) | 2914 rgb2.fcOptions = 0; |
2875 { | 2915 |
2876 ListView_SetTextColor(handle, RGB(DW_RED_VALUE(fore), | 2916 WinSetPresParam(handle, PP_FOREGROUNDCOLOR, sizeof(RGB2), &rgb2); |
2877 DW_GREEN_VALUE(fore), | 2917 |
2878 DW_BLUE_VALUE(fore))); | 2918 } |
2879 ListView_SetTextBkColor(handle, RGB(DW_RED_VALUE(back), | 2919 if((back & DW_RGB_COLOR) == DW_RGB_COLOR) |
2880 DW_GREEN_VALUE(back), | 2920 { |
2881 DW_BLUE_VALUE(back))); | 2921 RGB2 rgb2; |
2882 ListView_SetBkColor(handle, RGB(DW_RED_VALUE(back), | 2922 |
2883 DW_GREEN_VALUE(back), | 2923 rgb2.bBlue = DW_BLUE_VALUE(back); |
2884 DW_BLUE_VALUE(back))); | 2924 rgb2.bGreen = DW_GREEN_VALUE(back); |
2885 InvalidateRgn(handle, NULL, TRUE); | 2925 rgb2.bRed = DW_RED_VALUE(back); |
2886 return TRUE; | 2926 rgb2.fcOptions = 0; |
2887 } | 2927 |
2888 | 2928 WinSetPresParam(handle, PP_BACKGROUNDCOLOR, sizeof(RGB2), &rgb2); |
2889 if(cinfo) | 2929 return 0; |
2890 { | 2930 } |
2891 cinfo->fore = fore; | 2931 if((fore & DW_RGB_COLOR) == DW_RGB_COLOR) |
2892 cinfo->back = back; | 2932 return 0; |
2893 } | 2933 |
2894 else | 2934 /* Slight conversion */ |
2895 { | 2935 if(fore == DW_CLR_BLACK) |
2896 cinfo = calloc(1, sizeof(ColorInfo)); | 2936 fore = CLR_BLACK; |
2897 | 2937 if(fore == DW_CLR_WHITE) |
2898 cinfo->fore = fore; | 2938 fore = CLR_WHITE; |
2899 cinfo->back = back; | 2939 |
2900 cinfo->buddy = 0; | 2940 if(back == DW_CLR_BLACK) |
2901 | 2941 back = CLR_BLACK; |
2902 cinfo->pOldProc = SubclassWindow(handle, _colorwndproc); | 2942 if(back == DW_CLR_WHITE) |
2903 SetWindowLong(handle, GWL_USERDATA, (ULONG)cinfo); | 2943 back = CLR_WHITE; |
2904 } | 2944 |
2905 InvalidateRgn(handle, NULL, TRUE); | 2945 return (WinSetPresParam(handle, PP_FOREGROUNDCOLORINDEX, sizeof(ULONG), &fore) | |
2906 return TRUE; | 2946 WinSetPresParam(handle, PP_BACKGROUNDCOLORINDEX, sizeof(ULONG), &back)); |
2907 } | 2947 } |
2908 | 2948 |
2909 /* | 2949 /* |
2910 * Sets the font used by a specified window (widget) handle. | 2950 * Sets the font used by a specified window (widget) handle. |
2911 * Parameters: | 2951 * Parameters: |
2912 * handle: The window (widget) handle. | 2952 * handle: The window (widget) handle. |
2913 * border: Size of the window border in pixels. | 2953 * border: Size of the window border in pixels. |
2914 */ | 2954 */ |
2915 int dw_window_set_border(HWND handle, int border) | 2955 int dw_window_set_border(HWND handle, int border) |
2916 { | 2956 { |
2957 WinSendMsg(handle, WM_SETBORDERSIZE, MPFROMSHORT(border), MPFROMSHORT(border)); | |
2917 return 0; | 2958 return 0; |
2918 } | 2959 } |
2919 | 2960 |
2920 /* | 2961 /* |
2921 * Captures the mouse input to this window. | 2962 * Captures the mouse input to this window. |
2922 * Parameters: | 2963 * Parameters: |
2923 * handle: Handle to receive mouse input. | 2964 * handle: Handle to receive mouse input. |
2924 */ | 2965 */ |
2925 void dw_window_capture(HWND handle) | 2966 void dw_window_capture(HWND handle) |
2926 { | 2967 { |
2927 SetCapture(handle); | 2968 WinSetCapture(HWND_DESKTOP, handle); |
2928 } | 2969 } |
2929 | 2970 |
2930 /* | 2971 /* |
2931 * Releases previous mouse capture. | 2972 * Releases previous mouse capture. |
2932 */ | 2973 */ |
2933 void dw_window_release(void) | 2974 void dw_window_release(void) |
2934 { | 2975 { |
2935 ReleaseCapture(); | 2976 WinSetCapture(HWND_DESKTOP, NULLHANDLE); |
2977 } | |
2978 | |
2979 /* | |
2980 * Tracks this window movement. | |
2981 * Parameters: | |
2982 * handle: Handle to frame to be tracked. | |
2983 */ | |
2984 void dw_window_track(HWND handle) | |
2985 { | |
2986 WinSendMsg(handle, WM_TRACKFRAME, MPFROMSHORT(TF_MOVE), 0); | |
2936 } | 2987 } |
2937 | 2988 |
2938 /* | 2989 /* |
2939 * Changes the appearance of the mouse pointer. | 2990 * Changes the appearance of the mouse pointer. |
2940 * Parameters: | 2991 * Parameters: |
2941 * handle: Handle to widget for which to change. | 2992 * handle: Handle to widget for which to change. |
2942 * cursortype: ID of the pointer you want. | 2993 * cursortype: ID of the pointer you want. |
2943 */ | 2994 */ |
2944 void dw_window_pointer(HWND handle, int pointertype) | 2995 void dw_window_pointer(HWND handle, int pointertype) |
2945 { | 2996 { |
2946 SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(pointertype))); | 2997 WinSetPointer(handle, |
2998 WinQuerySysPointer(HWND_DESKTOP, | |
2999 pointertype, | |
3000 FALSE)); | |
2947 } | 3001 } |
2948 | 3002 |
2949 /* | 3003 /* |
2950 * Create a new Window Frame. | 3004 * Create a new Window Frame. |
2951 * Parameters: | 3005 * Parameters: |
2952 * owner: The Owner's window handle or HWND_DESKTOP. | 3006 * owner: The Owner's window handle or HWND_DESKTOP. |
2953 * title: The Window title. | 3007 * title: The Window title. |
2954 * flStyle: Style flags, see the DW reference. | 3008 * flStyle: Style flags, see the PM reference. |
2955 */ | 3009 */ |
2956 HWND dw_window_new(HWND hwndOwner, char *title, ULONG flStyle) | 3010 HWND dw_window_new(HWND hwndOwner, char *title, ULONG flStyle) |
2957 { | 3011 { |
2958 HWND hwndframe; | 3012 HWND hwndclient = 0, hwndframe; |
2959 Box *newbox = malloc(sizeof(Box)); | 3013 Box *newbox = calloc(1, sizeof(Box)); |
2960 ULONG flStyleEx = 0; | 3014 PFNWP *blah = malloc(sizeof(PFNWP)); |
2961 | 3015 |
2962 newbox->pad = 0; | 3016 newbox->pad = 0; |
2963 newbox->type = BOXVERT; | 3017 newbox->type = BOXVERT; |
2964 newbox->count = 0; | 3018 newbox->count = 0; |
2965 | 3019 |
2966 if(hwndOwner) | 3020 flStyle |= FCF_NOBYTEALIGN; |
2967 flStyleEx |= WS_EX_MDICHILD; | 3021 |
2968 | 3022 if(flStyle & DW_FCF_TITLEBAR) |
2969 if(!(flStyle & WS_CAPTION)) | 3023 newbox->titlebar = 1; |
2970 flStyle |= WS_POPUPWINDOW; | |
2971 | |
2972 if(flStyle & DW_FCF_TASKLIST) | |
2973 { | |
2974 ULONG newflags = (flStyle | WS_CLIPCHILDREN) & ~DW_FCF_TASKLIST; | |
2975 | |
2976 hwndframe = CreateWindowEx(flStyleEx, ClassName, title, newflags, CW_USEDEFAULT, CW_USEDEFAULT, | |
2977 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, NULL, NULL); | |
2978 } | |
2979 else | 3024 else |
2980 { | 3025 flStyle |= FCF_TITLEBAR; |
2981 flStyleEx |= WS_EX_TOOLWINDOW; | 3026 |
2982 | 3027 hwndframe = WinCreateStdWindow(hwndOwner, 0L, &flStyle, ClassName, title, 0L, NULLHANDLE, 0L, &hwndclient); |
2983 hwndframe = CreateWindowEx(flStyleEx, ClassName, title, flStyle | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, | 3028 newbox->hwndtitle = WinWindowFromID(hwndframe, FID_TITLEBAR); |
2984 CW_USEDEFAULT, CW_USEDEFAULT, hwndOwner, NULL, NULL, NULL); | 3029 if(!newbox->titlebar && newbox->hwndtitle) |
2985 } | 3030 WinSetParent(newbox->hwndtitle, HWND_OBJECT, FALSE); |
2986 SetWindowLong(hwndframe, GWL_USERDATA, (ULONG)newbox); | 3031 *blah = WinSubclassWindow(hwndframe, _sizeproc); |
2987 | 3032 WinSetWindowPtr(hwndframe, QWP_USER, blah); |
2988 #if 0 | 3033 WinSetWindowPtr(hwndclient, QWP_USER, newbox); |
2989 if(hwndOwner) | |
2990 SetParent(hwndframe, hwndOwner); | |
2991 #endif | |
2992 | 3034 |
2993 return hwndframe; | 3035 return hwndframe; |
2994 } | 3036 } |
2995 | 3037 |
2996 /* | 3038 /* |
2999 * type: Either BOXVERT (vertical) or BOXHORZ (horizontal). | 3041 * type: Either BOXVERT (vertical) or BOXHORZ (horizontal). |
3000 * pad: Number of pixels to pad around the box. | 3042 * pad: Number of pixels to pad around the box. |
3001 */ | 3043 */ |
3002 HWND dw_box_new(int type, int pad) | 3044 HWND dw_box_new(int type, int pad) |
3003 { | 3045 { |
3004 Box *newbox = malloc(sizeof(Box)); | 3046 Box *newbox = calloc(1, sizeof(Box)); |
3005 HWND hwndframe; | 3047 HWND hwndframe; |
3006 | 3048 |
3007 newbox->pad = pad; | 3049 newbox->pad = pad; |
3008 newbox->type = type; | 3050 newbox->type = type; |
3009 newbox->count = 0; | 3051 newbox->count = 0; |
3010 newbox->grouphwnd = (HWND)NULL; | 3052 newbox->grouphwnd = NULLHANDLE; |
3011 | 3053 |
3012 hwndframe = CreateWindow(FRAMECLASSNAME, | 3054 hwndframe = WinCreateWindow(HWND_OBJECT, |
3013 "", | 3055 WC_FRAME, |
3014 WS_CHILD | WS_CLIPCHILDREN, | 3056 NULL, |
3015 0,0,2000,1000, | 3057 WS_VISIBLE | WS_CLIPCHILDREN | |
3016 DW_HWND_OBJECT, | 3058 FS_NOBYTEALIGN, |
3017 NULL, | 3059 0,0,2000,1000, |
3018 NULL, | 3060 NULLHANDLE, |
3019 NULL); | 3061 HWND_TOP, |
3020 | 3062 0L, |
3021 newbox->cinfo.pOldProc = SubclassWindow(hwndframe, _colorwndproc); | 3063 NULL, |
3022 newbox->cinfo.fore = newbox->cinfo.back = -1; | 3064 NULL); |
3023 | 3065 |
3024 SetWindowLong(hwndframe, GWL_USERDATA, (ULONG)newbox); | 3066 newbox->oldproc = WinSubclassWindow(hwndframe, _controlproc); |
3067 WinSetWindowPtr(hwndframe, QWP_USER, newbox); | |
3068 dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); | |
3025 return hwndframe; | 3069 return hwndframe; |
3026 } | 3070 } |
3027 | 3071 |
3028 /* | 3072 /* |
3029 * Create a new Group Box to be packed. | 3073 * Create a new Group Box to be packed. |
3032 * pad: Number of pixels to pad around the box. | 3076 * pad: Number of pixels to pad around the box. |
3033 * title: Text to be displayined in the group outline. | 3077 * title: Text to be displayined in the group outline. |
3034 */ | 3078 */ |
3035 HWND dw_groupbox_new(int type, int pad, char *title) | 3079 HWND dw_groupbox_new(int type, int pad, char *title) |
3036 { | 3080 { |
3037 Box *newbox = malloc(sizeof(Box)); | 3081 Box *newbox = calloc(1, sizeof(Box)); |
3038 HWND hwndframe; | 3082 HWND hwndframe; |
3039 | 3083 |
3040 newbox->pad = pad; | 3084 newbox->pad = pad; |
3041 newbox->type = type; | 3085 newbox->type = type; |
3042 newbox->count = 0; | 3086 newbox->count = 0; |
3043 | 3087 |
3044 hwndframe = CreateWindow(FRAMECLASSNAME, | 3088 hwndframe = WinCreateWindow(HWND_OBJECT, |
3045 "", | 3089 WC_FRAME, |
3046 WS_CHILD, | 3090 NULL, |
3047 0,0,2000,1000, | 3091 WS_VISIBLE | |
3048 DW_HWND_OBJECT, | 3092 FS_NOBYTEALIGN, |
3049 NULL, | 3093 0,0,2000,1000, |
3050 NULL, | 3094 NULLHANDLE, |
3051 NULL); | 3095 HWND_TOP, |
3052 | 3096 0L, |
3053 newbox->grouphwnd = CreateWindow(BUTTONCLASSNAME, | 3097 NULL, |
3054 title, | 3098 NULL); |
3055 WS_CHILD | BS_GROUPBOX | | 3099 |
3056 WS_VISIBLE | WS_CLIPCHILDREN, | 3100 newbox->grouphwnd = WinCreateWindow(hwndframe, |
3057 0,0,2000,1000, | 3101 WC_STATIC, |
3058 hwndframe, | 3102 title, |
3059 NULL, | 3103 WS_VISIBLE | SS_GROUPBOX | |
3060 NULL, | 3104 WS_GROUP, |
3061 NULL); | 3105 0,0,2000,1000, |
3062 | 3106 NULLHANDLE, |
3063 SetWindowLong(hwndframe, GWL_USERDATA, (ULONG)newbox); | 3107 HWND_TOP, |
3108 0L, | |
3109 NULL, | |
3110 NULL); | |
3111 | |
3112 WinSetWindowPtr(hwndframe, QWP_USER, newbox); | |
3113 dw_window_set_color(hwndframe, DW_CLR_PALEGRAY, DW_CLR_PALEGRAY); | |
3114 dw_window_set_color(newbox->grouphwnd, DW_CLR_BLACK, DW_CLR_PALEGRAY); | |
3064 dw_window_set_font(newbox->grouphwnd, DefaultFont); | 3115 dw_window_set_font(newbox->grouphwnd, DefaultFont); |
3065 return hwndframe; | 3116 return hwndframe; |
3066 } | 3117 } |
3067 | 3118 |
3068 /* | 3119 /* |
3070 * Parameters: | 3121 * Parameters: |
3071 * id: An ID to be used with dw_window_from_id or 0L. | 3122 * id: An ID to be used with dw_window_from_id or 0L. |
3072 */ | 3123 */ |
3073 HWND dw_mdi_new(unsigned long id) | 3124 HWND dw_mdi_new(unsigned long id) |
3074 { | 3125 { |
3075 CLIENTCREATESTRUCT ccs; | |
3076 HWND hwndframe; | 3126 HWND hwndframe; |
3077 | 3127 |
3078 ccs.hWindowMenu = NULL; | 3128 hwndframe = WinCreateWindow(HWND_OBJECT, |
3079 ccs.idFirstChild = 0; | 3129 WC_FRAME, |
3080 | 3130 NULL, |
3081 hwndframe = CreateWindow("MDICLIENT", | 3131 WS_VISIBLE | WS_CLIPCHILDREN | |
3082 "", | 3132 FS_NOBYTEALIGN, |
3083 WS_CHILD | WS_CLIPSIBLINGS, | 3133 0,0,2000,1000, |
3084 0,0,2000,1000, | 3134 NULLHANDLE, |
3085 DW_HWND_OBJECT, | 3135 HWND_TOP, |
3086 NULL, | 3136 0L, |
3087 DWInstance, | 3137 NULL, |
3088 &ccs); | 3138 NULL); |
3089 return hwndframe; | 3139 return hwndframe; |
3090 } | 3140 } |
3091 | 3141 |
3092 /* | 3142 /* |
3093 * Create a bitmap object to be packed. | 3143 * Create a bitmap object to be packed. |
3094 * Parameters: | 3144 * Parameters: |
3095 * id: An ID to be used with dw_window_from_id or 0L. | 3145 * id: An ID to be used with WinWindowFromID() or 0L. |
3096 */ | 3146 */ |
3097 HWND dw_bitmap_new(ULONG id) | 3147 HWND dw_bitmap_new(ULONG id) |
3098 { | 3148 { |
3099 return CreateWindow(STATICCLASSNAME, | 3149 return WinCreateWindow(HWND_OBJECT, |
3100 "", | 3150 WC_STATIC, |
3101 SS_BITMAP | WS_CHILD | WS_CLIPCHILDREN, | 3151 NULL, |
3102 0,0,2000,1000, | 3152 WS_VISIBLE | SS_TEXT, |
3103 DW_HWND_OBJECT, | 3153 0,0,2000,1000, |
3104 NULL, | 3154 NULLHANDLE, |
3105 NULL, | 3155 HWND_TOP, |
3106 NULL); | 3156 id, |
3157 NULL, | |
3158 NULL); | |
3107 } | 3159 } |
3108 | 3160 |
3109 /* | 3161 /* |
3110 * Create a notebook object to be packed. | 3162 * Create a notebook object to be packed. |
3111 * Parameters: | 3163 * Parameters: |
3112 * id: An ID to be used for getting the resource from the | 3164 * id: An ID to be used for getting the resource from the |
3113 * resource file. | 3165 * resource file. |
3114 */ | 3166 */ |
3115 HWND dw_notebook_new(ULONG id, int top) | 3167 HWND dw_notebook_new(ULONG id, int top) |
3116 { | 3168 { |
3117 ULONG flags = 0; | 3169 ULONG flags; |
3118 HWND tmp; | 3170 HWND tmp; |
3119 NotebookPage **array = calloc(256, sizeof(NotebookPage *)); | 3171 |
3120 | 3172 if(top) |
3121 if(!top) | 3173 flags = BKS_MAJORTABTOP; |
3122 flags = TCS_BOTTOM; | 3174 else |
3123 | 3175 flags = BKS_MAJORTABBOTTOM; |
3124 tmp = CreateWindow(WC_TABCONTROL, | 3176 |
3125 "", | 3177 tmp = WinCreateWindow(HWND_OBJECT, |
3126 WS_CHILD | WS_CLIPCHILDREN, | 3178 WC_NOTEBOOK, |
3127 0,0,2000,1000, | 3179 NULL, |
3128 DW_HWND_OBJECT, | 3180 WS_VISIBLE | |
3129 NULL, | 3181 BKS_TABBEDDIALOG | |
3130 NULL, | 3182 flags, |
3131 NULL); | 3183 0,0,2000,1000, |
3132 SetWindowLong(tmp, GWL_USERDATA, (ULONG)array); | 3184 NULLHANDLE, |
3185 HWND_TOP, | |
3186 id, | |
3187 NULL, | |
3188 NULL); | |
3189 | |
3190 /* Fix tab sizes on Warp 3 */ | |
3191 if(!IS_WARP4()) | |
3192 { | |
3193 /* best sizes to be determined by trial and error */ | |
3194 WinSendMsg(tmp, BKM_SETDIMENSIONS,MPFROM2SHORT(102, 28), MPFROMSHORT( BKA_MAJORTAB)); | |
3195 } | |
3196 | |
3133 dw_window_set_font(tmp, DefaultFont); | 3197 dw_window_set_font(tmp, DefaultFont); |
3134 return tmp; | 3198 return tmp; |
3135 } | 3199 } |
3136 | 3200 |
3137 /* | 3201 /* |
3145 HMENUI tmp = malloc(sizeof(struct _hmenui)); | 3209 HMENUI tmp = malloc(sizeof(struct _hmenui)); |
3146 | 3210 |
3147 if(!tmp) | 3211 if(!tmp) |
3148 return NULL; | 3212 return NULL; |
3149 | 3213 |
3150 tmp->menu = CreatePopupMenu(); | 3214 tmp->menu = WinCreateWindow(HWND_OBJECT, |
3151 tmp->hwnd = NULL; | 3215 WC_MENU, |
3216 NULL, | |
3217 WS_VISIBLE, | |
3218 0,0,2000,1000, | |
3219 NULLHANDLE, | |
3220 HWND_TOP, | |
3221 id, | |
3222 NULL, | |
3223 NULL); | |
3152 return tmp; | 3224 return tmp; |
3153 } | 3225 } |
3154 | 3226 |
3155 /* | 3227 /* |
3156 * Create a menubar on a window. | 3228 * Create a menubar on a window. |
3162 HMENUI tmp = malloc(sizeof(struct _hmenui)); | 3234 HMENUI tmp = malloc(sizeof(struct _hmenui)); |
3163 | 3235 |
3164 if(!tmp) | 3236 if(!tmp) |
3165 return NULL; | 3237 return NULL; |
3166 | 3238 |
3167 tmp->menu = CreateMenu(); | 3239 tmp->menu = WinCreateWindow(location, |
3168 tmp->hwnd = location; | 3240 WC_MENU, |
3169 | 3241 NULL, |
3170 SetMenu(location, tmp->menu); | 3242 WS_VISIBLE | MS_ACTIONBAR, |
3243 0,0,2000,1000, | |
3244 location, | |
3245 HWND_TOP, | |
3246 FID_MENU, | |
3247 NULL, | |
3248 NULL); | |
3171 return tmp; | 3249 return tmp; |
3172 } | 3250 } |
3173 | 3251 |
3174 /* | 3252 /* |
3175 * Destroys a menu created with dw_menubar_new or dw_menu_new. | 3253 * Destroys a menu created with dw_menubar_new or dw_menu_new. |
3178 */ | 3256 */ |
3179 void dw_menu_destroy(HMENUI *menu) | 3257 void dw_menu_destroy(HMENUI *menu) |
3180 { | 3258 { |
3181 if(menu && *menu) | 3259 if(menu && *menu) |
3182 { | 3260 { |
3183 DestroyMenu((*menu)->menu); | 3261 WinDestroyWindow((*menu)->menu); |
3184 free(*menu); | 3262 free(*menu); |
3185 *menu = NULL; | 3263 *menu = NULL; |
3186 } | 3264 } |
3187 } | 3265 } |
3188 | 3266 |
3190 * Adds a menuitem or submenu to an existing menu. | 3268 * Adds a menuitem or submenu to an existing menu. |
3191 * Parameters: | 3269 * Parameters: |
3192 * menu: The handle the the existing menu. | 3270 * menu: The handle the the existing menu. |
3193 * title: The title text on the menu item to be added. | 3271 * title: The title text on the menu item to be added. |
3194 * id: An ID to be used for message passing. | 3272 * id: An ID to be used for message passing. |
3273 * flags: Extended attributes to set on the menu. | |
3195 * end: If TRUE memu is positioned at the end of the menu. | 3274 * end: If TRUE memu is positioned at the end of the menu. |
3196 * check: If TRUE menu is "check"able. | 3275 * check: If TRUE menu is "check"able. |
3197 * flags: Extended attributes to set on the menu. | |
3198 * submenu: Handle to an existing menu to be a submenu or NULL. | 3276 * submenu: Handle to an existing menu to be a submenu or NULL. |
3199 */ | 3277 */ |
3200 HWND dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) | 3278 HWND dw_menu_append_item(HMENUI menux, char *title, ULONG id, ULONG flags, int end, int check, HMENUI submenu) |
3201 { | 3279 { |
3202 MENUITEMINFO mii; | 3280 MENUITEM miSubMenu; |
3203 HMENU menu; | 3281 HWND menu; |
3204 | 3282 |
3205 if(!menux) | 3283 if(!menux) |
3206 return NULL; | 3284 return NULLHANDLE; |
3207 | 3285 |
3208 menu = menux->menu; | 3286 menu = menux->menu; |
3209 | 3287 |
3210 mii.cbSize = sizeof(MENUITEMINFO); | 3288 if(end) |
3211 mii.fMask = MIIM_ID | MIIM_SUBMENU | MIIM_TYPE; | 3289 miSubMenu.iPosition=MIT_END; |
3212 | |
3213 /* Convert from OS/2 style accellerators to Win32 style */ | |
3214 if(title) | |
3215 { | |
3216 char *tmp = title; | |
3217 | |
3218 while(*tmp) | |
3219 { | |
3220 if(*tmp == '~') | |
3221 *tmp = '&'; | |
3222 tmp++; | |
3223 } | |
3224 } | |
3225 | |
3226 if(title && *title) | |
3227 mii.fType = MFT_STRING; | |
3228 else | 3290 else |
3229 mii.fType = MFT_SEPARATOR; | 3291 miSubMenu.iPosition=0; |
3230 | 3292 |
3231 mii.wID = id; | 3293 if(strlen(title) == 0) |
3232 mii.hSubMenu = submenu ? submenu->menu : 0; | 3294 miSubMenu.afStyle=MIS_SEPARATOR | flags; |
3233 mii.dwTypeData = title; | 3295 else |
3234 mii.cch = strlen(title); | 3296 miSubMenu.afStyle=MIS_TEXT | flags; |
3235 | 3297 miSubMenu.afAttribute=0; |
3236 InsertMenuItem(menu, 65535, TRUE, &mii); | 3298 miSubMenu.id=id; |
3237 if(menux->hwnd) | 3299 miSubMenu.hwndSubMenu = submenu ? submenu->menu : 0; |
3238 DrawMenuBar(menux->hwnd); | 3300 miSubMenu.hItem=NULLHANDLE; |
3301 | |
3302 WinSendMsg(menu, | |
3303 MM_INSERTITEM, | |
3304 MPFROMP(&miSubMenu), | |
3305 MPFROMP(title)); | |
3239 return (HWND)id; | 3306 return (HWND)id; |
3240 } | 3307 } |
3241 | 3308 |
3242 /* | 3309 /* |
3243 * Sets the state of a menu item check. | 3310 * Sets the state of a menu item check. |
3246 * id: Menuitem id. | 3313 * id: Menuitem id. |
3247 * check: TRUE for checked FALSE for not checked. | 3314 * check: TRUE for checked FALSE for not checked. |
3248 */ | 3315 */ |
3249 void dw_menu_item_set_check(HMENUI menux, unsigned long id, int check) | 3316 void dw_menu_item_set_check(HMENUI menux, unsigned long id, int check) |
3250 { | 3317 { |
3251 MENUITEMINFO mii; | 3318 HWND menu; |
3252 HMENU menu; | |
3253 | 3319 |
3254 if(!menux) | 3320 if(!menux) |
3255 return; | 3321 return; |
3256 | 3322 |
3257 menu = menux->menu; | 3323 menu = menux->menu; |
3258 | 3324 |
3259 mii.cbSize = sizeof(MENUITEMINFO); | |
3260 mii.fMask = MIIM_STATE; | |
3261 if(check) | 3325 if(check) |
3262 mii.fState = MFS_CHECKED; | 3326 WinSendMsg(menu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), |
3327 MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)); | |
3263 else | 3328 else |
3264 mii.fState = MFS_UNCHECKED; | 3329 WinSendMsg(menu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), |
3265 SetMenuItemInfo(menu, id, FALSE, &mii); | 3330 MPFROM2SHORT(MIA_CHECKED, 0)); |
3266 } | 3331 } |
3267 | 3332 |
3268 /* | 3333 /* |
3269 * Pops up a context menu at given x and y coordinates. | 3334 * Pops up a context menu at given x and y coordinates. |
3270 * Parameters: | 3335 * Parameters: |
3275 */ | 3340 */ |
3276 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) | 3341 void dw_menu_popup(HMENUI *menu, HWND parent, int x, int y) |
3277 { | 3342 { |
3278 if(menu && *menu) | 3343 if(menu && *menu) |
3279 { | 3344 { |
3280 TrackPopupMenu((*menu)->menu, 0, x, y, 0, parent, NULL); | 3345 WinPopupMenu(HWND_DESKTOP, parent, (*menu)->menu, x, dw_screen_height() - y, 0, PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_VCONSTRAIN | PU_HCONSTRAIN); |
3281 free(*menu); | 3346 free(*menu); |
3282 *menu = NULL; | 3347 *menu = NULL; |
3283 } | 3348 } |
3284 } | 3349 } |
3285 | 3350 |
3351 /* | |
3352 * Returns the current X and Y coordinates of the mouse pointer. | |
3353 * Parameters: | |
3354 * x: Pointer to variable to store X coordinate. | |
3355 * y: Pointer to variable to store Y coordinate. | |
3356 */ | |
3357 void dw_pointer_query_pos(long *x, long *y) | |
3358 { | |
3359 POINTL ptl; | |
3360 | |
3361 WinQueryPointerPos(HWND_DESKTOP, &ptl); | |
3362 if(x && y) | |
3363 { | |
3364 *x = ptl.x; | |
3365 *y = dw_screen_height() - ptl.y; | |
3366 } | |
3367 } | |
3368 | |
3369 /* | |
3370 * Sets the X and Y coordinates of the mouse pointer. | |
3371 * Parameters: | |
3372 * x: X coordinate. | |
3373 * y: Y coordinate. | |
3374 */ | |
3375 void dw_pointer_set_pos(long x, long y) | |
3376 { | |
3377 WinSetPointerPos(HWND_DESKTOP, x, dw_screen_height() - y); | |
3378 } | |
3286 | 3379 |
3287 /* | 3380 /* |
3288 * Create a container object to be packed. | 3381 * Create a container object to be packed. |
3289 * Parameters: | 3382 * Parameters: |
3290 * id: An ID to be used for getting the resource from the | 3383 * id: An ID to be used for getting the resource from the |
3291 * resource file. | 3384 * resource file. |
3292 */ | 3385 */ |
3293 HWND dw_container_new(ULONG id) | 3386 HWND dw_container_new(ULONG id) |
3294 { | 3387 { |
3295 HWND tmp = CreateWindow(WC_LISTVIEW, | 3388 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3296 "", | 3389 WC_CONTAINER, |
3297 WS_CHILD | LVS_REPORT | | 3390 NULL, |
3298 LVS_SHAREIMAGELISTS | WS_BORDER | | 3391 WS_VISIBLE | CCS_READONLY | |
3299 WS_CLIPCHILDREN, | 3392 CCS_SINGLESEL | CCS_AUTOPOSITION, |
3300 0,0,2000,1000, | 3393 0,0,2000,1000, |
3301 DW_HWND_OBJECT, | 3394 NULLHANDLE, |
3302 (HMENU)id, | 3395 HWND_TOP, |
3303 NULL, | 3396 id, |
3304 NULL); | 3397 NULL, |
3305 ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo)); | 3398 NULL); |
3306 | |
3307 if(!cinfo) | |
3308 { | |
3309 DestroyWindow(tmp); | |
3310 return NULL; | |
3311 } | |
3312 | |
3313 cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc); | |
3314 | |
3315 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3316 dw_window_set_font(tmp, DefaultFont); | 3399 dw_window_set_font(tmp, DefaultFont); |
3317 return tmp; | 3400 return tmp; |
3318 } | 3401 } |
3319 | 3402 |
3320 /* | 3403 /* |
3323 * id: An ID to be used for getting the resource from the | 3406 * id: An ID to be used for getting the resource from the |
3324 * resource file. | 3407 * resource file. |
3325 */ | 3408 */ |
3326 HWND dw_tree_new(ULONG id) | 3409 HWND dw_tree_new(ULONG id) |
3327 { | 3410 { |
3328 HWND tmp = CreateWindow(WC_TREEVIEW, | 3411 CNRINFO cnrinfo; |
3329 "", | 3412 Box *newbox = calloc(1, sizeof(Box)); |
3330 WS_CHILD | TVS_HASLINES | | 3413 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3331 TVS_HASBUTTONS | TVS_LINESATROOT | | 3414 WC_CONTAINER, |
3332 WS_BORDER | WS_CLIPCHILDREN, | 3415 NULL, |
3333 0,0,2000,1000, | 3416 WS_VISIBLE | CCS_READONLY | |
3334 DW_HWND_OBJECT, | 3417 CCS_SINGLESEL | CCS_AUTOPOSITION, |
3335 (HMENU)id, | 3418 0,0,2000,1000, |
3336 NULL, | 3419 NULLHANDLE, |
3337 NULL); | 3420 HWND_TOP, |
3338 TreeView_SetItemHeight(tmp, 16); | 3421 id, |
3422 NULL, | |
3423 NULL); | |
3424 | |
3425 cnrinfo.flWindowAttr = CV_TREE | CA_TREELINE; | |
3426 cnrinfo.slBitmapOrIcon.cx = 16; | |
3427 cnrinfo.slBitmapOrIcon.cy = 16; | |
3428 | |
3429 WinSendMsg(tmp, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON)); | |
3430 newbox->oldproc = WinSubclassWindow(tmp, _TreeProc); | |
3431 WinSetWindowPtr(tmp, QWP_USER, newbox); | |
3339 dw_window_set_font(tmp, DefaultFont); | 3432 dw_window_set_font(tmp, DefaultFont); |
3340 return tmp; | 3433 return tmp; |
3341 } | 3434 } |
3342 | 3435 |
3343 /* | 3436 /* |
3344 * Returns the current X and Y coordinates of the mouse pointer. | |
3345 * Parameters: | |
3346 * x: Pointer to variable to store X coordinate. | |
3347 * y: Pointer to variable to store Y coordinate. | |
3348 */ | |
3349 void dw_pointer_query_pos(long *x, long *y) | |
3350 { | |
3351 POINT ptl; | |
3352 | |
3353 GetCursorPos(&ptl); | |
3354 if(x && y) | |
3355 { | |
3356 *x = ptl.x; | |
3357 *y = ptl.y; | |
3358 } | |
3359 } | |
3360 | |
3361 /* | |
3362 * Sets the X and Y coordinates of the mouse pointer. | |
3363 * Parameters: | |
3364 * x: X coordinate. | |
3365 * y: Y coordinate. | |
3366 */ | |
3367 void dw_pointer_set_pos(long x, long y) | |
3368 { | |
3369 SetCursorPos(x, y); | |
3370 } | |
3371 | |
3372 /* | |
3373 * Create a new static text window (widget) to be packed. | 3437 * Create a new static text window (widget) to be packed. |
3374 * Parameters: | 3438 * Parameters: |
3375 * text: The text to be display by the static text widget. | 3439 * text: The text to be display by the static text widget. |
3376 * id: An ID to be used with WinWindowFromID() or 0L. | 3440 * id: An ID to be used with WinWindowFromID() or 0L. |
3377 */ | 3441 */ |
3378 HWND dw_text_new(char *text, ULONG id) | 3442 HWND dw_text_new(char *text, ULONG id) |
3379 { | 3443 { |
3380 HWND tmp = CreateWindow(STATICCLASSNAME, | 3444 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3381 text, | 3445 WC_STATIC, |
3382 BS_TEXT | WS_CHILD | WS_CLIPCHILDREN, | 3446 text, |
3383 0,0,2000,1000, | 3447 WS_VISIBLE | SS_TEXT, |
3384 DW_HWND_OBJECT, | 3448 0,0,2000,1000, |
3385 (HMENU)id, | 3449 NULLHANDLE, |
3386 NULL, | 3450 HWND_TOP, |
3387 NULL); | 3451 id, |
3452 NULL, | |
3453 NULL); | |
3454 dw_window_set_font(tmp, DefaultFont); | |
3455 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); | |
3456 return tmp; | |
3457 } | |
3458 | |
3459 /* | |
3460 * Create a new status text window (widget) to be packed. | |
3461 * Parameters: | |
3462 * text: The text to be display by the static text widget. | |
3463 * id: An ID to be used with WinWindowFromID() or 0L. | |
3464 */ | |
3465 HWND dw_status_text_new(char *text, ULONG id) | |
3466 { | |
3467 PFNWP *blah = malloc(sizeof(PFNWP)); | |
3468 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
3469 WC_STATIC, | |
3470 text, | |
3471 WS_VISIBLE | SS_TEXT, | |
3472 0,0,2000,1000, | |
3473 NULLHANDLE, | |
3474 HWND_TOP, | |
3475 id, | |
3476 NULL, | |
3477 NULL); | |
3478 dw_window_set_font(tmp, DefaultFont); | |
3479 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); | |
3480 | |
3481 *blah = WinSubclassWindow(tmp, _statusproc); | |
3482 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3483 return tmp; | |
3484 } | |
3485 | |
3486 /* | |
3487 * Create a new Multiline Editbox window (widget) to be packed. | |
3488 * Parameters: | |
3489 * id: An ID to be used with WinWindowFromID() or 0L. | |
3490 */ | |
3491 HWND dw_mle_new(ULONG id) | |
3492 { | |
3493 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
3494 WC_MLE, | |
3495 "", | |
3496 WS_VISIBLE | | |
3497 MLS_BORDER | MLS_IGNORETAB | | |
3498 MLS_READONLY | MLS_VSCROLL, | |
3499 0,0,2000,1000, | |
3500 NULLHANDLE, | |
3501 HWND_TOP, | |
3502 id, | |
3503 NULL, | |
3504 NULL); | |
3505 dw_window_set_font(tmp, DefaultFont); | |
3388 dw_window_set_font(tmp, DefaultFont); | 3506 dw_window_set_font(tmp, DefaultFont); |
3389 return tmp; | 3507 return tmp; |
3390 } | 3508 } |
3391 | 3509 |
3392 /* | 3510 /* |
3393 * Create a new status text window (widget) to be packed. | 3511 * Create a new Entryfield window (widget) to be packed. |
3512 * Parameters: | |
3513 * text: The default text to be in the entryfield widget. | |
3514 * id: An ID to be used with WinWindowFromID() or 0L. | |
3515 */ | |
3516 HWND dw_entryfield_new(char *text, ULONG id) | |
3517 { | |
3518 | |
3519 WindowData *blah = calloc(1, sizeof(WindowData)); | |
3520 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
3521 WC_ENTRYFIELD, | |
3522 text, | |
3523 WS_VISIBLE | ES_MARGIN | | |
3524 ES_AUTOSCROLL | WS_TABSTOP, | |
3525 0,0,2000,1000, | |
3526 NULLHANDLE, | |
3527 HWND_TOP, | |
3528 id, | |
3529 NULL, | |
3530 NULL); | |
3531 dw_window_set_font(tmp, DefaultFont); | |
3532 blah->oldproc = WinSubclassWindow(tmp, _entryproc); | |
3533 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3534 return tmp; | |
3535 } | |
3536 | |
3537 /* | |
3538 * Create a new Entryfield (password) window (widget) to be packed. | |
3539 * Parameters: | |
3540 * text: The default text to be in the entryfield widget. | |
3541 * id: An ID to be used with WinWindowFromID() or 0L. | |
3542 */ | |
3543 HWND dw_entryfield_password_new(char *text, ULONG id) | |
3544 { | |
3545 WindowData *blah = calloc(1, sizeof(WindowData)); | |
3546 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
3547 WC_ENTRYFIELD, | |
3548 text, | |
3549 WS_VISIBLE | ES_MARGIN | ES_UNREADABLE | | |
3550 ES_AUTOSCROLL | WS_TABSTOP, | |
3551 0,0,2000,1000, | |
3552 NULLHANDLE, | |
3553 HWND_TOP, | |
3554 id, | |
3555 NULL, | |
3556 NULL); | |
3557 dw_window_set_font(tmp, DefaultFont); | |
3558 blah->oldproc = WinSubclassWindow(tmp, _entryproc); | |
3559 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3560 return tmp; | |
3561 } | |
3562 | |
3563 /* | |
3564 * Create a new Combobox window (widget) to be packed. | |
3565 * Parameters: | |
3566 * text: The default text to be in the combpbox widget. | |
3567 * id: An ID to be used with WinWindowFromID() or 0L. | |
3568 */ | |
3569 HWND dw_combobox_new(char *text, ULONG id) | |
3570 { | |
3571 WindowData *blah = calloc(1, sizeof(WindowData)); | |
3572 HWND tmp = WinCreateWindow(HWND_OBJECT, | |
3573 WC_COMBOBOX, | |
3574 text, | |
3575 WS_VISIBLE | CBS_DROPDOWN | WS_GROUP, | |
3576 0,0,2000,1000, | |
3577 NULLHANDLE, | |
3578 HWND_TOP, | |
3579 id, | |
3580 NULL, | |
3581 NULL); | |
3582 HENUM henum = WinBeginEnumWindows(tmp); | |
3583 HWND child; | |
3584 | |
3585 while((child = WinGetNextWindow(henum)) != NULLHANDLE) | |
3586 { | |
3587 WindowData *moreblah = calloc(1, sizeof(WindowData)); | |
3588 moreblah->oldproc = WinSubclassWindow(child, _comboentryproc); | |
3589 WinSetWindowPtr(child, QWP_USER, moreblah); | |
3590 } | |
3591 WinEndEnumWindows(henum); | |
3592 dw_window_set_font(tmp, DefaultFont); | |
3593 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_WHITE); | |
3594 blah->oldproc = WinSubclassWindow(tmp, _comboproc); | |
3595 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3596 return tmp; | |
3597 } | |
3598 | |
3599 /* | |
3600 * Create a new button window (widget) to be packed. | |
3394 * Parameters: | 3601 * Parameters: |
3395 * text: The text to be display by the static text widget. | 3602 * text: The text to be display by the static text widget. |
3396 * id: An ID to be used with WinWindowFromID() or 0L. | 3603 * id: An ID to be used with WinWindowFromID() or 0L. |
3397 */ | 3604 */ |
3398 HWND dw_status_text_new(char *text, ULONG id) | 3605 HWND dw_button_new(char *text, ULONG id) |
3399 { | 3606 { |
3400 HWND tmp = CreateWindow(STATICCLASSNAME, | 3607 BubbleButton *bubble = malloc(sizeof(BubbleButton)); |
3401 text, | 3608 |
3402 BS_TEXT | WS_CHILD | WS_CLIPCHILDREN, | 3609 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3403 0,0,2000,1000, | 3610 WC_BUTTON, |
3404 DW_HWND_OBJECT, | 3611 text, |
3405 (HMENU)id, | 3612 WS_VISIBLE, |
3406 NULL, | 3613 0,0,2000,1000, |
3407 NULL); | 3614 NULLHANDLE, |
3408 dw_window_set_font(tmp, DefaultFont); | 3615 HWND_TOP, |
3409 SubclassWindow(tmp, _statuswndproc); | 3616 id, |
3410 return tmp; | 3617 NULL, |
3411 } | 3618 NULL); |
3412 | 3619 |
3413 /* | 3620 bubble->id = id; |
3414 * Create a new Multiline Editbox window (widget) to be packed. | 3621 bubble->bubbletext[0] = '\0'; |
3415 * Parameters: | 3622 bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); |
3416 * id: An ID to be used with WinWindowFromID() or 0L. | 3623 |
3417 */ | 3624 WinSetWindowPtr(tmp, QWP_USER, bubble); |
3418 HWND dw_mle_new(ULONG id) | |
3419 { | |
3420 | |
3421 HWND tmp = CreateWindow(EDITCLASSNAME, | |
3422 "", | |
3423 WS_BORDER | | |
3424 WS_VSCROLL | ES_MULTILINE | | |
3425 ES_WANTRETURN | WS_CHILD | | |
3426 WS_CLIPCHILDREN, | |
3427 0,0,2000,1000, | |
3428 DW_HWND_OBJECT, | |
3429 (HMENU)id, | |
3430 NULL, | |
3431 NULL); | |
3432 dw_window_set_font(tmp, DefaultFont); | 3625 dw_window_set_font(tmp, DefaultFont); |
3433 return tmp; | 3626 return tmp; |
3434 } | 3627 } |
3435 | 3628 |
3436 /* | 3629 /* Function: GenResIDStr |
3437 * Create a new Entryfield window (widget) to be packed. | 3630 ** Abstract: Generate string '#nnnn' for a given ID for using with Button |
3438 * Parameters: | 3631 ** controls |
3439 * text: The default text to be in the entryfield widget. | 3632 */ |
3440 * id: An ID to be used with WinWindowFromID() or 0L. | 3633 |
3441 */ | 3634 void _GenResIDStr(CHAR *buff, ULONG ulID) |
3442 HWND dw_entryfield_new(char *text, ULONG id) | 3635 { |
3443 { | 3636 char *str; |
3444 HWND tmp = CreateWindow(EDITCLASSNAME, | 3637 int slen = 0; |
3445 text, | 3638 |
3446 ES_WANTRETURN | WS_CHILD | | 3639 *buff++ = '#'; |
3447 WS_BORDER | ES_AUTOHSCROLL | | 3640 |
3448 WS_CLIPCHILDREN, | 3641 str = buff; |
3449 0,0,2000,1000, | 3642 |
3450 DW_HWND_OBJECT, | 3643 do |
3451 (HMENU)id, | 3644 { |
3452 NULL, | 3645 *str++ = (ulID % 10) + '0'; |
3453 NULL); | 3646 ulID /= 10; |
3454 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); | 3647 slen++; |
3455 | 3648 } |
3456 cinfo->back = cinfo->fore = -1; | 3649 while(ulID); |
3457 cinfo->buddy = 0; | 3650 |
3458 | 3651 *str-- = 0; |
3459 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); | 3652 |
3460 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | 3653 for(; str > buff; str--, buff++) |
3461 dw_window_set_font(tmp, DefaultFont); | 3654 { |
3462 return tmp; | 3655 *buff ^= *str; |
3463 } | 3656 *str ^= *buff; |
3464 | 3657 *buff ^= *str; |
3465 /* | 3658 } |
3466 * Create a new Entryfield passwird window (widget) to be packed. | 3659 } |
3467 * Parameters: | 3660 |
3468 * text: The default text to be in the entryfield widget. | |
3469 * id: An ID to be used with WinWindowFromID() or 0L. | |
3470 */ | |
3471 HWND dw_entryfield_password_new(char *text, ULONG id) | |
3472 { | |
3473 HWND tmp = CreateWindow(EDITCLASSNAME, | |
3474 text, | |
3475 ES_WANTRETURN | WS_CHILD | | |
3476 ES_PASSWORD | WS_BORDER | | |
3477 ES_AUTOHSCROLL | WS_CLIPCHILDREN, | |
3478 0,0,2000,1000, | |
3479 DW_HWND_OBJECT, | |
3480 (HMENU)id, | |
3481 NULL, | |
3482 NULL); | |
3483 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); | |
3484 | |
3485 cinfo->back = cinfo->fore = -1; | |
3486 cinfo->buddy = 0; | |
3487 | |
3488 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); | |
3489 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3490 dw_window_set_font(tmp, DefaultFont); | |
3491 return tmp; | |
3492 } | |
3493 | |
3494 BOOL CALLBACK _subclass_child(HWND handle, LPARAM lp) | |
3495 { | |
3496 ColorInfo *cinfo = (ColorInfo *)lp; | |
3497 | |
3498 if(cinfo) | |
3499 { | |
3500 cinfo->buddy = handle; | |
3501 cinfo->pOldProc = (WNDPROC)SubclassWindow(handle, _colorwndproc); | |
3502 SetWindowLong(handle, GWL_USERDATA, (ULONG)cinfo); | |
3503 } | |
3504 return FALSE; | |
3505 } | |
3506 | |
3507 /* | |
3508 * Create a new Combobox window (widget) to be packed. | |
3509 * Parameters: | |
3510 * text: The default text to be in the combpbox widget. | |
3511 * id: An ID to be used with WinWindowFromID() or 0L. | |
3512 */ | |
3513 HWND dw_combobox_new(char *text, ULONG id) | |
3514 { | |
3515 HWND tmp = CreateWindow(COMBOBOXCLASSNAME, | |
3516 "", | |
3517 WS_CHILD | CBS_DROPDOWN | WS_CLIPCHILDREN, | |
3518 0,0,2000,1000, | |
3519 DW_HWND_OBJECT, | |
3520 (HMENU)id, | |
3521 NULL, | |
3522 NULL); | |
3523 ColorInfo *cinfo = (ColorInfo *)calloc(1, sizeof(ColorInfo)); | |
3524 ColorInfo *cinfo2 = (ColorInfo *)calloc(1, sizeof(ColorInfo)); | |
3525 | |
3526 if(!cinfo) | |
3527 { | |
3528 DestroyWindow(tmp); | |
3529 return NULL; | |
3530 } | |
3531 | |
3532 cinfo2->fore = cinfo->fore = -1; | |
3533 cinfo2->back = cinfo->back = -1; | |
3534 cinfo2->combo = cinfo->combo = tmp; | |
3535 EnumChildWindows(tmp, _subclass_child, (LPARAM)cinfo2); | |
3536 | |
3537 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3538 dw_window_set_font(tmp, DefaultFont); | |
3539 return tmp; | |
3540 } | |
3541 | |
3542 /* | |
3543 * Create a new button window (widget) to be packed. | |
3544 * Parameters: | |
3545 * text: The text to be display by the static text widget. | |
3546 * id: An ID to be used with WinWindowFromID() or 0L. | |
3547 */ | |
3548 HWND dw_button_new(char *text, ULONG id) | |
3549 { | |
3550 BubbleButton *bubble = malloc(sizeof(BubbleButton)); | |
3551 | |
3552 HWND tmp = CreateWindow(BUTTONCLASSNAME, | |
3553 text, | |
3554 WS_CHILD | BS_PUSHBUTTON | WS_CLIPCHILDREN, | |
3555 0,0,2000,1000, | |
3556 DW_HWND_OBJECT, | |
3557 (HMENU)id, | |
3558 NULL, | |
3559 NULL); | |
3560 | |
3561 bubble->id = id; | |
3562 bubble->bubbletext[0] = '\0'; | |
3563 bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc); | |
3564 | |
3565 SetWindowLong(tmp, GWL_USERDATA, (ULONG)bubble); | |
3566 dw_window_set_font(tmp, DefaultFont); | |
3567 return tmp; | |
3568 } | |
3569 | 3661 |
3570 /* | 3662 /* |
3571 * Create a new bitmap button window (widget) to be packed. | 3663 * Create a new bitmap button window (widget) to be packed. |
3572 * Parameters: | 3664 * Parameters: |
3573 * text: Bubble help text to be displayed. | 3665 * text: Bubble help text to be displayed. |
3574 * id: An ID of a bitmap in the resource file. | 3666 * id: An ID of a bitmap in the resource file. |
3575 */ | 3667 */ |
3576 HWND dw_bitmapbutton_new(char *text, ULONG id) | 3668 HWND dw_bitmapbutton_new(char *text, ULONG id) |
3577 { | 3669 { |
3670 char idbuf[256]; | |
3578 HWND tmp; | 3671 HWND tmp; |
3579 BubbleButton *bubble = malloc(sizeof(BubbleButton)); | 3672 BubbleButton *bubble = malloc(sizeof(BubbleButton)); |
3580 HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id)); | 3673 |
3581 | 3674 _GenResIDStr(idbuf, id); |
3582 tmp = CreateWindow(BUTTONCLASSNAME, | 3675 |
3583 "", | 3676 tmp = WinCreateWindow(HWND_OBJECT, |
3584 WS_CHILD | BS_PUSHBUTTON | | 3677 WC_BUTTON, |
3585 BS_BITMAP | WS_CLIPCHILDREN, | 3678 idbuf, |
3586 0,0,2000,1000, | 3679 WS_VISIBLE | BS_PUSHBUTTON | |
3587 DW_HWND_OBJECT, | 3680 BS_BITMAP | BS_AUTOSIZE | |
3588 (HMENU)id, | 3681 BS_NOPOINTERFOCUS, |
3589 NULL, | 3682 0,0,2000,1000, |
3590 NULL); | 3683 NULLHANDLE, |
3684 HWND_TOP, | |
3685 id, | |
3686 NULL, | |
3687 NULL); | |
3591 | 3688 |
3592 bubble->id = id; | 3689 bubble->id = id; |
3593 strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); | 3690 strncpy(bubble->bubbletext, text, BUBBLE_HELP_MAX - 1); |
3594 bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; | 3691 bubble->bubbletext[BUBBLE_HELP_MAX - 1] = '\0'; |
3595 bubble->pOldProc = (WNDPROC)SubclassWindow(tmp, _BtProc); | 3692 bubble->pOldProc = WinSubclassWindow(tmp, _BtProc); |
3596 | 3693 |
3597 SetWindowLong(tmp, GWL_USERDATA, (ULONG)bubble); | 3694 WinSetWindowPtr(tmp, QWP_USER, bubble); |
3598 | |
3599 SendMessage(tmp, BM_SETIMAGE, | |
3600 (WPARAM) IMAGE_BITMAP, | |
3601 (LPARAM) hbitmap); | |
3602 return tmp; | 3695 return tmp; |
3603 } | 3696 } |
3604 | 3697 |
3605 /* | 3698 /* |
3606 * Create a new spinbutton window (widget) to be packed. | 3699 * Create a new spinbutton window (widget) to be packed. |
3608 * text: The text to be display by the static text widget. | 3701 * text: The text to be display by the static text widget. |
3609 * id: An ID to be used with WinWindowFromID() or 0L. | 3702 * id: An ID to be used with WinWindowFromID() or 0L. |
3610 */ | 3703 */ |
3611 HWND dw_spinbutton_new(char *text, ULONG id) | 3704 HWND dw_spinbutton_new(char *text, ULONG id) |
3612 { | 3705 { |
3613 ULONG *data = malloc(sizeof(ULONG)); | 3706 PFNWP *blah = malloc(sizeof(PFNWP)); |
3614 HWND buddy = CreateWindow(EDITCLASSNAME, | 3707 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3615 text, | 3708 WC_SPINBUTTON, |
3616 WS_CHILD | WS_BORDER | | 3709 text, |
3617 ES_NUMBER | WS_CLIPCHILDREN, | 3710 WS_VISIBLE | SPBS_MASTER, |
3618 0,0,2000,1000, | 3711 0,0,2000,1000, |
3619 DW_HWND_OBJECT, | 3712 NULLHANDLE, |
3620 NULL, | 3713 HWND_TOP, |
3621 NULL, | 3714 id, |
3622 NULL); | 3715 NULL, |
3623 HWND tmp = CreateUpDownControl( | 3716 NULL); |
3624 WS_CHILD | UDS_ALIGNRIGHT | | 3717 dw_window_set_font(tmp, DefaultFont); |
3625 UDS_ARROWKEYS | UDS_SETBUDDYINT | | 3718 *blah = WinSubclassWindow(tmp, _entryproc); |
3626 UDS_WRAP | UDS_NOTHOUSANDS, | 3719 WinSetWindowPtr(tmp, QWP_USER, blah); |
3627 0, | |
3628 0, | |
3629 2000, | |
3630 1000, | |
3631 DW_HWND_OBJECT, | |
3632 id, | |
3633 DWInstance, | |
3634 buddy, | |
3635 0, | |
3636 100, | |
3637 0); | |
3638 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); | |
3639 | |
3640 cinfo->back = cinfo->fore = -1; | |
3641 cinfo->buddy = tmp; | |
3642 | |
3643 cinfo->pOldProc = SubclassWindow(buddy, _colorwndproc); | |
3644 SetWindowLong(buddy, GWL_USERDATA, (ULONG)cinfo); | |
3645 | |
3646 cinfo = calloc(1, sizeof(ColorInfo)); | |
3647 cinfo->buddy = buddy; | |
3648 cinfo->pOldProc = SubclassWindow(tmp, _spinnerwndproc); | |
3649 | |
3650 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3651 dw_window_set_font(buddy, DefaultFont); | |
3652 return tmp; | 3720 return tmp; |
3653 } | 3721 } |
3654 | 3722 |
3655 /* | 3723 /* |
3656 * Create a new radiobutton window (widget) to be packed. | 3724 * Create a new radiobutton window (widget) to be packed. |
3658 * text: The text to be display by the static text widget. | 3726 * text: The text to be display by the static text widget. |
3659 * id: An ID to be used with WinWindowFromID() or 0L. | 3727 * id: An ID to be used with WinWindowFromID() or 0L. |
3660 */ | 3728 */ |
3661 HWND dw_radiobutton_new(char *text, ULONG id) | 3729 HWND dw_radiobutton_new(char *text, ULONG id) |
3662 { | 3730 { |
3663 HWND tmp = CreateWindow(BUTTONCLASSNAME, | 3731 PFNWP *blah = malloc(sizeof(PFNWP)); |
3664 text, | 3732 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3665 WS_CHILD | BS_AUTORADIOBUTTON | | 3733 WC_BUTTON, |
3666 WS_CLIPCHILDREN, | 3734 text, |
3667 0,0,2000,1000, | 3735 WS_VISIBLE | |
3668 DW_HWND_OBJECT, | 3736 BS_AUTORADIOBUTTON, |
3669 (HMENU)id, | 3737 0,0,2000,1000, |
3670 NULL, | 3738 NULLHANDLE, |
3671 NULL); | 3739 HWND_TOP, |
3672 | 3740 id, |
3673 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); | 3741 NULL, |
3674 | 3742 NULL); |
3675 cinfo->back = cinfo->fore = -1; | |
3676 cinfo->buddy = 0; | |
3677 cinfo->user = 0; | |
3678 | |
3679 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); | |
3680 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3681 dw_window_set_font(tmp, DefaultFont); | 3743 dw_window_set_font(tmp, DefaultFont); |
3744 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); | |
3745 *blah = WinSubclassWindow(tmp, _entryproc); | |
3746 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3682 return tmp; | 3747 return tmp; |
3683 } | 3748 } |
3684 | 3749 |
3685 | |
3686 /* | 3750 /* |
3687 * Create a new percent bar window (widget) to be packed. | 3751 * Create a new percent bar window (widget) to be packed. |
3688 * Parameters: | 3752 * Parameters: |
3689 * id: An ID to be used with WinWindowFromID() or 0L. | 3753 * id: An ID to be used with WinWindowFromID() or 0L. |
3690 */ | 3754 */ |
3691 HWND dw_percent_new(ULONG id) | 3755 HWND dw_percent_new(ULONG id) |
3692 { | 3756 { |
3693 return CreateWindow(PROGRESS_CLASS, | 3757 PercentBar *blah = malloc(sizeof(PercentBar)); |
3694 "", | 3758 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3695 WS_CHILD | WS_CLIPCHILDREN, | 3759 WC_STATIC, |
3696 0,0,2000,1000, | 3760 "", |
3697 DW_HWND_OBJECT, | 3761 WS_VISIBLE | SS_TEXT, |
3698 NULL, | 3762 0,0,2000,1000, |
3699 NULL, | 3763 NULLHANDLE, |
3700 NULL); | 3764 HWND_TOP, |
3765 id, | |
3766 NULL, | |
3767 NULL); | |
3768 dw_window_set_font(tmp, DefaultFont); | |
3769 dw_window_set_color(tmp, DW_CLR_BLUE, DW_CLR_PALEGRAY); | |
3770 | |
3771 blah->oldproc = WinSubclassWindow(tmp, _percentproc); | |
3772 blah->pos = 0; | |
3773 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3774 return tmp; | |
3701 } | 3775 } |
3702 | 3776 |
3703 /* | 3777 /* |
3704 * Create a new checkbox window (widget) to be packed. | 3778 * Create a new checkbox window (widget) to be packed. |
3705 * Parameters: | 3779 * Parameters: |
3706 * text: The text to be display by the static text widget. | 3780 * text: The text to be display by the static text widget. |
3707 * id: An ID to be used with WinWindowFromID() or 0L. | 3781 * id: An ID to be used with WinWindowFromID() or 0L. |
3708 */ | 3782 */ |
3709 HWND dw_checkbox_new(char *text, ULONG id) | 3783 HWND dw_checkbox_new(char *text, ULONG id) |
3710 { | 3784 { |
3711 HWND tmp = CreateWindow(BUTTONCLASSNAME, | 3785 PFNWP *blah = malloc(sizeof(PFNWP)); |
3712 text, | 3786 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3713 WS_CHILD | BS_AUTOCHECKBOX | | 3787 WC_BUTTON, |
3714 BS_TEXT | WS_CLIPCHILDREN, | 3788 text, |
3715 0,0,2000,1000, | 3789 WS_VISIBLE | BS_AUTOCHECKBOX, |
3716 DW_HWND_OBJECT, | 3790 0,0,2000,1000, |
3717 NULL, | 3791 NULLHANDLE, |
3718 NULL, | 3792 HWND_TOP, |
3719 NULL); | 3793 id, |
3720 ColorInfo *cinfo = calloc(1, sizeof(ColorInfo)); | 3794 NULL, |
3721 | 3795 NULL); |
3722 cinfo->back = cinfo->fore = -1; | |
3723 cinfo->buddy = 0; | |
3724 cinfo->user = 1; | |
3725 | |
3726 cinfo->pOldProc = SubclassWindow(tmp, _colorwndproc); | |
3727 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3728 dw_window_set_font(tmp, DefaultFont); | 3796 dw_window_set_font(tmp, DefaultFont); |
3797 dw_window_set_color(tmp, DW_CLR_BLACK, DW_CLR_PALEGRAY); | |
3798 *blah = WinSubclassWindow(tmp, _entryproc); | |
3799 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3729 return tmp; | 3800 return tmp; |
3730 } | 3801 } |
3731 | 3802 |
3732 /* | 3803 /* |
3733 * Create a new listbox window (widget) to be packed. | 3804 * Create a new listbox window (widget) to be packed. |
3735 * id: An ID to be used with WinWindowFromID() or 0L. | 3806 * id: An ID to be used with WinWindowFromID() or 0L. |
3736 * multi: Multiple select TRUE or FALSE. | 3807 * multi: Multiple select TRUE or FALSE. |
3737 */ | 3808 */ |
3738 HWND dw_listbox_new(ULONG id, int multi) | 3809 HWND dw_listbox_new(ULONG id, int multi) |
3739 { | 3810 { |
3740 HWND tmp = CreateWindow(LISTBOXCLASSNAME, | 3811 PFNWP *blah = malloc(sizeof(PFNWP)); |
3741 "", | 3812 HWND tmp = WinCreateWindow(HWND_OBJECT, |
3742 LBS_NOINTEGRALHEIGHT | WS_CHILD | LBS_HASSTRINGS | | 3813 WC_LISTBOX, |
3743 LBS_NOTIFY | WS_BORDER | WS_CLIPCHILDREN | | 3814 NULL, |
3744 WS_VSCROLL | (multi ? LBS_EXTENDEDSEL : 0) , | 3815 WS_VISIBLE | LS_NOADJUSTPOS | |
3745 0,0,2000,1000, | 3816 (multi ? LS_MULTIPLESEL : 0), |
3746 DW_HWND_OBJECT, | 3817 0,0,2000,1000, |
3747 NULL, | 3818 NULLHANDLE, |
3748 NULL, | 3819 HWND_TOP, |
3749 NULL); | 3820 id, |
3750 ContainerInfo *cinfo = (ContainerInfo *)calloc(1, sizeof(ContainerInfo)); | 3821 NULL, |
3751 | 3822 NULL); |
3752 if(!cinfo) | |
3753 { | |
3754 DestroyWindow(tmp); | |
3755 return NULL; | |
3756 } | |
3757 | |
3758 cinfo->cinfo.fore = -1; | |
3759 cinfo->cinfo.back = -1; | |
3760 cinfo->pOldProc = (WNDPROC)SubclassWindow(tmp, _containerwndproc); | |
3761 | |
3762 SetWindowLong(tmp, GWL_USERDATA, (ULONG)cinfo); | |
3763 dw_window_set_font(tmp, DefaultFont); | 3823 dw_window_set_font(tmp, DefaultFont); |
3824 *blah = WinSubclassWindow(tmp, _entryproc); | |
3825 WinSetWindowPtr(tmp, QWP_USER, blah); | |
3764 return tmp; | 3826 return tmp; |
3765 } | 3827 } |
3766 | 3828 |
3767 /* | 3829 /* |
3768 * Sets the icon used for a given window. | 3830 * Sets the icon used for a given window. |
3770 * handle: Handle to the window. | 3832 * handle: Handle to the window. |
3771 * id: An ID to be used to specify the icon. | 3833 * id: An ID to be used to specify the icon. |
3772 */ | 3834 */ |
3773 void dw_window_set_icon(HWND handle, ULONG id) | 3835 void dw_window_set_icon(HWND handle, ULONG id) |
3774 { | 3836 { |
3775 HICON hicon = LoadIcon(DWInstance, MAKEINTRESOURCE(id)); | 3837 HPOINTER icon; |
3776 | 3838 |
3777 SendMessage(handle, WM_SETICON, | 3839 icon = WinLoadPointer(HWND_DESKTOP,NULLHANDLE,id); |
3778 (WPARAM) IMAGE_ICON, | 3840 WinSendMsg(handle, WM_SETICON, (MPARAM)icon, 0); |
3779 (LPARAM) hicon); | |
3780 } | 3841 } |
3781 | 3842 |
3782 /* | 3843 /* |
3783 * Sets the bitmap used for a given static window. | 3844 * Sets the bitmap used for a given static window. |
3784 * Parameters: | 3845 * Parameters: |
3785 * handle: Handle to the window. | 3846 * handle: Handle to the window. |
3786 * id: An ID to be used to specify the icon. | 3847 * id: An ID to be used to specify the icon. |
3787 */ | 3848 */ |
3788 void dw_window_set_bitmap(HWND handle, ULONG id) | 3849 void dw_window_set_bitmap(HWND handle, ULONG id) |
3789 { | 3850 { |
3790 HBITMAP hbitmap = LoadBitmap(DWInstance, MAKEINTRESOURCE(id)); | 3851 HBITMAP hbm; |
3791 | 3852 HPS hps = WinGetPS(handle); |
3792 SendMessage(handle, STM_SETIMAGE, | 3853 |
3793 (WPARAM) IMAGE_BITMAP, | 3854 hbm = GpiLoadBitmap(hps, NULLHANDLE, id, 0, 0); |
3794 (LPARAM) hbitmap); | 3855 WinSetWindowBits(handle,QWL_STYLE,SS_BITMAP,SS_BITMAP | 0x7f); |
3856 WinSendMsg( handle, SM_SETHANDLE, MPFROMP(hbm), NULL ); | |
3857 /*WinSetWindowULong( hwndDlg, QWL_USER, (ULONG) hbm );*/ | |
3858 WinReleasePS(hps); | |
3795 } | 3859 } |
3796 | 3860 |
3797 /* | 3861 /* |
3798 * Sets the text used for a given window. | 3862 * Sets the text used for a given window. |
3799 * Parameters: | 3863 * Parameters: |
3800 * handle: Handle to the window. | 3864 * handle: Handle to the window. |
3801 * text: The text associsated with a given window. | 3865 * text: The text associsated with a given window. |
3802 */ | 3866 */ |
3803 void dw_window_set_text(HWND handle, char *text) | 3867 void dw_window_set_text(HWND handle, char *text) |
3804 { | 3868 { |
3805 SetWindowText(handle, text); | 3869 WinSetWindowText(handle, text); |
3806 } | 3870 } |
3807 | 3871 |
3808 /* | 3872 /* |
3809 * Gets the text used for a given window. | 3873 * Gets the text used for a given window. |
3810 * Parameters: | 3874 * Parameters: |
3814 */ | 3878 */ |
3815 char *dw_window_get_text(HWND handle) | 3879 char *dw_window_get_text(HWND handle) |
3816 { | 3880 { |
3817 char tempbuf[4096] = ""; | 3881 char tempbuf[4096] = ""; |
3818 | 3882 |
3819 GetWindowText(handle, tempbuf, 4095); | 3883 WinQueryWindowText(handle, 4095, tempbuf); |
3820 tempbuf[4095] = 0; | 3884 tempbuf[4095] = 0; |
3821 | 3885 |
3822 return strdup(tempbuf); | 3886 return strdup(tempbuf); |
3823 } | 3887 } |
3824 | 3888 |
3827 * Parameters: | 3891 * Parameters: |
3828 * handle: Handle to the window. | 3892 * handle: Handle to the window. |
3829 */ | 3893 */ |
3830 void dw_window_disable(HWND handle) | 3894 void dw_window_disable(HWND handle) |
3831 { | 3895 { |
3832 EnableWindow(handle, FALSE); | 3896 WinEnableWindow(handle, FALSE); |
3833 } | 3897 } |
3834 | 3898 |
3835 /* | 3899 /* |
3836 * Enables given window (widget). | 3900 * Enables given window (widget). |
3837 * Parameters: | 3901 * Parameters: |
3838 * handle: Handle to the window. | 3902 * handle: Handle to the window. |
3839 */ | 3903 */ |
3840 void dw_window_enable(HWND handle) | 3904 void dw_window_enable(HWND handle) |
3841 { | 3905 { |
3842 EnableWindow(handle, TRUE); | 3906 WinEnableWindow(handle, TRUE); |
3843 } | 3907 } |
3844 | 3908 |
3845 /* | 3909 /* |
3846 * Gets the child window handle with specified ID. | 3910 * Gets the child window handle with specified ID. |
3847 * Parameters: | 3911 * Parameters: |
3848 * handle: Handle to the parent window. | 3912 * handle: Handle to the parent window. |
3849 * id: Integer ID of the child. | 3913 * id: Integer ID of the child. |
3850 */ | 3914 */ |
3851 HWND dw_window_from_id(HWND handle, int id) | 3915 HWND dw_window_from_id(HWND handle, int id) |
3852 { | 3916 { |
3853 return 0L; | 3917 HENUM henum; |
3854 } | 3918 HWND child; |
3855 /* | 3919 char tmpbuf[100]; |
3856 * Pack windows (widgets) into a box from the start (or top). | 3920 |
3921 henum = WinBeginEnumWindows(handle); | |
3922 while((child = WinGetNextWindow(henum)) != NULLHANDLE) | |
3923 { | |
3924 int windowid = WinQueryWindowUShort(child, QWS_ID); | |
3925 HWND found; | |
3926 | |
3927 WinQueryClassName(child, 99, tmpbuf); | |
3928 | |
3929 /* If the child is a box (frame) then recurse into it */ | |
3930 if(strncmp(tmpbuf, "#1", 3)==0) | |
3931 if((found = dw_window_from_id(child, id)) != NULLHANDLE) | |
3932 return found; | |
3933 | |
3934 if(windowid && windowid == id) | |
3935 { | |
3936 WinEndEnumWindows(henum); | |
3937 return child; | |
3938 } | |
3939 } | |
3940 WinEndEnumWindows(henum); | |
3941 return NULLHANDLE; | |
3942 } | |
3943 | |
3944 /* | |
3945 * Pack windows (widgets) into a box from the end (or bottom). | |
3857 * Parameters: | 3946 * Parameters: |
3858 * box: Window handle of the box to be packed into. | 3947 * box: Window handle of the box to be packed into. |
3859 * item: Window handle of the item to be back. | 3948 * item: Window handle of the item to be back. |
3860 * width: Width in pixels of the item or -1 to be self determined. | 3949 * width: Width in pixels of the item or -1 to be self determined. |
3861 * height: Height in pixels of the item or -1 to be self determined. | 3950 * height: Height in pixels of the item or -1 to be self determined. |
3862 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. | 3951 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. |
3863 * vsize: TRUE if the window (widget) should expand vertically to fill space given. | 3952 * vsize: TRUE if the window (widget) should expand vertically to fill space given. |
3864 * pad: Number of pixels of padding around the item. | 3953 * pad: Number of pixels of padding around the item. |
3865 */ | 3954 */ |
3866 void dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | 3955 void dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) |
3867 { | 3956 { |
3868 Box *thisbox; | 3957 Box *thisbox; |
3869 | 3958 |
3870 thisbox = (Box *)GetWindowLong(box, GWL_USERDATA); | 3959 if(WinWindowFromID(box, FID_CLIENT)) |
3960 { | |
3961 box = WinWindowFromID(box, FID_CLIENT); | |
3962 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
3963 } | |
3964 else | |
3965 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
3966 if(thisbox) | |
3967 { | |
3968 if(thisbox->type == BOXHORZ) | |
3969 dw_box_pack_start_stub(box, item, width, height, hsize, vsize, pad); | |
3970 else | |
3971 dw_box_pack_end_stub(box, item, width, height, hsize, vsize, pad); | |
3972 } | |
3973 } | |
3974 | |
3975 void dw_box_pack_end_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | |
3976 { | |
3977 HWND boxowner = NULLHANDLE; | |
3978 Box *thisbox; | |
3979 | |
3980 if(WinWindowFromID(box, FID_CLIENT)) | |
3981 { | |
3982 box = WinWindowFromID(box, FID_CLIENT); | |
3983 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
3984 hsize = TRUE; | |
3985 vsize = TRUE; | |
3986 } | |
3987 else | |
3988 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
3989 if(!thisbox) | |
3990 { | |
3991 box = WinWindowFromID(box, FID_CLIENT); | |
3992 if(box) | |
3993 { | |
3994 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
3995 hsize = TRUE; | |
3996 vsize = TRUE; | |
3997 } | |
3998 } | |
3871 if(thisbox) | 3999 if(thisbox) |
3872 { | 4000 { |
3873 int z; | 4001 int z; |
3874 Item *tmpitem, *thisitem = thisbox->items; | 4002 Item *tmpitem, *thisitem = thisbox->items; |
3875 char tmpbuf[100]; | 4003 char tmpbuf[100]; |
3879 for(z=0;z<thisbox->count;z++) | 4007 for(z=0;z<thisbox->count;z++) |
3880 { | 4008 { |
3881 tmpitem[z] = thisitem[z]; | 4009 tmpitem[z] = thisitem[z]; |
3882 } | 4010 } |
3883 | 4011 |
3884 GetClassName(item, tmpbuf, 99); | 4012 WinQueryClassName(item, 99, tmpbuf); |
3885 | 4013 |
3886 if(strnicmp(tmpbuf, FRAMECLASSNAME, 2)==0) | 4014 if(strncmp(tmpbuf, "#1", 3)==0) |
3887 tmpitem[thisbox->count].type = TYPEBOX; | 4015 tmpitem[thisbox->count].type = TYPEBOX; |
3888 else | 4016 else |
3889 tmpitem[thisbox->count].type = TYPEITEM; | 4017 tmpitem[thisbox->count].type = TYPEITEM; |
3890 | 4018 |
3891 tmpitem[thisbox->count].hwnd = item; | 4019 tmpitem[thisbox->count].hwnd = item; |
3907 if(thisbox->count) | 4035 if(thisbox->count) |
3908 free(thisitem); | 4036 free(thisitem); |
3909 | 4037 |
3910 thisbox->count++; | 4038 thisbox->count++; |
3911 | 4039 |
3912 SetParent(item, box); | 4040 /* Don't set the ownership if it's an entryfield or spinbutton */ |
3913 ShowWindow(item, SW_SHOW); | 4041 WinQueryClassName(item, 99, tmpbuf); |
3914 if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) | 4042 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) |
3915 { | 4043 { |
3916 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(item, GWL_USERDATA); | 4044 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0) |
3917 | 4045 WinSetOwner(item, boxowner); |
3918 if(cinfo) | 4046 else |
3919 { | 4047 WinSetOwner(item, box); |
3920 SetParent(cinfo->buddy, box); | |
3921 ShowWindow(cinfo->buddy, SW_SHOW); | |
3922 SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0); | |
3923 } | |
3924 } | 4048 } |
4049 WinSetParent(item, box, FALSE); | |
3925 } | 4050 } |
3926 } | 4051 } |
3927 | 4052 |
3928 /* | 4053 /* |
3929 * Sets the size of a given window (widget). | 4054 * Sets the size of a given window (widget). |
3932 * width: New width in pixels. | 4057 * width: New width in pixels. |
3933 * height: New height in pixels. | 4058 * height: New height in pixels. |
3934 */ | 4059 */ |
3935 void dw_window_set_usize(HWND handle, ULONG width, ULONG height) | 4060 void dw_window_set_usize(HWND handle, ULONG width, ULONG height) |
3936 { | 4061 { |
3937 SetWindowPos(handle, (HWND)NULL, 0, 0, width, height, SWP_SHOWWINDOW | SWP_NOZORDER | SWP_NOMOVE); | 4062 WinSetWindowPos(handle, NULLHANDLE, 0, 0, width, height, SWP_SHOW | SWP_SIZE); |
3938 } | 4063 } |
3939 | 4064 |
3940 /* | 4065 /* |
3941 * Returns the width of the screen. | 4066 * Returns the width of the screen. |
3942 */ | 4067 */ |
3943 int dw_screen_width(void) | 4068 int dw_screen_width(void) |
3944 { | 4069 { |
3945 return GetSystemMetrics(SM_CXSCREEN); | 4070 return WinQuerySysValue(HWND_DESKTOP,SV_CXSCREEN); |
3946 } | 4071 } |
3947 | 4072 |
3948 /* | 4073 /* |
3949 * Returns the height of the screen. | 4074 * Returns the height of the screen. |
3950 */ | 4075 */ |
3951 int dw_screen_height(void) | 4076 int dw_screen_height(void) |
3952 { | 4077 { |
3953 return GetSystemMetrics(SM_CYSCREEN); | 4078 return WinQuerySysValue(HWND_DESKTOP,SV_CYSCREEN); |
3954 } | 4079 } |
3955 | 4080 |
3956 /* This should return the current color depth */ | 4081 /* This should return the current color depth */ |
3957 unsigned long dw_color_depth(void) | 4082 unsigned long dw_color_depth(void) |
3958 { | 4083 { |
3959 int bpp; | 4084 HDC hdc = WinOpenWindowDC(HWND_DESKTOP); |
3960 HDC hdc = GetDC(HWND_DESKTOP); | 4085 long colors; |
3961 | 4086 |
3962 bpp = GetDeviceCaps(hdc, BITSPIXEL); | 4087 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, &colors); |
3963 | 4088 DevCloseDC(hdc); |
3964 ReleaseDC(HWND_DESKTOP, hdc); | 4089 return colors; |
3965 | |
3966 return bpp; | |
3967 } | 4090 } |
3968 | 4091 |
3969 | 4092 |
3970 /* | 4093 /* |
3971 * Sets the position of a given window (widget). | 4094 * Sets the position of a given window (widget). |
3974 * x: X location from the bottom left. | 4097 * x: X location from the bottom left. |
3975 * y: Y location from the bottom left. | 4098 * y: Y location from the bottom left. |
3976 */ | 4099 */ |
3977 void dw_window_set_pos(HWND handle, ULONG x, ULONG y) | 4100 void dw_window_set_pos(HWND handle, ULONG x, ULONG y) |
3978 { | 4101 { |
3979 SetWindowPos(handle, (HWND)NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); | 4102 int myy = _get_frame_height(handle) - (y + _get_height(handle)); |
4103 | |
4104 WinSetWindowPos(handle, NULLHANDLE, x, myy, 0, 0, SWP_MOVE); | |
3980 } | 4105 } |
3981 | 4106 |
3982 /* | 4107 /* |
3983 * Sets the position and size of a given window (widget). | 4108 * Sets the position and size of a given window (widget). |
3984 * Parameters: | 4109 * Parameters: |
3988 * width: Width of the widget. | 4113 * width: Width of the widget. |
3989 * height: Height of the widget. | 4114 * height: Height of the widget. |
3990 */ | 4115 */ |
3991 void dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height) | 4116 void dw_window_set_pos_size(HWND handle, ULONG x, ULONG y, ULONG width, ULONG height) |
3992 { | 4117 { |
3993 SetWindowPos(handle, (HWND)NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE); | 4118 int myy = _get_frame_height(handle) - (y + height); |
4119 | |
4120 WinSetWindowPos(handle, NULLHANDLE, x, myy, width, height, SWP_MOVE | SWP_SIZE | SWP_SHOW); | |
3994 } | 4121 } |
3995 | 4122 |
3996 /* | 4123 /* |
3997 * Gets the position and size of a given window (widget). | 4124 * Gets the position and size of a given window (widget). |
3998 * Parameters: | 4125 * Parameters: |
4002 * width: Width of the widget. | 4129 * width: Width of the widget. |
4003 * height: Height of the widget. | 4130 * height: Height of the widget. |
4004 */ | 4131 */ |
4005 void dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height) | 4132 void dw_window_get_pos_size(HWND handle, ULONG *x, ULONG *y, ULONG *width, ULONG *height) |
4006 { | 4133 { |
4007 WINDOWPLACEMENT wp; | 4134 SWP swp; |
4008 | 4135 WinQueryWindowPos(handle, &swp); |
4009 wp.length = sizeof(WINDOWPLACEMENT); | |
4010 | |
4011 GetWindowPlacement(handle, &wp); | |
4012 if(x) | 4136 if(x) |
4013 *x = wp.rcNormalPosition.left; | 4137 *x = swp.x; |
4014 if(y) | 4138 if(y) |
4015 *y = wp.rcNormalPosition.top; | 4139 *y = _get_frame_height(handle) - (swp.y + swp.cy); |
4016 if(width) | 4140 if(width) |
4017 *width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; | 4141 *width = swp.cx; |
4018 if(height) | 4142 if(height) |
4019 *height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; | 4143 *height = swp.cy; |
4020 | |
4021 } | 4144 } |
4022 | 4145 |
4023 /* | 4146 /* |
4024 * Sets the style of a given window (widget). | 4147 * Sets the style of a given window (widget). |
4025 * Parameters: | 4148 * Parameters: |
4027 * width: New width in pixels. | 4150 * width: New width in pixels. |
4028 * height: New height in pixels. | 4151 * height: New height in pixels. |
4029 */ | 4152 */ |
4030 void dw_window_set_style(HWND handle, ULONG style, ULONG mask) | 4153 void dw_window_set_style(HWND handle, ULONG style, ULONG mask) |
4031 { | 4154 { |
4032 ULONG tmp, currentstyle = GetWindowLong(handle, GWL_STYLE); | 4155 WinSetWindowBits(handle, QWL_STYLE, style, mask); |
4033 | |
4034 tmp = currentstyle | mask; | |
4035 tmp ^= mask; | |
4036 tmp |= style; | |
4037 | |
4038 SetWindowLong(handle, GWL_STYLE, tmp); | |
4039 } | |
4040 | |
4041 /* Finds the physical ID from the reference ID */ | |
4042 int _findnotebookid(NotebookPage **array, int pageid) | |
4043 { | |
4044 int z; | |
4045 | |
4046 for(z=0;z<256;z++) | |
4047 { | |
4048 if(array[z] && array[z]->realid == pageid) | |
4049 return z; | |
4050 } | |
4051 return -1; | |
4052 } | 4156 } |
4053 | 4157 |
4054 /* | 4158 /* |
4055 * Adds a new page to specified notebook. | 4159 * Adds a new page to specified notebook. |
4056 * Parameters: | 4160 * Parameters: |
4058 * flags: Any additional page creation flags. | 4162 * flags: Any additional page creation flags. |
4059 * front: If TRUE page is added at the beginning. | 4163 * front: If TRUE page is added at the beginning. |
4060 */ | 4164 */ |
4061 ULONG dw_notebook_page_new(HWND handle, ULONG flags, int front) | 4165 ULONG dw_notebook_page_new(HWND handle, ULONG flags, int front) |
4062 { | 4166 { |
4063 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | 4167 if(front) |
4064 | 4168 return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L, |
4065 if(array) | 4169 MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), BKA_FIRST)); |
4066 { | 4170 return (ULONG)WinSendMsg(handle, BKM_INSERTPAGE, 0L, |
4067 int z, refid = -1; | 4171 MPFROM2SHORT((BKA_STATUSTEXTON | BKA_AUTOPAGESIZE | BKA_MAJOR | flags), BKA_LAST)); |
4068 | 4172 } |
4069 for(z=0;z<256;z++) | 4173 |
4070 { | 4174 /* |
4071 if(_findnotebookid(array, z) == -1) | 4175 * Remove a page from a notebook. |
4072 { | 4176 * Parameters: |
4073 refid = z; | 4177 * handle: Handle to the notebook widget. |
4074 break; | 4178 * pageid: ID of the page to be destroyed. |
4075 } | 4179 */ |
4076 } | 4180 void dw_notebook_page_destroy(HWND handle, unsigned int pageid) |
4077 | 4181 { |
4078 if(refid == -1) | 4182 WinSendMsg(handle, BKM_DELETEPAGE, |
4079 return -1; | 4183 MPFROMLONG(pageid), (MPARAM)BKA_SINGLE); |
4080 | 4184 } |
4081 for(z=0;z<256;z++) | 4185 |
4082 { | 4186 /* |
4083 if(!array[z]) | 4187 * Queries the currently visible page ID. |
4084 { | 4188 * Parameters: |
4085 int oldpage = TabCtrl_GetCurSel(handle); | 4189 * handle: Handle to the notebook widget. |
4086 | 4190 */ |
4087 array[z] = calloc(1, sizeof(NotebookPage)); | 4191 unsigned int dw_notebook_page_query(HWND handle) |
4088 array[z]->realid = refid; | 4192 { |
4089 array[z]->item.mask = TCIF_TEXT; | 4193 return (int)WinSendMsg(handle, BKM_QUERYPAGEID,0L, MPFROM2SHORT(BKA_TOP, BKA_MAJOR)); |
4090 array[z]->item.iImage = -1; | 4194 } |
4091 array[z]->item.pszText = ""; | 4195 |
4092 TabCtrl_InsertItem(handle, z, &(array[z]->item)); | 4196 /* |
4093 | 4197 * Sets the currently visibale page ID. |
4094 if(oldpage > -1 && array[oldpage]) | 4198 * Parameters: |
4095 SetParent(array[oldpage]->hwnd, DW_HWND_OBJECT); | 4199 * handle: Handle to the notebook widget. |
4096 | 4200 * pageid: ID of the page to be made visible. |
4097 TabCtrl_SetCurSel(handle, z); | 4201 */ |
4098 return refid; | 4202 void dw_notebook_page_set(HWND handle, unsigned int pageid) |
4099 } | 4203 { |
4100 } | 4204 WinSendMsg(handle, BKM_TURNTOPAGE, MPFROMLONG(pageid), 0L); |
4101 } | |
4102 return -1; | |
4103 } | 4205 } |
4104 | 4206 |
4105 /* | 4207 /* |
4106 * Sets the text on the specified notebook tab. | 4208 * Sets the text on the specified notebook tab. |
4107 * Parameters: | 4209 * Parameters: |
4108 * handle: Notebook handle. | 4210 * handle: Notebook handle. |
4109 * pageid: Page ID of the tab to set. | 4211 * pageid: Page ID of the tab to set. |
4110 * text: Pointer to the text to set. | 4212 * text: Pointer to the text to set. |
4111 */ | 4213 */ |
4112 void dw_notebook_page_set_text(HWND handle, ULONG pageidx, char *text) | 4214 void dw_notebook_page_set_text(HWND handle, ULONG pageid, char *text) |
4113 { | 4215 { |
4114 | 4216 WinSendMsg(handle, BKM_SETTABTEXT, |
4115 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | 4217 MPFROMLONG(pageid), MPFROMP(text)); |
4116 int pageid; | |
4117 | |
4118 if(!array) | |
4119 return; | |
4120 | |
4121 pageid = _findnotebookid(array, pageidx); | |
4122 | |
4123 if(pageid > -1 && array[pageid]) | |
4124 { | |
4125 array[pageid]->item.mask = TCIF_TEXT; | |
4126 array[pageid]->item.pszText = text; | |
4127 TabCtrl_SetItem(handle, pageid, &(array[pageid]->item)); | |
4128 _resize_notebook_page(handle, pageid); | |
4129 } | |
4130 } | 4218 } |
4131 | 4219 |
4132 /* | 4220 /* |
4133 * Sets the text on the specified notebook tab status area. | 4221 * Sets the text on the specified notebook tab status area. |
4134 * Parameters: | 4222 * Parameters: |
4136 * pageid: Page ID of the tab to set. | 4224 * pageid: Page ID of the tab to set. |
4137 * text: Pointer to the text to set. | 4225 * text: Pointer to the text to set. |
4138 */ | 4226 */ |
4139 void dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text) | 4227 void dw_notebook_page_set_status_text(HWND handle, ULONG pageid, char *text) |
4140 { | 4228 { |
4229 WinSendMsg(handle, BKM_SETSTATUSLINETEXT, | |
4230 MPFROMLONG(pageid), MPFROMP(text)); | |
4141 } | 4231 } |
4142 | 4232 |
4143 /* | 4233 /* |
4144 * Packs the specified box into the notebook page. | 4234 * Packs the specified box into the notebook page. |
4145 * Parameters: | 4235 * Parameters: |
4146 * handle: Handle to the notebook to be packed. | 4236 * handle: Handle to the notebook to be packed. |
4147 * pageid: Page ID in the notebook which is being packed. | 4237 * pageid: Page ID in the notebook which is being packed. |
4148 * page: Box handle to be packed. | 4238 * page: Box handle to be packed. |
4149 */ | 4239 */ |
4150 void dw_notebook_pack(HWND handle, ULONG pageidx, HWND page) | 4240 void dw_notebook_pack(HWND handle, ULONG pageid, HWND page) |
4151 { | 4241 { |
4152 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | 4242 HWND tmpbox = dw_box_new(BOXVERT, 0); |
4153 int pageid; | 4243 |
4154 | 4244 dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0); |
4155 if(!array) | 4245 WinSubclassWindow(tmpbox, _wndproc); |
4156 return; | 4246 WinSendMsg(handle, BKM_SETPAGEWINDOWHWND, |
4157 | 4247 MPFROMLONG(pageid), MPFROMHWND(tmpbox)); |
4158 pageid = _findnotebookid(array, pageidx); | |
4159 | |
4160 if(pageid > -1 && array[pageid]) | |
4161 { | |
4162 HWND tmpbox = dw_box_new(BOXVERT, 0); | |
4163 | |
4164 dw_box_pack_start(tmpbox, page, 0, 0, TRUE, TRUE, 0); | |
4165 SubclassWindow(tmpbox, _wndproc); | |
4166 if(array[pageid]->hwnd) | |
4167 dw_window_destroy(array[pageid]->hwnd); | |
4168 array[pageid]->hwnd = tmpbox; | |
4169 if(pageidx == dw_notebook_page_query(handle)) | |
4170 { | |
4171 SetParent(tmpbox, handle); | |
4172 _resize_notebook_page(handle, pageid); | |
4173 } | |
4174 } | |
4175 } | |
4176 | |
4177 /* | |
4178 * Remove a page from a notebook. | |
4179 * Parameters: | |
4180 * handle: Handle to the notebook widget. | |
4181 * pageid: ID of the page to be destroyed. | |
4182 */ | |
4183 void dw_notebook_page_destroy(HWND handle, unsigned int pageidx) | |
4184 { | |
4185 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | |
4186 int newid = -1, z, pageid; | |
4187 | |
4188 if(!array) | |
4189 return; | |
4190 | |
4191 pageid = _findnotebookid(array, pageidx); | |
4192 | |
4193 if(pageid < 0) | |
4194 return; | |
4195 | |
4196 if(array[pageid]) | |
4197 { | |
4198 SetParent(array[pageid]->hwnd, DW_HWND_OBJECT); | |
4199 free(array[pageid]); | |
4200 array[pageid] = NULL; | |
4201 } | |
4202 | |
4203 TabCtrl_DeleteItem(handle, pageid); | |
4204 | |
4205 /* Shift the pages over 1 */ | |
4206 for(z=pageid;z<255;z++) | |
4207 array[z] = array[z+1]; | |
4208 array[255] = NULL; | |
4209 | |
4210 for(z=0;z<256;z++) | |
4211 { | |
4212 if(array[z]) | |
4213 { | |
4214 newid = z; | |
4215 break; | |
4216 } | |
4217 } | |
4218 if(newid > -1) | |
4219 { | |
4220 SetParent(array[newid]->hwnd, handle); | |
4221 _resize_notebook_page(handle, newid); | |
4222 dw_notebook_page_set(handle, array[newid]->realid); | |
4223 } | |
4224 } | |
4225 | |
4226 /* | |
4227 * Queries the currently visible page ID. | |
4228 * Parameters: | |
4229 * handle: Handle to the notebook widget. | |
4230 */ | |
4231 unsigned int dw_notebook_page_query(HWND handle) | |
4232 { | |
4233 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | |
4234 int physid = TabCtrl_GetCurSel(handle); | |
4235 | |
4236 if(physid > -1 && physid < 256 && array && array[physid]) | |
4237 return array[physid]->realid; | |
4238 return -1; | |
4239 } | |
4240 | |
4241 /* | |
4242 * Sets the currently visible page ID. | |
4243 * Parameters: | |
4244 * handle: Handle to the notebook widget. | |
4245 * pageid: ID of the page to be made visible. | |
4246 */ | |
4247 void dw_notebook_page_set(HWND handle, unsigned int pageidx) | |
4248 { | |
4249 NotebookPage **array = (NotebookPage **)GetWindowLong(handle, GWL_USERDATA); | |
4250 int pageid; | |
4251 | |
4252 if(!array) | |
4253 return; | |
4254 | |
4255 pageid = _findnotebookid(array, pageidx); | |
4256 | |
4257 if(pageid > -1 && pageid < 256) | |
4258 { | |
4259 int oldpage = TabCtrl_GetCurSel(handle); | |
4260 | |
4261 if(oldpage > -1 && array && array[oldpage]) | |
4262 SetParent(array[oldpage]->hwnd, DW_HWND_OBJECT); | |
4263 | |
4264 TabCtrl_SetCurSel(handle, pageid); | |
4265 | |
4266 SetParent(array[pageid]->hwnd, handle); | |
4267 _resize_notebook_page(handle, pageid); | |
4268 } | |
4269 } | 4248 } |
4270 | 4249 |
4271 /* | 4250 /* |
4272 * Appends the specified text to the listbox's (or combobox) entry list. | 4251 * Appends the specified text to the listbox's (or combobox) entry list. |
4273 * Parameters: | 4252 * Parameters: |
4274 * handle: Handle to the listbox to be appended to. | 4253 * handle: Handle to the listbox to be appended to. |
4275 * text: Text to append into listbox. | 4254 * text: Text to append into listbox. |
4276 */ | 4255 */ |
4277 void dw_listbox_append(HWND handle, char *text) | 4256 void dw_listbox_append(HWND handle, char *text) |
4278 { | 4257 { |
4279 char tmpbuf[100]; | 4258 WinSendMsg(handle, |
4280 | 4259 LM_INSERTITEM, |
4281 GetClassName(handle, tmpbuf, 99); | 4260 MPFROMSHORT(LIT_END), |
4282 | 4261 MPFROMP(text)); |
4283 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | |
4284 SendMessage(handle, | |
4285 CB_ADDSTRING, | |
4286 0, (LPARAM)text); | |
4287 else | |
4288 SendMessage(handle, | |
4289 LB_ADDSTRING, | |
4290 0, (LPARAM)text); | |
4291 } | 4262 } |
4292 | 4263 |
4293 /* | 4264 /* |
4294 * Clears the listbox's (or combobox) list of all entries. | 4265 * Clears the listbox's (or combobox) list of all entries. |
4295 * Parameters: | 4266 * Parameters: |
4296 * handle: Handle to the listbox to be cleared. | 4267 * handle: Handle to the listbox to be cleared. |
4297 */ | 4268 */ |
4298 void dw_listbox_clear(HWND handle) | 4269 void dw_listbox_clear(HWND handle) |
4299 { | 4270 { |
4300 char tmpbuf[100]; | 4271 WinSendMsg(handle, |
4301 | 4272 LM_DELETEALL, 0L, 0L); |
4302 GetClassName(handle, tmpbuf, 99); | 4273 } |
4303 | 4274 |
4304 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | 4275 /* |
4305 { | 4276 * Returns the listbox's item count. |
4306 char *buf = dw_window_get_text(handle); | 4277 * Parameters: |
4307 | 4278 * handle: Handle to the listbox to be cleared. |
4308 SendMessage(handle, | 4279 */ |
4309 CB_RESETCONTENT, 0L, 0L); | 4280 int dw_listbox_count(HWND handle) |
4310 | 4281 { |
4311 if(buf) | 4282 return (int)WinSendMsg(handle, |
4312 { | 4283 LM_QUERYITEMCOUNT,0L, 0L); |
4313 dw_window_set_text(handle, buf); | 4284 } |
4314 free(buf); | 4285 |
4315 } | 4286 /* |
4316 } | 4287 * Sets the topmost item in the viewport. |
4317 else | 4288 * Parameters: |
4318 SendMessage(handle, | 4289 * handle: Handle to the listbox to be cleared. |
4319 LB_RESETCONTENT, 0L, 0L); | 4290 * top: Index to the top item. |
4320 } | 4291 */ |
4321 | 4292 void dw_listbox_set_top(HWND handle, int top) |
4322 /* | 4293 { |
4323 * Sets the text of a given listbox entry. | 4294 WinSendMsg(handle, |
4324 * Parameters: | 4295 LM_SETTOPINDEX, |
4325 * handle: Handle to the listbox to be queried. | 4296 MPFROMSHORT(top), |
4326 * index: Index into the list to be queried. | 4297 0L); |
4327 * buffer: Buffer where text will be copied. | |
4328 */ | |
4329 void dw_listbox_set_text(HWND handle, unsigned int index, char *buffer) | |
4330 { | |
4331 unsigned int sel = (unsigned int)SendMessage(handle, LB_GETCURSEL, 0, 0); | |
4332 SendMessage(handle, LB_DELETESTRING, (WPARAM)index, 0); | |
4333 SendMessage(handle, LB_INSERTSTRING, (WPARAM)index, (LPARAM)buffer); | |
4334 SendMessage(handle, LB_SETCURSEL, (WPARAM)sel, 0); | |
4335 SendMessage(handle, LB_SETSEL, (WPARAM)TRUE, (LPARAM)sel); | |
4336 } | 4298 } |
4337 | 4299 |
4338 /* | 4300 /* |
4339 * Copies the given index item's text into buffer. | 4301 * Copies the given index item's text into buffer. |
4340 * Parameters: | 4302 * Parameters: |
4343 * buffer: Buffer where text will be copied. | 4305 * buffer: Buffer where text will be copied. |
4344 * length: Length of the buffer (including NULL). | 4306 * length: Length of the buffer (including NULL). |
4345 */ | 4307 */ |
4346 void dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length) | 4308 void dw_listbox_query_text(HWND handle, unsigned int index, char *buffer, unsigned int length) |
4347 { | 4309 { |
4348 SendMessage(handle, | 4310 WinSendMsg(handle, LM_QUERYITEMTEXT, MPFROM2SHORT(index, length), (MPARAM)buffer); |
4349 LB_GETTEXT, (WPARAM)index, (LPARAM)buffer); | 4311 } |
4312 | |
4313 /* | |
4314 * Sets the text of a given listbox entry. | |
4315 * Parameters: | |
4316 * handle: Handle to the listbox to be queried. | |
4317 * index: Index into the list to be queried. | |
4318 * buffer: Buffer where text will be copied. | |
4319 */ | |
4320 void dw_listbox_set_text(HWND handle, unsigned int index, char *buffer) | |
4321 { | |
4322 WinSendMsg(handle, LM_SETITEMTEXT, MPFROMSHORT(index), (MPARAM)buffer); | |
4350 } | 4323 } |
4351 | 4324 |
4352 /* | 4325 /* |
4353 * Returns the index to the item in the list currently selected. | 4326 * Returns the index to the item in the list currently selected. |
4354 * Parameters: | 4327 * Parameters: |
4355 * handle: Handle to the listbox to be queried. | 4328 * handle: Handle to the listbox to be queried. |
4356 */ | 4329 */ |
4357 unsigned int dw_listbox_selected(HWND handle) | 4330 unsigned int dw_listbox_selected(HWND handle) |
4358 { | 4331 { |
4359 char tmpbuf[100]; | 4332 return (unsigned int)WinSendMsg(handle, |
4360 | 4333 LM_QUERYSELECTION, |
4361 GetClassName(handle, tmpbuf, 99); | 4334 MPFROMSHORT(LIT_CURSOR), |
4362 | 4335 0); |
4363 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | |
4364 return (unsigned int)SendMessage(handle, | |
4365 CB_GETCURSEL, | |
4366 0, 0); | |
4367 | |
4368 return (unsigned int)SendMessage(handle, | |
4369 LB_GETCURSEL, | |
4370 0, 0); | |
4371 } | 4336 } |
4372 | 4337 |
4373 /* | 4338 /* |
4374 * Returns the index to the current selected item or -1 when done. | 4339 * Returns the index to the current selected item or -1 when done. |
4375 * Parameters: | 4340 * Parameters: |
4376 * handle: Handle to the listbox to be queried. | 4341 * handle: Handle to the listbox to be queried. |
4377 * where: Either the previous return or -1 to restart. | 4342 * where: Either the previous return or -1 to restart. |
4378 */ | 4343 */ |
4379 int dw_listbox_selected_multi(HWND handle, int where) | 4344 int dw_listbox_selected_multi(HWND handle, int where) |
4380 { | 4345 { |
4381 int *array, count, z; | 4346 int place = where; |
4382 | 4347 |
4383 count = (int)SendMessage(handle, LB_GETSELCOUNT, 0, 0); | 4348 if(where == -1) |
4384 if(count > 0) | 4349 place = LIT_FIRST; |
4385 { | 4350 |
4386 array = malloc(sizeof(int)*count); | 4351 place = (int)WinSendMsg(handle, |
4387 SendMessage(handle, LB_GETSELITEMS, (WPARAM)count, (LPARAM)array); | 4352 LM_QUERYSELECTION, |
4388 | 4353 MPFROMSHORT(place),0L); |
4389 if(where == -1) | 4354 if(place == LIT_NONE) |
4390 { | 4355 return -1; |
4391 int ret = array[0]; | 4356 return place; |
4392 free(array); | |
4393 return ret; | |
4394 } | |
4395 for(z=0;z<count;z++) | |
4396 { | |
4397 if(array[z] == where && (z+1) < count) | |
4398 { | |
4399 int ret = array[z+1]; | |
4400 free(array); | |
4401 return ret; | |
4402 } | |
4403 } | |
4404 free(array); | |
4405 } | |
4406 return -1; | |
4407 } | 4357 } |
4408 | 4358 |
4409 /* | 4359 /* |
4410 * Sets the selection state of a given index. | 4360 * Sets the selection state of a given index. |
4411 * Parameters: | 4361 * Parameters: |
4415 */ | 4365 */ |
4416 void dw_listbox_select(HWND handle, int index, int state) | 4366 void dw_listbox_select(HWND handle, int index, int state) |
4417 { | 4367 { |
4418 char tmpbuf[100]; | 4368 char tmpbuf[100]; |
4419 | 4369 |
4420 GetClassName(handle, tmpbuf, 99); | 4370 WinSendMsg(handle, LM_SELECTITEM, MPFROMSHORT(index), (MPARAM)state); |
4421 | 4371 |
4422 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | 4372 WinQueryClassName(handle, 99, tmpbuf); |
4423 SendMessage(handle, CB_SETCURSEL, (WPARAM)index, 0); | 4373 |
4424 else | 4374 /* If we are setting a combobox call the event handler manually */ |
4425 { | 4375 if(strncmp(tmpbuf, "#6", 3)==0) |
4426 SendMessage(handle, LB_SETCURSEL, (WPARAM)index, 0); | 4376 _run_event(handle, WM_CONTROL, MPFROM2SHORT(0, LN_SELECT), (MPARAM)handle); |
4427 SendMessage(handle, LB_SETSEL, (WPARAM)state, (LPARAM)index); | |
4428 } | |
4429 _wndproc(handle, WM_COMMAND, (WPARAM)(LBN_SELCHANGE << 16), (LPARAM)handle); | |
4430 } | 4377 } |
4431 | 4378 |
4432 /* | 4379 /* |
4433 * Deletes the item with given index from the list. | 4380 * Deletes the item with given index from the list. |
4434 * Parameters: | 4381 * Parameters: |
4435 * handle: Handle to the listbox to be set. | 4382 * handle: Handle to the listbox to be set. |
4436 * index: Item index. | 4383 * index: Item index. |
4437 */ | 4384 */ |
4438 void dw_listbox_delete(HWND handle, int index) | 4385 void dw_listbox_delete(HWND handle, int index) |
4439 { | 4386 { |
4440 SendMessage(handle, LB_DELETESTRING, (WPARAM)index, 0); | 4387 WinSendMsg(handle, LM_DELETEITEM, MPFROMSHORT(index), 0); |
4441 } | 4388 } |
4442 | 4389 |
4443 /* | |
4444 * Returns the listbox's item count. | |
4445 * Parameters: | |
4446 * handle: Handle to the listbox to be cleared. | |
4447 */ | |
4448 int dw_listbox_count(HWND handle) | |
4449 { | |
4450 char tmpbuf[100]; | |
4451 | |
4452 GetClassName(handle, tmpbuf, 99); | |
4453 | |
4454 if(strnicmp(tmpbuf, COMBOBOXCLASSNAME, strlen(COMBOBOXCLASSNAME))==0) | |
4455 return (int)SendMessage(handle, | |
4456 CB_GETCOUNT,0L, 0L); | |
4457 | |
4458 return (int)SendMessage(handle, | |
4459 LB_GETCOUNT,0L, 0L); | |
4460 } | |
4461 | |
4462 /* | |
4463 * Sets the topmost item in the viewport. | |
4464 * Parameters: | |
4465 * handle: Handle to the listbox to be cleared. | |
4466 * top: Index to the top item. | |
4467 */ | |
4468 void dw_listbox_set_top(HWND handle, int top) | |
4469 { | |
4470 SendMessage(handle, LB_SETTOPINDEX, (WPARAM)top, 0); | |
4471 } | |
4472 | |
4473 #define MLE_MAX 200000 | |
4474 /* | 4390 /* |
4475 * Adds text to an MLE box and returns the current point. | 4391 * Adds text to an MLE box and returns the current point. |
4476 * Parameters: | 4392 * Parameters: |
4477 * handle: Handle to the MLE to be queried. | 4393 * handle: Handle to the MLE to be queried. |
4478 * buffer: Text buffer to be imported. | 4394 * buffer: Text buffer to be imported. |
4479 * startpoint: Point to start entering text. | 4395 * startpoint: Point to start entering text. |
4480 */ | 4396 */ |
4481 unsigned int dw_mle_import(HWND handle, char *buffer, int startpoint) | 4397 unsigned int dw_mle_import(HWND handle, char *buffer, int startpoint) |
4482 { | 4398 { |
4483 char *tmpbuf = calloc(1, MLE_MAX+1); | 4399 unsigned long point = startpoint; |
4484 int len; | 4400 PBYTE mlebuf; |
4485 | 4401 |
4486 if(strlen(buffer) < 1) | 4402 /* Work around 64K limit */ |
4487 return startpoint; | 4403 if(!DosAllocMem((PPVOID) &mlebuf, 65536, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) |
4488 | 4404 { |
4489 startpoint++; | 4405 int amount, len = strlen(buffer), written = 0; |
4490 | 4406 |
4491 if(startpoint < 0) | 4407 while(written < len) |
4492 startpoint = 0; | 4408 { |
4493 | 4409 if((len - written) > 65535) |
4494 GetWindowText(handle, tmpbuf, MLE_MAX); | 4410 amount = 65535; |
4495 | 4411 else |
4496 len = strlen(tmpbuf); | 4412 amount = len - written; |
4497 if(len) | 4413 |
4498 { | 4414 memcpy(mlebuf, &buffer[written], amount); |
4499 char *dest = &tmpbuf[startpoint+strlen(buffer)-1], *start = &tmpbuf[startpoint]; | 4415 mlebuf[amount] = '\0'; |
4500 int copylen = len - startpoint; | 4416 |
4501 | 4417 WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount+1)); |
4502 if(copylen > 0) | 4418 WinSendMsg(handle, MLM_IMPORT, MPFROMP(&point), MPFROMLONG(amount + 1)); |
4503 memcpy(dest, start, copylen); | 4419 dw_mle_delete(handle, point, 1); |
4504 } | 4420 |
4505 memcpy(&tmpbuf[startpoint], buffer, strlen(buffer)); | 4421 written += amount; |
4506 | 4422 } |
4507 SetWindowText(handle, tmpbuf); | 4423 DosFreeMem(mlebuf); |
4508 | 4424 } |
4509 free(tmpbuf); | 4425 return point - 1; |
4510 return startpoint+strlen(buffer) - 1; | |
4511 } | 4426 } |
4512 | 4427 |
4513 /* | 4428 /* |
4514 * Grabs text from an MLE box. | 4429 * Grabs text from an MLE box. |
4515 * Parameters: | 4430 * Parameters: |
4518 * startpoint: Point to start grabbing text. | 4433 * startpoint: Point to start grabbing text. |
4519 * length: Amount of text to be grabbed. | 4434 * length: Amount of text to be grabbed. |
4520 */ | 4435 */ |
4521 void dw_mle_export(HWND handle, char *buffer, int startpoint, int length) | 4436 void dw_mle_export(HWND handle, char *buffer, int startpoint, int length) |
4522 { | 4437 { |
4523 char *tmpbuf = malloc(MLE_MAX+1); | 4438 PBYTE mlebuf; |
4524 | 4439 |
4525 GetWindowText(handle, tmpbuf, MLE_MAX); | 4440 /* Work around 64K limit */ |
4526 tmpbuf[MLE_MAX] = 0; | 4441 if(!DosAllocMem((PPVOID) &mlebuf, 65535, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_TILE)) |
4527 | 4442 { |
4528 memcpy(buffer, &tmpbuf[startpoint], length); | 4443 int amount, copied, written = 0; |
4529 | 4444 |
4530 free(tmpbuf); | 4445 while(written < length) |
4446 { | |
4447 if((length - written) > 65535) | |
4448 amount = 65535; | |
4449 else | |
4450 amount = length - written; | |
4451 | |
4452 WinSendMsg(handle, MLM_SETIMPORTEXPORT, MPFROMP(mlebuf), MPFROMLONG(amount)); | |
4453 copied = (int)WinSendMsg(handle, MLM_EXPORT, MPFROMP(&startpoint), MPFROMLONG(&amount)); | |
4454 | |
4455 if(copied) | |
4456 { | |
4457 memcpy(&buffer[written], mlebuf, copied); | |
4458 | |
4459 written += copied; | |
4460 } | |
4461 else | |
4462 break; | |
4463 } | |
4464 DosFreeMem(mlebuf); | |
4465 } | |
4531 } | 4466 } |
4532 | 4467 |
4533 /* | 4468 /* |
4534 * Obtains information about an MLE box. | 4469 * Obtains information about an MLE box. |
4535 * Parameters: | 4470 * Parameters: |
4537 * bytes: A pointer to a variable to return the total bytes. | 4472 * bytes: A pointer to a variable to return the total bytes. |
4538 * lines: A pointer to a variable to return the number of lines. | 4473 * lines: A pointer to a variable to return the number of lines. |
4539 */ | 4474 */ |
4540 void dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines) | 4475 void dw_mle_query(HWND handle, unsigned long *bytes, unsigned long *lines) |
4541 { | 4476 { |
4542 char *tmpbuf = malloc(MLE_MAX+1); | |
4543 | |
4544 GetWindowText(handle, tmpbuf, MLE_MAX); | |
4545 tmpbuf[MLE_MAX] = 0; | |
4546 | |
4547 if(bytes) | 4477 if(bytes) |
4548 *bytes = strlen(tmpbuf); | 4478 *bytes = (unsigned long)WinSendMsg(handle, MLM_QUERYTEXTLENGTH, 0, 0); |
4549 if(lines) | 4479 if(lines) |
4550 *lines = (unsigned long)SendMessage(handle, EM_GETLINECOUNT, 0, 0); | 4480 *lines = (unsigned long)WinSendMsg(handle, MLM_QUERYLINECOUNT, 0, 0); |
4551 | |
4552 free(tmpbuf); | |
4553 } | 4481 } |
4554 | 4482 |
4555 /* | 4483 /* |
4556 * Deletes text from an MLE box. | 4484 * Deletes text from an MLE box. |
4557 * Parameters: | 4485 * Parameters: |
4559 * startpoint: Point to start deleting text. | 4487 * startpoint: Point to start deleting text. |
4560 * length: Amount of text to be deleted. | 4488 * length: Amount of text to be deleted. |
4561 */ | 4489 */ |
4562 void dw_mle_delete(HWND handle, int startpoint, int length) | 4490 void dw_mle_delete(HWND handle, int startpoint, int length) |
4563 { | 4491 { |
4564 char *tmpbuf = malloc(MLE_MAX+1); | 4492 char *buf = malloc(length+1); |
4565 int len; | 4493 int z, dellen = length; |
4566 | 4494 |
4567 GetWindowText(handle, tmpbuf, MLE_MAX); | 4495 dw_mle_export(handle, buf, startpoint, length); |
4568 tmpbuf[MLE_MAX] = 0; | 4496 |
4569 | 4497 for(z=0;z<length-1;z++) |
4570 len = strlen(tmpbuf); | 4498 { |
4571 | 4499 if(strncmp(&buf[z], "\r\n", 2) == 0) |
4572 strcpy(&tmpbuf[startpoint], &tmpbuf[startpoint+length]); | 4500 dellen--; |
4573 | 4501 } |
4574 SetWindowText(handle, tmpbuf); | 4502 WinSendMsg(handle, MLM_DELETE, MPFROMLONG(startpoint), MPFROMLONG(dellen)); |
4575 | 4503 free(buf); |
4576 free(tmpbuf); | |
4577 } | 4504 } |
4578 | 4505 |
4579 /* | 4506 /* |
4580 * Clears all text from an MLE box. | 4507 * Clears all text from an MLE box. |
4581 * Parameters: | 4508 * Parameters: |
4582 * handle: Handle to the MLE to be cleared. | 4509 * handle: Handle to the MLE to be cleared. |
4583 */ | 4510 */ |
4584 void dw_mle_clear(HWND handle) | 4511 void dw_mle_clear(HWND handle) |
4585 { | 4512 { |
4586 SetWindowText(handle, ""); | 4513 unsigned long bytes; |
4514 | |
4515 dw_mle_query(handle, &bytes, NULL); | |
4516 | |
4517 WinSendMsg(handle, MLM_DELETE, MPFROMLONG(0), MPFROMLONG(bytes)); | |
4587 } | 4518 } |
4588 | 4519 |
4589 /* | 4520 /* |
4590 * Sets the visible line of an MLE box. | 4521 * Sets the visible line of an MLE box. |
4591 * Parameters: | 4522 * Parameters: |
4592 * handle: Handle to the MLE. | 4523 * handle: Handle to the MLE to be positioned. |
4593 * line: Line to be visible. | 4524 * line: Line to be visible. |
4594 */ | 4525 */ |
4595 void dw_mle_set_visible(HWND handle, int line) | 4526 void dw_mle_set_visible(HWND handle, int line) |
4596 { | 4527 { |
4597 int point = (int)SendMessage(handle, EM_LINEINDEX, (WPARAM)line, 0); | 4528 int tmppnt; |
4598 dw_mle_set(handle, point); | 4529 |
4530 if(line > 10) | |
4531 { | |
4532 tmppnt = (int)WinSendMsg(handle, MLM_CHARFROMLINE, MPFROMLONG(line - 10), 0); | |
4533 WinSendMsg(handle, MLM_SETFIRSTCHAR, MPFROMLONG(tmppnt), 0); | |
4534 } | |
4599 } | 4535 } |
4600 | 4536 |
4601 /* | 4537 /* |
4602 * Sets the editablity of an MLE box. | 4538 * Sets the editablity of an MLE box. |
4603 * Parameters: | 4539 * Parameters: |
4604 * handle: Handle to the MLE. | 4540 * handle: Handle to the MLE. |
4605 * state: TRUE if it can be edited, FALSE for readonly. | 4541 * state: TRUE if it can be edited, FALSE for readonly. |
4606 */ | 4542 */ |
4607 void dw_mle_set_editable(HWND handle, int state) | 4543 void dw_mle_set_editable(HWND handle, int state) |
4608 { | 4544 { |
4609 SendMessage(handle, EM_SETREADONLY, (WPARAM)(state ? FALSE : TRUE), 0); | 4545 WinSendMsg(handle, MLM_SETREADONLY, MPFROMLONG(state ? FALSE : TRUE), 0); |
4610 } | 4546 } |
4611 | 4547 |
4612 /* | 4548 /* |
4613 * Sets the word wrap state of an MLE box. | 4549 * Sets the word wrap state of an MLE box. |
4614 * Parameters: | 4550 * Parameters: |
4615 * handle: Handle to the MLE. | 4551 * handle: Handle to the MLE. |
4616 * state: TRUE if it wraps, FALSE if it doesn't. | 4552 * state: TRUE if it wraps, FALSE if it doesn't. |
4617 */ | 4553 */ |
4618 void dw_mle_set_word_wrap(HWND handle, int state) | 4554 void dw_mle_set_word_wrap(HWND handle, int state) |
4619 { | 4555 { |
4620 /* If ES_AUTOHSCROLL is not set and there is not | 4556 WinSendMsg(handle, MLM_SETWRAP, MPFROMLONG(state), 0); |
4621 * horizontal scrollbar it word wraps. | |
4622 */ | |
4623 if(state) | |
4624 dw_window_set_style(handle, 0, ES_AUTOHSCROLL); | |
4625 else | |
4626 dw_window_set_style(handle, ES_AUTOHSCROLL, ES_AUTOHSCROLL); | |
4627 } | 4557 } |
4628 | 4558 |
4629 /* | 4559 /* |
4630 * Sets the current cursor position of an MLE box. | 4560 * Sets the current cursor position of an MLE box. |
4631 * Parameters: | 4561 * Parameters: |
4632 * handle: Handle to the MLE to be positioned. | 4562 * handle: Handle to the MLE to be positioned. |
4633 * point: Point to position cursor. | 4563 * point: Point to position cursor. |
4634 */ | 4564 */ |
4635 void dw_mle_set(HWND handle, int point) | 4565 void dw_mle_set(HWND handle, int point) |
4636 { | 4566 { |
4637 SendMessage(handle, EM_SETSEL, (WPARAM)point, (LPARAM)point); | 4567 WinSendMsg(handle, MLM_SETSEL, MPFROMLONG(point), MPFROMLONG(point)); |
4638 SendMessage(handle, EM_SCROLLCARET, 0, 0); | |
4639 } | 4568 } |
4640 | 4569 |
4641 /* | 4570 /* |
4642 * Finds text in an MLE box. | 4571 * Finds text in an MLE box. |
4643 * Parameters: | 4572 * Parameters: |
4646 * point: Start point of search. | 4575 * point: Start point of search. |
4647 * flags: Search specific flags. | 4576 * flags: Search specific flags. |
4648 */ | 4577 */ |
4649 int dw_mle_search(HWND handle, char *text, int point, unsigned long flags) | 4578 int dw_mle_search(HWND handle, char *text, int point, unsigned long flags) |
4650 { | 4579 { |
4651 char *tmpbuf = malloc(MLE_MAX+1); | 4580 MLE_SEARCHDATA msd; |
4652 int z, len, textlen, retval = 0; | 4581 |
4653 | 4582 /* This code breaks with structure packing set to 1 (/Sp1 in VAC) |
4654 GetWindowText(handle, tmpbuf, MLE_MAX); | 4583 * if this is needed we need to add a pragma here. |
4655 tmpbuf[MLE_MAX] = 0; | 4584 */ |
4656 | 4585 msd.cb = sizeof(msd); |
4657 len = strlen(tmpbuf); | 4586 msd.pchFind = text; |
4658 textlen = strlen(text); | 4587 msd.pchReplace = NULL; |
4659 | 4588 msd.cchFind = strlen(text); |
4660 if(flags & DW_MLE_CASESENSITIVE) | 4589 msd.cchReplace = 0; |
4661 { | 4590 msd.iptStart = point; |
4662 for(z=point;z<(len-textlen) && !retval;z++) | 4591 msd.iptStop = -1; |
4663 { | 4592 |
4664 if(strncmp(&tmpbuf[z], text, textlen) == 0) | 4593 if(WinSendMsg(handle, MLM_SEARCH, MPFROMLONG(MLFSEARCH_SELECTMATCH | flags), (MPARAM)&msd)) |
4665 retval = z + textlen; | 4594 return (int)WinSendMsg(handle, MLM_QUERYSEL,(MPARAM)MLFQS_MAXSEL, 0); |
4666 } | 4595 return 0; |
4667 } | |
4668 else | |
4669 { | |
4670 for(z=point;z<(len-textlen) && !retval;z++) | |
4671 { | |
4672 if(strnicmp(&tmpbuf[z], text, textlen) == 0) | |
4673 retval = z + textlen; | |
4674 } | |
4675 } | |
4676 | |
4677 if(retval) | |
4678 { | |
4679 SendMessage(handle, EM_SETSEL, (WPARAM)retval - textlen, (LPARAM)retval); | |
4680 SendMessage(handle, EM_SCROLLCARET, 0, 0); | |
4681 } | |
4682 | |
4683 free(tmpbuf); | |
4684 | |
4685 return retval; | |
4686 } | 4596 } |
4687 | 4597 |
4688 /* | 4598 /* |
4689 * Stops redrawing of an MLE box. | 4599 * Stops redrawing of an MLE box. |
4690 * Parameters: | 4600 * Parameters: |
4691 * handle: Handle to the MLE to freeze. | 4601 * handle: Handle to the MLE to freeze. |
4692 */ | 4602 */ |
4693 void dw_mle_freeze(HWND handle) | 4603 void dw_mle_freeze(HWND handle) |
4694 { | 4604 { |
4605 WinSendMsg(handle, MLM_DISABLEREFRESH, 0, 0); | |
4695 } | 4606 } |
4696 | 4607 |
4697 /* | 4608 /* |
4698 * Resumes redrawing of an MLE box. | 4609 * Resumes redrawing of an MLE box. |
4699 * Parameters: | 4610 * Parameters: |
4700 * handle: Handle to the MLE to thaw. | 4611 * handle: Handle to the MLE to thaw. |
4701 */ | 4612 */ |
4702 void dw_mle_thaw(HWND handle) | 4613 void dw_mle_thaw(HWND handle) |
4703 { | 4614 { |
4615 WinSendMsg(handle, MLM_ENABLEREFRESH, 0, 0); | |
4704 } | 4616 } |
4705 | 4617 |
4706 /* | 4618 /* |
4707 * Returns the range of the percent bar. | 4619 * Returns the range of the percent bar. |
4708 * Parameters: | 4620 * Parameters: |
4709 * handle: Handle to the slider to be queried. | 4621 * handle: Handle to the slider to be queried. |
4710 */ | 4622 */ |
4711 unsigned int dw_percent_query_range(HWND handle) | 4623 unsigned int dw_percent_query_range(HWND handle) |
4712 { | 4624 { |
4713 return (unsigned int)SendMessage(handle, PBM_GETRANGE, (WPARAM)FALSE, 0); | 4625 unsigned long width; |
4626 | |
4627 dw_window_get_pos_size(handle, 0, 0, &width, 0); | |
4628 | |
4629 if(width - 6 < 1) | |
4630 return 1; | |
4631 return width - 6; | |
4714 } | 4632 } |
4715 | 4633 |
4716 /* | 4634 /* |
4717 * Sets the percent bar position. | 4635 * Sets the percent bar position. |
4718 * Parameters: | 4636 * Parameters: |
4719 * handle: Handle to the slider to be set. | 4637 * handle: Handle to the slider to be set. |
4720 * position: Position of the slider withing the range. | 4638 * position: Position of the slider withing the range. |
4721 */ | 4639 */ |
4722 void dw_percent_set_pos(HWND handle, unsigned int position) | 4640 void dw_percent_set_pos(HWND handle, unsigned int position) |
4723 { | 4641 { |
4724 SendMessage(handle, PBM_SETPOS, (WPARAM)position, 0); | 4642 PercentBar *pb = (PercentBar *)WinQueryWindowPtr(handle, 0); |
4643 | |
4644 if(pb) | |
4645 { | |
4646 RECTL rcl; | |
4647 | |
4648 pb->pos = position; | |
4649 WinQueryWindowRect(handle, &rcl); | |
4650 WinInvalidateRect(handle, &rcl, FALSE); | |
4651 } | |
4725 } | 4652 } |
4726 | 4653 |
4727 /* | 4654 /* |
4728 * Sets the spinbutton value. | 4655 * Sets the spinbutton value. |
4729 * Parameters: | 4656 * Parameters: |
4730 * handle: Handle to the spinbutton to be set. | 4657 * handle: Handle to the spinbutton to be set. |
4731 * position: Current value of the spinbutton. | 4658 * position: Current value of the spinbutton. |
4732 */ | 4659 */ |
4733 void dw_spinbutton_set_pos(HWND handle, long position) | 4660 void dw_spinbutton_set_pos(HWND handle, long position) |
4734 { | 4661 { |
4735 char tmpbuf[100]; | 4662 WinSendMsg(handle, SPBM_SETCURRENTVALUE, MPFROMLONG((long)position), 0L); |
4736 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | |
4737 | |
4738 sprintf(tmpbuf, "%d", position); | |
4739 | |
4740 if(cinfo && cinfo->buddy) | |
4741 SetWindowText(cinfo->buddy, tmpbuf); | |
4742 | |
4743 if(IS_WIN98PLUS) | |
4744 SendMessage(handle, UDM_SETPOS32, 0, (LPARAM)position); | |
4745 else | |
4746 SendMessage(handle, UDM_SETPOS, 0, (LPARAM)MAKELONG((short)position, 0)); | |
4747 } | 4663 } |
4748 | 4664 |
4749 /* | 4665 /* |
4750 * Sets the spinbutton limits. | 4666 * Sets the spinbutton limits. |
4751 * Parameters: | 4667 * Parameters: |
4752 * handle: Handle to the spinbutton to be set. | 4668 * handle: Handle to the spinbutton to be set. |
4753 * position: Current value of the spinbutton. | 4669 * upper: Upper limit. |
4754 * position: Current value of the spinbutton. | 4670 * lower: Lower limit. |
4755 */ | 4671 */ |
4756 void dw_spinbutton_set_limits(HWND handle, long upper, long lower) | 4672 void dw_spinbutton_set_limits(HWND handle, long upper, long lower) |
4757 { | 4673 { |
4758 if(IS_WIN98PLUS) | 4674 WinSendMsg(handle, SPBM_SETLIMITS, MPFROMLONG(upper), MPFROMLONG(lower)); |
4759 SendMessage(handle, UDM_SETRANGE32, (WPARAM)lower,(LPARAM)upper); | |
4760 else | |
4761 SendMessage(handle, UDM_SETRANGE32, (WPARAM)((short)lower), | |
4762 (LPARAM)((short)upper)); | |
4763 } | 4675 } |
4764 | 4676 |
4765 /* | 4677 /* |
4766 * Sets the entryfield character limit. | 4678 * Sets the entryfield character limit. |
4767 * Parameters: | 4679 * Parameters: |
4768 * handle: Handle to the spinbutton to be set. | 4680 * handle: Handle to the spinbutton to be set. |
4769 * limit: Number of characters the entryfield will take. | 4681 * limit: Number of characters the entryfield will take. |
4770 */ | 4682 */ |
4771 void dw_entryfield_set_limit(HWND handle, ULONG limit) | 4683 void dw_entryfield_set_limit(HWND handle, ULONG limit) |
4772 { | 4684 { |
4773 SendMessage(handle, EM_SETLIMITTEXT, (WPARAM)limit, 0); | 4685 WinSendMsg(handle, EM_SETTEXTLIMIT, (MPARAM)limit, (MPARAM)0); |
4774 } | 4686 } |
4687 | |
4775 | 4688 |
4776 /* | 4689 /* |
4777 * Returns the current value of the spinbutton. | 4690 * Returns the current value of the spinbutton. |
4778 * Parameters: | 4691 * Parameters: |
4779 * handle: Handle to the spinbutton to be queried. | 4692 * handle: Handle to the spinbutton to be queried. |
4780 */ | 4693 */ |
4781 long dw_spinbutton_query(HWND handle) | 4694 long dw_spinbutton_query(HWND handle) |
4782 { | 4695 { |
4783 if(IS_WIN98PLUS) | 4696 long tmpval = 0L; |
4784 return (long)SendMessage(handle, UDM_GETPOS32, 0, 0); | 4697 |
4785 else | 4698 WinSendMsg(handle, SPBM_QUERYVALUE, (MPARAM)&tmpval,0L); |
4786 return (long)SendMessage(handle, UDM_GETPOS, 0, 0); | 4699 return tmpval; |
4787 } | 4700 } |
4788 | 4701 |
4789 /* | 4702 /* |
4790 * Returns the state of the checkbox. | 4703 * Returns the state of the checkbox. |
4791 * Parameters: | 4704 * Parameters: |
4792 * handle: Handle to the checkbox to be queried. | 4705 * handle: Handle to the checkbox to be queried. |
4793 */ | 4706 */ |
4794 int dw_checkbox_query(HWND handle) | 4707 int dw_checkbox_query(HWND handle) |
4795 { | 4708 { |
4796 if(SendMessage(handle, BM_GETCHECK, 0, 0) == BST_CHECKED) | 4709 return (int)WinSendMsg(handle,BM_QUERYCHECK,0,0); |
4797 return TRUE; | |
4798 return FALSE; | |
4799 } | 4710 } |
4800 | 4711 |
4801 /* | 4712 /* |
4802 * Sets the state of the checkbox. | 4713 * Sets the state of the checkbox. |
4803 * Parameters: | 4714 * Parameters: |
4804 * handle: Handle to the checkbox to be queried. | 4715 * handle: Handle to the checkbox to be queried. |
4805 * value: TRUE for checked, FALSE for unchecked. | 4716 * value: TRUE for checked, FALSE for unchecked. |
4806 */ | 4717 */ |
4807 void dw_checkbox_set(HWND handle, int value) | 4718 void dw_checkbox_set(HWND handle, int value) |
4808 { | 4719 { |
4809 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | 4720 WinSendMsg(handle,BM_SETCHECK,MPFROMSHORT(value),0); |
4810 | |
4811 if(cinfo && !cinfo->user) | |
4812 SendMessage(handle, BM_CLICK, 0, 0); | |
4813 SendMessage(handle, BM_SETCHECK, (WPARAM)value, 0); | |
4814 } | 4721 } |
4815 | 4722 |
4816 /* | 4723 /* |
4817 * Inserts an item into a tree window (widget). | 4724 * Inserts an item into a tree window (widget). |
4818 * Parameters: | 4725 * Parameters: |
4822 * parent: Parent handle or 0 if root. | 4729 * parent: Parent handle or 0 if root. |
4823 * itemdata: Item specific data. | 4730 * itemdata: Item specific data. |
4824 */ | 4731 */ |
4825 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata) | 4732 HWND dw_tree_insert(HWND handle, char *title, unsigned long icon, HWND parent, void *itemdata) |
4826 { | 4733 { |
4827 TVITEM tvi; | 4734 ULONG cbExtra; |
4828 TVINSERTSTRUCT tvins; | 4735 PCNRITEM pci; |
4829 HTREEITEM hti; | 4736 RECORDINSERT ri; |
4830 void **ptrs= malloc(sizeof(void *) * 2); | 4737 |
4831 | 4738 /* Calculate extra bytes needed for each record besides that needed for the |
4832 ptrs[0] = title; | 4739 * MINIRECORDCORE structure |
4833 ptrs[1] = itemdata; | 4740 */ |
4834 | 4741 |
4835 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; | 4742 cbExtra = sizeof(CNRITEM) - sizeof(MINIRECORDCORE); |
4836 tvi.pszText = title; | 4743 |
4837 tvi.lParam = (LONG)ptrs; | 4744 /* Allocate memory for the parent record */ |
4838 tvi.cchTextMax = strlen(title); | 4745 |
4839 tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1); | 4746 pci = WinSendMsg(handle, CM_ALLOCRECORD, MPFROMLONG(cbExtra), MPFROMSHORT(1)); |
4840 | 4747 |
4841 tvins.item = tvi; | 4748 /* Fill in the parent record data */ |
4842 tvins.hParent = (HTREEITEM)parent; | 4749 |
4843 tvins.hInsertAfter = TVI_LAST; | 4750 pci->rc.cb = sizeof(MINIRECORDCORE); |
4844 | 4751 pci->rc.pszIcon = strdup(title); |
4845 hti = TreeView_InsertItem(handle, &tvins); | 4752 pci->rc.hptrIcon = icon; |
4846 | 4753 |
4847 return (HWND)hti; | 4754 pci->hptrIcon = icon; |
4755 pci->user = itemdata; | |
4756 | |
4757 memset(&ri, 0, sizeof(RECORDINSERT)); | |
4758 | |
4759 ri.cb = sizeof(RECORDINSERT); | |
4760 ri.pRecordOrder = (PRECORDCORE)CMA_END; | |
4761 ri.pRecordParent = (PRECORDCORE)NULL; | |
4762 ri.zOrder = (USHORT)CMA_TOP; | |
4763 ri.cRecordsInsert = 1; | |
4764 ri.fInvalidateRecord = TRUE; | |
4765 | |
4766 /* We are about to insert the child records. Set the parent record to be | |
4767 * the one we just inserted. | |
4768 */ | |
4769 ri.pRecordParent = (PRECORDCORE)parent; | |
4770 | |
4771 /* Insert the record */ | |
4772 WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(pci), MPFROMP(&ri)); | |
4773 | |
4774 return (HWND)pci; | |
4848 } | 4775 } |
4849 | 4776 |
4850 /* | 4777 /* |
4851 * Sets the text and icon of an item in a tree window (widget). | 4778 * Sets the text and icon of an item in a tree window (widget). |
4852 * Parameters: | 4779 * Parameters: |
4855 * title: The text title of the entry. | 4782 * title: The text title of the entry. |
4856 * icon: Handle to coresponding icon. | 4783 * icon: Handle to coresponding icon. |
4857 */ | 4784 */ |
4858 void dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon) | 4785 void dw_tree_set(HWND handle, HWND item, char *title, unsigned long icon) |
4859 { | 4786 { |
4860 TVITEM tvi; | 4787 PCNRITEM pci = (PCNRITEM)item; |
4861 void **ptrs; | 4788 |
4862 | 4789 if(!pci) |
4863 tvi.mask = TVIF_HANDLE; | 4790 return; |
4864 tvi.hItem = (HTREEITEM)item; | 4791 |
4865 | 4792 if(pci->rc.pszIcon) |
4866 TreeView_GetItem(handle, &tvi); | 4793 free(pci->rc.pszIcon); |
4867 | 4794 |
4868 ptrs = (void **)tvi.lParam; | 4795 pci->rc.pszIcon = strdup(title); |
4869 ptrs[0] = title; | 4796 pci->rc.hptrIcon = icon; |
4870 | 4797 |
4871 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE; | 4798 pci->hptrIcon = icon; |
4872 tvi.pszText = title; | 4799 |
4873 tvi.cchTextMax = strlen(title); | 4800 WinSendMsg(handle, CM_INVALIDATERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_TEXTCHANGED)); |
4874 tvi.iSelectedImage = tvi.iImage = _lookup_icon(handle, (HICON)icon, 1); | |
4875 tvi.hItem = (HTREEITEM)item; | |
4876 | |
4877 TreeView_SetItem(handle, &tvi); | |
4878 } | 4801 } |
4879 | 4802 |
4880 /* | 4803 /* |
4881 * Sets the item data of a tree item. | 4804 * Sets the item data of a tree item. |
4882 * Parameters: | 4805 * Parameters: |
4884 * item: Handle of the item to be modified. | 4807 * item: Handle of the item to be modified. |
4885 * itemdata: User defined data to be associated with item. | 4808 * itemdata: User defined data to be associated with item. |
4886 */ | 4809 */ |
4887 void dw_tree_set_data(HWND handle, HWND item, void *itemdata) | 4810 void dw_tree_set_data(HWND handle, HWND item, void *itemdata) |
4888 { | 4811 { |
4889 TVITEM tvi; | 4812 PCNRITEM pci = (PCNRITEM)item; |
4890 void **ptrs; | 4813 |
4891 | 4814 if(!pci) |
4892 tvi.mask = TVIF_HANDLE; | 4815 return; |
4893 tvi.hItem = (HTREEITEM)item; | 4816 |
4894 | 4817 pci->user = itemdata; |
4895 TreeView_GetItem(handle, &tvi); | |
4896 | |
4897 ptrs = (void **)tvi.lParam; | |
4898 ptrs[1] = itemdata; | |
4899 } | 4818 } |
4900 | 4819 |
4901 /* | 4820 /* |
4902 * Sets this item as the active selection. | 4821 * Sets this item as the active selection. |
4903 * Parameters: | 4822 * Parameters: |
4904 * handle: Handle to the tree window (widget) to be selected. | 4823 * handle: Handle to the tree window (widget) to be selected. |
4905 * item: Handle to the item to be selected. | 4824 * item: Handle to the item to be selected. |
4906 */ | 4825 */ |
4907 void dw_tree_item_select(HWND handle, HWND item) | 4826 void dw_tree_item_select(HWND handle, HWND item) |
4908 { | 4827 { |
4909 TreeView_SelectItem(handle, (HTREEITEM)item); | 4828 PRECORDCORE pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); |
4910 SetFocus(handle); | 4829 |
4830 while(pCore) | |
4831 { | |
4832 if(pCore->flRecordAttr & CRA_SELECTED) | |
4833 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)pCore, MPFROM2SHORT(FALSE, CRA_SELECTED | CRA_CURSORED)); | |
4834 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); | |
4835 } | |
4836 WinSendMsg(handle, CM_SETRECORDEMPHASIS, (MPARAM)item, MPFROM2SHORT(TRUE, CRA_SELECTED | CRA_CURSORED)); | |
4837 lastitem = 0; | |
4838 lasthcnr = 0; | |
4911 } | 4839 } |
4912 | 4840 |
4913 /* | 4841 /* |
4914 * Removes all nodes from a tree. | 4842 * Removes all nodes from a tree. |
4915 * Parameters: | 4843 * Parameters: |
4916 * handle: Handle to the window (widget) to be cleared. | 4844 * handle: Handle to the window (widget) to be cleared. |
4917 */ | 4845 */ |
4918 void dw_tree_clear(HWND handle) | 4846 void dw_tree_clear(HWND handle) |
4919 { | 4847 { |
4920 TreeView_DeleteAllItems(handle); | 4848 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, CMA_INVALIDATE | CMA_FREE)); |
4921 } | 4849 } |
4922 | 4850 |
4923 /* | 4851 /* |
4924 * Expands a node on a tree. | 4852 * Expands a node on a tree. |
4925 * Parameters: | 4853 * Parameters: |
4926 * handle: Handle to the tree window (widget). | 4854 * handle: Handle to the tree window (widget). |
4927 * item: Handle to node to be expanded. | 4855 * item: Handle to node to be expanded. |
4928 */ | 4856 */ |
4929 void dw_tree_expand(HWND handle, HWND item) | 4857 void dw_tree_expand(HWND handle, HWND item) |
4930 { | 4858 { |
4931 TreeView_Expand(handle, (HTREEITEM)item, TVE_EXPAND); | 4859 WinSendMsg(handle, CM_EXPANDTREE, MPFROMP(item), 0); |
4932 } | 4860 } |
4933 | 4861 |
4934 /* | 4862 /* |
4935 * Collapses a node on a tree. | 4863 * Collapses a node on a tree. |
4936 * Parameters: | 4864 * Parameters: |
4937 * handle: Handle to the tree window (widget). | 4865 * handle: Handle to the tree window (widget). |
4938 * item: Handle to node to be collapsed. | 4866 * item: Handle to node to be collapsed. |
4939 */ | 4867 */ |
4940 void dw_tree_collapse(HWND handle, HWND item) | 4868 void dw_tree_collapse(HWND handle, HWND item) |
4941 { | 4869 { |
4942 TreeView_Expand(handle, (HTREEITEM)item, TVE_COLLAPSE); | 4870 WinSendMsg(handle, CM_COLLAPSETREE, MPFROMP(item), 0); |
4943 } | 4871 } |
4944 | 4872 |
4945 /* | 4873 /* |
4946 * Removes a node from a tree. | 4874 * Removes a node from a tree. |
4947 * Parameters: | 4875 * Parameters: |
4948 * handle: Handle to the window (widget) to be cleared. | 4876 * handle: Handle to the window (widget) to be cleared. |
4949 * item: Handle to node to be deleted. | 4877 * item: Handle to node to be deleted. |
4950 */ | 4878 */ |
4951 void dw_tree_delete(HWND handle, HWND item) | 4879 void dw_tree_delete(HWND handle, HWND item) |
4952 { | 4880 { |
4953 TreeView_DeleteItem(handle, (HTREEITEM)item); | 4881 PCNRITEM pci = (PCNRITEM)item; |
4954 } | 4882 |
4883 if(!item) | |
4884 return; | |
4885 | |
4886 if(pci->rc.pszIcon) | |
4887 free(pci->rc.pszIcon); | |
4888 | |
4889 WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)&pci, MPFROM2SHORT(1, CMA_INVALIDATE | CMA_FREE)); | |
4890 } | |
4891 | |
4892 /* Some OS/2 specific container structs */ | |
4893 typedef struct _containerinfo { | |
4894 int count; | |
4895 void *data; | |
4896 HWND handle; | |
4897 } ContainerInfo; | |
4955 | 4898 |
4956 /* | 4899 /* |
4957 * Sets up the container columns. | 4900 * Sets up the container columns. |
4958 * Parameters: | 4901 * Parameters: |
4959 * handle: Handle to the container to be configured. | 4902 * handle: Handle to the container to be configured. |
4960 * flags: An array of unsigned longs with column flags. | 4903 * flags: An array of unsigned longs with column flags. |
4961 * titles: An array of strings with column text titles. | 4904 * titles: An array of strings with column text titles. |
4962 * count: The number of columns (this should match the arrays). | 4905 * count: The number of columns (this should match the arrays). |
4963 * separator: The column number that contains the main separator. | 4906 * separator: The column number that contains the main separator. |
4964 * (only used on OS/2 but must be >= 0 on all) | 4907 * (this item may only be used in OS/2) |
4965 */ | 4908 */ |
4966 int dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator) | 4909 int dw_container_setup(HWND handle, unsigned long *flags, char **titles, int count, int separator) |
4967 { | 4910 { |
4968 ContainerInfo *cinfo = (ContainerInfo *)GetWindowLong(handle, GWL_USERDATA); | 4911 PFIELDINFO details, first, left = NULL; |
4969 int z, l = 0; | 4912 FIELDINFOINSERT detin; |
4970 unsigned long *tempflags = malloc(sizeof(unsigned long) * (count + 2)); | 4913 CNRINFO cnri; |
4971 LV_COLUMN lvc; | 4914 int z; |
4972 | 4915 ULONG size = sizeof(RECORDCORE); |
4973 if(separator == -1) | 4916 ULONG *offStruct = malloc(count * sizeof(ULONG)); |
4974 l = 1; | 4917 ULONG *tempflags = malloc((count+1) * sizeof(ULONG)); |
4975 | 4918 ULONG *oldflags = (ULONG *)WinQueryWindowPtr(handle, 0); |
4976 memcpy(&tempflags[l], flags, sizeof(unsigned long) * count); | 4919 |
4977 tempflags[count + l] = 0; | 4920 if(!offStruct || !tempflags) |
4978 cinfo->flags = tempflags; | 4921 return FALSE; |
4979 | 4922 |
4980 | 4923 memcpy(tempflags, flags, count * sizeof(ULONG)); |
4924 tempflags[count] = 0; | |
4925 | |
4926 WinSetWindowPtr(handle, 0, tempflags); | |
4927 | |
4928 if(oldflags) | |
4929 free(oldflags); | |
4930 | |
4931 while((first = (PFIELDINFO)WinSendMsg(handle, CM_QUERYDETAILFIELDINFO, 0, MPFROMSHORT(CMA_FIRST))) != NULL) | |
4932 { | |
4933 WinSendMsg(handle, CM_REMOVEDETAILFIELDINFO, (MPARAM)&first, MPFROM2SHORT(1, CMA_FREE)); | |
4934 } | |
4935 | |
4936 /* Figure out the offsets to the items in the struct */ | |
4981 for(z=0;z<count;z++) | 4937 for(z=0;z<count;z++) |
4982 { | 4938 { |
4983 if(titles[z]) | 4939 offStruct[z] = size; |
4984 { | 4940 if(flags[z] & DW_CFA_BITMAPORICON) |
4985 lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM /*| LVCF_FORMAT*/; | 4941 size += sizeof(HPOINTER); |
4986 lvc.pszText = titles[z]; | 4942 else if(flags[z] & DW_CFA_STRING) |
4987 lvc.cchTextMax = strlen(titles[z]); | 4943 size += sizeof(char *); |
4988 lvc.fmt = flags[z]; | 4944 else if(flags[z] & DW_CFA_ULONG) |
4989 lvc.cx = 75; | 4945 size += sizeof(ULONG); |
4990 lvc.iSubItem = count; | 4946 else if(flags[z] & DW_CFA_DATE) |
4991 SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)z + l, (LPARAM)&lvc); | 4947 size += sizeof(CDATE); |
4992 } | 4948 else if(flags[z] & DW_CFA_TIME) |
4993 } | 4949 size += sizeof(CTIME); |
4994 ListView_SetExtendedListViewStyle(handle, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); | 4950 } |
4951 | |
4952 first = details = (PFIELDINFO)WinSendMsg(handle, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(count), 0L); | |
4953 | |
4954 if(!first) | |
4955 { | |
4956 free(offStruct); | |
4957 return FALSE; | |
4958 } | |
4959 | |
4960 for(z=0;z<count;z++) | |
4961 { | |
4962 if(z==separator-1) | |
4963 left=details; | |
4964 details->cb = sizeof(FIELDINFO); | |
4965 details->flData = flags[z]; | |
4966 details->flTitle = CFA_FITITLEREADONLY; | |
4967 details->pTitleData = titles[z]; | |
4968 details->offStruct = offStruct[z]; | |
4969 details = details->pNextFieldInfo; | |
4970 } | |
4971 | |
4972 detin.cb = sizeof(FIELDINFOINSERT); | |
4973 detin.fInvalidateFieldInfo = FALSE; | |
4974 detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST; | |
4975 detin.cFieldInfoInsert = (ULONG)count; | |
4976 | |
4977 WinSendMsg(handle, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin)); | |
4978 | |
4979 if(count > separator && separator > 0) | |
4980 { | |
4981 cnri.cb = sizeof(CNRINFO); | |
4982 cnri.pFieldInfoLast = left; | |
4983 cnri.xVertSplitbar = 150; | |
4984 | |
4985 WinSendMsg(handle, CM_SETCNRINFO, MPFROMP(&cnri), MPFROMLONG(CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR)); | |
4986 } | |
4987 | |
4988 free(offStruct); | |
4995 return TRUE; | 4989 return TRUE; |
4996 } | 4990 } |
4997 | 4991 |
4998 /* | 4992 /* |
4999 * Sets up the filesystem columns, note: filesystem always has an icon/filename field. | 4993 * Sets up the filesystem columns, note: filesystem always has an icon/filename field. |
5003 * titles: An array of strings with column text titles. | 4997 * titles: An array of strings with column text titles. |
5004 * count: The number of columns (this should match the arrays). | 4998 * count: The number of columns (this should match the arrays). |
5005 */ | 4999 */ |
5006 int dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count) | 5000 int dw_filesystem_setup(HWND handle, unsigned long *flags, char **titles, int count) |
5007 { | 5001 { |
5008 LV_COLUMN lvc; | 5002 char **newtitles = malloc(sizeof(char *) * (count + 2)); |
5009 | 5003 unsigned long *newflags = malloc(sizeof(unsigned long) * (count + 2)); |
5010 lvc.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; | 5004 |
5011 lvc.pszText = "Filename"; | 5005 newtitles[0] = "Icon"; |
5012 lvc.cchTextMax = 8; | 5006 newtitles[1] = "Filename"; |
5013 lvc.fmt = 0; | 5007 |
5014 if(!count) | 5008 newflags[0] = DW_CFA_BITMAPORICON | DW_CFA_CENTER | DW_CFA_HORZSEPARATOR | DW_CFA_SEPARATOR; |
5015 lvc.cx = 300; | 5009 newflags[1] = DW_CFA_STRING | DW_CFA_LEFT | DW_CFA_HORZSEPARATOR; |
5016 else | 5010 |
5017 lvc.cx = 150; | 5011 memcpy(&newtitles[2], titles, sizeof(char *) * count); |
5018 lvc.iSubItem = count; | 5012 memcpy(&newflags[2], flags, sizeof(unsigned long) * count); |
5019 SendMessage(handle, LVM_INSERTCOLUMN, (WPARAM)0, (LPARAM)&lvc); | 5013 |
5020 dw_container_setup(handle, flags, titles, count, -1); | 5014 dw_container_setup(handle, newflags, newtitles, count + 2, 2); |
5015 | |
5016 free(newtitles); | |
5017 free(newflags); | |
5021 return TRUE; | 5018 return TRUE; |
5022 } | 5019 } |
5023 | 5020 |
5024 /* | 5021 /* |
5025 * Obtains an icon from a module (or header in GTK). | 5022 * Obtains an icon from a module (or header in GTK). |
5029 * Windows, on GTK this is converted to a pointer | 5026 * Windows, on GTK this is converted to a pointer |
5030 * to an embedded XPM. | 5027 * to an embedded XPM. |
5031 */ | 5028 */ |
5032 unsigned long dw_icon_load(unsigned long module, unsigned long id) | 5029 unsigned long dw_icon_load(unsigned long module, unsigned long id) |
5033 { | 5030 { |
5034 return (unsigned long)LoadIcon(DWInstance, MAKEINTRESOURCE(id)); | 5031 return WinLoadPointer(HWND_DESKTOP,module,id); |
5035 } | 5032 } |
5036 | 5033 |
5037 /* | 5034 /* |
5038 * Frees a loaded resource in OS/2 and Windows. | 5035 * Frees a loaded resource in OS/2 and Windows. |
5039 * Parameters: | 5036 * Parameters: |
5040 * handle: Handle to icon returned by dw_icon_load(). | 5037 * handle: Handle to icon returned by dw_icon_load(). |
5041 */ | 5038 */ |
5042 void dw_icon_free(unsigned long handle) | 5039 void dw_icon_free(unsigned long handle) |
5043 { | 5040 { |
5044 DestroyIcon((HICON)handle); | 5041 WinDestroyPointer(handle); |
5045 } | 5042 } |
5046 | 5043 |
5047 /* | 5044 /* |
5048 * Allocates memory used to populate a container. | 5045 * Allocates memory used to populate a container. |
5049 * Parameters: | 5046 * Parameters: |
5050 * handle: Handle to the container window (widget). | 5047 * handle: Handle to the container window (widget). |
5051 * rowcount: The number of items to be populated. | 5048 * rowcount: The number of items to be populated. |
5052 */ | 5049 */ |
5053 void *dw_container_alloc(HWND handle, int rowcount) | 5050 void *dw_container_alloc(HWND handle, int rowcount) |
5054 { | 5051 { |
5055 LV_ITEM lvi; | 5052 ULONG *flags = (ULONG *)WinQueryWindowPtr(handle, 0); |
5056 int z; | 5053 int z, size = 0, totalsize, count = 0; |
5057 | 5054 PRECORDCORE temp; |
5058 lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT | LVIF_IMAGE; | 5055 ContainerInfo *ci; |
5059 lvi.iSubItem = 0; | 5056 void *blah = NULL; |
5060 /* Insert at the end */ | 5057 |
5061 lvi.iItem = 1000000; | 5058 if(!flags || rowcount < 1) |
5062 lvi.pszText = ""; | 5059 return NULL; |
5063 lvi.cchTextMax = 1; | 5060 |
5064 lvi.iImage = -1; | 5061 while(flags[count]) |
5062 count++; | |
5063 | |
5064 /* Figure out the offsets to the items in the struct */ | |
5065 for(z=0;z<count;z++) | |
5066 { | |
5067 if(flags[z] & DW_CFA_BITMAPORICON) | |
5068 size += sizeof(HPOINTER); | |
5069 else if(flags[z] & DW_CFA_STRING) | |
5070 size += sizeof(char *); | |
5071 else if(flags[z] & DW_CFA_ULONG) | |
5072 size += sizeof(ULONG); | |
5073 else if(flags[z] & DW_CFA_DATE) | |
5074 size += sizeof(CDATE); | |
5075 else if(flags[z] & DW_CFA_TIME) | |
5076 size += sizeof(CTIME); | |
5077 } | |
5078 | |
5079 totalsize = size + sizeof(RECORDCORE); | |
5080 | |
5081 z = 0; | |
5082 | |
5083 while((blah = (void *)WinSendMsg(handle, CM_ALLOCRECORD, MPFROMLONG(size), MPFROMLONG(rowcount))) == NULL) | |
5084 { | |
5085 z++; | |
5086 if(z > 5000000) | |
5087 break; | |
5088 DosSleep(1); | |
5089 } | |
5090 | |
5091 if(!blah) | |
5092 return NULL; | |
5093 | |
5094 temp = (PRECORDCORE)blah; | |
5065 | 5095 |
5066 for(z=0;z<rowcount;z++) | 5096 for(z=0;z<rowcount;z++) |
5067 ListView_InsertItem(handle, &lvi); | 5097 { |
5068 return (void *)handle; | 5098 temp->cb = totalsize; |
5069 } | 5099 temp = temp->preccNextRecord; |
5070 | 5100 } |
5071 /* Finds a icon in the table, otherwise it adds it to the table | 5101 |
5072 * and returns the index in the table. | 5102 ci = malloc(sizeof(struct _containerinfo)); |
5073 */ | 5103 |
5074 int _lookup_icon(HWND handle, HICON hicon, int type) | 5104 ci->count = rowcount; |
5075 { | 5105 ci->data = blah; |
5076 int z; | 5106 ci->handle = handle; |
5077 static HWND lasthwnd = NULL; | 5107 |
5078 | 5108 return (void *)ci; |
5079 if(!hSmall || !hLarge) | |
5080 { | |
5081 hSmall = ImageList_Create(16, 16, ILC_COLOR16, ICON_INDEX_LIMIT, 0); | |
5082 hLarge = ImageList_Create(32, 32, ILC_COLOR16, ICON_INDEX_LIMIT, 0); | |
5083 } | |
5084 for(z=0;z<ICON_INDEX_LIMIT;z++) | |
5085 { | |
5086 if(!lookup[z]) | |
5087 { | |
5088 lookup[z] = hicon; | |
5089 ImageList_AddIcon(hSmall, hicon); | |
5090 ImageList_AddIcon(hLarge, hicon); | |
5091 if(type) | |
5092 { | |
5093 TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL); | |
5094 } | |
5095 else | |
5096 { | |
5097 ListView_SetImageList(handle, hSmall, LVSIL_SMALL); | |
5098 ListView_SetImageList(handle, hLarge, LVSIL_NORMAL); | |
5099 } | |
5100 lasthwnd = handle; | |
5101 return z; | |
5102 } | |
5103 | |
5104 if(hicon == lookup[z]) | |
5105 { | |
5106 if(lasthwnd != handle) | |
5107 { | |
5108 if(type) | |
5109 { | |
5110 TreeView_SetImageList(handle, hSmall, TVSIL_NORMAL); | |
5111 } | |
5112 else | |
5113 { | |
5114 ListView_SetImageList(handle, hSmall, LVSIL_SMALL); | |
5115 ListView_SetImageList(handle, hLarge, LVSIL_NORMAL); | |
5116 } | |
5117 lasthwnd = handle; | |
5118 } | |
5119 return z; | |
5120 } | |
5121 } | |
5122 return -1; | |
5123 } | 5109 } |
5124 | 5110 |
5125 /* | 5111 /* |
5126 * Sets an item in specified row and column to the given data. | 5112 * Sets an item in specified row and column to the given data. |
5127 * Parameters: | 5113 * Parameters: |
5129 * pointer: Pointer to the allocated memory in dw_container_alloc(). | 5115 * pointer: Pointer to the allocated memory in dw_container_alloc(). |
5130 * column: Zero based column of data being set. | 5116 * column: Zero based column of data being set. |
5131 * row: Zero based row of data being set. | 5117 * row: Zero based row of data being set. |
5132 * data: Pointer to the data to be added. | 5118 * data: Pointer to the data to be added. |
5133 */ | 5119 */ |
5134 void dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon) | 5120 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data) |
5135 { | 5121 { |
5136 LV_ITEM lvi; | 5122 ULONG totalsize, size = 0, *flags = (ULONG *)WinQueryWindowPtr(handle, 0); |
5137 | 5123 int z, currentcount; |
5138 lvi.iItem = row; | 5124 ContainerInfo *ci = (ContainerInfo *)pointer; |
5139 lvi.iSubItem = 0; | 5125 PRECORDCORE temp; |
5140 lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE | LVIF_TEXT; | 5126 CNRINFO cnr; |
5141 lvi.pszText = filename; | 5127 void *dest; |
5142 lvi.cchTextMax = strlen(filename); | 5128 |
5143 lvi.iImage = _lookup_icon(handle, (HICON)icon, 0); | 5129 if(!ci) |
5144 | 5130 return; |
5145 ListView_SetItem(handle, &lvi); | 5131 |
5132 if(!flags) | |
5133 return; | |
5134 | |
5135 temp = (PRECORDCORE)ci->data; | |
5136 | |
5137 WinSendMsg(handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO))); | |
5138 currentcount = cnr.cRecords; | |
5139 | |
5140 /* Figure out the offsets to the items in the struct */ | |
5141 for(z=0;z<column;z++) | |
5142 { | |
5143 if(flags[z] & DW_CFA_BITMAPORICON) | |
5144 size += sizeof(HPOINTER); | |
5145 else if(flags[z] & DW_CFA_STRING) | |
5146 size += sizeof(char *); | |
5147 else if(flags[z] & DW_CFA_ULONG) | |
5148 size += sizeof(ULONG); | |
5149 else if(flags[z] & DW_CFA_DATE) | |
5150 size += sizeof(CDATE); | |
5151 else if(flags[z] & DW_CFA_TIME) | |
5152 size += sizeof(CTIME); | |
5153 } | |
5154 | |
5155 totalsize = size + sizeof(RECORDCORE); | |
5156 | |
5157 for(z=0;z<(row-currentcount);z++) | |
5158 temp = temp->preccNextRecord; | |
5159 | |
5160 dest = (void *)(((ULONG)temp)+((ULONG)totalsize)); | |
5161 | |
5162 if(flags[column] & DW_CFA_BITMAPORICON) | |
5163 memcpy(dest, data, sizeof(HPOINTER)); | |
5164 else if(flags[column] & DW_CFA_STRING) | |
5165 memcpy(dest, data, sizeof(char *)); | |
5166 else if(flags[column] & DW_CFA_ULONG) | |
5167 memcpy(dest, data, sizeof(ULONG)); | |
5168 else if(flags[column] & DW_CFA_DATE) | |
5169 memcpy(dest, data, sizeof(CDATE)); | |
5170 else if(flags[column] & DW_CFA_TIME) | |
5171 memcpy(dest, data, sizeof(CTIME)); | |
5146 } | 5172 } |
5147 | 5173 |
5148 /* | 5174 /* |
5149 * Sets an item in specified row and column to the given data. | 5175 * Sets an item in specified row and column to the given data. |
5150 * Parameters: | 5176 * Parameters: |
5152 * pointer: Pointer to the allocated memory in dw_container_alloc(). | 5178 * pointer: Pointer to the allocated memory in dw_container_alloc(). |
5153 * column: Zero based column of data being set. | 5179 * column: Zero based column of data being set. |
5154 * row: Zero based row of data being set. | 5180 * row: Zero based row of data being set. |
5155 * data: Pointer to the data to be added. | 5181 * data: Pointer to the data to be added. |
5156 */ | 5182 */ |
5157 void dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data) | 5183 void dw_filesystem_set_file(HWND handle, void *pointer, int row, char *filename, unsigned long icon) |
5158 { | 5184 { |
5159 dw_container_set_item(handle, pointer, column + 1, row, data); | 5185 dw_container_set_item(handle, pointer, 0, row, (void *)&icon); |
5186 dw_container_set_item(handle, pointer, 1, row, (void *)&filename); | |
5160 } | 5187 } |
5161 | 5188 |
5162 /* | 5189 /* |
5163 * Sets an item in specified row and column to the given data. | 5190 * Sets an item in specified row and column to the given data. |
5164 * Parameters: | 5191 * Parameters: |
5166 * pointer: Pointer to the allocated memory in dw_container_alloc(). | 5193 * pointer: Pointer to the allocated memory in dw_container_alloc(). |
5167 * column: Zero based column of data being set. | 5194 * column: Zero based column of data being set. |
5168 * row: Zero based row of data being set. | 5195 * row: Zero based row of data being set. |
5169 * data: Pointer to the data to be added. | 5196 * data: Pointer to the data to be added. |
5170 */ | 5197 */ |
5171 void dw_container_set_item(HWND handle, void *pointer, int column, int row, void *data) | 5198 void dw_filesystem_set_item(HWND handle, void *pointer, int column, int row, void *data) |
5172 { | 5199 { |
5173 ContainerInfo *cinfo = (ContainerInfo *)GetWindowLong(handle, GWL_USERDATA); | 5200 dw_container_set_item(handle, pointer, column + 2, row, data); |
5174 ULONG *flags; | |
5175 LV_ITEM lvi; | |
5176 char textbuffer[100], *destptr = textbuffer; | |
5177 | |
5178 if(!cinfo || !cinfo->flags || !data) | |
5179 return; | |
5180 | |
5181 flags = cinfo->flags; | |
5182 | |
5183 lvi.mask = LVIF_DI_SETITEM | LVIF_TEXT; | |
5184 lvi.iItem = row; | |
5185 lvi.iSubItem = column; | |
5186 | |
5187 if(flags[column] & DW_CFA_BITMAPORICON) | |
5188 { | |
5189 HICON hicon = *((HICON *)data); | |
5190 | |
5191 lvi.mask = LVIF_DI_SETITEM | LVIF_IMAGE; | |
5192 lvi.pszText = NULL; | |
5193 lvi.cchTextMax = 0; | |
5194 | |
5195 lvi.iImage = _lookup_icon(handle, hicon, 0); | |
5196 } | |
5197 else if(flags[column] & DW_CFA_STRING) | |
5198 { | |
5199 char *tmp = *((char **)data); | |
5200 | |
5201 if(!tmp) | |
5202 tmp = ""; | |
5203 | |
5204 lvi.pszText = tmp; | |
5205 lvi.cchTextMax = strlen(tmp); | |
5206 destptr = tmp; | |
5207 } | |
5208 else if(flags[column] & DW_CFA_ULONG) | |
5209 { | |
5210 ULONG tmp = *((ULONG *)data); | |
5211 | |
5212 sprintf(textbuffer, "%lu", tmp); | |
5213 | |
5214 lvi.pszText = textbuffer; | |
5215 lvi.cchTextMax = strlen(textbuffer); | |
5216 } | |
5217 else if(flags[column] & DW_CFA_DATE) | |
5218 { | |
5219 CDATE fdate = *((CDATE *)data); | |
5220 | |
5221 if(fdate.month > 0) | |
5222 sprintf(textbuffer, "%s %d, %d", monthlist[fdate.month-1], fdate.day, fdate.year); | |
5223 else | |
5224 strcpy(textbuffer, ""); | |
5225 lvi.pszText = textbuffer; | |
5226 lvi.cchTextMax = strlen(textbuffer); | |
5227 } | |
5228 else if(flags[column] & DW_CFA_TIME) | |
5229 { | |
5230 CTIME ftime = *((CTIME *)data); | |
5231 | |
5232 if(ftime.hours > 12) | |
5233 sprintf(textbuffer, "%d:%s%dpm", ftime.hours - 12, (ftime.minutes < 10) ? "0" : "", ftime.minutes); | |
5234 else | |
5235 sprintf(textbuffer, "%d:%s%dam", ftime.hours ? ftime.hours : 12, (ftime.minutes < 10) ? "0" : "", ftime.minutes); | |
5236 lvi.pszText = textbuffer; | |
5237 lvi.cchTextMax = strlen(textbuffer); | |
5238 } | |
5239 | |
5240 ListView_SetItem(handle, &lvi); | |
5241 } | 5201 } |
5242 | 5202 |
5243 /* | 5203 /* |
5244 * Sets the width of a column in the container. | 5204 * Sets the width of a column in the container. |
5245 * Parameters: | 5205 * Parameters: |
5247 * column: Zero based column of width being set. | 5207 * column: Zero based column of width being set. |
5248 * width: Width of column in pixels. | 5208 * width: Width of column in pixels. |
5249 */ | 5209 */ |
5250 void dw_container_set_column_width(HWND handle, int column, int width) | 5210 void dw_container_set_column_width(HWND handle, int column, int width) |
5251 { | 5211 { |
5252 ListView_SetColumnWidth(handle, column, width); | |
5253 } | 5212 } |
5254 | 5213 |
5255 /* | 5214 /* |
5256 * Sets the title of a row in the container. | 5215 * Sets the title of a row in the container. |
5257 * Parameters: | 5216 * Parameters: |
5259 * row: Zero based row of data being set. | 5218 * row: Zero based row of data being set. |
5260 * title: String title of the item. | 5219 * title: String title of the item. |
5261 */ | 5220 */ |
5262 void dw_container_set_row_title(void *pointer, int row, char *title) | 5221 void dw_container_set_row_title(void *pointer, int row, char *title) |
5263 { | 5222 { |
5264 LV_ITEM lvi; | 5223 ContainerInfo *ci = (ContainerInfo *)pointer; |
5265 HWND container = (HWND)pointer; | 5224 PRECORDCORE temp; |
5266 | 5225 int z, currentcount; |
5267 lvi.iItem = row; | 5226 CNRINFO cnr; |
5268 lvi.iSubItem = 0; | 5227 |
5269 lvi.mask = LVIF_PARAM; | 5228 if(!ci) |
5270 lvi.lParam = (LPARAM)title; | 5229 return; |
5271 | 5230 |
5272 if(!ListView_SetItem(container, &lvi) && lvi.lParam) | 5231 temp = (PRECORDCORE)ci->data; |
5273 lvi.lParam = 0; | 5232 |
5274 | 5233 WinSendMsg(ci->handle, CM_QUERYCNRINFO, (MPARAM)&cnr, MPFROMSHORT(sizeof(CNRINFO))); |
5234 currentcount = cnr.cRecords; | |
5235 | |
5236 for(z=0;z<(row-currentcount);z++) | |
5237 temp = temp->preccNextRecord; | |
5238 | |
5239 temp->pszIcon = title; | |
5240 temp->pszName = title; | |
5241 temp->pszText = title; | |
5275 } | 5242 } |
5276 | 5243 |
5277 /* | 5244 /* |
5278 * Sets the title of a row in the container. | 5245 * Sets the title of a row in the container. |
5279 * Parameters: | 5246 * Parameters: |
5281 * pointer: Pointer to the allocated memory in dw_container_alloc(). | 5248 * pointer: Pointer to the allocated memory in dw_container_alloc(). |
5282 * rowcount: The number of rows to be inserted. | 5249 * rowcount: The number of rows to be inserted. |
5283 */ | 5250 */ |
5284 void dw_container_insert(HWND handle, void *pointer, int rowcount) | 5251 void dw_container_insert(HWND handle, void *pointer, int rowcount) |
5285 { | 5252 { |
5286 /* This isn't a separate step in windows. */ | 5253 RECORDINSERT recin; |
5254 ContainerInfo *ci = (ContainerInfo *)pointer; | |
5255 int z; | |
5256 | |
5257 if(!ci) | |
5258 return; | |
5259 | |
5260 recin.cb = sizeof(RECORDINSERT); | |
5261 recin.pRecordOrder = (PRECORDCORE)CMA_END; | |
5262 recin.pRecordParent = NULL; | |
5263 recin.zOrder = CMA_TOP; | |
5264 recin.fInvalidateRecord = TRUE; | |
5265 recin.cRecordsInsert = rowcount; | |
5266 | |
5267 z = 0; | |
5268 | |
5269 while(WinSendMsg(handle, CM_INSERTRECORD, MPFROMP(ci->data), MPFROMP(&recin)) == 0) | |
5270 { | |
5271 z++; | |
5272 if(z > 5000000) | |
5273 break; | |
5274 DosSleep(1); | |
5275 } | |
5287 } | 5276 } |
5288 | 5277 |
5289 /* | 5278 /* |
5290 * Removes all rows from a container. | 5279 * Removes all rows from a container. |
5291 * Parameters: | 5280 * Parameters: |
5292 * handle: Handle to the window (widget) to be cleared. | 5281 * handle: Handle to the window (widget) to be cleared. |
5293 * redraw: TRUE to cause the container to redraw immediately. | 5282 * redraw: TRUE to cause the container to redraw immediately. |
5294 */ | 5283 */ |
5295 void dw_container_clear(HWND handle, int redraw) | 5284 void dw_container_clear(HWND handle, int redraw) |
5296 { | 5285 { |
5297 ListView_DeleteAllItems(handle); | 5286 int z = 0; |
5287 | |
5288 while((int)WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, (redraw ? CMA_INVALIDATE : 0) | CMA_FREE)) == -1) | |
5289 { | |
5290 z++; | |
5291 if(z > 5000000) | |
5292 break; | |
5293 DosSleep(1); | |
5294 } | |
5298 } | 5295 } |
5299 | 5296 |
5300 /* | 5297 /* |
5301 * Removes the first x rows from a container. | 5298 * Removes the first x rows from a container. |
5302 * Parameters: | 5299 * Parameters: |
5303 * handle: Handle to the window (widget) to be deleted from. | 5300 * handle: Handle to the window (widget) to be deleted from. |
5304 * rowcount: The number of rows to be deleted. | 5301 * rowcount: The number of rows to be deleted. |
5305 */ | 5302 */ |
5306 void dw_container_delete(HWND handle, int rowcount) | 5303 void dw_container_delete(HWND handle, int rowcount) |
5307 { | 5304 { |
5308 int z; | 5305 RECORDCORE *last, **prc = malloc(sizeof(RECORDCORE *) * rowcount); |
5309 | 5306 int current = 1, z; |
5310 for(z=0;z<rowcount;z++) | 5307 |
5311 { | 5308 prc[0] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); |
5312 ListView_DeleteItem(handle, 0); | 5309 |
5313 } | 5310 while(last && current < rowcount) |
5311 { | |
5312 prc[current] = last = (RECORDCORE *)WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)last, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); | |
5313 current++; | |
5314 } | |
5315 | |
5316 z = 0; | |
5317 | |
5318 while((int)WinSendMsg(handle, CM_REMOVERECORD, (MPARAM)prc, MPFROM2SHORT(current, CMA_INVALIDATE | CMA_FREE)) == -1) | |
5319 { | |
5320 z++; | |
5321 if(z > 5000000) | |
5322 break; | |
5323 DosSleep(1); | |
5324 } | |
5325 | |
5326 free(prc); | |
5314 } | 5327 } |
5315 | 5328 |
5316 /* | 5329 /* |
5317 * Scrolls container up or down. | 5330 * Scrolls container up or down. |
5318 * Parameters: | 5331 * Parameters: |
5324 void dw_container_scroll(HWND handle, int direction, long rows) | 5337 void dw_container_scroll(HWND handle, int direction, long rows) |
5325 { | 5338 { |
5326 switch(direction) | 5339 switch(direction) |
5327 { | 5340 { |
5328 case DW_SCROLL_TOP: | 5341 case DW_SCROLL_TOP: |
5329 ListView_Scroll(handle, 0, -10000000); | 5342 WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(-10000000)); |
5330 break; | 5343 break; |
5331 case DW_SCROLL_BOTTOM: | 5344 case DW_SCROLL_BOTTOM: |
5332 ListView_Scroll(handle, 0, 10000000); | 5345 WinSendMsg(handle, CM_SCROLLWINDOW, MPFROMSHORT(CMA_VERTICAL), MPFROMLONG(10000000)); |
5333 break; | 5346 break; |
5334 } | 5347 } |
5335 } | 5348 } |
5336 | 5349 |
5337 /* | 5350 /* |
5339 * Parameters: | 5352 * Parameters: |
5340 * handle: Handle to the window (widget) to be cleared. | 5353 * handle: Handle to the window (widget) to be cleared. |
5341 */ | 5354 */ |
5342 void dw_container_set_view(HWND handle, unsigned long flags, int iconwidth, int iconheight) | 5355 void dw_container_set_view(HWND handle, unsigned long flags, int iconwidth, int iconheight) |
5343 { | 5356 { |
5357 CNRINFO cnrinfo; | |
5358 | |
5359 cnrinfo.flWindowAttr = flags; | |
5360 cnrinfo.slBitmapOrIcon.cx = iconwidth; | |
5361 cnrinfo.slBitmapOrIcon.cy = iconheight; | |
5362 | |
5363 WinSendMsg(handle, CM_SETCNRINFO, &cnrinfo, MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON)); | |
5344 } | 5364 } |
5345 | 5365 |
5346 /* | 5366 /* |
5347 * Starts a new query of a container. | 5367 * Starts a new query of a container. |
5348 * Parameters: | 5368 * Parameters: |
5351 * return items that are currently selected. Otherwise | 5371 * return items that are currently selected. Otherwise |
5352 * it will return all records in the container. | 5372 * it will return all records in the container. |
5353 */ | 5373 */ |
5354 char *dw_container_query_start(HWND handle, unsigned long flags) | 5374 char *dw_container_query_start(HWND handle, unsigned long flags) |
5355 { | 5375 { |
5356 LV_ITEM lvi; | 5376 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)0L, MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); |
5357 | 5377 if(pCore) |
5358 if(flags) | 5378 { |
5359 _index = ListView_GetNextItem(handle, -1, LVNI_SELECTED); | 5379 if(flags) |
5360 else | 5380 { |
5361 _index = ListView_GetNextItem(handle, -1, LVNI_ALL); | 5381 while(pCore) |
5362 | 5382 { |
5363 | 5383 if(pCore->flRecordAttr & CRA_SELECTED) |
5364 lvi.iItem = _index; | 5384 return pCore->pszIcon; |
5365 lvi.mask = LVIF_PARAM; | 5385 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); |
5366 | 5386 } |
5367 ListView_GetItem(handle, &lvi); | 5387 } |
5368 | 5388 else |
5369 return (char *)lvi.lParam; | 5389 return pCore->pszIcon; |
5390 } | |
5391 return NULL; | |
5370 } | 5392 } |
5371 | 5393 |
5372 /* | 5394 /* |
5373 * Continues an existing query of a container. | 5395 * Continues an existing query of a container. |
5374 * Parameters: | 5396 * Parameters: |
5377 * return items that are currently selected. Otherwise | 5399 * return items that are currently selected. Otherwise |
5378 * it will return all records in the container. | 5400 * it will return all records in the container. |
5379 */ | 5401 */ |
5380 char *dw_container_query_next(HWND handle, unsigned long flags) | 5402 char *dw_container_query_next(HWND handle, unsigned long flags) |
5381 { | 5403 { |
5382 LV_ITEM lvi; | 5404 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); |
5383 | 5405 if(pCore) |
5384 if(flags) | 5406 { |
5385 _index = ListView_GetNextItem(handle, _index, LVNI_SELECTED); | 5407 if(flags) |
5386 else | 5408 { |
5387 _index = ListView_GetNextItem(handle, _index, LVNI_ALL); | 5409 while(pCore) |
5388 | 5410 { |
5389 if(_index == -1) | 5411 if(pCore->flRecordAttr & CRA_SELECTED) |
5390 return NULL; | 5412 return pCore->pszIcon; |
5391 | 5413 |
5392 lvi.iItem = _index; | 5414 pCore = WinSendMsg(handle, CM_QUERYRECORD, (MPARAM)pCore, MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)); |
5393 lvi.mask = LVIF_PARAM; | 5415 } |
5394 | 5416 } |
5395 ListView_GetItem(handle, &lvi); | 5417 else |
5396 | 5418 return pCore->pszIcon; |
5397 return (char *)lvi.lParam; | 5419 } |
5420 return NULL; | |
5398 } | 5421 } |
5399 | 5422 |
5400 /* | 5423 /* |
5401 * Creates a rendering context widget (window) to be packed. | 5424 * Creates a rendering context widget (window) to be packed. |
5402 * Parameters: | 5425 * Parameters: |
5404 * Returns: | 5427 * Returns: |
5405 * A handle to the widget or NULL on failure. | 5428 * A handle to the widget or NULL on failure. |
5406 */ | 5429 */ |
5407 HWND dw_render_new(unsigned long id) | 5430 HWND dw_render_new(unsigned long id) |
5408 { | 5431 { |
5409 Box *newbox = malloc(sizeof(Box)); | 5432 HWND hwndframe = WinCreateWindow(HWND_OBJECT, |
5410 HWND tmp = CreateWindow(ObjectClassName, | 5433 WC_FRAME, |
5411 "", | 5434 NULL, |
5412 WS_CHILD | WS_CLIPCHILDREN, | 5435 WS_VISIBLE | |
5413 0,0,2000,1000, | 5436 FS_NOBYTEALIGN, |
5414 DW_HWND_OBJECT, | 5437 0,0,2000,1000, |
5415 NULL, | 5438 NULLHANDLE, |
5416 NULL, | 5439 HWND_TOP, |
5417 NULL); | 5440 id, |
5418 newbox->pad = 0; | 5441 NULL, |
5419 newbox->type = 0; | 5442 NULL); |
5420 newbox->count = 0; | 5443 WinSubclassWindow(hwndframe, _RendProc); |
5421 newbox->grouphwnd = (HWND)NULL; | 5444 return hwndframe; |
5422 newbox->cinfo.pOldProc = SubclassWindow(tmp, _rendwndproc); | |
5423 newbox->cinfo.fore = newbox->cinfo.back = -1; | |
5424 | |
5425 SetWindowLong(tmp, GWL_USERDATA, (ULONG)newbox); | |
5426 return tmp; | |
5427 } | 5445 } |
5428 | 5446 |
5429 /* Sets the current foreground drawing color. | 5447 /* Sets the current foreground drawing color. |
5430 * Parameters: | 5448 * Parameters: |
5431 * red: red value. | 5449 * red: red value. |
5432 * green: green value. | 5450 * green: green value. |
5433 * blue: blue value. | 5451 * blue: blue value. |
5434 */ | 5452 */ |
5435 void dw_color_foreground_set(unsigned long value) | 5453 void dw_color_foreground_set(unsigned long value) |
5436 { | 5454 { |
5437 int threadid = dw_thread_id(); | 5455 _foreground = DW_RED_VALUE(value) << 16 | DW_GREEN_VALUE(value) << 8 | DW_BLUE_VALUE(value); |
5438 | |
5439 if(threadid < 0 || threadid >= THREAD_LIMIT) | |
5440 threadid = 0; | |
5441 | |
5442 DeleteObject(_hPen[threadid]); | |
5443 DeleteObject(_hBrush[threadid]); | |
5444 _foreground[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); | |
5445 _hPen[threadid] = CreatePen(PS_SOLID, 1, _foreground[threadid]); | |
5446 _hBrush[threadid] = CreateSolidBrush(_foreground[threadid]); | |
5447 } | 5456 } |
5448 | 5457 |
5449 /* Sets the current background drawing color. | 5458 /* Sets the current background drawing color. |
5450 * Parameters: | 5459 * Parameters: |
5451 * red: red value. | 5460 * red: red value. |
5452 * green: green value. | 5461 * green: green value. |
5453 * blue: blue value. | 5462 * blue: blue value. |
5454 */ | 5463 */ |
5455 void dw_color_background_set(unsigned long value) | 5464 void dw_color_background_set(unsigned long value) |
5456 { | 5465 { |
5457 int threadid = dw_thread_id(); | 5466 _background = DW_RED_VALUE(value) << 16 | DW_GREEN_VALUE(value) << 8 | DW_BLUE_VALUE(value); |
5458 | 5467 } |
5459 if(threadid < 0 || threadid >= THREAD_LIMIT) | 5468 |
5460 threadid = 0; | 5469 HPS _set_hps(HPS hps) |
5461 | 5470 { |
5462 _background[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); | 5471 LONG alTable[18]; |
5472 | |
5473 GpiQueryLogColorTable(hps, 0L, 0L, 18L, alTable); | |
5474 | |
5475 alTable[16] = _foreground; | |
5476 alTable[17] = _background; | |
5477 | |
5478 GpiCreateLogColorTable(hps, | |
5479 0L, | |
5480 LCOLF_CONSECRGB, | |
5481 0L, | |
5482 18, | |
5483 alTable); | |
5484 GpiSetColor(hps, 16); | |
5485 GpiSetBackColor(hps, 17); | |
5486 return hps; | |
5487 } | |
5488 | |
5489 HPS _set_colors(HWND handle) | |
5490 { | |
5491 HPS hps = WinGetPS(handle); | |
5492 | |
5493 _set_hps(hps); | |
5494 return hps; | |
5463 } | 5495 } |
5464 | 5496 |
5465 /* Draw a point on a window (preferably a render window). | 5497 /* Draw a point on a window (preferably a render window). |
5466 * Parameters: | 5498 * Parameters: |
5467 * handle: Handle to the window. | 5499 * handle: Handle to the window. |
5469 * x: X coordinate. | 5501 * x: X coordinate. |
5470 * y: Y coordinate. | 5502 * y: Y coordinate. |
5471 */ | 5503 */ |
5472 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) | 5504 void dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) |
5473 { | 5505 { |
5474 HDC hdcPaint; | 5506 HPS hps; |
5475 int threadid = dw_thread_id(); | 5507 int height; |
5476 | 5508 POINTL ptl; |
5477 if(threadid < 0 || threadid >= THREAD_LIMIT) | |
5478 threadid = 0; | |
5479 | 5509 |
5480 if(handle) | 5510 if(handle) |
5481 hdcPaint = GetDC(handle); | 5511 { |
5512 hps = _set_colors(handle); | |
5513 height = _get_height(handle); | |
5514 } | |
5482 else if(pixmap) | 5515 else if(pixmap) |
5483 hdcPaint = pixmap->hdc; | 5516 { |
5517 hps = _set_hps(pixmap->hps); | |
5518 height = pixmap->height; | |
5519 } | |
5484 else | 5520 else |
5485 return; | 5521 return; |
5486 | 5522 |
5487 SetPixel(hdcPaint, x, y, _foreground[threadid]); | 5523 ptl.x = x; |
5524 ptl.y = height - y - 1; | |
5525 | |
5526 GpiSetPel(hps, &ptl); | |
5488 if(!pixmap) | 5527 if(!pixmap) |
5489 ReleaseDC(handle, hdcPaint); | 5528 WinReleasePS(hps); |
5490 } | 5529 } |
5491 | 5530 |
5492 /* Draw a line on a window (preferably a render window). | 5531 /* Draw a line on a window (preferably a render window). |
5493 * Parameters: | 5532 * Parameters: |
5494 * handle: Handle to the window. | 5533 * handle: Handle to the window. |
5498 * x2: Second X coordinate. | 5537 * x2: Second X coordinate. |
5499 * y2: Second Y coordinate. | 5538 * y2: Second Y coordinate. |
5500 */ | 5539 */ |
5501 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) | 5540 void dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) |
5502 { | 5541 { |
5503 HDC hdcPaint; | 5542 HPS hps; |
5504 HPEN oldPen; | 5543 int height; |
5505 int threadid = dw_thread_id(); | 5544 POINTL ptl[2]; |
5506 | |
5507 if(threadid < 0 || threadid >= THREAD_LIMIT) | |
5508 threadid = 0; | |
5509 | 5545 |
5510 if(handle) | 5546 if(handle) |
5511 hdcPaint = GetDC(handle); | 5547 { |
5548 hps = _set_colors(handle); | |
5549 height = _get_height(handle); | |
5550 } | |
5512 else if(pixmap) | 5551 else if(pixmap) |
5513 hdcPaint = pixmap->hdc; | 5552 { |
5553 hps = _set_hps(pixmap->hps); | |
5554 height = pixmap->height; | |
5555 } | |
5514 else | 5556 else |
5515 return; | 5557 return; |
5516 | 5558 |
5517 oldPen = SelectObject(hdcPaint, _hPen[threadid]); | 5559 ptl[0].x = x1; |
5518 MoveToEx(hdcPaint, x1, y1, NULL); | 5560 ptl[0].y = height - y1 - 1; |
5519 LineTo(hdcPaint, x2, y2); | 5561 ptl[1].x = x2; |
5520 SelectObject(hdcPaint, oldPen); | 5562 ptl[1].y = height - y2 - 1; |
5521 /* For some reason Win98 (at least) fails | 5563 |
5522 * to draw the last pixel. So I do it myself. | 5564 GpiMove(hps, &ptl[0]); |
5523 */ | 5565 GpiLine(hps, &ptl[1]); |
5524 SetPixel(hdcPaint, x2, y2, _foreground[threadid]); | 5566 |
5525 if(!pixmap) | 5567 if(!pixmap) |
5526 ReleaseDC(handle, hdcPaint); | 5568 WinReleasePS(hps); |
5527 } | 5569 } |
5528 | 5570 |
5529 /* Draw a rectangle on a window (preferably a render window). | 5571 |
5530 * Parameters: | 5572 void _CopyFontSettings(HPS hpsSrc, HPS hpsDst) |
5531 * handle: Handle to the window. | 5573 { |
5532 * pixmap: Handle to the pixmap. (choose only one of these) | 5574 FONTMETRICS fm; |
5533 * x: X coordinate. | 5575 FATTRS fat; |
5534 * y: Y coordinate. | 5576 SIZEF sizf; |
5535 * width: Width of rectangle. | 5577 |
5536 * height: Height of rectangle. | 5578 GpiQueryFontMetrics(hpsSrc, sizeof(FONTMETRICS), &fm); |
5537 */ | 5579 |
5538 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) | 5580 memset(&fat, 0, sizeof(fat)); |
5539 { | 5581 |
5540 HDC hdcPaint; | 5582 fat.usRecordLength = sizeof(FATTRS); |
5541 HPEN oldPen; | 5583 fat.lMatch = fm.lMatch; |
5542 HBRUSH oldBrush; | 5584 strcpy(fat.szFacename, fm.szFacename); |
5543 int threadid = dw_thread_id(); | 5585 |
5544 | 5586 GpiCreateLogFont(hpsDst, 0, 1L, &fat); |
5545 if(threadid < 0 || threadid >= THREAD_LIMIT) | 5587 GpiSetCharSet(hpsDst, 1L); |
5546 threadid = 0; | 5588 |
5547 | 5589 sizf.cx = MAKEFIXED(fm.lEmInc,0); |
5548 if(handle) | 5590 sizf.cy = MAKEFIXED(fm.lMaxBaselineExt,0); |
5549 hdcPaint = GetDC(handle); | 5591 GpiSetCharBox(hpsDst, &sizf ); |
5550 else if(pixmap) | |
5551 hdcPaint = pixmap->hdc; | |
5552 else | |
5553 return; | |
5554 | |
5555 oldPen = SelectObject(hdcPaint, _hPen[threadid]); | |
5556 oldBrush = SelectObject(hdcPaint, _hBrush[threadid]); | |
5557 Rectangle(hdcPaint, x, y, x + width, y + height); | |
5558 SelectObject(hdcPaint, oldPen); | |
5559 SelectObject(hdcPaint, oldBrush); | |
5560 if(!pixmap) | |
5561 ReleaseDC(handle, hdcPaint); | |
5562 } | 5592 } |
5563 | 5593 |
5564 /* Draw text on a window (preferably a render window). | 5594 /* Draw text on a window (preferably a render window). |
5565 * Parameters: | 5595 * Parameters: |
5566 * handle: Handle to the window. | 5596 * handle: Handle to the window. |
5569 * y: Y coordinate. | 5599 * y: Y coordinate. |
5570 * text: Text to be displayed. | 5600 * text: Text to be displayed. |
5571 */ | 5601 */ |
5572 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text) | 5602 void dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text) |
5573 { | 5603 { |
5574 HDC hdc; | 5604 HPS hps; |
5575 int size = 9, z, mustdelete = 0; | 5605 int size = 9, z, height; |
5576 HFONT hFont, oldFont; | 5606 RECTL rcl; |
5577 int threadid = dw_thread_id(); | 5607 char fontname[128]; |
5578 | |
5579 if(threadid < 0 || threadid >= THREAD_LIMIT) | |
5580 threadid = 0; | |
5581 | 5608 |
5582 if(handle) | 5609 if(handle) |
5583 hdc = GetDC(handle); | 5610 { |
5611 hps = _set_colors(handle); | |
5612 height = _get_height(handle); | |
5613 _GetPPFont(handle, fontname); | |
5614 } | |
5584 else if(pixmap) | 5615 else if(pixmap) |
5585 hdc = pixmap->hdc; | 5616 { |
5617 HPS pixmaphps = WinGetPS(pixmap->handle); | |
5618 | |
5619 hps = _set_hps(pixmap->hps); | |
5620 height = pixmap->height; | |
5621 _GetPPFont(pixmap->handle, fontname); | |
5622 _CopyFontSettings(pixmaphps, hps); | |
5623 WinReleasePS(pixmaphps); | |
5624 } | |
5586 else | 5625 else |
5587 return; | 5626 return; |
5588 | 5627 |
5589 { | 5628 for(z=0;z<strlen(fontname);z++) |
5590 ColorInfo *cinfo; | 5629 { |
5591 | 5630 if(fontname[z]=='.') |
5592 if(handle) | 5631 break; |
5593 cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | 5632 } |
5594 else | 5633 size = atoi(fontname); |
5595 cinfo = (ColorInfo *)GetWindowLong(pixmap->handle, GWL_USERDATA); | 5634 |
5596 | 5635 rcl.xLeft = x; |
5597 if(cinfo) | 5636 rcl.yTop = height - y; |
5598 { | 5637 rcl.yBottom = rcl.yTop - (size*2); |
5599 hFont = _aquire_font(cinfo->fontname); | 5638 rcl.xRight = rcl.xLeft + (size * strlen(text)); |
5600 mustdelete = 1; | 5639 |
5601 } | 5640 WinDrawText(hps, -1, text, &rcl, DT_TEXTATTRS, DT_TEXTATTRS, DT_VCENTER | DT_LEFT | DT_TEXTATTRS); |
5602 } | 5641 |
5603 oldFont = SelectObject(hdc, hFont); | |
5604 SetTextColor(hdc, _foreground[threadid]); | |
5605 SetBkMode(hdc, TRANSPARENT); | |
5606 TextOut(hdc, x, y, text, strlen(text)); | |
5607 SelectObject(hdc, oldFont); | |
5608 if(mustdelete) | |
5609 DeleteObject(hFont); | |
5610 if(!pixmap) | 5642 if(!pixmap) |
5611 ReleaseDC(handle, hdc); | 5643 WinReleasePS(hps); |
5612 } | 5644 } |
5613 | 5645 |
5614 /* Query the width and height of a text string. | 5646 /* Query the width and height of a text string. |
5615 * Parameters: | 5647 * Parameters: |
5616 * handle: Handle to the window. | 5648 * handle: Handle to the window. |
5619 * width: Pointer to a variable to be filled in with the width. | 5651 * width: Pointer to a variable to be filled in with the width. |
5620 * height Pointer to a variable to be filled in with the height. | 5652 * height Pointer to a variable to be filled in with the height. |
5621 */ | 5653 */ |
5622 void dw_font_text_extents(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) | 5654 void dw_font_text_extents(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) |
5623 { | 5655 { |
5624 HDC hdc; | 5656 HPS hps; |
5625 int mustdelete = 0; | 5657 POINTL aptl[TXTBOX_COUNT]; |
5626 HFONT hFont, oldFont; | |
5627 SIZE sz; | |
5628 | 5658 |
5629 if(handle) | 5659 if(handle) |
5630 hdc = GetDC(handle); | 5660 { |
5661 hps = _set_colors(handle); | |
5662 } | |
5631 else if(pixmap) | 5663 else if(pixmap) |
5632 hdc = pixmap->hdc; | 5664 { |
5665 HPS pixmaphps = WinGetPS(pixmap->handle); | |
5666 | |
5667 hps = _set_hps(pixmap->hps); | |
5668 _CopyFontSettings(pixmaphps, hps); | |
5669 WinReleasePS(pixmaphps); | |
5670 } | |
5633 else | 5671 else |
5634 return; | 5672 return; |
5635 | 5673 |
5636 { | 5674 GpiQueryTextBox(hps, strlen(text), text, TXTBOX_COUNT, aptl); |
5637 ColorInfo *cinfo; | |
5638 | |
5639 if(handle) | |
5640 cinfo = (ColorInfo *)GetWindowLong(handle, GWL_USERDATA); | |
5641 else | |
5642 cinfo = (ColorInfo *)GetWindowLong(pixmap->handle, GWL_USERDATA); | |
5643 | |
5644 if(cinfo) | |
5645 { | |
5646 hFont = _aquire_font(cinfo->fontname); | |
5647 mustdelete = 1; | |
5648 } | |
5649 } | |
5650 oldFont = SelectObject(hdc, hFont); | |
5651 | |
5652 GetTextExtentPoint32(hdc, text, strlen(text), &sz); | |
5653 | 5675 |
5654 if(width) | 5676 if(width) |
5655 *width = sz.cx; | 5677 *width = aptl[TXTBOX_TOPRIGHT].x - aptl[TXTBOX_TOPLEFT].x; |
5656 | 5678 |
5657 if(height) | 5679 if(height) |
5658 *height = sz.cy; | 5680 *height = aptl[TXTBOX_TOPLEFT].y - aptl[TXTBOX_BOTTOMLEFT].y; |
5659 | 5681 |
5660 SelectObject(hdc, oldFont); | |
5661 if(mustdelete) | |
5662 DeleteObject(hFont); | |
5663 if(!pixmap) | 5682 if(!pixmap) |
5664 ReleaseDC(handle, hdc); | 5683 WinReleasePS(hps); |
5684 } | |
5685 | |
5686 /* Draw a rectangle on a window (preferably a render window). | |
5687 * Parameters: | |
5688 * handle: Handle to the window. | |
5689 * pixmap: Handle to the pixmap. (choose only one of these) | |
5690 * fill: Fill box TRUE or FALSE. | |
5691 * x: X coordinate. | |
5692 * y: Y coordinate. | |
5693 * width: Width of rectangle. | |
5694 * height: Height of rectangle. | |
5695 */ | |
5696 void dw_draw_rect(HWND handle, HPIXMAP pixmap, int fill, int x, int y, int width, int height) | |
5697 { | |
5698 HPS hps; | |
5699 int thisheight; | |
5700 POINTL ptl[2]; | |
5701 | |
5702 if(handle) | |
5703 { | |
5704 hps = _set_colors(handle); | |
5705 thisheight = _get_height(handle); | |
5706 } | |
5707 else if(pixmap) | |
5708 { | |
5709 hps = _set_hps(pixmap->hps); | |
5710 thisheight = pixmap->height; | |
5711 } | |
5712 else | |
5713 return; | |
5714 | |
5715 ptl[0].x = x; | |
5716 ptl[0].y = thisheight - y - 1; | |
5717 ptl[1].x = x + width - 1; | |
5718 ptl[1].y = thisheight - y - height; | |
5719 | |
5720 GpiMove(hps, &ptl[0]); | |
5721 GpiBox(hps, fill ? DRO_OUTLINEFILL : DRO_OUTLINE, &ptl[1], 0, 0); | |
5722 | |
5723 if(!pixmap) | |
5724 WinReleasePS(hps); | |
5665 } | 5725 } |
5666 | 5726 |
5667 /* Call this after drawing to the screen to make sure | 5727 /* Call this after drawing to the screen to make sure |
5668 * anything you have drawn is visible. | 5728 * anything you have drawn is visible. |
5669 */ | 5729 */ |
5681 * Returns: | 5741 * Returns: |
5682 * A handle to a pixmap or NULL on failure. | 5742 * A handle to a pixmap or NULL on failure. |
5683 */ | 5743 */ |
5684 HPIXMAP dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) | 5744 HPIXMAP dw_pixmap_new(HWND handle, unsigned long width, unsigned long height, int depth) |
5685 { | 5745 { |
5746 BITMAPINFOHEADER bmih; | |
5747 SIZEL sizl = { 0, 0 }; | |
5686 HPIXMAP pixmap; | 5748 HPIXMAP pixmap; |
5687 BITMAP bm; | |
5688 HDC hdc; | 5749 HDC hdc; |
5750 HPS hps; | |
5751 ULONG ulFlags; | |
5752 LONG cPlanes, cBitCount; | |
5689 | 5753 |
5690 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) | 5754 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) |
5691 return NULL; | 5755 return NULL; |
5692 | 5756 |
5693 hdc = GetDC(handle); | 5757 hps = WinGetPS(handle); |
5758 | |
5759 hdc = GpiQueryDevice(hps); | |
5760 ulFlags = GpiQueryPS(hps, &sizl); | |
5761 | |
5762 pixmap->handle = handle; | |
5763 pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc); | |
5764 pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); | |
5765 | |
5766 DevQueryCaps(hdc, CAPS_COLOR_PLANES , 1L, &cPlanes); | |
5767 if (!depth) | |
5768 { | |
5769 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1L, &cBitCount); | |
5770 depth = cBitCount; | |
5771 } | |
5772 | |
5773 memset(&bmih, 0, sizeof(BITMAPINFOHEADER)); | |
5774 bmih.cbFix = sizeof(BITMAPINFOHEADER); | |
5775 bmih.cx = (SHORT)width; | |
5776 bmih.cy = (SHORT)height; | |
5777 bmih.cPlanes = (SHORT)cPlanes; | |
5778 bmih.cBitCount = (SHORT)depth; | |
5694 | 5779 |
5695 pixmap->width = width; pixmap->height = height; | 5780 pixmap->width = width; pixmap->height = height; |
5696 | 5781 |
5697 pixmap->handle = handle; | 5782 pixmap->hbm = GpiCreateBitmap(pixmap->hps, (PBITMAPINFOHEADER2)&bmih, 0L, NULL, NULL); |
5698 pixmap->hbm = CreateCompatibleBitmap(hdc, width, height); | 5783 |
5699 pixmap->hdc = CreateCompatibleDC(hdc); | 5784 GpiSetBitmap(pixmap->hps, pixmap->hbm); |
5700 | 5785 |
5701 SelectObject(pixmap->hdc, pixmap->hbm); | 5786 if (depth>8) |
5702 | 5787 GpiCreateLogColorTable(pixmap->hps, LCOL_PURECOLOR, LCOLF_RGB, 0, 0, NULL ); |
5703 ReleaseDC(handle, hdc); | 5788 |
5789 WinReleasePS(hps); | |
5704 | 5790 |
5705 return pixmap; | 5791 return pixmap; |
5706 } | 5792 } |
5707 | 5793 |
5708 /* | 5794 /* |
5713 * Returns: | 5799 * Returns: |
5714 * A handle to a pixmap or NULL on failure. | 5800 * A handle to a pixmap or NULL on failure. |
5715 */ | 5801 */ |
5716 HPIXMAP dw_pixmap_grab(HWND handle, ULONG id) | 5802 HPIXMAP dw_pixmap_grab(HWND handle, ULONG id) |
5717 { | 5803 { |
5804 BITMAPINFOHEADER bmih; | |
5805 SIZEL sizl = { 0, 0 }; | |
5718 HPIXMAP pixmap; | 5806 HPIXMAP pixmap; |
5719 BITMAP bm; | |
5720 HDC hdc; | 5807 HDC hdc; |
5808 HPS hps; | |
5809 ULONG ulFlags; | |
5721 | 5810 |
5722 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) | 5811 if (!(pixmap = calloc(1,sizeof(struct _hpixmap)))) |
5723 return NULL; | 5812 return NULL; |
5724 | 5813 |
5725 hdc = GetDC(handle); | 5814 hps = WinGetPS(handle); |
5726 | 5815 |
5727 | 5816 hdc = GpiQueryDevice(hps); |
5728 pixmap->hbm = LoadBitmap(DWInstance, MAKEINTRESOURCE(id)); | 5817 ulFlags = GpiQueryPS(hps, &sizl); |
5729 pixmap->hdc = CreateCompatibleDC(hdc); | 5818 |
5730 | 5819 pixmap->hdc = DevOpenDC(dwhab, OD_MEMORY, "*", 0L, NULL, hdc); |
5731 GetObject(pixmap->hbm, sizeof(BITMAP), (void *)&bm); | 5820 pixmap->hps = GpiCreatePS (dwhab, pixmap->hdc, &sizl, ulFlags | GPIA_ASSOC); |
5732 | 5821 |
5733 pixmap->width = bm.bmWidth; pixmap->height = bm.bmHeight; | 5822 pixmap->hbm = GpiLoadBitmap(pixmap->hps, NULLHANDLE, id, 0, 0); |
5734 | 5823 |
5735 SelectObject(pixmap->hdc, pixmap->hbm); | 5824 GpiQueryBitmapParameters(pixmap->hbm, &bmih); |
5736 | 5825 |
5737 ReleaseDC(handle, hdc); | 5826 GpiSetBitmap(pixmap->hps, pixmap->hbm); |
5827 | |
5828 pixmap->width = bmih.cx; pixmap->height = bmih.cy; | |
5829 | |
5830 WinReleasePS(hps); | |
5738 | 5831 |
5739 return pixmap; | 5832 return pixmap; |
5740 } | 5833 } |
5741 | 5834 |
5742 /* | 5835 /* |
5745 * pixmap: Handle to a pixmap returned by | 5838 * pixmap: Handle to a pixmap returned by |
5746 * dw_pixmap_new.. | 5839 * dw_pixmap_new.. |
5747 */ | 5840 */ |
5748 void dw_pixmap_destroy(HPIXMAP pixmap) | 5841 void dw_pixmap_destroy(HPIXMAP pixmap) |
5749 { | 5842 { |
5750 if(pixmap) | 5843 GpiSetBitmap(pixmap->hps, NULLHANDLE); |
5751 { | 5844 GpiDeleteBitmap(pixmap->hbm); |
5752 DeleteDC(pixmap->hdc); | 5845 GpiAssociate(pixmap->hps, NULLHANDLE); |
5753 DeleteObject(pixmap->hbm); | 5846 GpiDestroyPS(pixmap->hps); |
5754 free(pixmap); | 5847 DevCloseDC(pixmap->hdc); |
5755 } | 5848 free(pixmap); |
5756 } | 5849 } |
5757 | 5850 |
5758 /* | 5851 /* |
5759 * Copies from one item to another. | 5852 * Copies from one item to another. |
5760 * Parameters: | 5853 * Parameters: |
5769 * xsrc: X coordinate of source. | 5862 * xsrc: X coordinate of source. |
5770 * ysrc: Y coordinate of source. | 5863 * ysrc: Y coordinate of source. |
5771 */ | 5864 */ |
5772 void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) | 5865 void dw_pixmap_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc) |
5773 { | 5866 { |
5774 HDC hdcdest; | 5867 HPS hpsdest; |
5775 HDC hdcsrc; | 5868 HPS hpssrc; |
5869 POINTL ptl[4]; | |
5870 int destheight, srcheight; | |
5776 | 5871 |
5777 if(dest) | 5872 if(dest) |
5778 hdcdest = GetDC(dest); | 5873 { |
5874 hpsdest = WinGetPS(dest); | |
5875 destheight = _get_height(dest); | |
5876 } | |
5779 else if(destp) | 5877 else if(destp) |
5780 hdcdest = destp->hdc; | 5878 { |
5879 hpsdest = destp->hps; | |
5880 destheight = destp->height; | |
5881 } | |
5781 else | 5882 else |
5782 return; | 5883 return; |
5783 | 5884 |
5784 if(src) | 5885 if(src) |
5785 hdcsrc = GetDC(src); | 5886 { |
5887 hpssrc = WinGetPS(src); | |
5888 srcheight = _get_height(src); | |
5889 } | |
5786 else if(srcp) | 5890 else if(srcp) |
5787 hdcsrc = srcp->hdc; | 5891 { |
5892 hpssrc = srcp->hps; | |
5893 srcheight = srcp->height; | |
5894 } | |
5788 else | 5895 else |
5896 { | |
5897 if(!destp) | |
5898 WinReleasePS(hpsdest); | |
5789 return; | 5899 return; |
5790 | 5900 } |
5791 BitBlt(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, SRCCOPY); | 5901 |
5902 ptl[0].x = xdest; | |
5903 ptl[0].y = (destheight - ydest) - height; | |
5904 ptl[1].x = ptl[0].x + width; | |
5905 ptl[1].y = destheight - ydest; | |
5906 ptl[2].x = xsrc; | |
5907 ptl[2].y = srcheight - (ysrc + height); | |
5908 ptl[3].x = ptl[2].x + width; | |
5909 ptl[3].y = ptl[2].y + height; | |
5910 | |
5911 GpiBitBlt(hpsdest, hpssrc, 4, ptl, ROP_SRCCOPY, BBO_IGNORE); | |
5792 | 5912 |
5793 if(!destp) | 5913 if(!destp) |
5794 ReleaseDC(dest, hdcdest); | 5914 WinReleasePS(hpsdest); |
5795 if(!srcp) | 5915 if(!srcp) |
5796 ReleaseDC(src, hdcsrc); | 5916 WinReleasePS(hpssrc); |
5797 } | 5917 } |
5798 | 5918 |
5799 /* | 5919 /* |
5800 * Emits a beep. | 5920 * Emits a beep. |
5801 * Parameters: | 5921 * Parameters: |
5802 * freq: Frequency. | 5922 * freq: Frequency. |
5803 * dur: Duration. | 5923 * dur: Duration. |
5804 */ | 5924 */ |
5805 void dw_beep(int freq, int dur) | 5925 void dw_beep(int freq, int dur) |
5806 { | 5926 { |
5807 Beep(freq, dur); | 5927 DosBeep(freq, dur); |
5808 } | 5928 } |
5809 | 5929 |
5810 /* | 5930 /* |
5811 * Returns the handle to an unnamed mutex semaphore. | 5931 * Returns the handle to an unnamed mutex semaphore. |
5812 */ | 5932 */ |
5813 HMTX dw_mutex_new(void) | 5933 HMTX dw_mutex_new(void) |
5814 { | 5934 { |
5815 return (HMTX)CreateMutex(NULL, FALSE, NULL); | 5935 HMTX mutex; |
5936 | |
5937 DosCreateMutexSem(NULL, &mutex, 0, FALSE); | |
5938 return mutex; | |
5816 } | 5939 } |
5817 | 5940 |
5818 /* | 5941 /* |
5819 * Closes a semaphore created by dw_mutex_new(). | 5942 * Closes a semaphore created by dw_mutex_new(). |
5820 * Parameters: | 5943 * Parameters: |
5821 * mutex: The handle to the mutex returned by dw_mutex_new(). | 5944 * mutex: The handle to the mutex returned by dw_mutex_new(). |
5822 */ | 5945 */ |
5823 void dw_mutex_close(HMTX mutex) | 5946 void dw_mutex_close(HMTX mutex) |
5824 { | 5947 { |
5825 CloseHandle((HANDLE)mutex); | 5948 DosCloseMutexSem(mutex); |
5826 } | 5949 } |
5827 | 5950 |
5828 /* | 5951 /* |
5829 * Tries to gain access to the semaphore, if it can't it blocks. | 5952 * Tries to gain access to the semaphore, if it can't it blocks. |
5830 * Parameters: | 5953 * Parameters: |
5831 * mutex: The handle to the mutex returned by dw_mutex_new(). | 5954 * mutex: The handle to the mutex returned by dw_mutex_new(). |
5832 */ | 5955 */ |
5833 void dw_mutex_lock(HMTX mutex) | 5956 void dw_mutex_lock(HMTX mutex) |
5834 { | 5957 { |
5835 WaitForSingleObject((HANDLE)mutex, INFINITE); | 5958 DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT); |
5836 } | 5959 } |
5837 | 5960 |
5838 /* | 5961 /* |
5839 * Reliquishes the access to the semaphore. | 5962 * Reliquishes the access to the semaphore. |
5840 * Parameters: | 5963 * Parameters: |
5841 * mutex: The handle to the mutex returned by dw_mutex_new(). | 5964 * mutex: The handle to the mutex returned by dw_mutex_new(). |
5842 */ | 5965 */ |
5843 void dw_mutex_unlock(HMTX mutex) | 5966 void dw_mutex_unlock(HMTX mutex) |
5844 { | 5967 { |
5845 ReleaseMutex((HANDLE)mutex); | 5968 DosReleaseMutexSem(mutex); |
5846 } | 5969 } |
5847 | 5970 |
5848 /* | 5971 /* |
5849 * Returns the handle to an unnamed event semaphore. | 5972 * Returns the handle to an unnamed event semaphore. |
5850 */ | 5973 */ |
5851 HEV dw_event_new(void) | 5974 HEV dw_event_new(void) |
5852 { | 5975 { |
5853 return CreateEvent(NULL, TRUE, FALSE, NULL); | 5976 HEV blah; |
5977 | |
5978 if(DosCreateEventSem (NULL, &blah, 0L, FALSE)) | |
5979 return 0; | |
5980 | |
5981 return blah; | |
5854 } | 5982 } |
5855 | 5983 |
5856 /* | 5984 /* |
5857 * Resets a semaphore created by dw_event_new(). | 5985 * Resets a semaphore created by dw_event_new(). |
5858 * Parameters: | 5986 * Parameters: |
5859 * eve: The handle to the event returned by dw_event_new(). | 5987 * eve: The handle to the event returned by dw_event_new(). |
5860 */ | 5988 */ |
5861 int dw_event_reset(HEV eve) | 5989 int dw_event_reset(HEV eve) |
5862 { | 5990 { |
5863 return ResetEvent(eve); | 5991 ULONG count; |
5992 | |
5993 if(DosResetEventSem(eve, &count)) | |
5994 return FALSE; | |
5995 return TRUE; | |
5864 } | 5996 } |
5865 | 5997 |
5866 /* | 5998 /* |
5867 * Posts a semaphore created by dw_event_new(). Causing all threads | 5999 * Posts a semaphore created by dw_event_new(). Causing all threads |
5868 * waiting on this event in dw_event_wait to continue. | 6000 * waiting on this event in dw_event_wait to continue. |
5869 * Parameters: | 6001 * Parameters: |
5870 * eve: The handle to the event returned by dw_event_new(). | 6002 * eve: The handle to the event returned by dw_event_new(). |
5871 */ | 6003 */ |
5872 int dw_event_post(HEV eve) | 6004 int dw_event_post(HEV eve) |
5873 { | 6005 { |
5874 return SetEvent(eve); | 6006 if(DosPostEventSem(eve)) |
5875 } | 6007 return FALSE; |
6008 return TRUE; | |
6009 } | |
6010 | |
5876 | 6011 |
5877 /* | 6012 /* |
5878 * Waits on a semaphore created by dw_event_new(), until the | 6013 * Waits on a semaphore created by dw_event_new(), until the |
5879 * event gets posted or until the timeout expires. | 6014 * event gets posted or until the timeout expires. |
5880 * Parameters: | 6015 * Parameters: |
5881 * eve: The handle to the event returned by dw_event_new(). | 6016 * eve: The handle to the event returned by dw_event_new(). |
5882 */ | 6017 */ |
5883 int dw_event_wait(HEV eve, unsigned long timeout) | 6018 int dw_event_wait(HEV eve, unsigned long timeout) |
5884 { | 6019 { |
5885 int rc; | 6020 int rc = DosWaitEventSem(eve, timeout); |
5886 | 6021 if(!rc) |
5887 rc = WaitForSingleObject(eve, timeout); | |
5888 if(rc == WAIT_OBJECT_0) | |
5889 return 1; | 6022 return 1; |
5890 if(rc == WAIT_ABANDONED) | 6023 if(rc == ERROR_TIMEOUT) |
5891 return -1; | 6024 return -1; |
5892 return 0; | 6025 return 0; |
5893 } | 6026 } |
5894 | 6027 |
5895 /* | 6028 /* |
5897 * Parameters: | 6030 * Parameters: |
5898 * eve: The handle to the event returned by dw_event_new(). | 6031 * eve: The handle to the event returned by dw_event_new(). |
5899 */ | 6032 */ |
5900 int dw_event_close(HEV *eve) | 6033 int dw_event_close(HEV *eve) |
5901 { | 6034 { |
5902 if(eve) | 6035 if(!eve || ~DosCloseEventSem(*eve)) |
5903 return CloseHandle(*eve); | 6036 return FALSE; |
5904 return FALSE; | 6037 return TRUE; |
6038 } | |
6039 | |
6040 /* | |
6041 * Encapsulate the message queues on OS/2. | |
6042 */ | |
6043 void _dwthreadstart(void *data) | |
6044 { | |
6045 HAB thishab = WinInitialize(0); | |
6046 HMQ thishmq = WinCreateMsgQueue(dwhab, 0); | |
6047 void (*threadfunc)(void *) = NULL; | |
6048 void **tmp = (void **)data; | |
6049 | |
6050 threadfunc = (void (*)(void *))tmp[0]; | |
6051 threadfunc(tmp[1]); | |
6052 | |
6053 free(tmp); | |
6054 | |
6055 WinDestroyMsgQueue(thishmq); | |
6056 WinTerminate(thishab); | |
5905 } | 6057 } |
5906 | 6058 |
5907 /* | 6059 /* |
5908 * Creates a new thread with a starting point of func. | 6060 * Creates a new thread with a starting point of func. |
5909 * Parameters: | 6061 * Parameters: |
5911 * data: Parameter(s) passed to the function. | 6063 * data: Parameter(s) passed to the function. |
5912 * stack: Stack size of new thread (OS/2 and Windows only). | 6064 * stack: Stack size of new thread (OS/2 and Windows only). |
5913 */ | 6065 */ |
5914 DWTID dw_thread_new(void *func, void *data, int stack) | 6066 DWTID dw_thread_new(void *func, void *data, int stack) |
5915 { | 6067 { |
5916 #if defined(__CYGWIN__) | 6068 void **tmp = malloc(sizeof(void *) * 2); |
5917 return 0; | 6069 |
5918 #else | 6070 tmp[0] = func; |
5919 return (DWTID)_beginthread((void(*)(void *))func, stack, data); | 6071 tmp[1] = data; |
6072 | |
6073 return (DWTID)_beginthread((void (*)(void *))_dwthreadstart, NULL, stack, (void *)tmp); | |
6074 } | |
6075 | |
6076 /* | |
6077 * Ends execution of current thread immediately. | |
6078 */ | |
6079 void dw_thread_end(void) | |
6080 { | |
6081 _endthread(); | |
6082 } | |
6083 | |
6084 /* | |
6085 * Returns the current thread's ID. | |
6086 */ | |
6087 DWTID dw_thread_id(void) | |
6088 { | |
6089 return (DWTID)_threadid; | |
6090 } | |
6091 | |
6092 /* | |
6093 * Cleanly terminates a DW session, should be signal handler safe. | |
6094 * Parameters: | |
6095 * exitcode: Exit code reported to the operating system. | |
6096 */ | |
6097 void dw_exit(int exitcode) | |
6098 { | |
6099 /* In case we are in a signal handler, don't | |
6100 * try to free memory that could possibly be | |
6101 * free()'d by the runtime already. | |
6102 */ | |
6103 #ifndef NO_SIGNALS | |
6104 Root = NULL; | |
5920 #endif | 6105 #endif |
5921 } | |
5922 | |
5923 /* | |
5924 * Ends execution of current thread immediately. | |
5925 */ | |
5926 void dw_thread_end(void) | |
5927 { | |
5928 #if !defined(__CYGWIN__) | |
5929 _endthread(); | |
5930 #endif | |
5931 } | |
5932 | |
5933 /* | |
5934 * Returns the current thread's ID. | |
5935 */ | |
5936 DWTID dw_thread_id(void) | |
5937 { | |
5938 #if defined(__CYGWIN__) | |
5939 return 0; | |
5940 #else | |
5941 return (DWTID)GetCurrentThreadId(); | |
5942 #endif | |
5943 } | |
5944 | |
5945 /* | |
5946 * Cleanly terminates a DW session, should be signal handler safe. | |
5947 * Parameters: | |
5948 * exitcode: Exit code reported to the operating system. | |
5949 */ | |
5950 void dw_exit(int exitcode) | |
5951 { | |
5952 exit(exitcode); | 6106 exit(exitcode); |
5953 } | 6107 } |
5954 | 6108 |
5955 /* | 6109 /* |
5956 * Pack a splitbar (sizer) into the specified box from the start. | 6110 * Pack a splitbar (sizer) into the specified box from the start. |
5957 * Parameters: | 6111 * Parameters: |
5958 * box: Window handle of the box to be packed into. | 6112 * box: Window handle of the box to be packed into. |
5959 */ | 6113 */ |
5960 void dw_box_pack_splitbar_start(HWND box) | 6114 void dw_box_pack_splitbar_start(HWND box) |
5961 { | 6115 { |
5962 Box *thisbox = (Box *)GetWindowLong(box, GWL_USERDATA); | 6116 Box *thisbox; |
5963 | 6117 |
6118 if(WinWindowFromID(box, FID_CLIENT)) | |
6119 { | |
6120 box = WinWindowFromID(box, FID_CLIENT); | |
6121 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6122 } | |
6123 else | |
6124 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
5964 if(thisbox) | 6125 if(thisbox) |
5965 { | 6126 { |
5966 HWND tmp = CreateWindow(SplitbarClassName, | 6127 HWND tmp = WinCreateWindow(HWND_OBJECT, |
5967 "", | 6128 SplitbarClassName, |
5968 WS_CHILD | WS_CLIPCHILDREN, | 6129 NULL, |
5969 0,0,2000,1000, | 6130 WS_VISIBLE, |
5970 DW_HWND_OBJECT, | 6131 0,0,2000,1000, |
5971 NULL, | 6132 NULLHANDLE, |
5972 NULL, | 6133 HWND_TOP, |
5973 NULL); | 6134 0L, |
6135 NULL, | |
6136 NULL); | |
5974 if(thisbox->type == BOXVERT) | 6137 if(thisbox->type == BOXVERT) |
5975 dw_box_pack_start(box, tmp, 1, SPLITBAR_WIDTH, TRUE, FALSE, 0); | 6138 dw_box_pack_start(box, tmp, 1, SPLITBAR_WIDTH, TRUE, FALSE, 0); |
5976 else | 6139 else |
5977 dw_box_pack_start(box, tmp, SPLITBAR_WIDTH, 1, FALSE, TRUE, 0); | 6140 dw_box_pack_start(box, tmp, SPLITBAR_WIDTH, 1, FALSE, TRUE, 0); |
5978 | 6141 |
5984 * Parameters: | 6147 * Parameters: |
5985 * box: Window handle of the box to be packed into. | 6148 * box: Window handle of the box to be packed into. |
5986 */ | 6149 */ |
5987 void dw_box_pack_splitbar_end(HWND box) | 6150 void dw_box_pack_splitbar_end(HWND box) |
5988 { | 6151 { |
5989 Box *thisbox = (Box *)GetWindowLong(box, GWL_USERDATA); | 6152 Box *thisbox; |
5990 | 6153 |
6154 if(WinWindowFromID(box, FID_CLIENT)) | |
6155 { | |
6156 box = WinWindowFromID(box, FID_CLIENT); | |
6157 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6158 } | |
6159 else | |
6160 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
5991 if(thisbox) | 6161 if(thisbox) |
5992 { | 6162 { |
5993 HWND tmp = CreateWindow(SplitbarClassName, | 6163 HWND tmp = WinCreateWindow(HWND_OBJECT, |
5994 "", | 6164 SplitbarClassName, |
5995 WS_CHILD | WS_CLIPCHILDREN, | 6165 NULL, |
5996 0,0,2000,1000, | 6166 WS_VISIBLE, |
5997 DW_HWND_OBJECT, | 6167 0,0,2000,1000, |
5998 NULL, | 6168 NULLHANDLE, |
5999 NULL, | 6169 HWND_TOP, |
6000 NULL); | 6170 0L, |
6171 NULL, | |
6172 NULL); | |
6001 if(thisbox->type == BOXVERT) | 6173 if(thisbox->type == BOXVERT) |
6002 dw_box_pack_end(box, tmp, 1, SPLITBAR_WIDTH, TRUE, FALSE, 0); | 6174 dw_box_pack_end(box, tmp, 1, SPLITBAR_WIDTH, TRUE, FALSE, 0); |
6003 else | 6175 else |
6004 dw_box_pack_end(box, tmp, SPLITBAR_WIDTH, 1, FALSE, TRUE, 0); | 6176 dw_box_pack_end(box, tmp, SPLITBAR_WIDTH, 1, FALSE, TRUE, 0); |
6005 | 6177 |
6006 } | 6178 } |
6007 } | 6179 } |
6008 | 6180 |
6009 /* | 6181 /* |
6010 * Pack windows (widgets) into a box from the end (or bottom). | 6182 * Pack windows (widgets) into a box from the start (or top). |
6011 * Parameters: | 6183 * Parameters: |
6012 * box: Window handle of the box to be packed into. | 6184 * box: Window handle of the box to be packed into. |
6013 * item: Window handle of the item to be back. | 6185 * item: Window handle of the item to be back. |
6014 * width: Width in pixels of the item or -1 to be self determined. | 6186 * width: Width in pixels of the item or -1 to be self determined. |
6015 * height: Height in pixels of the item or -1 to be self determined. | 6187 * height: Height in pixels of the item or -1 to be self determined. |
6016 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. | 6188 * hsize: TRUE if the window (widget) should expand horizontally to fill space given. |
6017 * vsize: TRUE if the window (widget) should expand vertically to fill space given. | 6189 * vsize: TRUE if the window (widget) should expand vertically to fill space given. |
6018 * pad: Number of pixels of padding around the item. | 6190 * pad: Number of pixels of padding around the item. |
6019 */ | 6191 */ |
6020 void dw_box_pack_end(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | 6192 void dw_box_pack_start(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) |
6021 { | 6193 { |
6022 Box *thisbox; | 6194 Box *thisbox; |
6023 | 6195 |
6024 thisbox = (Box *)GetWindowLong(box, GWL_USERDATA); | 6196 if(WinWindowFromID(box, FID_CLIENT)) |
6197 { | |
6198 box = WinWindowFromID(box, FID_CLIENT); | |
6199 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6200 } | |
6201 else | |
6202 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6203 if(thisbox) | |
6204 { | |
6205 if(thisbox->type == BOXHORZ) | |
6206 dw_box_pack_end_stub(box, item, width, height, hsize, vsize, pad); | |
6207 else | |
6208 dw_box_pack_start_stub(box, item, width, height, hsize, vsize, pad); | |
6209 } | |
6210 } | |
6211 | |
6212 void dw_box_pack_start_stub(HWND box, HWND item, int width, int height, int hsize, int vsize, int pad) | |
6213 { | |
6214 HWND boxowner = NULLHANDLE; | |
6215 Box *thisbox; | |
6216 | |
6217 if(WinWindowFromID(box, FID_CLIENT)) | |
6218 { | |
6219 box = WinWindowFromID(box, FID_CLIENT); | |
6220 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6221 hsize = TRUE; | |
6222 vsize = TRUE; | |
6223 } | |
6224 else | |
6225 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6025 if(thisbox) | 6226 if(thisbox) |
6026 { | 6227 { |
6027 int z; | 6228 int z; |
6028 Item *tmpitem, *thisitem = thisbox->items; | 6229 Item *tmpitem, *thisitem = thisbox->items; |
6029 char tmpbuf[100]; | 6230 char tmpbuf[100]; |
6033 for(z=0;z<thisbox->count;z++) | 6234 for(z=0;z<thisbox->count;z++) |
6034 { | 6235 { |
6035 tmpitem[z+1] = thisitem[z]; | 6236 tmpitem[z+1] = thisitem[z]; |
6036 } | 6237 } |
6037 | 6238 |
6038 GetClassName(item, tmpbuf, 99); | 6239 WinQueryClassName(item, 99, tmpbuf); |
6039 | 6240 |
6040 if(strnicmp(tmpbuf, FRAMECLASSNAME, 2)==0) | 6241 if(strncmp(tmpbuf, "#1", 3)==0) |
6041 tmpitem[0].type = TYPEBOX; | 6242 tmpitem[0].type = TYPEBOX; |
6042 else | 6243 else |
6043 tmpitem[0].type = TYPEITEM; | 6244 tmpitem[0].type = TYPEITEM; |
6044 | 6245 |
6045 tmpitem[0].hwnd = item; | 6246 tmpitem[0].hwnd = item; |
6061 if(thisbox->count) | 6262 if(thisbox->count) |
6062 free(thisitem); | 6263 free(thisitem); |
6063 | 6264 |
6064 thisbox->count++; | 6265 thisbox->count++; |
6065 | 6266 |
6066 SetParent(item, box); | 6267 WinQueryClassName(item, 99, tmpbuf); |
6067 ShowWindow(item, SW_SHOW); | 6268 /* Don't set the ownership if it's an entryfield or spinbutton */ |
6068 if(strncmp(tmpbuf, UPDOWN_CLASS, strlen(UPDOWN_CLASS))==0) | 6269 if(strncmp(tmpbuf, "#6", 3)!=0 && strncmp(tmpbuf, "#32", 3)!=0) |
6069 { | 6270 { |
6070 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(item, GWL_USERDATA); | 6271 if((boxowner = WinQueryWindow(box, QW_OWNER)) != 0) |
6071 | 6272 WinSetOwner(item, boxowner); |
6072 if(cinfo) | 6273 else |
6274 WinSetOwner(item, box); | |
6275 } | |
6276 WinSetParent(item, box, FALSE); | |
6277 } | |
6278 } | |
6279 | |
6280 /* The following two functions graciously contributed by Peter Nielsen. */ | |
6281 static ULONG _ParseBuildLevel (char* pchBuffer, ULONG ulSize) { | |
6282 char* pchStart = pchBuffer; | |
6283 char* pchEnd = pchStart + ulSize - 2; | |
6284 | |
6285 while (pchEnd >= pchStart) | |
6286 { | |
6287 if ((pchEnd[0] == '#') && (pchEnd[1] == '@')) | |
6288 { | |
6289 *pchEnd-- = '\0'; | |
6290 while (pchEnd >= pchStart) | |
6073 { | 6291 { |
6074 SetParent(cinfo->buddy, box); | 6292 if ((pchEnd[0] == '@') && (pchEnd[1] == '#')) |
6075 ShowWindow(cinfo->buddy, SW_SHOW); | 6293 { |
6076 SendMessage(item, UDM_SETBUDDY, (WPARAM)cinfo->buddy, 0); | 6294 ULONG ulMajor = 0; |
6295 ULONG ulMinor = 0; | |
6296 | |
6297 char* pch = pchEnd + 2; | |
6298 while (!isdigit (*pch) && *pch) | |
6299 pch++; | |
6300 | |
6301 while (isdigit (*pch)) | |
6302 ulMajor = ulMajor * 10 + *pch++ - '0'; | |
6303 | |
6304 if (*pch == '.') | |
6305 { | |
6306 while (isdigit (*++pch)) | |
6307 ulMinor = ulMinor * 10 + *pch - '0'; | |
6308 } | |
6309 return ((ulMajor << 16) | ulMinor); | |
6310 } | |
6311 pchEnd--; | |
6077 } | 6312 } |
6078 } | 6313 } |
6079 } | 6314 pchEnd--; |
6315 } | |
6316 return (0); | |
6317 } | |
6318 | |
6319 ULONG _GetSystemBuildLevel(void) { | |
6320 /* The build level info is normally available in the end of the OS2KRNL file. However, this is not the case in some beta versions of OS/2. | |
6321 * We first try to find the info in the 256 last bytes of the file. If that fails, we load the entire file and search it completely. | |
6322 */ | |
6323 ULONG ulBootDrive = 0; | |
6324 ULONG ulBuild = 0; | |
6325 if (DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ulBootDrive)) == NO_ERROR) | |
6326 { | |
6327 char achFileName[11] = { (char)('A'+ulBootDrive-1),':','\\','O','S','2','K','R','N','L','\0' }; | |
6328 HFILE hfile; | |
6329 ULONG ulResult; | |
6330 if (DosOpen (achFileName, &hfile, &ulResult, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_FAIL_ON_ERROR | OPEN_FLAGS_NO_CACHE | OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL) == NO_ERROR) | |
6331 { | |
6332 ULONG ulFileSize = 0; | |
6333 if (DosSetFilePtr (hfile, 0, FILE_END, &ulFileSize) == NO_ERROR) | |
6334 { | |
6335 const ULONG ulFirstTry = min (256, ulFileSize); | |
6336 if (DosSetFilePtr (hfile, -(LONG)ulFirstTry, FILE_END, &ulResult) == NO_ERROR) | |
6337 { | |
6338 char *pchBuffer = malloc(ulFirstTry); | |
6339 if (DosRead (hfile, pchBuffer, ulFirstTry, &ulResult) == NO_ERROR) | |
6340 { | |
6341 ulBuild = _ParseBuildLevel (pchBuffer, ulFirstTry); | |
6342 if (ulBuild == 0) | |
6343 { | |
6344 if (DosSetFilePtr (hfile, 0, FILE_BEGIN, &ulResult) == NO_ERROR) | |
6345 { | |
6346 free(pchBuffer); | |
6347 pchBuffer = malloc(ulFileSize); | |
6348 | |
6349 if (DosRead (hfile, pchBuffer, ulFileSize, &ulResult) == NO_ERROR) | |
6350 ulBuild = _ParseBuildLevel (pchBuffer, ulFileSize); | |
6351 } | |
6352 } | |
6353 } | |
6354 free(pchBuffer); | |
6355 } | |
6356 } | |
6357 DosClose (hfile); | |
6358 } | |
6359 } | |
6360 return (ulBuild); | |
6080 } | 6361 } |
6081 | 6362 |
6082 /* | 6363 /* |
6083 * Sets the default focus item for a window/dialog. | 6364 * Sets the default focus item for a window/dialog. |
6084 * Parameters: | 6365 * Parameters: |
6085 * window: Toplevel window or dialog. | 6366 * window: Toplevel window or dialog. |
6086 * defaultitem: Handle to the dialog item to be default. | 6367 * defaultitem: Handle to the dialog item to be default. |
6087 */ | 6368 */ |
6088 void dw_window_default(HWND window, HWND defaultitem) | 6369 void dw_window_default(HWND window, HWND defaultitem) |
6089 { | 6370 { |
6090 Box *thisbox = (Box *)GetWindowLong(window, GWL_USERDATA); | 6371 Box *thisbox = NULL; |
6372 HWND box; | |
6373 | |
6374 box = WinWindowFromID(window, FID_CLIENT); | |
6375 if(box) | |
6376 thisbox = WinQueryWindowPtr(box, QWP_USER); | |
6091 | 6377 |
6092 if(thisbox) | 6378 if(thisbox) |
6093 thisbox->defaultitem = defaultitem; | 6379 thisbox->defaultitem = defaultitem; |
6094 } | 6380 } |
6095 | 6381 |
6099 * window: Window (widget) to look for the ENTER press. | 6385 * window: Window (widget) to look for the ENTER press. |
6100 * next: Window (widget) to move to next (or click) | 6386 * next: Window (widget) to move to next (or click) |
6101 */ | 6387 */ |
6102 void dw_window_click_default(HWND window, HWND next) | 6388 void dw_window_click_default(HWND window, HWND next) |
6103 { | 6389 { |
6104 ColorInfo *cinfo = (ColorInfo *)GetWindowLong(window, GWL_USERDATA); | 6390 WindowData *blah = (WindowData *)WinQueryWindowPtr(window, QWP_USER); |
6105 | 6391 char tmpbuf[100]; |
6106 if(cinfo) | 6392 |
6107 cinfo->clickdefault = next; | 6393 WinQueryClassName(window, 99, tmpbuf); |
6394 | |
6395 /* These are the window classes which can | |
6396 * obtain input focus. | |
6397 */ | |
6398 if(strncmp(tmpbuf, "#6", 3) == 0 && blah) | |
6399 blah->clickdefault = next; | |
6108 } | 6400 } |
6109 | 6401 |
6110 /* | 6402 /* |
6111 * Returns some information about the current operating environment. | 6403 * Returns some information about the current operating environment. |
6112 * Parameters: | 6404 * Parameters: |
6113 * env: Pointer to a DWEnv struct. | 6405 * env: Pointer to a DWEnv struct. |
6114 */ | 6406 */ |
6115 void dw_environment_query(DWEnv *env) | 6407 void dw_environment_query(DWEnv *env) |
6116 { | 6408 { |
6409 ULONG Build; | |
6410 | |
6117 if(!env) | 6411 if(!env) |
6118 return; | 6412 return; |
6119 | 6413 |
6120 /* Get the Windows version. */ | 6414 /* The default is OS/2 2.0 */ |
6121 | 6415 strcpy(env->osName,"OS/2"); |
6122 env->MajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); | 6416 env->MajorVersion = 2; |
6123 env->MinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); | 6417 env->MinorVersion = 0; |
6124 | 6418 |
6125 /* Get the build number for Windows NT/Windows 2000. */ | 6419 Build = _GetSystemBuildLevel(); |
6126 | 6420 env->MinorBuild = Build & 0xFFFF; |
6127 env->MinorBuild = 0; | 6421 env->MajorBuild = Build >> 16; |
6128 | 6422 |
6129 if (dwVersion < 0x80000000) | 6423 if (aulBuffer[0] == 20) |
6130 { | 6424 { |
6131 if(env->MajorVersion == 5 && env->MinorVersion == 1) | 6425 int i = (unsigned int)aulBuffer[1]; |
6132 strcpy(env->osName, "Windows XP"); | 6426 if (i > 20) |
6133 else if(env->MajorVersion == 5 && env->MinorVersion == 0) | 6427 { |
6134 strcpy(env->osName, "Windows 2000"); | 6428 strcpy(env->osName,"Warp"); |
6135 else | 6429 env->MajorVersion = (int)i/10; |
6136 strcpy(env->osName, "Windows NT"); | 6430 env->MinorVersion = i-(((int)i/10)*10); |
6137 | 6431 } |
6138 env->MajorBuild = (DWORD)(HIWORD(dwVersion)); | 6432 else if (i == 10) |
6139 } | 6433 env->MinorVersion = 1; |
6140 else | 6434 } |
6141 { | |
6142 strcpy(env->osName, "Windows 95/98/ME"); | |
6143 env->MajorBuild = 0; | |
6144 } | |
6145 | |
6146 strcpy(env->buildDate, __DATE__); | 6435 strcpy(env->buildDate, __DATE__); |
6147 strcpy(env->buildTime, __TIME__); | 6436 strcpy(env->buildTime, __TIME__); |
6148 env->DWMajorVersion = DW_MAJOR_VERSION; | 6437 env->DWMajorVersion = DW_MAJOR_VERSION; |
6149 env->DWMinorVersion = DW_MINOR_VERSION; | 6438 env->DWMinorVersion = DW_MINOR_VERSION; |
6150 env->DWSubVersion = DW_SUB_VERSION; | 6439 env->DWSubVersion = DW_SUB_VERSION; |
6162 * the file path on success. | 6451 * the file path on success. |
6163 * | 6452 * |
6164 */ | 6453 */ |
6165 char *dw_file_browse(char *title, char *defpath, char *ext, int flags) | 6454 char *dw_file_browse(char *title, char *defpath, char *ext, int flags) |
6166 { | 6455 { |
6167 OPENFILENAME of; | 6456 FILEDLG fild; |
6168 char filenamebuf[1001] = ""; | 6457 HWND hwndFile; |
6169 int rc; | 6458 int len; |
6459 | |
6460 if(defpath) | |
6461 strcpy(fild.szFullFile, defpath); | |
6462 else | |
6463 strcpy(fild.szFullFile, ""); | |
6464 | |
6465 len = strlen(fild.szFullFile); | |
6466 | |
6467 if(len) | |
6468 { | |
6469 if(fild.szFullFile[len-1] != '\\') | |
6470 strcat(fild.szFullFile, "\\"); | |
6471 } | |
6472 strcat(fild.szFullFile, "*"); | |
6170 | 6473 |
6171 if(ext) | 6474 if(ext) |
6172 { | 6475 { |
6173 strcpy(filenamebuf, "*."); | 6476 strcat(fild.szFullFile, "."); |
6174 strcat(filenamebuf, ext); | 6477 strcat(fild.szFullFile, ext); |
6175 } | 6478 } |
6176 | 6479 |
6177 memset(&of, 0, sizeof(OPENFILENAME)); | 6480 fild.cbSize = sizeof(FILEDLG); |
6178 | 6481 fild.fl = /*FDS_HELPBUTTON |*/ FDS_CENTER | FDS_OPEN_DIALOG; |
6179 of.lStructSize = sizeof(OPENFILENAME); | 6482 fild.pszTitle = title; |
6180 of.hwndOwner = HWND_DESKTOP; | 6483 fild.pszOKButton = ((flags & DW_FILE_SAVE) ? "Save" : "Open"); |
6181 of.hInstance = DWInstance; | 6484 fild.ulUser = 0L; |
6182 of.lpstrInitialDir = defpath; | 6485 fild.pfnDlgProc = (PFNWP)WinDefFileDlgProc; |
6183 of.lpstrTitle = title; | 6486 fild.lReturn = 0L; |
6184 of.lpstrFile = filenamebuf; | 6487 fild.lSRC = 0L; |
6185 of.nMaxFile = 1000; | 6488 fild.hMod = 0; |
6186 of.lpstrDefExt = ext; | 6489 fild.x = 0; |
6187 of.Flags = 0; | 6490 fild.y = 0; |
6188 | 6491 fild.pszIType = (PSZ)NULL; |
6189 if(flags & DW_FILE_SAVE) | 6492 fild.papszITypeList = (PAPSZ)NULL; |
6190 rc = GetSaveFileName(&of); | 6493 fild.pszIDrive = (PSZ)NULL; |
6191 else | 6494 fild.papszIDriveList= (PAPSZ)NULL; |
6192 rc = GetOpenFileName(&of); | 6495 fild.sEAType = (SHORT)0; |
6193 | 6496 fild.papszFQFilename= (PAPSZ)NULL; |
6194 if(rc) | 6497 fild.ulFQFCount = 0L; |
6195 return strdup(of.lpstrFile); | 6498 |
6196 | 6499 hwndFile = WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fild); |
6500 if(hwndFile) | |
6501 { | |
6502 switch(fild.lReturn) | |
6503 { | |
6504 case DID_OK: | |
6505 return strdup(fild.szFullFile); | |
6506 case DID_CANCEL: | |
6507 return NULL; | |
6508 } | |
6509 } | |
6197 return NULL; | 6510 return NULL; |
6198 } | 6511 } |
6199 | 6512 |
6200 /* | 6513 /* |
6201 * Execute and external program in a seperate session. | 6514 * Execute and external program in a seperate session. |
6206 * Returns: | 6519 * Returns: |
6207 * -1 on error. | 6520 * -1 on error. |
6208 */ | 6521 */ |
6209 int dw_exec(char *program, int type, char **params) | 6522 int dw_exec(char *program, int type, char **params) |
6210 { | 6523 { |
6211 char **newparams; | 6524 return spawnvp(P_NOWAIT, program, (const char **)params); |
6212 int retcode, count = 0, z; | |
6213 | |
6214 while(params[count]) | |
6215 { | |
6216 count++; | |
6217 } | |
6218 | |
6219 newparams = (char **)malloc(sizeof(char *) * (count+1)); | |
6220 | |
6221 for(z=0;z<count;z++) | |
6222 { | |
6223 newparams[z] = malloc(strlen(params[z])+3); | |
6224 strcpy(newparams[z], "\""); | |
6225 strcat(newparams[z], params[z]); | |
6226 strcat(newparams[z], "\""); | |
6227 } | |
6228 newparams[count] = NULL; | |
6229 | |
6230 retcode = spawnvp(P_NOWAIT, program, newparams); | |
6231 | |
6232 for(z=0;z<count;z++) | |
6233 { | |
6234 free(newparams[z]); | |
6235 } | |
6236 free(newparams); | |
6237 | |
6238 return retcode; | |
6239 } | 6525 } |
6240 | 6526 |
6241 /* | 6527 /* |
6242 * Loads a web browser pointed at the given URL. | 6528 * Loads a web browser pointed at the given URL. |
6243 * Parameters: | 6529 * Parameters: |
6244 * url: Uniform resource locator. | 6530 * url: Uniform resource locator. |
6245 */ | 6531 */ |
6246 int dw_browse(char *url) | 6532 int dw_browse(char *url) |
6247 { | 6533 { |
6248 char *browseurl = url; | 6534 /* Is there a way to find the webbrowser in Unix? */ |
6249 int retcode; | 6535 char *execargs[3], browser[1024], *newurl = NULL; |
6250 | 6536 int len; |
6251 if(strlen(url) > 7 && strncmp(url, "file://", 7) == 0) | 6537 |
6252 { | 6538 PrfQueryProfileString(HINI_USERPROFILE, "WPURLDEFAULTSETTINGS", |
6253 int len, z; | 6539 "DefaultBrowserExe", NULL, browser, 1024); |
6254 | 6540 |
6255 browseurl = &url[7]; | 6541 len = strlen(browser) - strlen("explore.exe"); |
6256 len = strlen(browseurl); | 6542 |
6257 | 6543 execargs[0] = browser; |
6258 for(z=0;z<len;z++) | 6544 execargs[1] = url; |
6545 execargs[2] = NULL; | |
6546 | |
6547 /* Special case for Web Explorer, it requires file:/// instead | |
6548 * of file:// so I am handling it here. | |
6549 */ | |
6550 if(len > 0) | |
6551 { | |
6552 if(stricmp(&browser[len], "explore.exe") == 0) | |
6259 { | 6553 { |
6260 if(browseurl[z] == '|') | 6554 int newlen, z; |
6261 browseurl[z] = ':'; | 6555 newurl = alloca(strlen(url) + 2); |
6262 if(browseurl[z] == '/') | 6556 sprintf(newurl, "file:///%s", &url[7]); |
6263 browseurl[z] = '\\'; | 6557 newlen = strlen(newurl); |
6558 for(z=8;z<(newlen-8);z++) | |
6559 { | |
6560 if(newurl[z] == '|') | |
6561 newurl[z] = ':'; | |
6562 if(newurl[z] == '/') | |
6563 newurl[z] = '\\'; | |
6564 } | |
6565 execargs[1] = newurl; | |
6264 } | 6566 } |
6265 } | 6567 } |
6266 | 6568 |
6267 retcode = (int)ShellExecute(NULL, "open", browseurl, NULL, NULL, SW_SHOWNORMAL); | 6569 return dw_exec(browser, DW_EXEC_GUI, execargs); |
6268 if(retcode<33 && retcode != 2) | |
6269 return -1; | |
6270 return 1; | |
6271 } | 6570 } |
6272 | 6571 |
6273 /* | 6572 /* |
6274 * Returns a pointer to a static buffer which containes the | 6573 * Returns a pointer to a static buffer which containes the |
6275 * current user directory. Or the root directory (C:\ on | 6574 * current user directory. Or the root directory (C:\ on |
6279 { | 6578 { |
6280 static char _user_dir[1024] = ""; | 6579 static char _user_dir[1024] = ""; |
6281 | 6580 |
6282 if(!_user_dir[0]) | 6581 if(!_user_dir[0]) |
6283 { | 6582 { |
6284 /* Figure out how to do this the "Windows way" */ | |
6285 char *home = getenv("HOME"); | 6583 char *home = getenv("HOME"); |
6286 | 6584 |
6287 if(home) | 6585 if(home) |
6288 strcpy(_user_dir, home); | 6586 strcpy(_user_dir, home); |
6289 else | 6587 else |
6299 * function: Function pointer to be called. | 6597 * function: Function pointer to be called. |
6300 * data: Pointer to the data to be passed to the function. | 6598 * data: Pointer to the data to be passed to the function. |
6301 */ | 6599 */ |
6302 void dw_window_function(HWND handle, void *function, void *data) | 6600 void dw_window_function(HWND handle, void *function, void *data) |
6303 { | 6601 { |
6304 SendMessage(handle, WM_USER, (WPARAM)function, (LPARAM)data); | 6602 WinSendMsg(handle, WM_USER, (MPARAM)function, (MPARAM)data); |
6305 } | 6603 } |
6306 | 6604 |
6307 #ifndef NO_SIGNALS | 6605 #ifndef NO_SIGNALS |
6308 /* | 6606 /* |
6309 * Add a callback to a window event. | 6607 * Add a callback to a window event. |
6315 */ | 6613 */ |
6316 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) | 6614 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) |
6317 { | 6615 { |
6318 ULONG message = 0L; | 6616 ULONG message = 0L; |
6319 | 6617 |
6618 if(strcmp(signame, "lose-focus") == 0) | |
6619 { | |
6620 char tmpbuf[100]; | |
6621 | |
6622 WinQueryClassName(window, 99, tmpbuf); | |
6623 | |
6624 if(strncmp(tmpbuf, "#2", 3) == 0) | |
6625 { | |
6626 HENUM henum = WinBeginEnumWindows(window); | |
6627 HWND child = WinGetNextWindow(henum); | |
6628 WinEndEnumWindows(henum); | |
6629 if(child) | |
6630 window = child; | |
6631 } | |
6632 } | |
6320 if(window && signame && sigfunc) | 6633 if(window && signame && sigfunc) |
6321 { | 6634 { |
6322 if(stricmp(signame, "set-focus") == 0) | |
6323 window = _normalize_handle(window); | |
6324 | |
6325 if((message = _findsigmessage(signame)) != 0) | 6635 if((message = _findsigmessage(signame)) != 0) |
6326 _new_signal(message, window, sigfunc, data); | 6636 _new_signal(message, window, sigfunc, data); |
6327 } | 6637 } |
6328 } | 6638 } |
6329 | 6639 |
6468 count--; | 6778 count--; |
6469 break; | 6779 break; |
6470 case 1003L: | 6780 case 1003L: |
6471 case 1004L: | 6781 case 1004L: |
6472 dw_window_destroy(testwindow);; | 6782 dw_window_destroy(testwindow);; |
6473 count--; | 6783 count--; |
6474 break; | 6784 break; |
6475 } | 6785 } |
6476 if(!count) | 6786 if(!count) |
6477 exit(0); | 6787 exit(0); |
6478 break; | 6788 break; |
6485 { | 6795 { |
6486 dw_window_destroy((HWND)data); | 6796 dw_window_destroy((HWND)data); |
6487 /* Return -1 to allow the default handlers to return. */ | 6797 /* Return -1 to allow the default handlers to return. */ |
6488 count--; | 6798 count--; |
6489 if(!count) | 6799 if(!count) |
6490 exit(0); | 6800 exit(0); |
6491 return -1; | 6801 return -1; |
6492 } | 6802 } |
6493 #endif | 6803 #endif |
6494 | 6804 |
6495 /* | 6805 /* |
6496 * Let's demonstrate the functionality of this library. :) | 6806 * Let's demonstrate the functionality of this library. :) |
6497 */ | 6807 */ |
6498 int WINAPI WinMain( | 6808 int main(void) |
6499 HINSTANCE hInstance, | |
6500 HINSTANCE hPrevInstance, | |
6501 LPSTR lpCmdLine, | |
6502 int nCmdShow | |
6503 ) | |
6504 { | 6809 { |
6505 ULONG flStyle = DW_FCF_SYSMENU | DW_FCF_TITLEBAR | | 6810 ULONG flStyle = DW_FCF_SYSMENU | DW_FCF_TITLEBAR | |
6506 DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER; | 6811 DW_FCF_SHELLPOSITION | DW_FCF_TASKLIST | DW_FCF_DLGBORDER; |
6507 int pageid; | 6812 int pageid; |
6508 | 6813 |
6549 dw_window_show(mainwindow); | 6854 dw_window_show(mainwindow); |
6550 | 6855 |
6551 dw_window_set_usize(mainwindow, 170, 340); | 6856 dw_window_set_usize(mainwindow, 170, 340); |
6552 | 6857 |
6553 /* Another small example */ | 6858 /* Another small example */ |
6554 flStyle |= DW_FCF_MINMAX | DW_FCF_SIZEBORDER; | 6859 flStyle |= FCF_MINMAX | FCF_SIZEBORDER; |
6555 | 6860 |
6556 testwindow = dw_window_new(HWND_DESKTOP, "Wow a test dialog! :) yay!", flStyle); | 6861 testwindow = dw_window_new(HWND_DESKTOP, "Wow a test dialog! :) yay!", flStyle); |
6557 | 6862 |
6558 testbox = dw_box_new(BOXVERT, 0); | 6863 testbox = dw_box_new(BOXVERT, 0); |
6559 | 6864 |
6568 pageid = dw_notebook_page_new(notebook, 0L, FALSE); | 6873 pageid = dw_notebook_page_new(notebook, 0L, FALSE); |
6569 | 6874 |
6570 dw_notebook_page_set_text(notebook, pageid, "Test page"); | 6875 dw_notebook_page_set_text(notebook, pageid, "Test page"); |
6571 dw_notebook_page_set_status_text(notebook, pageid, "Test page"); | 6876 dw_notebook_page_set_status_text(notebook, pageid, "Test page"); |
6572 | 6877 |
6573 dw_notebook_pack(notebook, pageid, testbox); | 6878 dw_notebook_pack(notebook, pageid, testbox); |
6574 | 6879 |
6575 testok = dw_button_new("Ok", 1003L); | 6880 testok = dw_button_new("Ok", 1003L); |
6576 | 6881 |
6577 dw_box_pack_start(testbox, testok, 60, 40, TRUE, TRUE, 10); | 6882 dw_box_pack_start(testbox, testok, 60, 40, TRUE, TRUE, 10); |
6578 | 6883 |
6603 dw_window_set_font(testcancel2, "9.WarpSans"); | 6908 dw_window_set_font(testcancel2, "9.WarpSans"); |
6604 | 6909 |
6605 dw_window_show(testwindow); | 6910 dw_window_show(testwindow); |
6606 | 6911 |
6607 #ifdef USE_FILTER | 6912 #ifdef USE_FILTER |
6608 | |
6609 dw_main(0L, (void *)testfilter); | 6913 dw_main(0L, (void *)testfilter); |
6610 #else | 6914 #else |
6611 /* Setup the function callbacks */ | 6915 /* Setup the function callbacks */ |
6612 dw_signal_connect(okbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow); | 6916 dw_signal_connect(okbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow); |
6613 dw_signal_connect(cancelbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow); | 6917 dw_signal_connect(cancelbutton, "clicked", DW_SIGNAL_FUNC(test_callback), (void *)mainwindow); |