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