|
|
1.1 root 1: /***************************************************************************
2: * *
3: * PROGRAM : MultiPad.c *
4: * *
5: * PURPOSE : To give a multi-Notepad demonstration of the new MDI *
6: * API in Windows 3.0 *
7: * *
8: * FUNCTIONS : WinMain() - Calls the initialization function *
9: * and processes message loop *
10: * *
11: * MPFrameWndProc() - Window function for the "frame" *
12: * window, which controls the menu *
13: * and contains the MDI document *
14: * windows as child windows. *
15: * *
16: * MPMDIChildWndProc() - Window function for the individual *
17: * document windows *
18: * *
19: * InitializeMenu() - Handles enabling/greying of menu *
20: * items according to the app's state.*
21: * *
22: * CloseAllChildren - Destroys all MDI child windows. *
23: * *
24: * CommandHandler() - Processes the "frame" window's *
25: * WM_COMMAND messages. *
26: * *
27: * AboutDlgProc() - Dialog function for the ubiquitous *
28: * About.. dialog. *
29: * *
30: * SetWrap() - Alters word wrapping in the edit *
31: * control. *
32: * *
33: * MPError() - Flashes an error messagebox. *
34: * *
35: * QueryCloseChild - Prompts for saving current MDI *
36: * child window. *
37: * *
38: * QueryCloseAllChildren() - Asks whether it is OK to close *
39: * down app. *
40: * *
41: ***************************************************************************/
42:
43: #include "multipad.h"
44: #include <string.h>
45: #include <stdio.h>
46:
47:
48: /* global variables used in this module or among more than one module */
49: HANDLE hInst; /* Program instance handle */
50: HANDLE hAccel; /* Main accelerator resource */
51: HWND hwndFrame = NULL; /* Handle to main window */
52: HWND hwndMDIClient = NULL; /* Handle to MDI client */
53: HWND hwndActive = NULL; /* Handle to currently activated child */
54: HWND hwndActiveEdit = NULL; /* Handle to edit control */
55: LONG styleDefault = WS_MAXIMIZE; /* Default style bits for child windows */
56: /* The first window is created maximized */
57: /* to resemble Notepad. Later children */
58: /* are normal windows. */
59: LPSTR lpMenu = IDMULTIPAD; /* Contains the resource id of the */
60: /* current frame menu */
61:
62:
63: /* Forward declarations of helper functions in this module */
64: VOID NEAR PASCAL InitializeMenu (HANDLE);
65: VOID NEAR PASCAL CommandHandler (HWND, UINT, LONG);
66: BOOL NEAR PASCAL SetWrap (HWND,BOOL);
67: BOOL NEAR PASCAL QueryCloseAllChildren ( VOID );
68: INT NEAR PASCAL QueryCloseChild (HWND);
69: LPSTR GetCmdLine( VOID );
70:
71: /****************************************************************************
72: * *
73: * FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) *
74: * *
75: * PURPOSE : Creates the "frame" window, does some initialization and *
76: * enters the message loop. *
77: * *
78: ****************************************************************************/
79: int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
80: HANDLE hInstance; /* current instance */
81: HANDLE hPrevInstance; /* previous instance */
82: LPSTR lpCmdLine; /* command line */
83: int nCmdShow; /* show-window type (open/icon) */
84: {
85: MSG msg;
86:
87: hInst = hInstance;
88:
89: /* If this is the first instance of the app. register window classes */
90: if (!hPrevInstance){
91: if (!InitializeApplication ())
92: return 0;
93: }
94:
95: lpCmdLine = GetCmdLine();
96:
97: /* Create the frame and do other initialization */
98: if (!InitializeInstance (lpCmdLine, nCmdShow))
99: return 0;
100:
101: /* Enter main message loop */
102: while (GetMessage (&msg, NULL, 0, 0)){
103: /* If a keyboard message is for the MDI , let the MDI client
104: * take care of it. Otherwise, check to see if it's a normal
105: * accelerator key (like F3 = find next). Otherwise, just handle
106: * the message as usual.
107: */
108: if ( !TranslateMDISysAccel (hwndMDIClient, &msg) &&
109: !TranslateAccelerator (hwndFrame, hAccel, &msg)){
110: TranslateMessage (&msg);
111: DispatchMessage (&msg);
112: }
113: }
114: return 0;
115: }
116:
117: /****************************************************************************
118: * *
119: * FUNCTION : MPFrameWndProc (hwnd, msg, wParam, lParam ) *
120: * *
121: * PURPOSE : The window function for the "frame" window, which controls *
122: * the menu and encompasses all the MDI child windows. Does *
123: * the major part of the message processing. Specifically, in *
124: * response to: *
125: * *
126: * WM_CREATE : Creates and displays the "frame". *
127: * *
128: * WM_INITMENU : Sets up the state of the menu. *
129: * *
130: * WM_WININICHANGE & : If default printer characteristics*
131: * WM_DEVMODECHANGE have been changed, reinitialises *
132: * printer DC. *
133: * *
134: * WM_COMMAND : Passes control to a command- *
135: * handling function. *
136: * *
137: * WM_CLOSE : Quits the app. if all the child *
138: * windows agree. *
139: * *
140: * WM_QUERYENDSESSION : Checks that all child windows *
141: * agree to quit. *
142: * *
143: * WM_DESTROY : Destroys frame window and quits *
144: * app. *
145: * *
146: ****************************************************************************/
147: LONG APIENTRY MPFrameWndProc (
148: register HWND hwnd,
149: UINT msg,
150: UINT wParam,
151: LONG lParam)
152:
153: {
154: switch (msg){
155: case WM_CREATE:{
156:
157: CLIENTCREATESTRUCT ccs;
158: HDC hdc;
159:
160: /* Find window menu where children will be listed */
161: ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd),WINDOWMENU);
162: ccs.idFirstChild = IDM_WINDOWCHILD;
163:
164: /* Create the MDI client filling the client area */
165: hwndMDIClient = CreateWindow ("mdiclient",
166: NULL,
167: WS_CHILD | WS_CLIPCHILDREN |
168: WS_VSCROLL | WS_HSCROLL,
169: 0,
170: 0,
171: 0,
172: 0,
173: hwnd,
174: (HMENU)0xCAC,
175: hInst,
176: (LPSTR)&ccs);
177:
178:
179: ShowWindow (hwndMDIClient,SW_SHOW);
180:
181: /* Check if printer can be initialized */
182: if (hdc = GetPrinterDC (TRUE)){
183: DeleteDC (hdc);
184: }
185:
186: break;
187: }
188:
189: case WM_INITMENU:
190: /* Set up the menu state */
191: InitializeMenu ((HMENU)wParam);
192: break;
193:
194: case WM_WININICHANGE:
195: case WM_DEVMODECHANGE:{
196:
197: /* If control panel changes default printer characteristics,
198: * reinitialize our printer information...
199: */
200: HDC hdc;
201:
202: if (hdc = GetPrinterDC (TRUE)){
203: DeleteDC (hdc);
204: }
205: break;
206: }
207:
208:
209: case WM_COMMAND:
210: /* Direct all menu selection or accelerator commands to another
211: * function
212: */
213: CommandHandler(hwnd, wParam, lParam);
214: break;
215:
216: case WM_CLOSE:
217: /* don't close if any children cancel the operation */
218: if (!QueryCloseAllChildren ())
219: break;
220: DestroyWindow (hwnd);
221: break;
222:
223: case WM_QUERYENDSESSION:
224: /* Before session ends, check that all files are saved */
225: return QueryCloseAllChildren ();
226:
227: case WM_DESTROY:
228: PostQuitMessage (0);
229: break;
230:
231: default:
232: /* use DefFrameProc() instead of DefWindowProc() since there
233: * are things that have to be handled differently because of MDI
234: */
235: return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam);
236: }
237: return 0;
238: }
239:
240: /****************************************************************************
241: * *
242: * FUNCTION : MPMDIWndProc ( hwnd, msg, wParam, lParam ) *
243: * *
244: * PURPOSE : The window function for the individual document windows, *
245: * each of which has a "note". Each of these windows contain *
246: * one multi-line edit control filling their client area. *
247: * In response to the following: *
248: * *
249: * WM_CREATE : Creates & diplays an edit control *
250: * and does some initialization. *
251: * *
252: * WM_MDIACTIVATE : Activates/deactivates the child. *
253: * *
254: * WM_SETFOCUS : Sets focus on the edit control. *
255: * *
256: * WM_SIZE : Resizes the edit control. *
257: * *
258: * WM_COMMAND : Processes some of the edit *
259: * commands, saves files and alters *
260: * the edit wrap state. *
261: * *
262: * WM_CLOSE : Closes child if it is ok to do so.*
263: * *
264: * WM_QUERYENDSESSION : Same as above. *
265: * *
266: ****************************************************************************/
267:
268: LONG APIENTRY MPMDIChildWndProc (
269: register HWND hwnd,
270: UINT msg,
271: register UINT wParam,
272: LONG lParam)
273:
274: {
275: HWND hwndEdit;
276:
277: switch (msg){
278: case WM_CREATE:
279: /* Create an edit control */
280: hwndEdit = CreateWindow ("edit",
281: NULL,
282: WS_CHILD|WS_HSCROLL|WS_MAXIMIZE|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSCROLL|ES_AUTOVSCROLL|ES_MULTILINE,
283: 0,
284: 0,
285: 0,
286: 0,
287: hwnd,
288: (HMENU)ID_EDIT,
289: hInst,
290: NULL);
291:
292: /* Remember the window handle and initialize some window attributes */
293: SetWindowLong (hwnd, GWL_HWNDEDIT, (LONG) hwndEdit);
294: SetWindowWord (hwnd, GWW_CHANGED, FALSE);
295: SetWindowWord (hwnd, GWL_WORDWRAP, FALSE);
296: SetWindowWord (hwnd, GWW_UNTITLED, TRUE);
297: SetFocus (hwndEdit);
298: break;
299:
300: case WM_MDIACTIVATE:
301: /* If we're activating this child, remember it */
302: if (GET_WM_MDIACTIVATE_FACTIVATE(hwnd, wParam, lParam)){
303: hwndActive = hwnd;
304: hwndActiveEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
305: }
306: else{
307: hwndActive = NULL;
308: hwndActiveEdit = NULL;
309: }
310: break;
311:
312: case WM_QUERYENDSESSION:
313: /* Prompt to save the child */
314: return !QueryCloseChild (hwnd);
315:
316: case WM_CLOSE:
317: /* If its OK to close the child, do so, else ignore */
318: if (QueryCloseChild (hwnd))
319: goto CallDCP;
320: else
321: break;
322:
323: case WM_SIZE:{
324: RECT rc;
325:
326: /* On creation or resize, size the edit control. */
327: hwndEdit = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
328: GetClientRect (hwnd, &rc);
329: MoveWindow (hwndEdit,
330: rc.left,
331: rc.top,
332: rc.right-rc.left,
333: rc.bottom-rc.top,
334: TRUE);
335: goto CallDCP;
336: }
337:
338: case WM_SETFOCUS:
339: SetFocus ((HWND)GetWindowLong (hwnd, GWL_HWNDEDIT));
340: break;
341:
342: case WM_COMMAND:
343: switch (LOWORD(wParam)){
344: case ID_EDIT:
345: switch (GET_WM_COMMAND_CMD(wParam, lParam)){
346: case EN_CHANGE:
347:
348: /* If the contents of the edit control have changed,
349: set the changed flag
350: */
351: SetWindowWord (hwnd, GWW_CHANGED, TRUE);
352: break;
353:
354: case EN_ERRSPACE:
355: /* If the control is out of space, honk */
356: MessageBeep (0);
357: break;
358:
359: default:
360: goto CallDCP;
361: }
362: break;
363:
364: case IDM_FILESAVE:
365: /* If empty file, ignore save */
366: if ((GetWindowWord(hwnd, GWW_UNTITLED)) && (!ChangeFile(hwnd)))
367: break;
368:
369: /* Save the contents of the edit control and reset the
370: * changed flag
371: */
372: SaveFile (hwnd);
373: SetWindowWord (hwnd, GWW_CHANGED, FALSE);
374: break;
375:
376: case IDM_EDITWRAP: {
377: INT fWrap = GetWindowWord (hwnd, GWL_WORDWRAP);
378:
379: /* Set the wrap state, or report it */
380: if (GET_WM_COMMAND_HWND(wParam, lParam)){
381: fWrap = !fWrap;
382: if(!SetWrap (hwnd, fWrap)){
383: fWrap = !fWrap; /* call failed, restore original fWrap */
384: }
385: }
386:
387: /* return wrap state */
388: return fWrap;
389: }
390:
391: default:
392: goto CallDCP;
393: }
394: break;
395:
396: default:
397: CallDCP:
398: /* Again, since the MDI default behaviour is a little different,
399: * call DefMDIChildProc instead of DefWindowProc()
400: */
401: return DefMDIChildProc (hwnd, msg, wParam, lParam);
402: }
403: return FALSE;
404: }
405:
406:
407: /****************************************************************************
408: * *
409: * FUNCTION : AboutDlgProc ( hwnd, msg, wParam, lParam ) *
410: * *
411: * PURPOSE : Dialog function for the About MultiPad... dialog. *
412: * *
413: ****************************************************************************/
414: BOOL APIENTRY AboutDlgProc (
415: HWND hwnd,
416: register UINT msg,
417: register UINT wParam,
418: LONG lParam)
419: {
420: switch (msg){
421: case WM_INITDIALOG:
422: /* nothing to initialize */
423: break;
424:
425: case WM_COMMAND:
426: switch (LOWORD(wParam)){
427: case IDOK:
428: case IDCANCEL:
429: EndDialog(hwnd, 0);
430: break;
431:
432: default:
433: return FALSE;
434: }
435: break;
436:
437: default:
438: return FALSE;
439: }
440:
441: return TRUE;
442: UNREFERENCED_PARAMETER(lParam);
443: }
444:
445: /****************************************************************************
446: * *
447: * FUNCTION : Initializemenu ( hMenu ) *
448: * *
449: * PURPOSE : Sets up greying, enabling and checking of main menu items *
450: * based on the app's state. *
451: * *
452: ****************************************************************************/
453: VOID NEAR PASCAL InitializeMenu (register HANDLE hmenu)
454: {
455: register WORD status;
456: WORD i;
457: INT j;
458: LONG l;
459:
460: /* Is there any active child to talk to? */
461: if (hwndActiveEdit){
462: /* If edit control can respond to an undo request, enable the
463: * undo selection.
464: */
465: if (SendMessage (hwndActiveEdit, EM_CANUNDO, 0, 0L))
466:
467: status = MF_ENABLED;
468: else
469: status = MF_GRAYED;
470: EnableMenuItem (hmenu, IDM_EDITUNDO, status);
471:
472: /* If edit control is non-empty, allow cut/copy/clear */
473: l = (LONG)SendMessage(hwndActiveEdit, EM_GETSEL, NULL, NULL);
474:
475:
476: status = (WORD) ((HIWORD(l) == LOWORD(l)) ? MF_GRAYED : MF_ENABLED);
477: EnableMenuItem (hmenu, IDM_EDITCUT, status);
478: EnableMenuItem (hmenu, IDM_EDITCOPY, status);
479: EnableMenuItem (hmenu, IDM_EDITCLEAR, status);
480:
481: status=MF_GRAYED;
482: /* If the clipboard contains some CF_TEXT data, allow paste */
483: if (OpenClipboard (hwndFrame)){
484: UINT wFmt = 0;
485:
486: while (wFmt = EnumClipboardFormats (wFmt))
487: if (wFmt == CF_TEXT){
488: status = MF_ENABLED;
489: break;
490: }
491:
492: CloseClipboard ();
493: }
494: EnableMenuItem (hmenu, IDM_EDITPASTE, status);
495:
496: /* Set the word wrap state for the window */
497: if ((WORD) SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 0, 0)))
498: status = MF_CHECKED;
499: else
500: status = MF_UNCHECKED;
501: CheckMenuItem (hmenu, IDM_EDITWRAP, status);
502:
503: /* Enable search menu items only if there is a search string */
504: if (*szSearch)
505: status = MF_ENABLED;
506: else
507: status = MF_GRAYED;
508: EnableMenuItem (hmenu, IDM_SEARCHNEXT, status);
509: EnableMenuItem (hmenu, IDM_SEARCHPREV, status);
510:
511: /* Enable File/Print only if a printer is available */
512: status = (WORD) (iPrinter ? MF_ENABLED : MF_GRAYED);
513: EnableMenuItem (hmenu, IDM_FILEPRINT, status);
514:
515: /* select all and wrap toggle always enabled */
516: status = MF_ENABLED;
517: EnableMenuItem(hmenu, IDM_EDITSELECT, status);
518: EnableMenuItem(hmenu, IDM_EDITWRAP, status);
519: EnableMenuItem(hmenu, IDM_SEARCHFIND, status);
520: }
521: else {
522: /* There are no active child windows */
523: status = MF_GRAYED;
524:
525: /* No active window, so disable everything */
526: for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i++)
527: EnableMenuItem (hmenu, i, status);
528:
529: CheckMenuItem (hmenu, IDM_EDITWRAP, MF_UNCHECKED);
530:
531: for (i = IDM_SEARCHFIRST; i <= IDM_SEARCHLAST; i++)
532: EnableMenuItem (hmenu, i, status);
533:
534: EnableMenuItem (hmenu, IDM_FILEPRINT, status);
535:
536: }
537:
538: /* The following menu items are enabled if there is an active window */
539: EnableMenuItem (hmenu, IDM_FILESAVE, status);
540: EnableMenuItem (hmenu, IDM_FILESAVEAS, status);
541: EnableMenuItem (hmenu, IDM_WINDOWTILE, status);
542: EnableMenuItem (hmenu, IDM_WINDOWCASCADE, status);
543: EnableMenuItem (hmenu, IDM_WINDOWICONS, status);
544: EnableMenuItem (hmenu, IDM_WINDOWCLOSEALL, status);
545:
546: /* Allow printer setup only if printer driver supports device initialization */
547: if (iPrinter < 2)
548: status = MF_GRAYED;
549: EnableMenuItem ( hmenu, IDM_FILESETUP, status);
550: UNREFERENCED_PARAMETER(j);
551:
552: }
553:
554: /****************************************************************************
555: * *
556: * FUNCTION : CloseAllChildren () *
557: * *
558: * PURPOSE : Destroys all MDI child windows. *
559: * *
560: ****************************************************************************/
561: VOID NEAR PASCAL CloseAllChildren ()
562: {
563: register HWND hwndT;
564:
565: /* hide the MDI client window to avoid multiple repaints */
566: ShowWindow(hwndMDIClient,SW_HIDE);
567:
568: /* As long as the MDI client has a child, destroy it */
569: while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){
570:
571: /* Skip the icon title windows */
572: while (hwndT && GetWindow (hwndT, GW_OWNER))
573: hwndT = GetWindow (hwndT, GW_HWNDNEXT);
574:
575: if (!hwndT)
576: break;
577:
578: SendMessage (hwndMDIClient, WM_MDIDESTROY, (UINT)hwndT, 0L);
579: }
580: }
581:
582: /****************************************************************************
583: * *
584: * FUNCTION : CommandHandler () *
585: * *
586: * PURPOSE : Processes all "frame" WM_COMMAND messages. *
587: * *
588: ****************************************************************************/
589: VOID NEAR PASCAL CommandHandler (
590: register HWND hwnd,
591: register UINT wParam,
592: LONG lParam)
593:
594: {
595: switch (LOWORD(wParam)){
596: case IDM_FILENEW:
597: /* Add a new, empty MDI child */
598: AddFile (NULL);
599: break;
600:
601: case IDM_FILEOPEN:
602: MyReadFile (hwnd);
603: break;
604:
605: case IDM_FILESAVE:
606: /* Save the active child MDI */
607: SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_FILESAVE, 0, 0));
608: break;
609:
610: case IDM_FILESAVEAS:
611: /* Save active child MDI under another name */
612: if (ChangeFile (hwndActive))
613: SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_FILESAVE, 0, 0));
614: break;
615:
616: case IDM_FILEPRINT:
617: /* Print the active child MDI */
618: PrintFile (hwndActive);
619: break;
620:
621: case IDM_FILESETUP:
622: /* Set up the printer environment for this app */
623: GetInitializationData (hwnd);
624: break;
625:
626: case IDM_FILEMENU:{
627:
628: /* lengthen / shorten the size of the MDI menu */
629: HMENU hMenu;
630: HMENU hWindowMenu;
631: INT i;
632:
633: if (lpMenu == IDMULTIPAD){
634: lpMenu = IDMULTIPAD2;
635: i = SHORTMENU;
636: }
637: else{
638: lpMenu = IDMULTIPAD;
639: i = WINDOWMENU;
640: }
641:
642: hMenu = LoadMenu (hInst, lpMenu);
643: hWindowMenu = GetSubMenu (hMenu, i);
644:
645: /* Set the new menu */
646: hMenu = (HMENU)SendMessage (hwndMDIClient,
647: WM_MDISETMENU,
648: (UINT)hMenu,
649: (LONG)hWindowMenu);
650:
651: DestroyMenu (hMenu);
652: DrawMenuBar (hwndFrame);
653: break;
654: }
655:
656: case IDM_FILEEXIT:
657: /* Close Multipad */
658: SendMessage (hwnd, WM_CLOSE, 0, 0L);
659: break;
660:
661: case IDM_HELPABOUT:{
662:
663: DialogBox(hInst, (LPSTR)IDD_ABOUT, hwnd, (WNDPROC)AboutDlgProc);
664: break;
665: }
666:
667: /* The following are edit commands. Pass these off to the active
668: * child's edit control window.
669: */
670: case IDM_EDITCOPY:
671: SendMessage (hwndActiveEdit, WM_COPY, 0, 0L);
672: break;
673:
674: case IDM_EDITPASTE:
675: SendMessage (hwndActiveEdit, WM_PASTE, 0, 0L);
676: break;
677:
678: case IDM_EDITCUT:
679: SendMessage (hwndActiveEdit, WM_CUT, 0, 0L);
680: break;
681:
682: case IDM_EDITCLEAR:
683: SendMessage (hwndActiveEdit, EM_REPLACESEL, 0,( LONG)(LPSTR)"");
684: break;
685:
686: case IDM_EDITSELECT:
687: SendMessage(hwndActiveEdit, EM_SETSEL, GET_EM_SETSEL_MPS(0, 0xe000));
688: break;
689:
690: case IDM_EDITUNDO:
691: SendMessage (hwndActiveEdit, EM_UNDO, 0, 0L);
692: break;
693:
694: case IDM_EDITWRAP:
695: SendMessage(hwndActive, WM_COMMAND, GET_WM_COMMAND_MPS(IDM_EDITWRAP, 1, 0));
696: break;
697:
698: case IDM_SEARCHFIND:
699: /* Put up the find dialog box */
700: Find ();
701: break;
702:
703: case IDM_SEARCHNEXT:
704: /* Find next occurence */
705: FindNext ();
706: break;
707:
708: case IDM_SEARCHPREV:
709: /* Find previous occurence */
710: FindPrev ();
711: break;
712:
713: /* The following are window commands - these are handled by the
714: * MDI Client.
715: */
716: case IDM_WINDOWTILE:
717: /* Tile MDI windows */
718: SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L);
719: break;
720:
721: case IDM_WINDOWCASCADE:
722: /* Cascade MDI windows */
723: SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
724: break;
725:
726: case IDM_WINDOWICONS:
727: /* Auto - arrange MDI icons */
728: SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
729: break;
730:
731: case IDM_WINDOWCLOSEALL:
732: /* Abort operation if something is not saved */
733: if (!QueryCloseAllChildren())
734: break;
735:
736: CloseAllChildren();
737:
738: /* Show the window since CloseAllChilren() hides the window
739: * for fewer repaints.
740: */
741: ShowWindow( hwndMDIClient, SW_SHOW);
742:
743: break;
744:
745: default:
746: /*
747: * This is essential, since there are frame WM_COMMANDS generated
748: * by the MDI system for activating child windows via the
749: * window menu.
750: */
751: DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND, wParam, lParam);
752: }
753: }
754: /****************************************************************************
755: * *
756: * FUNCTION : SetWrap () *
757: * *
758: * PURPOSE : Changes the word wrapping in an edit control. Since this *
759: * cannot be done by direct means, the function creates a new *
760: * edit control, moves data from the old control to the new *
761: * control and destroys the original control. Note that the *
762: * function assumes that the child being modified is currently*
763: * active. * *
764: * *
765: ****************************************************************************/
766:
767: BOOL NEAR PASCAL SetWrap(
768: HWND hwnd,
769: BOOL fWrap)
770:
771: {
772: LONG dws;
773: HANDLE hT;
774: HANDLE hTT;
775: HWND hwndOld;
776: HWND hwndNew;
777: RECT rc;
778:
779: /* Change word wrap mode */
780: SetWindowLong (hwnd, GWL_WORDWRAP, fWrap);
781:
782: /* Create the appropriate window style, adding a horizontal scroll
783: * facility if wrapping is not present.
784: */
785: dws = WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE;
786: if (!fWrap)
787: dws |= WS_HSCROLL | ES_AUTOHSCROLL;
788:
789: /* Create a new child window */
790: hwndNew = CreateWindow ( "edit",
791: NULL,
792: dws,
793: 0,
794: SW_SHOW,
795: 0,
796: 0,
797: hwnd,
798: (HMENU)ID_EDIT,
799: hInst,
800: NULL);
801:
802: /* Get handle to current edit control */
803: hwndOld = (HWND)GetWindowLong (hwnd, GWL_HWNDEDIT);
804:
805: /* Get the data handle of the old control */
806: hT = (HANDLE)SendMessage (hwndOld, EM_GETHANDLE, 0, 0L);
807:
808: /* Create a dummy data handle and make it the handle to
809: * the old edit control( hT still references the text of
810: * old control).
811: */
812: hTT = LocalAlloc (LHND, 0);
813: if(!hTT){
814: MessageBox(hwnd, "<SetWrap> Not enough memory. Can't Change Wrap Mode!", NULL, MB_OK | MB_ICONHAND);
815: return(FALSE);
816: }
817:
818: SendMessage (hwndOld, EM_SETHANDLE, (UINT)hTT, 0L);
819:
820: /* Make the new window the window of interest and destroy the
821: * old control.
822: */
823: SetWindowLong (hwnd, GWL_HWNDEDIT, (LONG)hwndNew);
824: hwndActiveEdit = hwndNew;
825: DestroyWindow (hwndOld);
826:
827: /* Cause the window to be properly sized */
828: SendMessage (hwnd, WM_SIZE, 0, 0L);
829:
830: /* Free the new window's old data handle and set it to
831: * hT (text of old edit control)
832: */
833: LocalFree ((HANDLE)SendMessage (hwndNew, EM_GETHANDLE, 0, 0L));
834: SendMessage (hwndNew, EM_SETHANDLE, (UINT)hT, 0L);
835:
836: ShowWindow (hwndNew, SW_SHOW);
837:
838: /* Set focus to the new edit control */
839: SetFocus (hwndNew);
840:
841: UNREFERENCED_PARAMETER(rc);
842: }
843:
844:
845: /****************************************************************************
846: * *
847: * FUNCTION : MPError ( hwnd, flags, id, ...) *
848: * *
849: * PURPOSE : Flashes a Message Box to the user. The format string is *
850: * taken from the STRINGTABLE. *
851: * *
852: * RETURNS : Returns value returned by MessageBox() to the caller. *
853: * *
854: ****************************************************************************/
855: SHORT MPError(
856: HWND hwnd,
857: WORD bFlags,
858: WORD id,
859: char *psz )
860: {
861: CHAR sz[160];
862: CHAR szFmt[128];
863:
864: LoadString (hInst, id, szFmt, sizeof (szFmt));
865: sprintf (sz, szFmt, psz );
866: LoadString (hInst, (WORD)IDS_APPNAME, (LPSTR)szFmt, sizeof (szFmt));
867: return( (SHORT)MessageBox (hwndFrame, sz, szFmt, bFlags));
868: UNREFERENCED_PARAMETER(hwnd);
869: }
870:
871:
872: /****************************************************************************
873: * *
874: * FUNCTION : QueryCloseAllChildren() *
875: * *
876: * PURPOSE : Asks the child windows if it is ok to close up app. Nothing*
877: * is destroyed at this point. The z-order is not changed. *
878: * *
879: * RETURNS : TRUE - If all children agree to the query. *
880: * FALSE- If any one of them disagrees. *
881: * *
882: ****************************************************************************/
883:
884: BOOL NEAR PASCAL QueryCloseAllChildren()
885: {
886: register HWND hwndT;
887:
888: for ( hwndT = GetWindow (hwndMDIClient, GW_CHILD);
889: hwndT;
890: hwndT = GetWindow (hwndT, GW_HWNDNEXT) ){
891:
892: /* Skip if an icon title window */
893: if (GetWindow (hwndT, GW_OWNER))
894: continue;
895:
896: if (SendMessage (hwndT, WM_QUERYENDSESSION, 0, 0L))
897: return FALSE;
898: }
899: return TRUE;
900: }
901:
902: /****************************************************************************
903: * *
904: * FUNCTION : QueryCloseChild (hwnd) *
905: * *
906: * PURPOSE : If the child MDI is unsaved, allow the user to save, not *
907: * save, or cancel the close operation. *
908: * *
909: * RETURNS : TRUE - if user chooses save or not save, or if the file *
910: * has not changed. *
911: * FALSE - otherwise. *
912: * *
913: ****************************************************************************/
914:
915: BOOL NEAR PASCAL QueryCloseChild(register HWND hwnd)
916: {
917: CHAR sz [64];
918: register INT i;
919:
920: /* Return OK if edit control has not changed. */
921: if (!GetWindowWord (hwnd, GWW_CHANGED))
922: return TRUE;
923:
924: GetWindowText (hwnd, sz, sizeof(sz));
925:
926: /* Ask user whether to save / not save / cancel */
927: i = MPError (hwnd,
928: MB_YESNOCANCEL|MB_ICONQUESTION,IDS_CLOSESAVE,
929: (LPSTR)sz);
930:
931: switch (i){
932: case IDYES:
933: /* User wants file saved */
934: SaveFile(hwnd);
935: break;
936:
937: case IDNO:
938: /* User doesn't want file saved */
939: break;
940:
941: default:
942: /* We couldn't do the messagebox, or not ok to close */
943: return FALSE;
944: }
945: return TRUE;
946: }
947:
948:
949: LPSTR GetCmdLine( VOID )
950: {
951: LPSTR lpCmdLine, lpT;
952:
953: lpCmdLine = GetCommandLine();
954:
955: // on Win32, lpCmdLine's first string includes its own name, remove this
956: // to make it exactly like the windows command line.
957:
958: if (*lpCmdLine) {
959: lpT = strchr(lpCmdLine, ' '); // skip self name
960: if (lpT) {
961: lpCmdLine = lpT;
962: while (*lpCmdLine == ' ') {
963: lpCmdLine++; // skip spaces to end or first cmd
964: }
965: } else {
966: lpCmdLine += strlen(lpCmdLine); // point to NULL
967: }
968: }
969: return(lpCmdLine);
970: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.