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