diff --git a/TextView.cpp b/TextView.cpp index 83f97190..c2d58155 100644 --- a/TextView.cpp +++ b/TextView.cpp @@ -14,6 +14,7 @@ Copyright (C) 2000 Nick Gammon. #include "sendvw.h" #include "mainfrm.h" #include "doc.h" +#include <../src/afximpl.h> #include "dialogs\GoToLineDlg.h" #include "dialogs\LuaGsubDlg.h" @@ -21,7 +22,7 @@ Copyright (C) 2000 Nick Gammon. #pragma warning( disable : 4100) // unreferenced formal parameter #ifdef _DEBUG -//#define new DEBUG_NEW +#define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif @@ -225,62 +226,6 @@ void CTextView::OnEscape() } -void CTextView::SerializeRaw(CArchive& ar) - // Read/Write object as stand-alone file. -{ - ASSERT_VALID(this); - - if (ar.IsStoring()) - { - CString strContents; - GetEditCtrl().GetWindowText (strContents); - ar.Write(strContents, strContents.GetLength ()); - } - else - { - CFile* pFile = ar.GetFile(); - ASSERT(pFile->GetPosition() == 0); - DWORD nLen = pFile->GetLength(); - // ReadFromArchive takes the number of characters as argument - - // REPLACING: ReadFromArchive(ar, (UINT)nFileSize/sizeof(TCHAR)); - - // with this (we got garbage at times): - - LPVOID hText = LocalAlloc(LMEM_MOVEABLE, (nLen+1)*sizeof(TCHAR)); - if (hText == NULL) - AfxThrowMemoryException(); - - LPTSTR lpszText = (LPTSTR)LocalLock(hText); - ASSERT(lpszText != NULL); - if (ar.Read(lpszText, nLen*sizeof(TCHAR)) != nLen*sizeof(TCHAR)) - { - LocalUnlock(hText); - LocalFree(hText); - AfxThrowArchiveException(CArchiveException::endOfFile); - } - // Replace the editing edit buffer with the newly loaded data - lpszText[nLen] = '\0'; - - // set the text with SetWindowText, then free - BOOL bResult = ::SetWindowText(m_hWnd, lpszText); - LocalUnlock(hText); - LocalFree(hText); - - // make sure that SetWindowText was successful - if (!bResult || ::GetWindowTextLength(m_hWnd) < (int)nLen) - AfxThrowMemoryException(); - - // remove old shadow buffer - delete[] m_pShadowBuffer; - m_pShadowBuffer = NULL; - m_nShadowSize = 0; - - } - ASSERT_VALID(this); -} /* end of CTextView::SerializeRaw */ - - void CTextView::OnViewMaximize() { WINDOWPLACEMENT wp; @@ -1760,3 +1705,136 @@ void CTextView::OnUpdateCompleteFunction(CCmdUI* pCmdUI) { pCmdUI->Enable (); } + + +#define VERSION_6 MAKELONG(0, 6) + +// from Worstje + +void CTextView::Serialize(CArchive& ar) + // Read and write CTextView object to archive, with length prefix. +{ + ASSERT_VALID(this); + ASSERT(m_hWnd != NULL); + if (ar.IsStoring()) + { + UINT nLen = GetBufferLength(); + ar << (DWORD)nLen; + WriteToArchive(ar); + } + else + { + DWORD dwLen; + ar >> dwLen; + if (dwLen > GetEditCtrl().GetLimitText()) + // Larger than edit control limit. Call SetLimitText() to set your own max size. + // Refer to documentation for EM_LIMITTEXT for max sizes for your target OS. + AfxThrowArchiveException(CArchiveException::badIndex); + UINT nLen = (UINT)dwLen; + ReadFromArchive(ar, nLen); + } + ASSERT_VALID(this); +} + +void CTextView::ReadFromArchive(CArchive& ar, UINT nLen) + // Read certain amount of text from the file, assume at least nLen + // characters (not bytes) are in the file. +{ + ASSERT_VALID(this); + + LPVOID hText = LocalAlloc(LMEM_MOVEABLE, (nLen+1)*sizeof(TCHAR)); + + //LPVOID hText = LocalAlloc(LMEM_MOVEABLE, static_cast(::ATL::AtlMultiplyThrow(static_cast(nLen+1),static_cast(sizeof(TCHAR))))); + if (hText == NULL) + AfxThrowMemoryException(); + + LPTSTR lpszText = (LPTSTR)LocalLock(hText); + ASSERT(lpszText != NULL); + if (ar.Read(lpszText, nLen*sizeof(TCHAR)) != nLen*sizeof(TCHAR)) + { + LocalUnlock(hText); + LocalFree(hText); + AfxThrowArchiveException(CArchiveException::endOfFile); + } + // Replace the editing edit buffer with the newly loaded data + lpszText[nLen] = '\0'; + + +#ifndef _UNICODE + if (_AfxGetComCtlVersion() >= VERSION_6) + { + // set the text with SetWindowText, then free + BOOL bResult = ::SetWindowText(m_hWnd, lpszText); + LocalUnlock(hText); + LocalFree(hText); + + // make sure that SetWindowText was successful + if (!bResult || ::GetWindowTextLength(m_hWnd) < (int)nLen) + AfxThrowMemoryException(); + + // remove old shadow buffer + delete[] m_pShadowBuffer; + m_pShadowBuffer = NULL; + m_nShadowSize = 0; + + ASSERT_VALID(this); + return; + } +#endif + + LocalUnlock(hText); + HLOCAL hOldText = GetEditCtrl().GetHandle(); + ASSERT(hOldText != NULL); + LocalFree(hOldText); + GetEditCtrl().SetHandle((HLOCAL)hText); + Invalidate(); + ASSERT_VALID(this); +} + +void CTextView::WriteToArchive(CArchive& ar) + // Write just the text to an archive, no length prefix. +{ + ASSERT_VALID(this); + LPCTSTR lpszText = LockBuffer(); + ASSERT(lpszText != NULL); + UINT nLen = GetBufferLength(); + TRY + { + ar.Write(lpszText, nLen*sizeof(TCHAR)); + } + CATCH_ALL(e) + { + UnlockBuffer(); + THROW_LAST(); + } + END_CATCH_ALL + UnlockBuffer(); + ASSERT_VALID(this); +} + +void CTextView::SerializeRaw(CArchive& ar) + // Read/Write object as stand-alone file. +{ + ASSERT_VALID(this); + if (ar.IsStoring()) + { + WriteToArchive(ar); + } + else + { + CFile* pFile = ar.GetFile(); + ASSERT(pFile->GetPosition() == 0); + ULONGLONG nFileSize = pFile->GetLength(); + if (nFileSize/sizeof(TCHAR) > GetEditCtrl().GetLimitText()) + { + // Larger than edit control limit. Call SetLimitText() to set your own max size. + // Refer to documentation for EM_LIMITTEXT for max sizes for your target OS. + AfxMessageBox(AFX_IDP_FILE_TOO_LARGE); + AfxThrowUserException(); + } + // ReadFromArchive takes the number of characters as argument + ReadFromArchive(ar, (UINT)nFileSize/sizeof(TCHAR)); + } + ASSERT_VALID(this); +} + diff --git a/TextView.h b/TextView.h index bcfd50de..bccc8cd9 100644 --- a/TextView.h +++ b/TextView.h @@ -52,6 +52,11 @@ class CTextView : public CEditView CString & result, int & count); + + virtual void Serialize(CArchive& ar); + virtual void ReadFromArchive(CArchive& ar, UINT nLen); + virtual void WriteToArchive(CArchive& ar); + // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTextView) public: