Annotation of mstools/samples/multipad/multipad.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.