home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / wordpad / wordpdoc.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  17KB  |  618 lines

  1. // wordpdoc.cpp : implementation of the CWordPadDoc class
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14.  
  15. #include "wordpad.h"
  16. #include "wordpdoc.h"
  17. #include "wordpvw.h"
  18. #include "cntritem.h"
  19. #include "srvritem.h"
  20. #include "formatba.h"
  21.  
  22. #include "mainfrm.h"
  23. #include "ipframe.h"
  24. #include "buttondi.h"
  25. #include "helpids.h"
  26. #include "strings.h"
  27. #include "unitspag.h"
  28. #include "docopt.h"
  29. #include "optionsh.h"
  30.  
  31. #include "multconv.h"
  32.  
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37.  
  38. extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
  39. extern UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax);
  40.  
  41. #ifndef OFN_EXPLORER
  42. #define OFN_EXPLORER 0x00080000L
  43. #endif
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CWordPadDoc
  46. IMPLEMENT_DYNCREATE(CWordPadDoc, CRichEditDoc)
  47.  
  48. BEGIN_MESSAGE_MAP(CWordPadDoc, CRichEditDoc)
  49.     //{{AFX_MSG_MAP(CWordPadDoc)
  50.     ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
  51.     ON_UPDATE_COMMAND_UI(ID_OLE_VERB_POPUP, OnUpdateOleVerbPopup)
  52.     ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)
  53.     ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateIfEmbedded)
  54.     ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateIfEmbedded)
  55.     ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateIfEmbedded)
  56.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateIfEmbedded)
  57.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_DIRECT, OnUpdateIfEmbedded)
  58.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, OnUpdateIfEmbedded)
  59.     //}}AFX_MSG_MAP
  60.     ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)
  61.     ON_COMMAND(ID_OLE_EDIT_LINKS, CRichEditDoc::OnEditLinks)
  62.     ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, CRichEditDoc::OnUpdateObjectVerbMenu)
  63.     ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, CRichEditDoc::OnUpdateObjectVerbMenu)
  64.     ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, CRichEditDoc::OnUpdateEditLinksMenu)
  65. END_MESSAGE_MAP()
  66.  
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CWordPadDoc construction/destruction
  69.  
  70. CWordPadDoc::CWordPadDoc()
  71. {
  72.     m_nDocType = -1;
  73.     m_nNewDocType = -1;
  74. }
  75.  
  76. BOOL CWordPadDoc::OnNewDocument()
  77. {
  78.     if (!CRichEditDoc::OnNewDocument())
  79.         return FALSE;
  80.  
  81.     //correct type already set in theApp.m_nNewDocType;
  82.     int nDocType = (IsEmbedded()) ? RD_EMBEDDED : theApp.m_nNewDocType;
  83.  
  84.     GetView()->SetDefaultFont(IsTextType(nDocType));
  85.     SetDocType(nDocType);
  86.  
  87.     return TRUE;
  88. }
  89.  
  90. void CWordPadDoc::ReportSaveLoadException(LPCTSTR lpszPathName,
  91.     CException* e, BOOL bSaving, UINT nIDP)
  92. {
  93.     if (!m_bDeferErrors && e != NULL)
  94.     {
  95.         ASSERT_VALID(e);
  96.         if (e->IsKindOf(RUNTIME_CLASS(CFileException)))
  97.         {
  98.             switch (((CFileException*)e)->m_cause)
  99.             {
  100.             case CFileException::fileNotFound:
  101.             case CFileException::badPath:
  102.                 nIDP = AFX_IDP_FAILED_INVALID_PATH;
  103.                 break;
  104.             case CFileException::diskFull:
  105.                 nIDP = AFX_IDP_FAILED_DISK_FULL;
  106.                 break;
  107.             case CFileException::accessDenied:
  108.                 nIDP = bSaving ? AFX_IDP_FAILED_ACCESS_WRITE :
  109.                         AFX_IDP_FAILED_ACCESS_READ;
  110.                 if (((CFileException*)e)->m_lOsError == ERROR_WRITE_PROTECT)
  111.                     nIDP = IDS_WRITEPROTECT;
  112.                 break;
  113.             case CFileException::tooManyOpenFiles:
  114.                 nIDP = IDS_TOOMANYFILES;
  115.                 break;
  116.             case CFileException::directoryFull:
  117.                 nIDP = IDS_DIRFULL;
  118.                 break;
  119.             case CFileException::sharingViolation:
  120.                 nIDP = IDS_SHAREVIOLATION;
  121.                 break;
  122.             case CFileException::lockViolation:
  123.             case CFileException::badSeek:
  124.             case CFileException::generic:
  125.             case CFileException::invalidFile:
  126.             case CFileException::hardIO:
  127.                 nIDP = bSaving ? AFX_IDP_FAILED_IO_ERROR_WRITE :
  128.                         AFX_IDP_FAILED_IO_ERROR_READ;
  129.                 break;
  130.             default:
  131.                 break;
  132.             }
  133.             CString prompt;
  134.             AfxFormatString1(prompt, nIDP, lpszPathName);
  135.             AfxMessageBox(prompt, MB_ICONEXCLAMATION, nIDP);
  136.             return;
  137.         }
  138.     }
  139.     CRichEditDoc::ReportSaveLoadException(lpszPathName, e, bSaving, nIDP);
  140.     return;
  141. }
  142.  
  143. BOOL CWordPadDoc::OnOpenDocument(LPCTSTR lpszPathName)
  144. {
  145.     if (m_lpRootStg != NULL) // we are embedded
  146.     {
  147.         // we really want to use the converter on this storage
  148.         m_nNewDocType = RD_EMBEDDED;
  149.     }
  150.     else
  151.     {
  152.         if (theApp.cmdInfo.m_bForceTextMode)
  153.             m_nNewDocType = RD_TEXT;
  154.         else
  155.         {
  156.             CFileException fe;
  157.             m_nNewDocType = GetDocTypeFromName(lpszPathName, fe);
  158.             if (m_nNewDocType == -1)
  159.             {
  160.                 ReportSaveLoadException(lpszPathName, &fe, FALSE,
  161.                     AFX_IDP_FAILED_TO_OPEN_DOC);
  162.                 return FALSE;
  163.             }
  164.             if (m_nNewDocType == RD_TEXT && theApp.m_bForceOEM)
  165.                 m_nNewDocType = RD_OEMTEXT;
  166.         }
  167.         ScanForConverters();
  168.         if (!doctypes[m_nNewDocType].bRead)
  169.         {
  170.             CString str;
  171.             CString strName = doctypes[m_nNewDocType].GetString(DOCTYPE_DOCTYPE);
  172.             AfxFormatString1(str, IDS_CANT_LOAD, strName);
  173.             AfxMessageBox(str, MB_OK|MB_ICONINFORMATION);
  174.             return FALSE;
  175.         }
  176.     }
  177.  
  178. //  SetDocType(nNewDocType);
  179.     if (!CRichEditDoc::OnOpenDocument(lpszPathName))
  180.         return FALSE;
  181.     return TRUE;
  182. }
  183.  
  184. void CWordPadDoc::Serialize(CArchive& ar)
  185. {
  186.     COleMessageFilter* pFilter = AfxOleGetMessageFilter();
  187.     ASSERT(pFilter != NULL);
  188.     pFilter->EnableBusyDialog(FALSE);
  189.     if (ar.IsLoading())
  190.         SetDocType(m_nNewDocType);
  191.     CRichEditDoc::Serialize(ar);
  192.     pFilter->EnableBusyDialog(TRUE);
  193. }
  194.  
  195. BOOL CWordPadDoc::DoSave(LPCTSTR pszPathName, BOOL bReplace /*=TRUE*/)
  196.     // Save the document data to a file
  197.     // pszPathName = path name where to save document file
  198.     // if pszPathName is NULL then the user will be prompted (SaveAs)
  199.     // note: pszPathName can be different than 'm_strPathName'
  200.     // if 'bReplace' is TRUE will change file name if successful (SaveAs)
  201.     // if 'bReplace' is FALSE will not change path name (SaveCopyAs)
  202. {
  203.     CString newName = pszPathName;
  204.     int nOrigDocType = m_nDocType;  //saved in case of SaveCopyAs or failure
  205.  
  206.     //  newName     bWrite  type    result
  207.     //  empty       TRUE    -       SaveAs dialog
  208.     //  empty       FALSE   -       SaveAs dialog
  209.     //  notempty    TRUE    -       nothing
  210.     //  notempty    FALSE   W6      warn (change to wordpad, save as, cancel)
  211.     //  notempty    FALSE   other   warn (save as, cancel)
  212.  
  213.     BOOL bModified = IsModified();
  214.  
  215.     ScanForConverters();
  216.  
  217.     BOOL bSaveAs = FALSE;
  218.     if (newName.IsEmpty())
  219.         bSaveAs = TRUE;
  220.     else if (!doctypes[m_nDocType].bWrite)
  221.     {
  222.         if (m_nDocType == RD_WINWORD6)
  223.         {
  224.             //      DWORD nHelpIDs[] =
  225.             //      {
  226.             //          0, 0
  227.             //      };
  228.             int nRes = CButtonDialog::DisplayMessageBox(
  229.                 MAKEINTRESOURCE(IDS_WORD6_WARNING), AfxGetAppName(),
  230.                 MAKEINTRESOURCE(IDS_WORD6_WARNING_BUTTONS),
  231.                 MB_ICONQUESTION, 1, 2);
  232.             if (nRes == 0) // Save
  233.                 SetDocType(RD_WORDPAD, TRUE);
  234.             else if (nRes == 2) // Cancel
  235.                 return FALSE;
  236.             else
  237.                 bSaveAs = TRUE;
  238.             // else save as
  239.         }
  240.         else //
  241.         {
  242.             if (AfxMessageBox(IDS_SAVE_UNSUPPORTED,
  243.                 MB_YESNO | MB_ICONQUESTION) != IDYES)
  244.             {
  245.                 return FALSE;
  246.             }
  247.             else
  248.                 bSaveAs = TRUE;
  249.         }
  250.     }
  251.  
  252.     if (m_lpRootStg == NULL && IsTextType(m_nDocType) &&
  253.         !GetView()->IsFormatText())
  254.     {
  255.         // formatting changed in plain old text file
  256.         DWORD nHelpIDs[] =
  257.         {
  258.             0, IDH_WORDPAD_WORD6FILE,
  259.             0, IDH_WORDPAD_FORMATTED,
  260.             0, IDH_WORDPAD_TEXTFILE,
  261.             0, 0
  262.         };
  263.         CString str;
  264.         AfxFormatString1(str, IDS_SAVE_FORMAT_TEXT, GetTitle());
  265.         int nRes = CButtonDialog::DisplayMessageBox(str,
  266.             MAKEINTRESOURCE(AFX_IDS_APP_TITLE),
  267.             MAKEINTRESOURCE(IDS_TF_BUTTONS), MB_ICONQUESTION, 0, 3, nHelpIDs);
  268.         if (nRes == 3)
  269.             return FALSE;
  270.         int nDocType = (nRes == 0) ? RD_DEFAULT:    //Word 6
  271.                     (nRes == 1) ? RD_RICHTEXT : //RTF
  272.                     RD_TEXT;                    //text
  273.         if (IsTextType(m_nDocType) && nDocType != RD_TEXT)
  274.             SetDocType(nDocType, TRUE);
  275.         if (nDocType != RD_TEXT)
  276.             bSaveAs = TRUE;
  277.     }
  278.  
  279.     GetView()->GetParentFrame()->RecalcLayout();
  280.     if (bSaveAs)
  281.     {
  282.         newName = m_strPathName;
  283.         if (bReplace && newName.IsEmpty())
  284.         {
  285.             newName = m_strTitle;
  286.             int iBad = newName.FindOneOf(_T(" #%;/\\"));    // dubious filename
  287.             if (iBad != -1)
  288.                 newName.ReleaseBuffer(iBad);
  289.  
  290.             // append the default suffix if there is one
  291.             newName += GetExtFromType(m_nDocType);
  292.         }
  293.  
  294.         int nDocType = m_nDocType;
  295.         if (!theApp.PromptForFileName(newName,
  296.             bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
  297.             OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, &nDocType))
  298.         {
  299.             SetDocType(nOrigDocType, TRUE);
  300.             return FALSE;       // don't even try to save
  301.         }
  302.         SetDocType(nDocType, TRUE);
  303.     }
  304.  
  305.     BeginWaitCursor();
  306.     if (!OnSaveDocument(newName))
  307.     {
  308.         if (pszPathName == NULL)
  309.         {
  310.             // be sure to delete the file
  311.             TRY
  312.             {
  313.                 CFile::Remove(newName);
  314.             }
  315.             CATCH_ALL(e)
  316.             {
  317.                 TRACE0("Warning: failed to delete file after failed SaveAs\n");
  318.             }
  319.             END_CATCH_ALL
  320.         }
  321.         // restore orginal document type
  322.         SetDocType(nOrigDocType, TRUE);
  323.         EndWaitCursor();
  324.         return FALSE;
  325.     }
  326.  
  327.     EndWaitCursor();
  328.     if (bReplace)
  329.     {
  330.         int nType = m_nDocType;
  331.         SetDocType(nOrigDocType, TRUE);
  332.         SetDocType(nType);
  333.         // Reset the title and change the document name
  334.         SetPathName(newName, TRUE);
  335.         ASSERT(m_strPathName == newName);       // must be set
  336.     }
  337.     else // SaveCopyAs
  338.     {
  339.         SetDocType(nOrigDocType, TRUE);
  340.         SetModifiedFlag(bModified);
  341.     }
  342.     return TRUE;        // success
  343. }
  344.  
  345. class COIPF : public COleIPFrameWnd
  346. {
  347. public:
  348.     CFrameWnd* GetMainFrame() { return m_pMainFrame;}
  349.     CFrameWnd* GetDocFrame() { return m_pDocFrame;}
  350. };
  351.  
  352. void CWordPadDoc::OnDeactivateUI(BOOL bUndoable)
  353. {
  354.     if (GetView()->m_bDelayUpdateItems)
  355.         UpdateAllItems(NULL);
  356.     SaveState(m_nDocType);
  357.     CRichEditDoc::OnDeactivateUI(bUndoable);
  358.     COIPF* pFrame = (COIPF*)m_pInPlaceFrame;
  359.     if (pFrame != NULL)
  360.     {
  361.         if (pFrame->GetMainFrame() != NULL)
  362.             ForceDelayed(pFrame->GetMainFrame());
  363.         if (pFrame->GetDocFrame() != NULL)
  364.             ForceDelayed(pFrame->GetDocFrame());
  365.     }
  366. }
  367.  
  368. void CWordPadDoc::ForceDelayed(CFrameWnd* pFrameWnd)
  369. {
  370.     ASSERT_VALID(this);
  371.     ASSERT_VALID(pFrameWnd);
  372.  
  373.     POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  374.     while (pos != NULL)
  375.     {
  376.         // show/hide the next control bar
  377.         CControlBar* pBar =
  378.             (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  379.  
  380.         BOOL bVis = pBar->GetStyle() & WS_VISIBLE;
  381.         UINT swpFlags = 0;
  382.         if ((pBar->m_nStateFlags & CControlBar::delayHide) && bVis)
  383.             swpFlags = SWP_HIDEWINDOW;
  384.         else if ((pBar->m_nStateFlags & CControlBar::delayShow) && !bVis)
  385.             swpFlags = SWP_SHOWWINDOW;
  386.         pBar->m_nStateFlags &= ~(CControlBar::delayShow|CControlBar::delayHide);
  387.         if (swpFlags != 0)
  388.         {
  389.             pBar->SetWindowPos(NULL, 0, 0, 0, 0, swpFlags|
  390.                 SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  391.         }
  392.     }
  393. }
  394.  
  395. /////////////////////////////////////////////////////////////////////////////
  396. // CWordPadDoc Attributes
  397. CLSID CWordPadDoc::GetClassID()
  398. {
  399.     return (m_pFactory == NULL) ? CLSID_NULL : m_pFactory->GetClassID();
  400. }
  401.  
  402. void CWordPadDoc::SetDocType(int nNewDocType, BOOL bNoOptionChange)
  403. {
  404.     ASSERT(nNewDocType != -1);
  405.     if (nNewDocType == m_nDocType)
  406.         return;
  407.  
  408.     m_bRTF = !IsTextType(nNewDocType);
  409.     if (bNoOptionChange)
  410.         m_nDocType = nNewDocType;
  411.     else
  412.     {
  413.         SaveState(m_nDocType);
  414.         m_nDocType = nNewDocType;
  415.         RestoreState(m_nDocType);
  416.     }
  417. }
  418.  
  419. CWordPadView* CWordPadDoc::GetView()
  420. {
  421.     POSITION pos = GetFirstViewPosition();
  422.     return (CWordPadView* )GetNextView( pos );
  423. }
  424.  
  425. /////////////////////////////////////////////////////////////////////////////
  426. // CWordPadDoc Operations
  427.  
  428. CFile* CWordPadDoc::GetFile(LPCTSTR pszPathName, UINT nOpenFlags, CFileException* pException)
  429. {
  430.     CTrackFile* pFile = NULL;
  431.     CFrameWnd* pWnd = GetView()->GetParentFrame();
  432. #ifdef CONVERTERS
  433.     ScanForConverters();
  434.  
  435.     // if writing use current doc type otherwise use new doc type
  436.     int nType = (nOpenFlags & CFile::modeReadWrite) ? m_nDocType : m_nNewDocType;
  437.     // m_nNewDocType will be same as m_nDocType except when opening a new file
  438.     if (doctypes[nType].pszConverterName != NULL)
  439.         pFile = new CConverter(doctypes[nType].pszConverterName, pWnd);
  440.     else
  441. #endif
  442.     if (nType == RD_OEMTEXT)
  443.         pFile = new COEMFile(pWnd);
  444.     else
  445.         pFile = new CTrackFile(pWnd);
  446.     if (!pFile->Open(pszPathName, nOpenFlags, pException))
  447.     {
  448.         delete pFile;
  449.         return NULL;
  450.     }
  451.     if (nOpenFlags & (CFile::modeWrite | CFile::modeReadWrite))
  452.         pFile->m_dwLength = 0; // can't estimate this
  453.     else
  454.         pFile->m_dwLength = pFile->GetLength();
  455.     return pFile;
  456. }
  457.  
  458. CRichEditCntrItem* CWordPadDoc::CreateClientItem(REOBJECT* preo) const
  459. {
  460.     // cast away constness of this
  461.     return new CWordPadCntrItem(preo, (CWordPadDoc*)this);
  462. }
  463.  
  464. /////////////////////////////////////////////////////////////////////////////
  465. // CWordPadDoc server implementation
  466.  
  467. COleServerItem* CWordPadDoc::OnGetEmbeddedItem()
  468. {
  469.     // OnGetEmbeddedItem is called by the framework to get the COleServerItem
  470.     //  that is associated with the document.  It is only called when necessary.
  471.  
  472.     CEmbeddedItem* pItem = new CEmbeddedItem(this);
  473.     ASSERT_VALID(pItem);
  474.     return pItem;
  475. }
  476.  
  477. /////////////////////////////////////////////////////////////////////////////
  478. // CWordPadDoc serialization
  479.  
  480. /////////////////////////////////////////////////////////////////////////////
  481. // CWordPadDoc diagnostics
  482.  
  483. #ifdef _DEBUG
  484. void CWordPadDoc::AssertValid() const
  485. {
  486.     CRichEditDoc::AssertValid();
  487. }
  488.  
  489. void CWordPadDoc::Dump(CDumpContext& dc) const
  490. {
  491.     CRichEditDoc::Dump(dc);
  492. }
  493. #endif //_DEBUG
  494.  
  495. /////////////////////////////////////////////////////////////////////////////
  496. // CWordPadDoc commands
  497.  
  498. int CWordPadDoc::MapType(int nType)
  499. {
  500.     if (nType == RD_OEMTEXT)
  501.         nType = RD_TEXT;
  502.     else if (!IsInPlaceActive() && nType == RD_EMBEDDED)
  503.         nType = RD_RICHTEXT;
  504.     return nType;
  505. }
  506.  
  507. void CWordPadDoc::OnViewOptions()
  508. {
  509.     int nType = MapType(m_nDocType);
  510.     int nFirstPage = 3;
  511.     if (nType == RD_TEXT)
  512.         nFirstPage = 1;
  513.     else if (nType == RD_RICHTEXT)
  514.         nFirstPage = 2;
  515.     else if (nType == RD_WRITE)
  516.         nFirstPage = 4;
  517.     else if (nType == RD_EMBEDDED)
  518.         nFirstPage = 5;
  519.  
  520.     SaveState(nType);
  521.  
  522.     COptionSheet sheet(IDS_OPTIONS, NULL, nFirstPage);
  523.  
  524.     if (sheet.DoModal() == IDOK)
  525.     {
  526.         CWordPadView* pView = GetView();
  527.         if (theApp.m_bWordSel)
  528.             pView->GetRichEditCtrl().SetOptions(ECOOP_OR, ECO_AUTOWORDSELECTION);
  529.         else
  530.         {
  531.             pView->GetRichEditCtrl().SetOptions(ECOOP_AND,
  532.                 ~(DWORD)ECO_AUTOWORDSELECTION);
  533.         }
  534.         RestoreState(nType);
  535.     }
  536. }
  537.  
  538. void CWordPadDoc::OnUpdateOleVerbPopup(CCmdUI* pCmdUI)
  539. {
  540.     pCmdUI->m_pParentMenu = pCmdUI->m_pMenu;
  541.     CRichEditDoc::OnUpdateObjectVerbMenu(pCmdUI);
  542. }
  543.  
  544. BOOL CWordPadDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  545. {
  546.     if (nCode == CN_COMMAND && nID == ID_OLE_VERB_POPUP)
  547.         nID = ID_OLE_VERB_FIRST;
  548.     return CRichEditDoc::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  549. }
  550.  
  551. void CWordPadDoc::SaveState(int nType)
  552. {
  553.     if (nType == -1)
  554.         return;
  555.     nType = MapType(nType);
  556.     CWordPadView* pView = GetView();
  557.     if (pView != NULL)
  558.     {
  559.         CFrameWnd* pFrame = pView->GetParentFrame();
  560.         ASSERT(pFrame != NULL);
  561.         // save current state
  562.         pFrame->SendMessage(WPM_BARSTATE, 0, nType);
  563.         theApp.GetDocOptions(nType).m_nWordWrap = pView->m_nWordWrap;
  564.     }
  565. }
  566.  
  567. void CWordPadDoc::RestoreState(int nType)
  568. {
  569.     if (nType == -1)
  570.         return;
  571.     nType = MapType(nType);
  572.     CWordPadView* pView = GetView();
  573.     if (pView != NULL)
  574.     {
  575.         CFrameWnd* pFrame = pView->GetParentFrame();
  576.         ASSERT(pFrame != NULL);
  577.         // set new state
  578.         pFrame->SendMessage(WPM_BARSTATE, 1, nType);
  579.         int nWrapNew = theApp.GetDocOptions(nType).m_nWordWrap;
  580.         if (pView->m_nWordWrap != nWrapNew)
  581.         {
  582.             pView->m_nWordWrap = nWrapNew;
  583.             pView->WrapChanged();
  584.         }
  585.     }
  586. }
  587.  
  588. void CWordPadDoc::OnCloseDocument()
  589. {
  590.     SaveState(m_nDocType);
  591.     CRichEditDoc::OnCloseDocument();
  592. }
  593.  
  594. void CWordPadDoc::PreCloseFrame(CFrameWnd* pFrameArg)
  595. {
  596.     CRichEditDoc::PreCloseFrame(pFrameArg);
  597.     SaveState(m_nDocType);
  598. }
  599.  
  600. void CWordPadDoc::OnFileSendMail()
  601. {
  602.     if (m_strTitle.Find('.') == -1)
  603.     {
  604.         // add the extension because the default extension will be wrong
  605.         CString strOldTitle = m_strTitle;
  606.         m_strTitle += GetExtFromType(m_nDocType);
  607.         CRichEditDoc::OnFileSendMail();
  608.         m_strTitle = strOldTitle;
  609.     }
  610.     else
  611.         CRichEditDoc::OnFileSendMail();
  612. }
  613.  
  614. void CWordPadDoc::OnUpdateIfEmbedded(CCmdUI* pCmdUI)
  615. {
  616.     pCmdUI->Enable(!IsEmbedded());
  617. }
  618.