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

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: }

unix.superglobalmegacorp.com

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