|
|
1.1 ! root 1: // This is a part of the Microsoft Foundation Classes C++ library. ! 2: // Copyright (C) 1992 Microsoft Corporation ! 3: // All rights reserved. ! 4: // ! 5: // This source code is only intended as a supplement to the ! 6: // Microsoft Foundation Classes Reference and Microsoft ! 7: // QuickHelp documentation provided with the library. ! 8: // See these sources for detailed information regarding the ! 9: // Microsoft Foundation Classes product. ! 10: ! 11: #include "oclient.h" ! 12: #include "mainwnd.h" ! 13: #include "itemwnd.h" ! 14: ! 15: #include <afxdlgs.h> ! 16: ! 17: ///////////////////////////////////////////////////////////////////////////// ! 18: // File menu commands ! 19: ! 20: void CMainWnd::OnFileNew() ! 21: { ! 22: if (!SaveAsNeeded()) ! 23: return; ! 24: ! 25: InitFile(FALSE); ! 26: } ! 27: ! 28: void CMainWnd::OnFileOpen() ! 29: { ! 30: if (!SaveAsNeeded()) ! 31: return; ! 32: ! 33: CString newName = m_fileName; ! 34: if (!DoFileDlg(newName, IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST)) ! 35: return; ! 36: ! 37: CFile file; ! 38: if (!file.Open(newName, CFile::modeRead | CFile::shareDenyWrite)) ! 39: { ! 40: ErrorMessage(E_FAILED_TO_READ_FILE); ! 41: return; ! 42: } ! 43: ! 44: /* Deregister the current document, and re-init */ ! 45: m_fileName = newName; ! 46: InitFile(TRUE); ! 47: ! 48: /* If we failed to read, we already destroyed ! 49: * all the objects, so go back to File New-like state */ ! 50: Hourglass(TRUE); ! 51: TRY ! 52: { ! 53: CArchive loadArchive(&file, CArchive::load); ! 54: this->Serialize(loadArchive); // load me ! 55: } ! 56: CATCH (CException, e) ! 57: { ! 58: Hourglass(FALSE); ! 59: ErrorMessage(E_FAILED_TO_READ_FILE); ! 60: InitFile(FALSE); // just re-init it like New ! 61: file.Close(); ! 62: return; ! 63: } ! 64: END_CATCH ! 65: ! 66: Hourglass(FALSE); ! 67: m_fDirty = FALSE; ! 68: file.Close(); ! 69: } ! 70: ! 71: ! 72: void CMainWnd::OnFileSave() ! 73: { ! 74: // do the save ! 75: DoSave(m_fileName); ! 76: } ! 77: ! 78: ! 79: void CMainWnd::OnFileSaveAs() ! 80: { ! 81: // save to new name ! 82: DoSave(NULL); ! 83: } ! 84: ! 85: ///////////////////////////////////////////////////////////////////////////// ! 86: // Basic file operations ! 87: ! 88: void CMainWnd::InitFile(BOOL fOpen) ! 89: { ! 90: m_fDirty = FALSE; ! 91: ! 92: /* If New, reset the file name */ ! 93: if (!fOpen) ! 94: m_fileName.Empty(); ! 95: ! 96: /* Deregister the edited document, and wipe out the objects. */ ! 97: DeregisterDoc(); ! 98: ! 99: /* Reset the title bar, and register the OLE client document */ ! 100: SetTitle(); ! 101: } ! 102: ! 103: static void FormatString1(CString&s, UINT idFormat, ! 104: const char* szData, const char* szAlternate) ! 105: { ! 106: char szTmp[CBMESSAGEMAX]; ! 107: CString format; ! 108: format.LoadString(idFormat); ! 109: ! 110: if (szData[0] == '\0') ! 111: szData = szAlternate; ! 112: ! 113: wsprintf(szTmp, (LPCSTR)format, (LPCSTR)szData); ! 114: s = szTmp; ! 115: } ! 116: ! 117: BOOL CMainWnd::SaveAsNeeded() ! 118: { ! 119: if (!m_fDirty) ! 120: return TRUE; ! 121: ! 122: CString prompt; ! 123: FormatString1(prompt, IDS_MAYBESAVE, m_fileName, strUntitled); ! 124: ! 125: /* Ask "Do you wish to save your changes?" */ ! 126: switch (MessageBox(prompt, AfxGetAppName(), MB_YESNOCANCEL | MB_ICONQUESTION)) ! 127: { ! 128: case IDCANCEL: ! 129: return FALSE; // don't continue ! 130: break; ! 131: ! 132: case IDYES: ! 133: /* If so, either Save or Update, as appropriate. */ ! 134: if (!DoSave(m_fileName)) ! 135: return FALSE; // don't continue ! 136: break; ! 137: ! 138: case IDNO: ! 139: /* If not saving changes, revert the document */ ! 140: m_document.NotifyRevert(); ! 141: break; ! 142: ! 143: default: ! 144: ASSERT(FALSE); ! 145: break; ! 146: } ! 147: return TRUE; // keep going ! 148: } ! 149: ! 150: BOOL CMainWnd::DoSave(const char* szFileName) ! 151: // note: can be different than 'm_fileName' for SaveAs ! 152: // will set 'm_fileName' if successful ! 153: { ! 154: CString newName = szFileName; ! 155: if (newName.IsEmpty()) ! 156: { ! 157: // no file name, prompt for new one ! 158: if (!DoFileDlg(newName, IDS_SAVEFILE, ! 159: OFN_HIDEREADONLY | OFN_PATHMUSTEXIST)) ! 160: return FALSE; ! 161: } ! 162: ! 163: CFile file; ! 164: if (!file.Open(newName, CFile::modeCreate | ! 165: CFile::modeReadWrite | CFile::shareExclusive)) ! 166: { ! 167: ErrorMessage(E_INVALID_FILENAME); ! 168: return FALSE; ! 169: } ! 170: ! 171: Hourglass(TRUE); ! 172: TRY ! 173: { ! 174: CArchive saveArchive(&file, CArchive::store); ! 175: this->Serialize(saveArchive); // save me ! 176: } ! 177: CATCH (CException, e) ! 178: { ! 179: Hourglass(FALSE); ! 180: ErrorMessage(E_FAILED_TO_SAVE_FILE); ! 181: file.Close(); ! 182: return FALSE; ! 183: } ! 184: END_CATCH ! 185: ! 186: Hourglass(FALSE); ! 187: file.Close(); ! 188: ! 189: // notify library ! 190: m_document.NotifySaved(); ! 191: m_fDirty = FALSE; ! 192: ! 193: // Reset the title and change the document name ! 194: m_fileName = newName; ! 195: SetTitle(); ! 196: ! 197: return TRUE; // success ! 198: } ! 199: ! 200: ///////////////////////////////////////////////////////////////////////////// ! 201: // Actual reading/writing of data ! 202: ! 203: void CMainWnd::Serialize(CArchive& ar) ! 204: { ! 205: CFrameWnd::Serialize(ar); // does nothing I hope ! 206: WORD wMagic = 0x0DAF; ! 207: ! 208: if (ar.IsStoring()) ! 209: { ! 210: ar << wMagic; ! 211: // First count up number of OLE Objects to write ! 212: CItemWnd* pItemWnd; ! 213: WORD cCompleteObjectsToWrite = 0; ! 214: WORD cIncompleteObjects = 0; ! 215: ! 216: for (pItemWnd = (CItemWnd*)GetTopWindow(); pItemWnd != NULL; ! 217: pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow()) ! 218: { ! 219: if (pItemWnd->IsComplete()) ! 220: cCompleteObjectsToWrite++; ! 221: else ! 222: cIncompleteObjects++; ! 223: } ! 224: ! 225: TRACE("%d complete objects to write, %d incomplete ones to ignore\n", ! 226: cCompleteObjectsToWrite, cIncompleteObjects); ! 227: ! 228: CString prompt; ! 229: prompt.LoadString(IDS_SAVEINCOMPLETE); ! 230: if (cIncompleteObjects > 0 && MessageBox(prompt, AfxGetAppName(), ! 231: MB_YESNO | MB_ICONQUESTION) != IDYES) ! 232: { ! 233: TRACE("Aborting save\n"); ! 234: AfxThrowArchiveException(CArchiveException::generic); ! 235: } ! 236: ! 237: ar << cCompleteObjectsToWrite; ! 238: ! 239: #ifdef _DEBUG ! 240: WORD cObjectsWritten = 0; ! 241: #endif ! 242: // reverse order (easier to rebuild that way) ! 243: for (pItemWnd = (CItemWnd*)GetTopWindow(); pItemWnd != NULL; ! 244: pItemWnd = (CItemWnd*)pItemWnd->GetNextWindow()) ! 245: { ! 246: if (pItemWnd->IsComplete()) ! 247: { ! 248: pItemWnd->Serialize(ar); ! 249: // NOTE: don't use WriteObject since we know the actual ! 250: // class for pItemWnd ! 251: #ifdef _DEBUG ! 252: cObjectsWritten++; ! 253: #endif ! 254: } ! 255: } ! 256: #ifdef _DEBUG ! 257: ASSERT(cObjectsWritten == cCompleteObjectsToWrite); ! 258: #endif ! 259: } ! 260: else // loading ! 261: { ! 262: WORD w; ! 263: ar >> w; ! 264: ! 265: if (w != wMagic) ! 266: { ! 267: TRACE("invalid magic number at start of file\n"); ! 268: AfxThrowArchiveException(CArchiveException::generic); ! 269: } ! 270: ! 271: WORD cObjectsToRead; ! 272: ar >> cObjectsToRead; ! 273: ! 274: for (UINT iObj = 0; iObj < cObjectsToRead; iObj++) ! 275: { ! 276: CItemWnd* pItemWnd = new CItemWnd(this); ! 277: ! 278: pItemWnd->Serialize(ar); ! 279: } ! 280: } ! 281: } ! 282: ! 283: ! 284: ///////////////////////////////////////////////////////////////////////////// ! 285: ! 286: void CMainWnd::SetTitle() ! 287: { ! 288: const char* pszName; ! 289: char szTitle[CBMESSAGEMAX + _MAX_PATH]; ! 290: ! 291: pszName = (m_fileName.IsEmpty()) ? strUntitled : m_fileName; ! 292: wsprintf(szTitle, "%s - %s", (LPCSTR)AfxGetAppName(), (LPCSTR)pszName); ! 293: ! 294: /* Perform the client document registration */ ! 295: if (m_document.IsOpen()) ! 296: { ! 297: m_document.NotifyRename(pszName); ! 298: } ! 299: else ! 300: { ! 301: if (!m_document.Register(AfxGetAppName(), pszName)) ! 302: { ! 303: ErrorMessage(W_FAILED_TO_NOTIFY); ! 304: ASSERT(!m_document.IsOpen()); ! 305: } ! 306: } ! 307: ! 308: SetWindowText(szTitle); ! 309: } ! 310: ! 311: void CMainWnd::DeregisterDoc() ! 312: { ! 313: /* Destroy all the objects */ ! 314: ClearAll(); ! 315: ! 316: /* Release the document */ ! 317: if (m_document.IsOpen()) ! 318: { ! 319: m_document.Revoke(); ! 320: } ! 321: } ! 322: ! 323: ///////////////////////////////////////////////////////////////////////////// ! 324: // File Dialog prompts ! 325: ! 326: static void Normalize(LPSTR lpstrFile); ! 327: ! 328: BOOL CMainWnd::DoFileDlg(CString& fileName, UINT nIDTitle, DWORD lFlags) ! 329: { ! 330: CString title; ! 331: CString filter; ! 332: CString ext; ! 333: VERIFY(title.LoadString(nIDTitle)); ! 334: VERIFY(filter.LoadString(IDS_FILTER)); ! 335: VERIFY(ext.LoadString(IDS_EXTENSION)); ! 336: ! 337: ! 338: CFileDialog dlg(TRUE, ext, fileName, lFlags, filter); ! 339: ! 340: dlg.m_ofn.lpstrTitle = title; ! 341: ! 342: if (dlg.DoModal() == IDCANCEL) ! 343: return FALSE; ! 344: ! 345: fileName = dlg.GetFileName() + '.' + dlg.GetFileExt(); ! 346: return TRUE; ! 347: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.