comparison win/dw.c @ 58:5c66a108aa47

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