|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.