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