Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

843 lines
23 KiB

  1. // wordpdoc.cpp : implementation of the CWordPadDoc class
  2. //
  3. // Copyright (C) 1992-1999 Microsoft Corporation
  4. // All rights reserved.
  5. #include "stdafx.h"
  6. #include "wordpad.h"
  7. #include "wordpdoc.h"
  8. #include "wordpvw.h"
  9. #include "cntritem.h"
  10. #include "srvritem.h"
  11. #include "formatba.h"
  12. #include "mainfrm.h"
  13. #include "ipframe.h"
  14. #include "helpids.h"
  15. #include "strings.h"
  16. #include "unitspag.h"
  17. #include "docopt.h"
  18. #include "optionsh.h"
  19. #include "multconv.h"
  20. #include "fixhelp.h"
  21. BOOL AskAboutFormatLoss(CWordPadDoc *pDoc) ;
  22. //
  23. // These defines are from ..\shell\userpri\uconvert.h
  24. //
  25. #define REVERSE_BYTE_ORDER_MARK 0xFFFE
  26. #define BYTE_ORDER_MARK 0xFEFF
  27. BOOL CheckForUnicodeTextFile(LPCTSTR lpszPathName) ;
  28. #ifdef _DEBUG
  29. #undef THIS_FILE
  30. static char BASED_CODE THIS_FILE[] = __FILE__;
  31. #endif
  32. extern BOOL AFXAPI AfxFullPath(LPTSTR lpszPathOut, LPCTSTR lpszFileIn);
  33. extern UINT AFXAPI AfxGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax);
  34. #ifndef OFN_EXPLORER
  35. #define OFN_EXPLORER 0x00080000L
  36. #endif
  37. //
  38. // This small class implements the "This is an unsupported save format" dialog.
  39. // It's main purpose is to provide a place to hang the "always convert to RTF"
  40. // checkbox.
  41. //
  42. class UnsupportedSaveFormatDialog : public CDialog
  43. {
  44. public:
  45. UnsupportedSaveFormatDialog()
  46. : CDialog(TEXT("UnsupportedSaveFormatDialog")),
  47. m_always_convert_to_rtf(false)
  48. {
  49. }
  50. BOOL ShouldAlwaysConvertToRTF() {return m_always_convert_to_rtf;}
  51. protected:
  52. BOOL m_always_convert_to_rtf;
  53. void DoDataExchange(CDataExchange *pDX)
  54. {
  55. CDialog::DoDataExchange(pDX);
  56. DDX_Check(pDX, IDC_ALWAYS_RTF, m_always_convert_to_rtf);
  57. }
  58. };
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CWordPadDoc
  61. IMPLEMENT_DYNCREATE(CWordPadDoc, CRichEdit2Doc)
  62. BEGIN_MESSAGE_MAP(CWordPadDoc, CRichEdit2Doc)
  63. //{{AFX_MSG_MAP(CWordPadDoc)
  64. ON_COMMAND(ID_VIEW_OPTIONS, OnViewOptions)
  65. ON_UPDATE_COMMAND_UI(ID_OLE_VERB_POPUP, OnUpdateOleVerbPopup)
  66. ON_COMMAND(ID_FILE_SEND_MAIL, OnFileSendMail)
  67. ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateIfEmbedded)
  68. ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateIfEmbedded)
  69. ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateIfEmbedded)
  70. ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateIfEmbedded)
  71. ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_DIRECT, OnUpdateIfEmbedded)
  72. ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, OnUpdateIfEmbedded)
  73. //}}AFX_MSG_MAP
  74. ON_UPDATE_COMMAND_UI(ID_FILE_SEND_MAIL, OnUpdateFileSendMail)
  75. ON_COMMAND(ID_OLE_EDIT_LINKS, OnEditLinks)
  76. ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, CRichEdit2Doc::OnUpdateObjectVerbMenu)
  77. ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, CRichEdit2Doc::OnUpdateObjectVerbMenu)
  78. ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, CRichEdit2Doc::OnUpdateEditLinksMenu)
  79. END_MESSAGE_MAP()
  80. /////////////////////////////////////////////////////////////////////////////
  81. // CWordPadDoc construction/destruction
  82. CWordPadDoc::CWordPadDoc()
  83. {
  84. m_nDocType = -1;
  85. m_nNewDocType = -1;
  86. m_short_filename = NULL;
  87. }
  88. BOOL CWordPadDoc::OnNewDocument()
  89. {
  90. if (!CRichEdit2Doc::OnNewDocument())
  91. return FALSE;
  92. //correct type already set in theApp.m_nNewDocType;
  93. int nDocType = (IsEmbedded()) ? RD_EMBEDDED : theApp.m_nNewDocType;
  94. GetView()->SetDefaultFont(IsTextType(nDocType));
  95. SetDocType(nDocType);
  96. return TRUE;
  97. }
  98. void CWordPadDoc::ReportSaveLoadException(LPCTSTR lpszPathName,
  99. CException* e, BOOL bSaving, UINT nIDP)
  100. {
  101. if (!m_bDeferErrors && e != NULL)
  102. {
  103. ASSERT_VALID(e);
  104. if (e->IsKindOf(RUNTIME_CLASS(CFileException)))
  105. {
  106. switch (((CFileException*)e)->m_cause)
  107. {
  108. case CFileException::fileNotFound:
  109. case CFileException::badPath:
  110. nIDP = AFX_IDP_FAILED_INVALID_PATH;
  111. break;
  112. case CFileException::diskFull:
  113. nIDP = AFX_IDP_FAILED_DISK_FULL;
  114. break;
  115. case CFileException::accessDenied:
  116. nIDP = AFX_IDP_FILE_ACCESS_DENIED;
  117. if (((CFileException*)e)->m_lOsError == ERROR_WRITE_PROTECT)
  118. nIDP = IDS_WRITEPROTECT;
  119. break;
  120. case CFileException::tooManyOpenFiles:
  121. nIDP = IDS_TOOMANYFILES;
  122. break;
  123. case CFileException::directoryFull:
  124. nIDP = IDS_DIRFULL;
  125. break;
  126. case CFileException::sharingViolation:
  127. nIDP = IDS_SHAREVIOLATION;
  128. break;
  129. case CFileException::lockViolation:
  130. case CFileException::badSeek:
  131. case CFileException::generic:
  132. case CFileException::invalidFile:
  133. case CFileException::hardIO:
  134. nIDP = bSaving ? AFX_IDP_FAILED_IO_ERROR_WRITE :
  135. AFX_IDP_FAILED_IO_ERROR_READ;
  136. break;
  137. default:
  138. break;
  139. }
  140. CString prompt;
  141. AfxFormatString1(prompt, nIDP, lpszPathName);
  142. AfxMessageBox(prompt, MB_ICONEXCLAMATION, nIDP);
  143. return;
  144. }
  145. }
  146. CRichEdit2Doc::ReportSaveLoadException(lpszPathName, e, bSaving, nIDP);
  147. return;
  148. }
  149. BOOL CheckForUnicodeTextFile(LPCTSTR lpszPathName)
  150. {
  151. BOOL fRet = FALSE ;
  152. HANDLE hFile = (HANDLE) 0 ;
  153. WORD wBOM ;
  154. DWORD dwBytesRead = 0 ;
  155. BOOL bTmp ;
  156. if (lpszPathName == NULL)
  157. {
  158. return FALSE ;
  159. }
  160. hFile = CreateFile(
  161. lpszPathName,
  162. GENERIC_READ,
  163. FILE_SHARE_READ | FILE_SHARE_WRITE,
  164. NULL,
  165. OPEN_EXISTING,
  166. FILE_ATTRIBUTE_NORMAL,
  167. NULL) ;
  168. if (hFile == INVALID_HANDLE_VALUE)
  169. {
  170. return FALSE ;
  171. }
  172. bTmp = ReadFile(
  173. hFile,
  174. &wBOM,
  175. sizeof(WORD),
  176. &dwBytesRead,
  177. NULL) ;
  178. if (bTmp)
  179. {
  180. if (dwBytesRead == sizeof(WORD))
  181. {
  182. if ( (wBOM == BYTE_ORDER_MARK) ||
  183. (wBOM == REVERSE_BYTE_ORDER_MARK) )
  184. {
  185. fRet = TRUE ;
  186. }
  187. }
  188. }
  189. CloseHandle(hFile) ;
  190. return fRet ;
  191. }
  192. BOOL CWordPadDoc::OnOpenDocument2(LPCTSTR lpszPathName, bool defaultToText, BOOL* pbAccessDenied)
  193. {
  194. if (pbAccessDenied)
  195. *pbAccessDenied = FALSE;
  196. if (m_lpRootStg != NULL) // we are embedded
  197. {
  198. // we really want to use the converter on this storage
  199. m_nNewDocType = RD_EMBEDDED;
  200. }
  201. else
  202. {
  203. if (theApp.cmdInfo.m_bForceTextMode)
  204. m_nNewDocType = RD_TEXT;
  205. else
  206. {
  207. CFileException fe;
  208. m_nNewDocType = GetDocTypeFromName(lpszPathName, fe, defaultToText);
  209. if (m_nNewDocType == -1)
  210. {
  211. if (defaultToText)
  212. {
  213. ReportSaveLoadException(lpszPathName, &fe, FALSE,
  214. AFX_IDP_FAILED_TO_OPEN_DOC);
  215. }
  216. return FALSE;
  217. }
  218. if (RD_FEWINWORD5 == m_nNewDocType)
  219. {
  220. AfxMessageBox(IDS_FEWINWORD5_DOC, MB_OK, MB_ICONINFORMATION);
  221. if (pbAccessDenied)
  222. *pbAccessDenied = TRUE;
  223. return FALSE;
  224. }
  225. if (m_nNewDocType == RD_TEXT && theApp.m_bForceOEM)
  226. m_nNewDocType = RD_OEMTEXT;
  227. }
  228. ScanForConverters();
  229. if (!doctypes[m_nNewDocType].bRead || DocTypeDisabled(m_nNewDocType))
  230. {
  231. CString str;
  232. CString strName = doctypes[m_nNewDocType].GetString(DOCTYPE_DOCTYPE);
  233. AfxFormatString1(str, IDS_CANT_LOAD, strName);
  234. AfxMessageBox(str, MB_OK|MB_ICONINFORMATION);
  235. if (pbAccessDenied)
  236. *pbAccessDenied = TRUE;
  237. return FALSE;
  238. }
  239. }
  240. if (RD_TEXT == m_nNewDocType)
  241. {
  242. if (CheckForUnicodeTextFile(lpszPathName))
  243. m_nNewDocType = RD_UNICODETEXT;
  244. }
  245. if (!CRichEdit2Doc::OnOpenDocument(lpszPathName))
  246. return FALSE;
  247. // Update any Ole links
  248. COleUpdateDialog(this).DoModal();
  249. return TRUE;
  250. }
  251. BOOL CWordPadDoc::OnOpenDocument(LPCTSTR lpszPathName)
  252. {
  253. BOOL bAccessDenied = FALSE;
  254. if (OnOpenDocument2(lpszPathName, NO_DEFAULT_TO_TEXT, &bAccessDenied))
  255. {
  256. delete [] m_short_filename;
  257. m_short_filename = NULL;
  258. return TRUE;
  259. }
  260. // if we know we failed, don't try the short name
  261. if (bAccessDenied)
  262. return FALSE;
  263. LPTSTR short_filename = new TCHAR[MAX_PATH];
  264. if (NULL == short_filename)
  265. AfxThrowMemoryException();
  266. if (0 == ::GetShortPathName(lpszPathName, short_filename, MAX_PATH))
  267. {
  268. delete [] short_filename;
  269. if (ERROR_FILE_NOT_FOUND == GetLastError())
  270. {
  271. CFileException fe(CFileException::fileNotFound);
  272. ReportSaveLoadException(lpszPathName, &fe, FALSE,
  273. AFX_IDP_FAILED_TO_OPEN_DOC);
  274. return FALSE;
  275. }
  276. AfxThrowFileException(
  277. CFileException::generic,
  278. GetLastError(),
  279. lpszPathName);
  280. }
  281. if (OnOpenDocument2(short_filename))
  282. {
  283. delete [] m_short_filename;
  284. m_short_filename = short_filename;
  285. return TRUE;
  286. }
  287. delete [] short_filename;
  288. return FALSE;
  289. }
  290. void CWordPadDoc::Serialize(CArchive& ar)
  291. {
  292. COleMessageFilter* pFilter = AfxOleGetMessageFilter();
  293. ASSERT(pFilter != NULL);
  294. pFilter->EnableBusyDialog(FALSE);
  295. if (ar.IsLoading())
  296. SetDocType(m_nNewDocType);
  297. //
  298. // Strip (or output) the byte order mark if this is a Unicode file
  299. //
  300. if (m_bUnicode)
  301. {
  302. if (ar.IsLoading())
  303. {
  304. WORD byte_order_mark;
  305. ar >> byte_order_mark;
  306. // No support for byte-reversed files
  307. ASSERT(BYTE_ORDER_MARK == byte_order_mark);
  308. }
  309. else
  310. {
  311. ar << (WORD) BYTE_ORDER_MARK;
  312. }
  313. }
  314. CRichEdit2Doc::Serialize(ar);
  315. pFilter->EnableBusyDialog(TRUE);
  316. }
  317. BOOL AskAboutFormatLoss(CWordPadDoc *pDoc)
  318. {
  319. UNREFERENCED_PARAMETER(pDoc);
  320. return (IDYES == AfxMessageBox(IDS_SAVE_FORMAT_TEXT, MB_YESNO));
  321. }
  322. BOOL CWordPadDoc::DoSave(LPCTSTR pszPathName, BOOL bReplace /*=TRUE*/)
  323. // Save the document data to a file
  324. // pszPathName = path name where to save document file
  325. // if pszPathName is NULL then the user will be prompted (SaveAs)
  326. // note: pszPathName can be different than 'm_strPathName'
  327. // if 'bReplace' is TRUE will change file name if successful (SaveAs)
  328. // if 'bReplace' is FALSE will not change path name (SaveCopyAs)
  329. {
  330. if (NULL != pszPathName)
  331. if (pszPathName == m_strPathName && NULL != m_short_filename)
  332. pszPathName = m_short_filename;
  333. CString newName = pszPathName;
  334. int nOrigDocType = m_nDocType; //saved in case of SaveCopyAs or failure
  335. int nDocType ;
  336. // newName bWrite type result
  337. // empty TRUE - SaveAs dialog
  338. // empty FALSE - SaveAs dialog
  339. // notempty TRUE - nothing
  340. // notempty FALSE W6 warn (change to wordpad, save as, cancel)
  341. // notempty FALSE other warn (save as, cancel)
  342. BOOL bModified = IsModified();
  343. ScanForConverters();
  344. BOOL bSaveAs = FALSE;
  345. if (newName.IsEmpty())
  346. {
  347. bSaveAs = TRUE;
  348. }
  349. else if (!doctypes[m_nDocType].bWrite)
  350. {
  351. if (!theApp.ShouldAlwaysConvertToRTF())
  352. {
  353. UnsupportedSaveFormatDialog dialog;
  354. if (IDOK != dialog.DoModal())
  355. return FALSE;
  356. if (dialog.ShouldAlwaysConvertToRTF())
  357. theApp.SetAlwaysConvertToRTF();
  358. }
  359. m_nDocType = RD_RICHTEXT;
  360. }
  361. if (m_lpRootStg == NULL && IsTextType(m_nDocType) &&
  362. !bSaveAs && !GetView()->IsFormatText())
  363. {
  364. if (!AskAboutFormatLoss(this))
  365. bSaveAs = TRUE;
  366. }
  367. GetView()->GetParentFrame()->RecalcLayout();
  368. if (bSaveAs)
  369. {
  370. newName = m_strPathName;
  371. if (bReplace && newName.IsEmpty())
  372. {
  373. newName = m_strTitle;
  374. int iBad = newName.FindOneOf(_T(" #%;/\\")); // dubious filename
  375. if (iBad != -1)
  376. newName.ReleaseBuffer(iBad);
  377. // append the default suffix if there is one
  378. newName += GetExtFromType(m_nDocType);
  379. }
  380. nDocType = m_nDocType;
  381. promptloop:
  382. if (!theApp.PromptForFileName(newName,
  383. bReplace ? AFX_IDS_SAVEFILE : AFX_IDS_SAVEFILECOPY,
  384. OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, FALSE, &nDocType))
  385. {
  386. SetDocType(nOrigDocType, TRUE);
  387. return FALSE; // don't even try to save
  388. }
  389. else
  390. {
  391. //
  392. // If we are transitioning from non-text to text, we need
  393. // to warn the user if there is any formatting / graphics
  394. // that will be lost
  395. //
  396. if (IsTextType(nDocType))
  397. {
  398. if (m_lpRootStg == NULL && !GetView()->IsFormatText())
  399. {
  400. if (!AskAboutFormatLoss(this))
  401. goto promptloop;
  402. }
  403. }
  404. }
  405. SetDocType(nDocType, TRUE);
  406. }
  407. BeginWaitCursor();
  408. if (!OnSaveDocument(newName))
  409. {
  410. //
  411. // The original code deleted the file if an error occurred, on the
  412. // assumption that if we tried to save a file and something went wrong
  413. // but there was a file there after the save, the file is probably
  414. // bogus. This fails if there is an existing file that doesn't have
  415. // write access but does have delete access. How can this happen?
  416. // The security UI does not remove delete access when you remove
  417. // write access.
  418. //
  419. // restore orginal document type
  420. SetDocType(nOrigDocType, TRUE);
  421. EndWaitCursor();
  422. return FALSE;
  423. }
  424. EndWaitCursor();
  425. if (bReplace)
  426. {
  427. int nType = m_nDocType;
  428. SetDocType(nOrigDocType, TRUE);
  429. SetDocType(nType);
  430. // Reset the title and change the document name
  431. if (NULL == m_short_filename
  432. || 0 != newName.CompareNoCase(m_short_filename))
  433. {
  434. SetPathName(newName, TRUE);
  435. // If we saved to a new filename, reset the short name
  436. if (bSaveAs)
  437. {
  438. delete [] m_short_filename;
  439. m_short_filename = NULL;
  440. }
  441. }
  442. }
  443. else // SaveCopyAs
  444. {
  445. SetDocType(nOrigDocType, TRUE);
  446. SetModifiedFlag(bModified);
  447. }
  448. return TRUE; // success
  449. }
  450. class COIPF : public COleIPFrameWnd
  451. {
  452. public:
  453. CFrameWnd* GetMainFrame() { return m_pMainFrame;}
  454. CFrameWnd* GetDocFrame() { return m_pDocFrame;}
  455. };
  456. void CWordPadDoc::OnDeactivateUI(BOOL bUndoable)
  457. {
  458. if (GetView()->m_bDelayUpdateItems)
  459. UpdateAllItems(NULL);
  460. SaveState(m_nDocType);
  461. CRichEdit2Doc::OnDeactivateUI(bUndoable);
  462. COIPF* pFrame = (COIPF*)m_pInPlaceFrame;
  463. if (pFrame != NULL)
  464. {
  465. if (pFrame->GetMainFrame() != NULL)
  466. ForceDelayed(pFrame->GetMainFrame());
  467. if (pFrame->GetDocFrame() != NULL)
  468. ForceDelayed(pFrame->GetDocFrame());
  469. }
  470. }
  471. void CWordPadDoc::ForceDelayed(CFrameWnd* pFrameWnd)
  472. {
  473. ASSERT_VALID(this);
  474. ASSERT_VALID(pFrameWnd);
  475. POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
  476. while (pos != NULL)
  477. {
  478. // show/hide the next control bar
  479. CControlBar* pBar =
  480. (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
  481. BOOL bVis = pBar->GetStyle() & WS_VISIBLE;
  482. UINT swpFlags = 0;
  483. if ((pBar->m_nStateFlags & CControlBar::delayHide) && bVis)
  484. swpFlags = SWP_HIDEWINDOW;
  485. else if ((pBar->m_nStateFlags & CControlBar::delayShow) && !bVis)
  486. swpFlags = SWP_SHOWWINDOW;
  487. pBar->m_nStateFlags &= ~(CControlBar::delayShow|CControlBar::delayHide);
  488. if (swpFlags != 0)
  489. {
  490. pBar->SetWindowPos(NULL, 0, 0, 0, 0, swpFlags|
  491. SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  492. }
  493. }
  494. }
  495. /////////////////////////////////////////////////////////////////////////////
  496. // CWordPadDoc Attributes
  497. CLSID CWordPadDoc::GetClassID()
  498. {
  499. return (m_pFactory == NULL) ? CLSID_NULL : m_pFactory->GetClassID();
  500. }
  501. void CWordPadDoc::SetDocType(int nNewDocType, BOOL bNoOptionChange)
  502. {
  503. ASSERT(nNewDocType != -1);
  504. if (nNewDocType == m_nDocType)
  505. return;
  506. m_bRTF = !IsTextType(nNewDocType);
  507. m_bUnicode = (nNewDocType == RD_UNICODETEXT);
  508. if (bNoOptionChange)
  509. m_nDocType = nNewDocType;
  510. else
  511. {
  512. SaveState(m_nDocType);
  513. m_nDocType = nNewDocType;
  514. RestoreState(m_nDocType);
  515. }
  516. }
  517. CWordPadView* CWordPadDoc::GetView()
  518. {
  519. POSITION pos = GetFirstViewPosition();
  520. return (CWordPadView* )GetNextView( pos );
  521. }
  522. /////////////////////////////////////////////////////////////////////////////
  523. // CWordPadDoc Operations
  524. CFile* CWordPadDoc::GetFile(LPCTSTR pszPathName, UINT nOpenFlags, CFileException* pException)
  525. {
  526. CTrackFile* pFile = NULL;
  527. CFrameWnd* pWnd = GetView()->GetParentFrame();
  528. #ifdef CONVERTERS
  529. ScanForConverters();
  530. // if writing use current doc type otherwise use new doc type
  531. int nType = (nOpenFlags & CFile::modeReadWrite) ? m_nDocType : m_nNewDocType;
  532. // m_nNewDocType will be same as m_nDocType except when opening a new file
  533. if (doctypes[nType].pszConverterName != NULL)
  534. pFile = new CConverter(doctypes[nType].pszConverterName, pWnd);
  535. else
  536. #endif
  537. if (nType == RD_OEMTEXT)
  538. pFile = new COEMFile(pWnd);
  539. else
  540. pFile = new CTrackFile(pWnd);
  541. if (!pFile->Open(pszPathName, nOpenFlags, pException))
  542. {
  543. delete pFile;
  544. return NULL;
  545. }
  546. if (nOpenFlags & (CFile::modeWrite | CFile::modeReadWrite))
  547. pFile->m_dwLength = 0; // can't estimate this
  548. else
  549. pFile->m_dwLength = pFile->GetLength();
  550. return pFile;
  551. }
  552. CRichEdit2CntrItem* CWordPadDoc::CreateClientItem(REOBJECT* preo) const
  553. {
  554. // cast away constness of this
  555. return new CWordPadCntrItem(preo, (CWordPadDoc*)this);
  556. }
  557. /////////////////////////////////////////////////////////////////////////////
  558. // CWordPadDoc server implementation
  559. COleServerItem* CWordPadDoc::OnGetEmbeddedItem()
  560. {
  561. // OnGetEmbeddedItem is called by the framework to get the COleServerItem
  562. // that is associated with the document. It is only called when necessary.
  563. CEmbeddedItem* pItem = new CEmbeddedItem(this);
  564. ASSERT_VALID(pItem);
  565. return pItem;
  566. }
  567. /////////////////////////////////////////////////////////////////////////////
  568. // CWordPadDoc serialization
  569. /////////////////////////////////////////////////////////////////////////////
  570. // CWordPadDoc diagnostics
  571. #ifdef _DEBUG
  572. void CWordPadDoc::AssertValid() const
  573. {
  574. CRichEdit2Doc::AssertValid();
  575. }
  576. void CWordPadDoc::Dump(CDumpContext& dc) const
  577. {
  578. CRichEdit2Doc::Dump(dc);
  579. }
  580. #endif //_DEBUG
  581. /////////////////////////////////////////////////////////////////////////////
  582. // CWordPadDoc commands
  583. int CWordPadDoc::MapType(int nType)
  584. {
  585. if (nType == RD_OEMTEXT || nType == RD_UNICODETEXT)
  586. nType = RD_TEXT;
  587. else if (!IsInPlaceActive() && nType == RD_EMBEDDED)
  588. nType = RD_RICHTEXT;
  589. return nType;
  590. }
  591. void CWordPadDoc::OnViewOptions()
  592. {
  593. int nType = MapType(m_nDocType);
  594. int nFirstPage = 3;
  595. if (nType == RD_TEXT)
  596. nFirstPage = 1;
  597. else if (nType == RD_RICHTEXT)
  598. nFirstPage = 2;
  599. else if (nType == RD_WRITE)
  600. nFirstPage = 4;
  601. else if (nType == RD_EMBEDDED)
  602. nFirstPage = 5;
  603. SaveState(nType);
  604. COptionSheet sheet(IDS_OPTIONS, NULL, nFirstPage);
  605. if (sheet.DoModal() == IDOK)
  606. {
  607. CWordPadView* pView = GetView();
  608. if (theApp.m_bWordSel)
  609. pView->GetRichEditCtrl().SetOptions(ECOOP_OR, ECO_AUTOWORDSELECTION);
  610. else
  611. {
  612. pView->GetRichEditCtrl().SetOptions(ECOOP_AND,
  613. ~(DWORD)ECO_AUTOWORDSELECTION);
  614. }
  615. RestoreState(nType);
  616. }
  617. }
  618. void CWordPadDoc::OnUpdateOleVerbPopup(CCmdUI* pCmdUI)
  619. {
  620. pCmdUI->m_pParentMenu = pCmdUI->m_pMenu;
  621. CRichEdit2Doc::OnUpdateObjectVerbMenu(pCmdUI);
  622. }
  623. BOOL CWordPadDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  624. {
  625. if (nCode == CN_COMMAND && nID == ID_OLE_VERB_POPUP)
  626. nID = ID_OLE_VERB_FIRST;
  627. return CRichEdit2Doc::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  628. }
  629. void CWordPadDoc::SaveState(int nType)
  630. {
  631. if (nType == -1)
  632. return;
  633. nType = MapType(nType);
  634. CWordPadView* pView = GetView();
  635. if (pView != NULL)
  636. {
  637. CFrameWnd* pFrame = pView->GetParentFrame();
  638. ASSERT(pFrame != NULL);
  639. // save current state
  640. pFrame->SendMessage(WPM_BARSTATE, 0, nType);
  641. theApp.GetDocOptions(nType).m_nWordWrap = pView->m_nWordWrap;
  642. }
  643. }
  644. void CWordPadDoc::RestoreState(int nType)
  645. {
  646. if (nType == -1)
  647. return;
  648. nType = MapType(nType);
  649. CWordPadView* pView = GetView();
  650. if (pView != NULL)
  651. {
  652. CFrameWnd* pFrame = pView->GetParentFrame();
  653. ASSERT(pFrame != NULL);
  654. // set new state
  655. pFrame->SendMessage(WPM_BARSTATE, 1, nType);
  656. int nWrapNew = theApp.GetDocOptions(nType).m_nWordWrap;
  657. if (pView->m_nWordWrap != nWrapNew)
  658. {
  659. pView->m_nWordWrap = nWrapNew;
  660. pView->WrapChanged();
  661. }
  662. }
  663. }
  664. void CWordPadDoc::OnCloseDocument()
  665. {
  666. SaveState(m_nDocType);
  667. CRichEdit2Doc::OnCloseDocument();
  668. }
  669. void CWordPadDoc::PreCloseFrame(CFrameWnd* pFrameArg)
  670. {
  671. CRichEdit2Doc::PreCloseFrame(pFrameArg);
  672. SaveState(m_nDocType);
  673. }
  674. void CWordPadDoc::OnFileSendMail()
  675. {
  676. if (m_strTitle.Find('.') == -1)
  677. {
  678. // add the extension because the default extension will be wrong
  679. CString strOldTitle = m_strTitle;
  680. m_strTitle += GetExtFromType(m_nDocType);
  681. CRichEdit2Doc::OnFileSendMail();
  682. m_strTitle = strOldTitle;
  683. }
  684. else
  685. CRichEdit2Doc::OnFileSendMail();
  686. }
  687. void CWordPadDoc::OnUpdateIfEmbedded(CCmdUI* pCmdUI)
  688. {
  689. pCmdUI->Enable(!IsEmbedded());
  690. }
  691. void CWordPadDoc::OnEditLinks()
  692. {
  693. g_fDisableStandardHelp = TRUE ;
  694. SetHelpFixHook() ;
  695. COleLinksDialog dlg(this, GetRoutingView_());
  696. dlg.m_el.dwFlags |= ELF_DISABLECANCELLINK;
  697. dlg.DoModal();
  698. RemoveHelpFixHook() ;
  699. g_fDisableStandardHelp = FALSE ;
  700. }