|
|
1.1 ! root 1: // mpmain.cpp : Defines the class behaviors for the frame and children. ! 2: // Multipad is a standard MDI application where each child ! 3: // window is similar to the "Notepad" application. This ! 4: // example illustrates document-maintenance techniques such ! 5: // as typical file Open and Save processing, printing, and ! 6: // managing MDI document children windows. ! 7: // ! 8: // This is a part of the Microsoft Foundation Classes C++ library. ! 9: // Copyright (C) 1992 Microsoft Corporation ! 10: // All rights reserved. ! 11: // ! 12: // This source code is only intended as a supplement to the ! 13: // Microsoft Foundation Classes Reference and Microsoft ! 14: // QuickHelp documentation provided with the library. ! 15: // See these sources for detailed information regarding the ! 16: // Microsoft Foundation Classes product. ! 17: ! 18: #include "multipad.h" ! 19: #include <direct.h> ! 20: ! 21: #pragma code_seg("_MPTEXT") ! 22: ! 23: // a simple way to reduce size of C runtimes ! 24: // disable the use of getenv and argv/argc ! 25: extern "C" void _setargv() { } ! 26: extern "C" void _setenvp() { } ! 27: ! 28: // MRU information ! 29: static CString mruFileNames [4]; ! 30: ! 31: ///////////////////////////////////////////////////////////////////////////// ! 32: // The one global application object. ! 33: // ! 34: CMultiPad multiPad("MultiPad"); ! 35: ! 36: ! 37: ///////////////////////////////////////////////////////////////////////////// ! 38: // MPError: ! 39: // A useful printf()-style error routine, which formats and displays a ! 40: // message box. Note that "idFmt" is a resource ID, which should be an ! 41: // fprintf()-style format string. ! 42: // ! 43: short MPError(int bFlags, int idFmt, ...) ! 44: { ! 45: char sz[160]; ! 46: CString strFmt; ! 47: ! 48: strFmt.LoadString(idFmt); ! 49: wvsprintf(sz, (LPCSTR)strFmt, (LPCSTR)(&idFmt + 1)); ! 50: ! 51: return multiPad.m_pMainWnd->MessageBox(sz, AfxGetAppName(), bFlags); ! 52: } ! 53: ! 54: ///////////////////////////////////////////////////////////////////////////// ! 55: // CMPFrame ! 56: ! 57: CMPFrame::CMPFrame(const char* szTitle) : m_statBar() ! 58: { ! 59: m_bShortMenu = FALSE; ! 60: m_pActiveChild = NULL; ! 61: Create(NULL, szTitle, WS_OVERLAPPEDWINDOW, rectDefault, NULL, ! 62: MAKEINTRESOURCE(IDMULTIPAD)); ! 63: } ! 64: ! 65: // OnMenuSelect: ! 66: // As the user highlights different menu items, we are called. We decide ! 67: // which string would be appropriate to put in our status bar. ! 68: // ! 69: // Note some OnMenuSelect messages go to the active child; we just ask the ! 70: // frame to handle these. ! 71: // ! 72: void CMPChild::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) ! 73: { ! 74: GetParentFrame()->SendMessage(WM_MENUSELECT, nItemID, ! 75: MAKELONG(nFlags, hSysMenu)); ! 76: } ! 77: void CMPFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu) ! 78: { ! 79: char szBuf [128]; ! 80: ! 81: UINT ids = 0; ! 82: ! 83: if (nFlags == 0xFFFF && hSysMenu == NULL) ! 84: { ! 85: ids = IDS_ALTPMT; ! 86: } ! 87: else if (nFlags & MF_POPUP) ! 88: { ! 89: ids = IDS_MENUPMT; ! 90: } ! 91: else if ((nFlags & MF_SEPARATOR) == 0) ! 92: { ! 93: if (nItemID >= AFX_IDM_FIRST_MDICHILD) ! 94: ids = IDS_ACTTHISWIN; ! 95: else if (nItemID >= IDM_FILE1 && nItemID <= IDM_FILE4) ! 96: ids = IDS_OPENTHISFILE; ! 97: else ! 98: ids = nItemID; ! 99: } ! 100: ! 101: if (ids != 0) ! 102: LoadString(AfxGetResourceHandle(), ids, szBuf, sizeof (szBuf)); ! 103: else ! 104: szBuf[0] = '\0'; ! 105: ! 106: m_statBar.SetText(szBuf); ! 107: } ! 108: ! 109: // OnCreate: ! 110: // When we're created, in addition to the usual CMDIFrameWnd::OnCreate work, ! 111: // we create a CStatBar status bar window (defined in bar.h and bar.cpp). ! 112: // ! 113: int CMPFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) ! 114: { ! 115: char szBuf [128]; ! 116: ! 117: // Create the status bar, with the usual "Press ALT to choose commands". ! 118: // ! 119: m_statBar.Create(this, CRect(0, 0, 0, 0)); ! 120: LoadString(AfxGetResourceHandle(), IDS_ALTPMT, szBuf, sizeof (szBuf)); ! 121: m_statBar.SetText(szBuf); ! 122: ! 123: return CMDIFrameWnd::OnCreate(lpCreateStruct); ! 124: } ! 125: ! 126: // OnSize: ! 127: // The Windows 3.0 SDK documentation says that, in the case of an MDI Frame ! 128: // window, the ON_SIZE message MUST be passed on to the system after any ! 129: // processing. This sizes the MDI Client window to the whole client area ! 130: // of the frame. ! 131: // ! 132: // Note that instead, you can simply use the MoveWindow function to move the ! 133: // MDI Client window yourself. In fact, you must do this yourself if you ! 134: // don't want the MDI Client to take up the whole Frame client area. If you ! 135: // use MoveWindow, do not pass the ON_SIZE message on for default processing. ! 136: // ! 137: // In our case, we leave some room at the bottom for a status bar. ! 138: // ! 139: void CMPFrame::OnSize(UINT size, int cx, int cy) ! 140: { ! 141: if (size != SIZEICONIC) ! 142: { ! 143: int cxBorder = GetSystemMetrics(SM_CXBORDER); ! 144: int cyBorder = GetSystemMetrics(SM_CYBORDER); ! 145: CRect rcStatBar; ! 146: int cyStatBar; ! 147: ! 148: m_statBar.GetWindowRect(rcStatBar); ! 149: cyStatBar = rcStatBar.bottom - rcStatBar.top; ! 150: HDWP hdwp = ::BeginDeferWindowPos(2); ! 151: ::DeferWindowPos(hdwp, m_statBar.m_hWnd, NULL, -cxBorder, ! 152: cy - cyStatBar + cyBorder, cx + cxBorder * 2, cyStatBar, ! 153: SWP_NOACTIVATE | SWP_NOZORDER); ! 154: ::DeferWindowPos(hdwp, m_hWndMDIClient, NULL, 0, 0, ! 155: cx, cy - cyStatBar + cyBorder, SWP_NOZORDER | SWP_NOACTIVATE); ! 156: ::EndDeferWindowPos(hdwp); ! 157: } ! 158: } ! 159: ! 160: // OnInitMenu: ! 161: // The menu needs to be updated, so we observe our status and gray or check ! 162: // any appropriate menu items. ! 163: // ! 164: ! 165: BOOL bUpdateMRU = TRUE; ! 166: ! 167: void CMPFrame::OnInitMenu(CMenu* pMenu) ! 168: { ! 169: extern char szSearch[]; ! 170: ! 171: UINT nStatus; ! 172: int i; ! 173: ! 174: if (IsIconic()) ! 175: return; ! 176: ! 177: if (bUpdateMRU) ! 178: { ! 179: BOOL bMaximized = HIWORD(::SendMessage(m_hWndMDIClient, ! 180: WM_MDIGETACTIVE, 0, 0)); ! 181: CMenu * pFileMenu = pMenu->GetSubMenu(bMaximized ? 1 : 0); ! 182: ! 183: if (mruFileNames[0].GetLength() > 0) ! 184: { ! 185: char szCurDir [64]; ! 186: ! 187: pFileMenu->DeleteMenu(IDM_FILEMRU, MF_BYCOMMAND); ! 188: pFileMenu->DeleteMenu(IDM_FILE1, MF_BYCOMMAND); ! 189: pFileMenu->DeleteMenu(IDM_FILE2, MF_BYCOMMAND); ! 190: pFileMenu->DeleteMenu(IDM_FILE3, MF_BYCOMMAND); ! 191: pFileMenu->DeleteMenu(IDM_FILE4, MF_BYCOMMAND); ! 192: ! 193: _getcwd(szCurDir, sizeof (szCurDir)); ! 194: int cchCurDir = strlen(szCurDir); ! 195: if (szCurDir[cchCurDir - 1] != '\\') ! 196: { ! 197: szCurDir[cchCurDir++] = '\\'; ! 198: szCurDir[cchCurDir] = '\0'; ! 199: } ! 200: ! 201: for (i = 0; i < 4; i += 1) ! 202: { ! 203: char szBuf [128]; ! 204: char* pch; ! 205: ! 206: if (mruFileNames[i].GetLength() == 0) ! 207: break; ! 208: ! 209: pch = szBuf; ! 210: *pch++ = '&'; ! 211: *pch++ = '1' + i; ! 212: *pch++ = ' '; ! 213: strcpy(pch, (const char*)mruFileNames[i]); ! 214: if (strncmp(szCurDir, (const char*)mruFileNames[i], ! 215: cchCurDir) == 0) ! 216: { ! 217: strcpy(pch, pch + cchCurDir); ! 218: } ! 219: ! 220: pFileMenu->InsertMenu(IDM_FILEEXIT, MF_STRING | MF_BYCOMMAND, ! 221: IDM_FILE1 + i, szBuf); ! 222: } ! 223: ! 224: pFileMenu->InsertMenu(IDM_FILEEXIT, MF_SEPARATOR, IDM_FILEMRU); ! 225: } ! 226: ! 227: pFileMenu->Detach(); ! 228: bUpdateMRU = FALSE; ! 229: } ! 230: ! 231: if (m_pActiveChild != NULL) ! 232: { ! 233: if (m_pActiveChild->m_edit.CanUndo()) ! 234: nStatus = MF_ENABLED; ! 235: else ! 236: nStatus = MF_GRAYED; ! 237: ! 238: pMenu->EnableMenuItem(IDM_EDITUNDO, nStatus); ! 239: ! 240: LONG lSel = m_pActiveChild->m_edit.GetSel(); ! 241: nStatus = (HIWORD(lSel) == LOWORD(lSel)) ? MF_GRAYED : MF_ENABLED; ! 242: pMenu->EnableMenuItem(IDM_EDITCUT, nStatus); ! 243: pMenu->EnableMenuItem(IDM_EDITCOPY, nStatus); ! 244: pMenu->EnableMenuItem(IDM_EDITCLEAR, nStatus); ! 245: ! 246: nStatus = MF_GRAYED; ! 247: if (OpenClipboard()) ! 248: { ! 249: int nFmt = 0; ! 250: ! 251: while ((nFmt = EnumClipboardFormats(nFmt)) != 0) ! 252: { ! 253: if (nFmt == CF_TEXT) ! 254: { ! 255: nStatus = MF_ENABLED; ! 256: break; ! 257: } ! 258: } ! 259: ! 260: CloseClipboard(); ! 261: } ! 262: pMenu->EnableMenuItem(IDM_EDITPASTE, nStatus); ! 263: ! 264: if (m_pActiveChild->m_bWordWrap) ! 265: nStatus = MF_CHECKED; ! 266: else ! 267: nStatus = MF_UNCHECKED; ! 268: pMenu->CheckMenuItem(IDM_EDITWRAP, nStatus); ! 269: ! 270: if (m_pFindReplace != NULL) ! 271: pMenu->EnableMenuItem(IDM_SEARCHFIND, MF_GRAYED); ! 272: else ! 273: pMenu->EnableMenuItem(IDM_SEARCHFIND, MF_ENABLED); ! 274: ! 275: if (m_strFind.GetLength() == 0) ! 276: nStatus = MF_GRAYED; ! 277: else ! 278: nStatus = MF_ENABLED; ! 279: pMenu->EnableMenuItem(IDM_SEARCHNEXT, nStatus); ! 280: pMenu->EnableMenuItem(IDM_SEARCHPREV, nStatus); ! 281: ! 282: // Select All and Wrap toggle always enabled. ! 283: // ! 284: nStatus = MF_ENABLED; ! 285: pMenu->EnableMenuItem(IDM_EDITSELECT, nStatus); ! 286: pMenu->EnableMenuItem(IDM_EDITWRAP, nStatus); ! 287: pMenu->EnableMenuItem(IDM_EDITSETFONT, nStatus); ! 288: } ! 289: else ! 290: { ! 291: nStatus = MF_GRAYED; ! 292: ! 293: for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i += 1) ! 294: pMenu->EnableMenuItem(i, nStatus); ! 295: ! 296: pMenu->CheckMenuItem(IDM_EDITWRAP, MF_UNCHECKED); ! 297: ! 298: pMenu->EnableMenuItem(IDM_SEARCHFIND, nStatus); ! 299: pMenu->EnableMenuItem(IDM_SEARCHNEXT, nStatus); ! 300: pMenu->EnableMenuItem(IDM_SEARCHPREV, nStatus); ! 301: ! 302: pMenu->EnableMenuItem(IDM_FILEPRINT, nStatus); ! 303: } ! 304: ! 305: // nStatus is last value in m_pActiveChild test ! 306: pMenu->EnableMenuItem(IDM_FILEPRINT, nStatus); ! 307: pMenu->EnableMenuItem(IDM_FILESAVE, nStatus); ! 308: pMenu->EnableMenuItem(IDM_FILESAVEAS, nStatus); ! 309: pMenu->EnableMenuItem(IDM_WINDOWTILE, nStatus); ! 310: pMenu->EnableMenuItem(IDM_WINDOWCASCADE, nStatus); ! 311: pMenu->EnableMenuItem(IDM_WINDOWICONS, nStatus); ! 312: pMenu->EnableMenuItem(IDM_WINDOWCLOSEALL, nStatus); ! 313: ! 314: } ! 315: ! 316: void AddFileToMRU(const char* szFileName) ! 317: { ! 318: int i; ! 319: ! 320: bUpdateMRU = TRUE; ! 321: ! 322: for (i = 0; i < 4; i += 1) ! 323: { ! 324: if (szFileName == mruFileNames[i]) ! 325: { ! 326: if (i != 0) ! 327: { ! 328: CString temp = mruFileNames[0]; ! 329: mruFileNames[0] = mruFileNames[i]; ! 330: mruFileNames[i] = temp; ! 331: } ! 332: return; ! 333: } ! 334: } ! 335: ! 336: for (i = 3; i > 0; i -= 1) ! 337: mruFileNames[i] = mruFileNames[i - 1]; ! 338: mruFileNames[0] = szFileName; ! 339: } ! 340: ! 341: ! 342: ///////////////////////////////////////////////////////////////////////////// ! 343: // File menu commands ! 344: ! 345: void CMPFrame::CmdFileNew() ! 346: { ! 347: new CMPChild(NULL); ! 348: } ! 349: ! 350: void CMPFrame::CmdFileOpen() ! 351: { ! 352: ReadFile(); ! 353: } ! 354: ! 355: void CMPFrame::CmdWinCloseAll() ! 356: { ! 357: if (QueryCloseAllChildren()) ! 358: { ! 359: CloseAllChildren(); ! 360: ::ShowWindow(m_hWndMDIClient, SW_SHOW); ! 361: } ! 362: } ! 363: ! 364: BOOL CMPFrame::QueryCloseAllChildren() ! 365: { ! 366: CWnd* pWnd; ! 367: ! 368: for (pWnd = CWnd::FromHandle(::GetWindow(m_hWndMDIClient, GW_CHILD)); pWnd != NULL; ! 369: pWnd = pWnd->GetNextWindow()) ! 370: { ! 371: if (pWnd->GetWindow(GW_OWNER) != NULL) ! 372: continue; ! 373: ! 374: if (pWnd->SendMessage(WM_QUERYENDSESSION)) ! 375: return FALSE; ! 376: } ! 377: ! 378: return TRUE; ! 379: } ! 380: ! 381: void CMPFrame::CloseAllChildren() ! 382: { ! 383: CWnd* pWnd; ! 384: ! 385: // Hide the MDI client window to avoid multiple repaints. ! 386: // ! 387: ::ShowWindow(m_hWndMDIClient, SW_HIDE); ! 388: ! 389: // As long as the MDI client has a child, destroy it. ! 390: // ! 391: while ((pWnd = CWnd::FromHandle(m_hWndMDIClient)->GetWindow(GW_CHILD)) != NULL) ! 392: { ! 393: // Skip the icon title windows. ! 394: // ! 395: while (pWnd != NULL && pWnd->GetWindow(GW_OWNER) != NULL) ! 396: pWnd = pWnd->GetNextWindow(); ! 397: ! 398: if (pWnd == NULL) ! 399: break; ! 400: ! 401: pWnd->DestroyWindow(); ! 402: } ! 403: } ! 404: ! 405: BOOL CMPFrame::OnQueryEndSession() ! 406: { ! 407: return QueryCloseAllChildren(); ! 408: } ! 409: ! 410: void CMPFrame::OnClose() ! 411: { ! 412: if (QueryCloseAllChildren()) ! 413: { ! 414: if (m_pFindReplace != NULL) ! 415: { ! 416: // Do not delete, use DestroyWindow ! 417: m_pFindReplace->SendMessage(WM_COMMAND, IDCANCEL, 0L); ! 418: } ! 419: this->DestroyWindow(); ! 420: } ! 421: } ! 422: ! 423: void CMPFrame::CmdMDITile() ! 424: { ! 425: MDITile(); ! 426: } ! 427: ! 428: void CMPFrame::CmdMDICascade() ! 429: { ! 430: MDICascade(); ! 431: } ! 432: ! 433: void CMPFrame::CmdMDIIconArrange() ! 434: { ! 435: MDIIconArrange(); ! 436: } ! 437: ! 438: void CMPFrame::CmdFileExit() ! 439: { ! 440: OnClose(); ! 441: } ! 442: ! 443: // CmdToggleMenu: ! 444: // Switch between "Full" and "Short" menus. ! 445: // ! 446: void CMPFrame::CmdToggleMenu() ! 447: { ! 448: CMenu menu; ! 449: UINT id, i; ! 450: ! 451: if (m_bShortMenu) ! 452: { ! 453: id = IDMULTIPAD; ! 454: i = WINDOWMENU; ! 455: m_bShortMenu = FALSE; ! 456: } ! 457: else ! 458: { ! 459: id = IDMULTIPAD2; ! 460: i = SHORTMENU; ! 461: m_bShortMenu = TRUE; ! 462: } ! 463: ! 464: menu.LoadMenu(id); ! 465: MDISetMenu(&menu, menu.GetSubMenu(i))->DestroyMenu(); ! 466: menu.Detach(); // Keep it from being destroyed. ! 467: DrawMenuBar(); ! 468: ! 469: bUpdateMRU = TRUE; ! 470: } ! 471: ! 472: ///////////////////////////////////////////////////////////////////////////// ! 473: // Handle profile stuff ! 474: static char BASED_CODE szIniFile[] = "multipad.ini"; ! 475: void LoadMRU() ! 476: { ! 477: char szBuf [128]; ! 478: ! 479: GetPrivateProfileString(AfxGetAppName(), "File1", "", ! 480: szBuf, sizeof (szBuf), szIniFile); ! 481: mruFileNames[0] = szBuf; ! 482: ! 483: GetPrivateProfileString(AfxGetAppName(), "File2", "", ! 484: szBuf, sizeof (szBuf), szIniFile); ! 485: mruFileNames[1] = szBuf; ! 486: ! 487: GetPrivateProfileString(AfxGetAppName(), "File3", "", ! 488: szBuf, sizeof (szBuf), szIniFile); ! 489: mruFileNames[2] = szBuf; ! 490: ! 491: GetPrivateProfileString(AfxGetAppName(), "File4", "", ! 492: szBuf, sizeof (szBuf), szIniFile); ! 493: mruFileNames[3] = szBuf; ! 494: ! 495: bUpdateMRU = TRUE; ! 496: } ! 497: ! 498: void SaveMRU() ! 499: { ! 500: WritePrivateProfileString(AfxGetAppName(), "File1", ! 501: mruFileNames[0], szIniFile); ! 502: WritePrivateProfileString(AfxGetAppName(), "File2", ! 503: mruFileNames[1], szIniFile); ! 504: WritePrivateProfileString(AfxGetAppName(), "File3", ! 505: mruFileNames[2], szIniFile); ! 506: WritePrivateProfileString(AfxGetAppName(), "File4", ! 507: mruFileNames[3], szIniFile); ! 508: } ! 509: ! 510: void CMPFrame::CmdFileMRU() ! 511: { ! 512: int mruIndex = (GetCurrentMessage()->wParam) - IDM_FILE1; ! 513: ReadFile(mruFileNames[mruIndex]); ! 514: } ! 515: ! 516: ///////////////////////////////////////////////////////////////////////////// ! 517: // Help menu commands ! 518: ! 519: void CMPFrame::CmdHelpAbout() ! 520: { ! 521: CModalDialog aboutBox(IDD_ABOUT, this); ! 522: aboutBox.DoModal(); ! 523: } ! 524: ! 525: ///////////////////////////////////////////////////////////////////////////// ! 526: // CMPFrame message map ! 527: BEGIN_MESSAGE_MAP(CMPFrame, CMDIFrameWnd) ! 528: ON_WM_INITMENU() ! 529: ON_WM_MENUSELECT() ! 530: ON_WM_CLOSE() ! 531: ON_WM_QUERYENDSESSION() ! 532: ON_WM_SIZE() ! 533: ON_WM_CREATE() ! 534: ! 535: ON_COMMAND(IDM_FILENEW, CmdFileNew) ! 536: ON_COMMAND(IDM_FILEOPEN, CmdFileOpen) ! 537: ON_COMMAND(IDM_FILEMENU, CmdToggleMenu) ! 538: ON_COMMAND(IDM_FILE1, CmdFileMRU) ! 539: ON_COMMAND(IDM_FILE2, CmdFileMRU) ! 540: ON_COMMAND(IDM_FILE3, CmdFileMRU) ! 541: ON_COMMAND(IDM_FILE4, CmdFileMRU) ! 542: ON_COMMAND(IDM_FILEEXIT, CmdFileExit) ! 543: ! 544: ON_COMMAND(IDM_WINDOWTILE, CmdMDITile) ! 545: ON_COMMAND(IDM_WINDOWCASCADE, CmdMDICascade) ! 546: ON_COMMAND(IDM_WINDOWICONS, CmdMDIIconArrange) ! 547: ON_COMMAND(IDM_WINDOWCLOSEALL, CmdWinCloseAll) ! 548: ! 549: ON_COMMAND(IDM_HELPABOUT, CmdHelpAbout) ! 550: ! 551: // Find stuff ! 552: ON_REGISTERED_MESSAGE(m_nMsgFind, CmdFindHelper) ! 553: /* helper for CFindReplace */ ! 554: ! 555: ON_COMMAND(IDM_SEARCHFIND, CmdFind) ! 556: ON_COMMAND(IDM_SEARCHNEXT, CmdFindNext) ! 557: ON_COMMAND(IDM_SEARCHPREV, CmdFindPrev) ! 558: ! 559: END_MESSAGE_MAP() ! 560: ! 561: ! 562: ////////////////////////////////////////////////////////////////////////// ! 563: // CMPChild routines ! 564: int CMPChild::OnCreate(LPCREATESTRUCT) ! 565: { ! 566: CRect rect(0, 0, 0, 0); ! 567: ! 568: m_edit.Create(WS_BORDER | WS_HSCROLL | WS_VISIBLE | WS_VSCROLL | ! 569: ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_NOHIDESEL | ! 570: WS_MAXIMIZE, rect, this, ID_EDIT); ! 571: ! 572: m_bChanged = FALSE; ! 573: m_bWordWrap = FALSE; ! 574: m_bUntitled = TRUE; ! 575: m_edit.SetFocus(); ! 576: ! 577: return 0; ! 578: } ! 579: ! 580: void CMPChild::OnSize(UINT nFlags, int cx, int cy) ! 581: { ! 582: CRect rc; ! 583: ! 584: GetClientRect(&rc); ! 585: rc.InflateRect(GetSystemMetrics(SM_CXBORDER), ! 586: GetSystemMetrics(SM_CYBORDER)); ! 587: m_edit.MoveWindow(rc); ! 588: ! 589: // This MUST be passed along for MDI to work properly. It handles all ! 590: // of the maximize, minimize, restore logic. ! 591: // ! 592: CMDIChildWnd::OnSize(nFlags, cx, cy); ! 593: } ! 594: ! 595: // CMPChild: ! 596: // We keep tabs on who the active child is. ! 597: // ! 598: void CMPChild::OnMDIActivate(BOOL bActivate, CWnd* pWndActivate, ! 599: CWnd* pWndDeactivate) ! 600: { ! 601: if (bActivate) ! 602: CMPFrame::SetActiveChild((CMPChild*)pWndActivate); ! 603: else if (CMPFrame::GetActiveChild() == pWndDeactivate) ! 604: CMPFrame::SetActiveChild(NULL); ! 605: } ! 606: ! 607: // OnEditChange: ! 608: // The user's been editing the buffer. Remember that it no longer matches ! 609: // the original disk file. ! 610: // ! 611: void CMPChild::OnEditChange() ! 612: { ! 613: m_bChanged = TRUE; ! 614: } ! 615: ! 616: // OnEditErrSpace: ! 617: // No more room in this buffer! Windows limits the size of the CEdit's text ! 618: // to 32Kb. ! 619: // ! 620: void CMPChild::OnEditErrSpace() ! 621: { ! 622: MessageBeep(0); ! 623: } ! 624: ! 625: BOOL CMPChild::OnQueryEndSession() ! 626: { ! 627: return !QueryCloseChild(); ! 628: } ! 629: ! 630: // OnSetFocus: ! 631: // Whenever a child gets the focus, it gives it to its child CEdit instead. ! 632: // ! 633: void CMPChild::OnSetFocus(CWnd* pWndOldFocus) ! 634: { ! 635: m_edit.SetFocus(); ! 636: CMDIChildWnd::OnSetFocus(pWndOldFocus); ! 637: } ! 638: ! 639: // SetWrap: ! 640: // Edit windows are difficult to wrap/unwrap the text within. This code ! 641: // uses a temporary edit window scheme, transferring the old text into ! 642: // a new window to make it wrap properly. ! 643: // ! 644: void CMPChild::SetWrap(BOOL bWrap) ! 645: { ! 646: LONG dws; ! 647: HANDLE hText; ! 648: HANDLE hDummyText; ! 649: ! 650: // Change word wrap mode. ! 651: // ! 652: m_bWordWrap = bWrap; ! 653: ! 654: // Create the appropriate window style, adding a horizontal scroll ! 655: // facility if wrapping is not present. ! 656: // ! 657: dws = WS_BORDER | WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ! 658: ES_NOHIDESEL | ES_MULTILINE; ! 659: if (!bWrap) ! 660: dws |= WS_HSCROLL | ES_AUTOHSCROLL; ! 661: ! 662: // Get the data handle of the old control. ! 663: // ! 664: hText = m_edit.GetHandle(); ! 665: ! 666: // Create a dummy data handle and make it the handle to ! 667: // the old edit control (hText still references the text of ! 668: // old control). ! 669: // ! 670: hDummyText = LocalAlloc(LHND, 0); ! 671: m_edit.SetHandle(hDummyText); ! 672: m_edit.DestroyWindow(); ! 673: ! 674: // Create a new child window. ! 675: // ! 676: CRect rc(0, 0, 0, 0); ! 677: m_edit.Create(dws, rc, this, ID_EDIT); ! 678: ! 679: // Cause the window to be properly sized. ! 680: // ! 681: SendMessage(WM_SIZE, 0, 0L); ! 682: ! 683: // Free the new window's old data handle and set it to ! 684: // hText (text of old edit control). ! 685: // ! 686: // LocalFree(m_edit.GetHandle()); ! 687: m_edit.SetHandle(hText); ! 688: m_edit.SetFont(&m_font); ! 689: ! 690: m_edit.ShowWindow(SW_SHOW); ! 691: ! 692: // Set focus to the new edit control. ! 693: m_edit.SetFocus(); ! 694: } ! 695: ! 696: ///////////////////////////////////////////////////////////////////////////// ! 697: // File menu commands ! 698: ! 699: void CMPChild::CmdFileSave() ! 700: { ! 701: if (m_bUntitled && !ChangeFile()) ! 702: return; ! 703: ! 704: SaveFile(); ! 705: } ! 706: ! 707: void CMPChild::CmdFileSaveAs() ! 708: { ! 709: if (ChangeFile()) ! 710: SaveFile(); ! 711: } ! 712: ! 713: void CMPChild::OnClose() ! 714: { ! 715: if (QueryCloseChild()) ! 716: CMDIChildWnd::OnClose(); ! 717: } ! 718: ! 719: void CMPChild::PostNcDestroy() ! 720: { ! 721: delete this; ! 722: } ! 723: ! 724: BOOL CMPChild::QueryCloseChild() ! 725: { ! 726: char sz[64]; ! 727: ! 728: // Return OK if text has not changed. ! 729: // ! 730: if (!m_bChanged) ! 731: return TRUE; ! 732: ! 733: GetWindowText(sz, sizeof (sz)); ! 734: ! 735: // Ask user whether to save, not save, or cancel. ! 736: // ! 737: switch (MPError(MB_YESNOCANCEL | MB_ICONQUESTION, IDS_CLOSESAVE, ! 738: (LPCSTR)sz)) ! 739: { ! 740: case IDYES: ! 741: // User wants file saved. ! 742: // ! 743: SaveFile(); ! 744: break; ! 745: ! 746: case IDNO: ! 747: // User doesn't want file saved. OK to close child. ! 748: // ! 749: break; ! 750: ! 751: default: ! 752: // We couldn't do the message box, or not OK to close. ! 753: // ! 754: return FALSE; ! 755: } ! 756: ! 757: return TRUE; ! 758: } ! 759: ! 760: ///////////////////////////////////////////////////////////////////////////// ! 761: // Edit menu commands ! 762: ! 763: void CMPChild::CmdSetFont() ! 764: { ! 765: LOGFONT lfInitial; ! 766: ! 767: if (m_edit.GetFont() == NULL) ! 768: { ! 769: // using SystemFont ! 770: CFont sysFont; ! 771: VERIFY(sysFont.CreateStockObject(SYSTEM_FONT)); ! 772: VERIFY(sysFont.GetObject(sizeof(lfInitial), &lfInitial)); ! 773: } ! 774: else ! 775: m_edit.GetFont()->GetObject(sizeof(lfInitial), &lfInitial); ! 776: ! 777: CFontDialog fontDialog(&lfInitial, CF_SCREENFONTS); ! 778: ! 779: if (fontDialog.DoModal() == IDOK) ! 780: { ! 781: m_font.DeleteObject(); ! 782: m_font.CreateFontIndirect(&fontDialog.m_lf); ! 783: m_edit.SetFont(&m_font); ! 784: } ! 785: } ! 786: ! 787: void CMPChild::CmdWordWrap() ! 788: { ! 789: SetWrap(!m_bWordWrap); ! 790: } ! 791: ! 792: void CMPChild::CmdUndo() ! 793: { ! 794: m_edit.Undo(); ! 795: } ! 796: ! 797: void CMPChild::CmdCut() ! 798: { ! 799: m_edit.Cut(); ! 800: } ! 801: ! 802: void CMPChild::CmdCopy() ! 803: { ! 804: m_edit.Copy(); ! 805: } ! 806: ! 807: void CMPChild::CmdPaste() ! 808: { ! 809: m_edit.Paste(); ! 810: } ! 811: ! 812: void CMPChild::CmdClear() ! 813: { ! 814: m_edit.ReplaceSel(""); ! 815: } ! 816: ! 817: void CMPChild::CmdSelectAll() ! 818: { ! 819: m_edit.SetSel(MAKELONG(0, 0xE000)); ! 820: } ! 821: ! 822: ///////////////////////////////////////////////////////////////////////////// ! 823: // CMPChild message map ! 824: BEGIN_MESSAGE_MAP(CMPChild, CMDIChildWnd) ! 825: ON_WM_CREATE() ! 826: ON_WM_MDIACTIVATE() ! 827: ON_WM_QUERYENDSESSION() ! 828: ON_WM_CLOSE() ! 829: ON_WM_SIZE() ! 830: ON_WM_SETFOCUS() ! 831: ON_WM_MENUSELECT() ! 832: ! 833: ON_EN_CHANGE(ID_EDIT, OnEditChange) ! 834: ! 835: ON_COMMAND(IDM_FILESAVE, CmdFileSave) ! 836: ON_COMMAND(IDM_FILESAVEAS, CmdFileSaveAs) ! 837: ON_COMMAND(IDM_FILEPRINT, PrintFile) ! 838: ON_COMMAND(IDM_EDITWRAP, CmdWordWrap) ! 839: ON_COMMAND(IDM_EDITUNDO, CmdUndo) ! 840: ON_COMMAND(IDM_EDITCUT, CmdCut) ! 841: ON_COMMAND(IDM_EDITCOPY, CmdCopy) ! 842: ON_COMMAND(IDM_EDITPASTE, CmdPaste) ! 843: ON_COMMAND(IDM_EDITCLEAR, CmdClear) ! 844: ON_COMMAND(IDM_EDITSETFONT, CmdSetFont) ! 845: ON_COMMAND(IDM_EDITSELECT, CmdSelectAll) ! 846: END_MESSAGE_MAP() ! 847: ! 848: ! 849: int CMultiPad::ExitInstance() ! 850: { ! 851: extern CPrinter* thePrinter; ! 852: delete thePrinter; ! 853: ! 854: SaveMRU(); ! 855: return CWinApp::ExitInstance(); ! 856: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.