|
|
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.