Merge 15268:15329 from trunk
[reactos.git] / rosapps / lib / dflat32 / applicat.c
1 /* ------------- applicat.c ------------- */
2
3 #include "dflat32/dflat.h"
4
5 static BOOL DisplayModified = FALSE;
6 DFWINDOW ApplicationWindow;
7
8 extern DBOX Display;
9 extern DBOX Windows;
10
11 #ifdef INCLUDE_LOGGING
12 extern DBOX Log;
13 #endif
14
15 #ifdef INCLUDE_SHELLDOS
16 static void ShellDOS(DFWINDOW);
17 #endif
18 static void DfCreateMenu(DFWINDOW);
19 static void CreateStatusBar(DFWINDOW);
20 static void SelectColors(DFWINDOW);
21
22 #ifdef INCLUDE_WINDOWOPTIONS
23 static void SelectTexture(void);
24 static void SelectBorder(DFWINDOW);
25 static void SelectTitle(DFWINDOW);
26 static void SelectStatusBar(DFWINDOW);
27 #endif
28
29 static DFWINDOW oldFocus;
30 #ifdef INCLUDE_MULTI_WINDOWS
31 static void CloseAll(DFWINDOW, int);
32 static void MoreWindows(DFWINDOW);
33 static void ChooseWindow(DFWINDOW, int);
34 static int WindowSel;
35 static char Menus[9][26] =
36 {
37 "~1. ",
38 "~2. ",
39 "~3. ",
40 "~4. ",
41 "~5. ",
42 "~6. ",
43 "~7. ",
44 "~8. ",
45 "~9. "
46 };
47 #endif
48
49 /* --------------- CREATE_WINDOW Message -------------- */
50 static int CreateWindowMsg(DFWINDOW wnd)
51 {
52 int rtn;
53
54 ApplicationWindow = wnd;
55 #ifdef INCLUDE_WINDOWOPTIONS
56 if (cfg.Border)
57 SetCheckBox(&Display, ID_BORDER);
58 if (cfg.Title)
59 SetCheckBox(&Display, ID_TITLE);
60 if (cfg.StatusBar)
61 SetCheckBox(&Display, ID_STATUSBAR);
62 if (cfg.Texture)
63 SetCheckBox(&Display, ID_TEXTURE);
64 #endif
65 SelectColors(wnd);
66 #ifdef INCLUDE_WINDOWOPTIONS
67 SelectBorder(wnd);
68 SelectTitle(wnd);
69 SelectStatusBar(wnd);
70 #endif
71 rtn = BaseWndProc(APPLICATION, wnd, CREATE_WINDOW, 0, 0);
72 if (wnd->extension != NULL)
73 DfCreateMenu(wnd);
74 CreateStatusBar(wnd);
75 return rtn;
76 }
77
78 /* --------- ADDSTATUS Message ---------- */
79 static void AddStatusMsg(DFWINDOW wnd, PARAM p1)
80 {
81 if (wnd->StatusBar != NULL) {
82 if (p1 && *(char *)p1)
83 DfSendMessage(wnd->StatusBar, SETTEXT, p1, 0);
84 else
85 DfSendMessage(wnd->StatusBar, CLEARTEXT, 0, 0);
86 DfSendMessage(wnd->StatusBar, PAINT, 0, 0);
87 }
88 }
89
90 /* -------- SETFOCUS Message -------- */
91 static void SetFocusMsg(DFWINDOW wnd, BOOL p1)
92 {
93 if (p1)
94 DfSendMessage(inFocus, SETFOCUS, FALSE, 0);
95 inFocus = p1 ? wnd : NULL;
96 if (isVisible(wnd))
97 DfSendMessage(wnd, BORDER, 0, 0);
98 else
99 DfSendMessage(wnd, SHOW_WINDOW, 0, 0);
100 }
101
102 /* ------- SIZE Message -------- */
103 static void SizeMsg(DFWINDOW wnd, PARAM p1, PARAM p2)
104 {
105 BOOL WasVisible;
106 WasVisible = isVisible(wnd);
107 if (WasVisible)
108 DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
109 if (p1-GetLeft(wnd) < 30)
110 p1 = GetLeft(wnd) + 30;
111 BaseWndProc(APPLICATION, wnd, DFM_SIZE, p1, p2);
112 DfCreateMenu(wnd);
113 CreateStatusBar(wnd);
114 if (WasVisible)
115 DfSendMessage(wnd, SHOW_WINDOW, 0, 0);
116 }
117
118 /* ----------- KEYBOARD Message ------------ */
119 static int KeyboardMsg(DFWINDOW wnd, PARAM p1, PARAM p2)
120 {
121 if (WindowMoving || WindowSizing || (int) p1 == F1)
122 return BaseWndProc(APPLICATION, wnd, KEYBOARD, p1, p2);
123 switch ((int) p1) {
124 case ALT_F4:
125 DfPostMessage(wnd, CLOSE_WINDOW, 0, 0);
126 return TRUE;
127 #ifdef INCLUDE_MULTI_WINDOWS
128 case ALT_F6:
129 SetNextFocus();
130 return TRUE;
131 #endif
132 case ALT_HYPHEN:
133 BuildSystemMenu(wnd);
134 return TRUE;
135 default:
136 break;
137 }
138 DfPostMessage(wnd->MenuBarWnd, KEYBOARD, p1, p2);
139 return TRUE;
140 }
141
142 /* --------- SHIFT_CHANGED Message -------- */
143 static void ShiftChangedMsg(DFWINDOW wnd, PARAM p1)
144 {
145 extern BOOL AltDown;
146 if ((int)p1 & ALTKEY)
147 AltDown = TRUE;
148 else if (AltDown) {
149 AltDown = FALSE;
150 if (wnd->MenuBarWnd != inFocus)
151 DfSendMessage(NULL, HIDE_CURSOR, 0, 0);
152 DfSendMessage(wnd->MenuBarWnd, KEYBOARD, F10, 0);
153 }
154 }
155
156 /* -------- COMMAND Message ------- */
157 static void CommandMsg(DFWINDOW wnd, PARAM p1, PARAM p2)
158 {
159 switch ((int)p1) {
160 case ID_HELP:
161 DisplayHelp(wnd, DFlatApplication);
162 break;
163 case ID_HELPHELP:
164 DisplayHelp(wnd, "HelpHelp");
165 break;
166 case ID_EXTHELP:
167 DisplayHelp(wnd, "ExtHelp");
168 break;
169 case ID_KEYSHELP:
170 DisplayHelp(wnd, "KeysHelp");
171 break;
172 case ID_HELPINDEX:
173 DisplayHelp(wnd, "HelpIndex");
174 break;
175 #ifdef TESTING_DFLAT
176 case ID_LOADHELP:
177 LoadHelpFile();
178 break;
179 #endif
180 #ifdef INCLUDE_LOGGING
181 case ID_LOG:
182 MessageLog(wnd);
183 break;
184 #endif
185 #ifdef INCLUDE_SHELLDOS
186 case ID_DOS:
187 ShellDOS(wnd);
188 break;
189 #endif
190 case ID_EXIT:
191 case ID_SYSCLOSE:
192 DfPostMessage(wnd, CLOSE_WINDOW, 0, 0);
193 break;
194 case ID_DISPLAY:
195 if (DfDialogBox(wnd, &Display, TRUE, NULL)) {
196 if (inFocus == wnd->MenuBarWnd || inFocus == wnd->StatusBar)
197 oldFocus = ApplicationWindow;
198 else
199 oldFocus = inFocus;
200 DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
201 SelectColors(wnd);
202 #ifdef INCLUDE_WINDOWOPTIONS
203 SelectBorder(wnd);
204 SelectTitle(wnd);
205 SelectStatusBar(wnd);
206 SelectTexture();
207 #endif
208 DfCreateMenu(wnd);
209 CreateStatusBar(wnd);
210 DfSendMessage(wnd, SHOW_WINDOW, 0, 0);
211 DfSendMessage(oldFocus, SETFOCUS, TRUE, 0);
212 }
213 break;
214 case ID_SAVEOPTIONS:
215 SaveConfig();
216 break;
217 #ifdef INCLUDE_MULTI_WINDOWS
218 case ID_WINDOW:
219 ChooseWindow(wnd, (int)p2-2);
220 break;
221 case ID_CLOSEALL:
222 CloseAll(wnd, FALSE);
223 break;
224 case ID_MOREWINDOWS:
225 MoreWindows(wnd);
226 break;
227 #endif
228 #ifdef INCLUDE_RESTORE
229 case ID_SYSRESTORE:
230 #endif
231 case ID_SYSMOVE:
232 case ID_SYSSIZE:
233 #ifdef INCLUDE_MINIMIZE
234 case ID_SYSMINIMIZE:
235 #endif
236 #ifdef INCLUDE_MAXIMIZE
237 case ID_SYSMAXIMIZE:
238 #endif
239 BaseWndProc(APPLICATION, wnd, DFM_COMMAND, p1, p2);
240 break;
241 default:
242 if (inFocus != wnd->MenuBarWnd && inFocus != wnd)
243 DfPostMessage(inFocus, DFM_COMMAND, p1, p2);
244 break;
245 }
246 }
247
248 /* --------- CLOSE_WINDOW Message -------- */
249 static int CloseWindowMsg(DFWINDOW wnd)
250 {
251 int rtn;
252 #ifdef INCLUDE_MULTI_WINDOWS
253 CloseAll(wnd, TRUE);
254 WindowSel = 0;
255 #endif
256 DfPostMessage(NULL, DFM_STOP, 0, 0);
257 rtn = BaseWndProc(APPLICATION, wnd, CLOSE_WINDOW, 0, 0);
258 UnLoadHelpFile();
259 DisplayModified = FALSE;
260 ApplicationWindow = NULL;
261 return rtn;
262 }
263
264 /* --- APPLICATION Window Class window processing module --- */
265 int ApplicationProc(DFWINDOW wnd, DFMESSAGE msg, PARAM p1, PARAM p2)
266 {
267 switch (msg)
268 {
269 case CREATE_WINDOW:
270 return CreateWindowMsg(wnd);
271 case DFM_HIDE_WINDOW:
272 if (wnd == inFocus)
273 inFocus = NULL;
274 break;
275 case ADDSTATUS:
276 AddStatusMsg(wnd, p1);
277 return TRUE;
278 case SETFOCUS:
279 if ((int)p1 == (inFocus != wnd)) {
280 SetFocusMsg(wnd, (BOOL) p1);
281 return TRUE;
282 }
283 break;
284 case DFM_SIZE:
285 SizeMsg(wnd, p1, p2);
286 return TRUE;
287 #ifdef INCLUDE_MINIMIZE
288 case MINIMIZE:
289 return TRUE;
290 #endif
291 case KEYBOARD:
292 return KeyboardMsg(wnd, p1, p2);
293 case SHIFT_CHANGED:
294 ShiftChangedMsg(wnd, p1);
295 return TRUE;
296 case PAINT:
297 if (isVisible(wnd)) {
298 #ifdef INCLUDE_WINDOWOPTIONS
299 int cl = cfg.Texture ? APPLCHAR : ' ';
300 #else
301 int cl = APPLCHAR;
302 #endif
303 ClearWindow(wnd, (DFRECT *)p1, cl);
304 }
305 return TRUE;
306 case DFM_COMMAND:
307 CommandMsg(wnd, p1, p2);
308 return TRUE;
309 case CLOSE_WINDOW:
310 return CloseWindowMsg(wnd);
311 default:
312 break;
313 }
314 return BaseWndProc(APPLICATION, wnd, msg, p1, p2);
315 }
316
317 #ifdef INCLUDE_SHELLDOS
318 static void SwitchCursor(void)
319 {
320 DfSendMessage(NULL, SAVE_CURSOR, 0, 0);
321 SwapCursorStack();
322 DfSendMessage(NULL, RESTORE_CURSOR, 0, 0);
323 }
324
325 /* ------- Shell out to DOS ---------- */
326 static void ShellDOS(DFWINDOW wnd)
327 {
328 oldFocus = inFocus;
329 DfSendMessage(wnd, DFM_HIDE_WINDOW, 0, 0);
330 SwitchCursor();
331 printf("To return to %s, execute the DOS exit command.",
332 DFlatApplication);
333 fflush(stdout);
334 _spawnl(P_WAIT, getenv("COMSPEC"), " ", NULL);
335 SwitchCursor();
336 DfSendMessage(wnd, SHOW_WINDOW, 0, 0);
337 DfSendMessage(oldFocus, SETFOCUS, TRUE, 0);
338 }
339 #endif
340
341 /* -------- Create the menu bar -------- */
342 static void DfCreateMenu(DFWINDOW wnd)
343 {
344 AddAttribute(wnd, HASMENUBAR);
345 if (wnd->MenuBarWnd != NULL)
346 DfSendMessage(wnd->MenuBarWnd, CLOSE_WINDOW, 0, 0);
347 wnd->MenuBarWnd = DfCreateWindow(MENUBAR,
348 NULL,
349 GetClientLeft(wnd),
350 GetClientTop(wnd)-1,
351 1,
352 ClientWidth(wnd),
353 NULL,
354 wnd,
355 NULL,
356 0);
357 DfSendMessage(wnd->MenuBarWnd,BUILDMENU,
358 (PARAM)wnd->extension,0);
359 AddAttribute(wnd->MenuBarWnd, VISIBLE);
360 }
361
362 /* ----------- Create the status bar ------------- */
363 static void CreateStatusBar(DFWINDOW wnd)
364 {
365 if (wnd->StatusBar != NULL) {
366 DfSendMessage(wnd->StatusBar, CLOSE_WINDOW, 0, 0);
367 wnd->StatusBar = NULL;
368 }
369 if (TestAttribute(wnd, HASSTATUSBAR)) {
370 wnd->StatusBar = DfCreateWindow(STATUSBAR,
371 NULL,
372 GetClientLeft(wnd),
373 GetBottom(wnd),
374 1,
375 ClientWidth(wnd),
376 NULL,
377 wnd,
378 NULL,
379 0);
380 AddAttribute(wnd->StatusBar, VISIBLE);
381 }
382 }
383
384 #ifdef INCLUDE_MULTI_WINDOWS
385 /* -------- return the name of a document window ------- */
386 static char *WindowName(DFWINDOW wnd)
387 {
388 if (GetTitle(wnd) == NULL)
389 {
390 if (GetClass(wnd) == DIALOG)
391 return ((DBOX *)(wnd->extension))->HelpName;
392 else
393 return "Untitled";
394 }
395 else
396 return GetTitle(wnd);
397 }
398
399 /* ----------- Prepare the Window menu ------------ */
400 void PrepWindowMenu(void *w, struct Menu *mnu)
401 {
402 DFWINDOW wnd = w;
403 struct PopDown *p0 = mnu->Selections;
404 struct PopDown *pd = mnu->Selections + 2;
405 struct PopDown *ca = mnu->Selections + 13;
406 int MenuNo = 0;
407 DFWINDOW cwnd;
408
409 mnu->Selection = 0;
410 oldFocus = NULL;
411
412 if (GetClass(wnd) != APPLICATION)
413 {
414 oldFocus = wnd;
415
416 /* point to the APPLICATION window */
417 if (ApplicationWindow == NULL)
418 return;
419
420 cwnd = FirstWindow(ApplicationWindow);
421 /* get the first 9 document windows */
422 while (cwnd != NULL && MenuNo < 9)
423 {
424 if (GetClass(cwnd) != MENUBAR &&
425 GetClass(cwnd) != STATUSBAR)
426 {
427 /* add the document window to the menu */
428 strncpy (Menus[MenuNo]+4, WindowName(cwnd), 20);
429 pd->SelectionTitle = Menus[MenuNo];
430 if (cwnd == oldFocus)
431 {
432 /* mark the current document */
433 pd->Attrib |= CHECKED;
434 mnu->Selection = MenuNo+2;
435 }
436 else
437 pd->Attrib &= ~CHECKED;
438 pd++;
439 MenuNo++;
440 }
441 cwnd = NextWindow(cwnd);
442 }
443 }
444
445 if (MenuNo)
446 p0->SelectionTitle = "~Close all";
447 else
448 p0->SelectionTitle = NULL;
449
450 if (MenuNo >= 9)
451 {
452 *pd++ = *ca;
453 if (mnu->Selection == 0)
454 mnu->Selection = 11;
455 }
456 pd->SelectionTitle = NULL;
457 }
458
459 /* window processing module for the More Windows dialog box */
460 static int WindowPrep(DFWINDOW wnd,DFMESSAGE msg,PARAM p1,PARAM p2)
461 {
462 switch (msg) {
463 case INITIATE_DIALOG: {
464 DFWINDOW wnd1;
465 DFWINDOW cwnd = ControlWindow(&Windows,ID_WINDOWLIST);
466 int sel = 0;
467 if (cwnd == NULL)
468 return FALSE;
469 wnd1 = FirstWindow(ApplicationWindow);
470 while (wnd1 != NULL) {
471 if (wnd1 != wnd && GetClass(wnd1) != MENUBAR &&
472 GetClass(wnd1) != STATUSBAR) {
473 if (wnd1 == oldFocus)
474 WindowSel = sel;
475 DfSendMessage(cwnd, ADDTEXT,
476 (PARAM) WindowName(wnd1), 0);
477 sel++;
478 }
479 wnd1 = NextWindow(wnd1);
480 }
481 DfSendMessage(cwnd, LB_SETSELECTION, WindowSel, 0);
482 AddAttribute(cwnd, VSCROLLBAR);
483 DfPostMessage(cwnd, SHOW_WINDOW, 0, 0);
484 break;
485 }
486 case DFM_COMMAND:
487 switch ((int) p1) {
488 case ID_OK:
489 if ((int)p2 == 0)
490 WindowSel = DfSendMessage(
491 ControlWindow(&Windows,
492 ID_WINDOWLIST),
493 LB_CURRENTSELECTION, 0, 0);
494 break;
495 case ID_WINDOWLIST:
496 if ((int) p2 == LB_CHOOSE)
497 DfSendMessage(wnd, DFM_COMMAND, ID_OK, 0);
498 break;
499 default:
500 break;
501 }
502 break;
503 default:
504 break;
505 }
506 return DefaultWndProc(wnd, msg, p1, p2);
507 }
508
509 /* ---- the More Windows command on the Window menu ---- */
510 static void MoreWindows(DFWINDOW wnd)
511 {
512 if (DfDialogBox(wnd, &Windows, TRUE, WindowPrep))
513 ChooseWindow(wnd, WindowSel);
514 }
515
516 /* ----- user chose a window from the Window menu
517 or the More Window dialog box ----- */
518 static void ChooseWindow(DFWINDOW wnd, int WindowNo)
519 {
520 DFWINDOW cwnd = FirstWindow(wnd);
521 while (cwnd != NULL)
522 {
523 if (GetClass(cwnd) != MENUBAR &&
524 GetClass(cwnd) != STATUSBAR)
525 if (WindowNo-- == 0)
526 break;
527 cwnd = NextWindow(cwnd);
528 }
529 if (cwnd != NULL) {
530 DfSendMessage(cwnd, SETFOCUS, TRUE, 0);
531 if (cwnd->condition == ISMINIMIZED)
532 DfSendMessage(cwnd, RESTORE, 0, 0);
533 }
534 }
535
536 /* ----- Close all document windows ----- */
537 static void CloseAll(DFWINDOW wnd, int closing)
538 {
539 DFWINDOW wnd1, wnd2;
540
541 DfSendMessage(wnd, SETFOCUS, TRUE, 0);
542 wnd1 = LastWindow(wnd);
543 while (wnd1 != NULL)
544 {
545 wnd2 = PrevWindow(wnd1);
546 if (GetClass(wnd1) != MENUBAR && GetClass(wnd1) != STATUSBAR)
547 {
548 ClearVisible(wnd1);
549 DfSendMessage(wnd1, CLOSE_WINDOW, 0, 0);
550 }
551 wnd1 = wnd2;
552 }
553 if (!closing)
554 DfSendMessage(wnd, PAINT, 0, 0);
555 }
556
557 #endif /* #ifdef INCLUDE_MULTI_WINDOWS */
558
559 static void DoWindowColors(DFWINDOW wnd)
560 {
561 DFWINDOW cwnd;
562
563 InitWindowColors(wnd);
564 cwnd = FirstWindow(wnd);
565 while (cwnd != NULL)
566 {
567 DoWindowColors(cwnd);
568 if (GetClass(cwnd) == TEXT && GetText(cwnd) != NULL)
569 DfSendMessage(cwnd, CLEARTEXT, 0, 0);
570 cwnd = NextWindow(cwnd);
571 }
572 }
573
574 /* set up colors for the application window */
575 static void SelectColors(DFWINDOW wnd)
576 {
577 memcpy(cfg.clr, color, sizeof color);
578 DoWindowColors(wnd);
579 }
580
581
582 #ifdef INCLUDE_WINDOWOPTIONS
583
584 /* ----- select the screen texture ----- */
585 static void SelectTexture(void)
586 {
587 cfg.Texture = CheckBoxSetting(&Display, ID_TEXTURE);
588 }
589
590 /* -- select whether the application screen has a border -- */
591 static void SelectBorder(DFWINDOW wnd)
592 {
593 cfg.Border = CheckBoxSetting(&Display, ID_BORDER);
594 if (cfg.Border)
595 AddAttribute(wnd, HASBORDER);
596 else
597 ClearAttribute(wnd, HASBORDER);
598 }
599
600 /* select whether the application screen has a status bar */
601 static void SelectStatusBar(DFWINDOW wnd)
602 {
603 cfg.StatusBar = CheckBoxSetting(&Display, ID_STATUSBAR);
604 if (cfg.StatusBar)
605 AddAttribute(wnd, HASSTATUSBAR);
606 else
607 ClearAttribute(wnd, HASSTATUSBAR);
608 }
609
610 /* select whether the application screen has a title bar */
611 static void SelectTitle(DFWINDOW wnd)
612 {
613 cfg.Title = CheckBoxSetting(&Display, ID_TITLE);
614 if (cfg.Title)
615 AddAttribute(wnd, HASTITLEBAR);
616 else
617 ClearAttribute(wnd, HASTITLEBAR);
618 }
619
620 #endif
621
622 /* EOF */