comparison win/dw.c @ 57:1ed95c8ec2ff

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