⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oledoc1.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		// abort changes to the current docfile
		RELEASE(m_lpRootStg);

		// create new temporary docfile
		LPSTORAGE lpStorage;
		SCODE sc = ::StgCreateDocfile(NULL, STGM_DELETEONRELEASE|
			STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_EXCLUSIVE|STGM_CREATE,
			0, &lpStorage);
		if (sc != S_OK)
			return FALSE;

		ASSERT(lpStorage != NULL);
		m_lpRootStg = lpStorage;
	}

	return TRUE;
}

BOOL COleDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
	USES_CONVERSION;

	ASSERT(lpszPathName == NULL || AfxIsValidString(lpszPathName));

	// just use default implementation if 'docfile' not enabled
	if (!m_bCompoundFile && m_lpRootStg == NULL)
	{
		ASSERT(lpszPathName != NULL);
		return CDocument::OnOpenDocument(lpszPathName);
	}

	if (IsModified())
		TRACE0("Warning: OnOpenDocument replaces an unsaved document.\n");

	// abort changes to current docfile
	if (lpszPathName != NULL)
	{
		DeleteContents();
		RELEASE(m_lpRootStg);
	}
	SetModifiedFlag();  // dirty during de-serialize

	BOOL bResult = FALSE;
	TRY
	{
		if (m_lpRootStg == NULL)
		{
			LPCOLESTR lpsz = T2COLE(lpszPathName);

			// use STGM_CONVERT if necessary
			SCODE sc;
			LPSTORAGE lpStorage = NULL;
			if (StgIsStorageFile(lpsz) == S_FALSE)
			{
				// convert existing storage file
				sc = StgCreateDocfile(lpsz, STGM_READWRITE|
					STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_CONVERT,
					0, &lpStorage);
				if (FAILED(sc) || lpStorage == NULL)
					sc = StgCreateDocfile(lpsz, STGM_READ|
						STGM_TRANSACTED|STGM_CONVERT, 0, &lpStorage);
			}
			else
			{
				// open new storage file
				sc = StgOpenStorage(lpsz, NULL,
					STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_DENY_WRITE,
					0, 0, &lpStorage);
				if (FAILED(sc) || lpStorage == NULL)
					sc = StgOpenStorage(lpsz, NULL,
						STGM_READ|STGM_TRANSACTED, 0, 0, &lpStorage);
			}
			if (FAILED(sc))
				AfxThrowOleException(sc);

			ASSERT(lpStorage != NULL);
			m_lpRootStg = lpStorage;
		}

		// use helper to read document from storage
		LoadFromStorage();

		SetModifiedFlag(FALSE); // start off with unmodified
		bResult = TRUE;
	}
	CATCH_ALL(e)
	{
		DeleteContents();   // removed failed contents
		RELEASE(m_lpRootStg);

		// if not file-based load, return exceptions to the caller
		if (lpszPathName == NULL)
		{
			THROW_LAST();
			ASSERT(FALSE);  // not reached
		}

		TRY
		{
			ReportSaveLoadException(lpszPathName, e,
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		}
		END_TRY
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	return bResult;
}

BOOL COleDocument::OnSaveDocument(LPCTSTR lpszPathName)
	// lpszPathName must be fully qualified
{
	USES_CONVERSION;

	ASSERT(lpszPathName == NULL || AfxIsValidString(lpszPathName));

	// use default implementation if 'docfile' not enabled
	if (!m_bCompoundFile && m_lpRootStg == NULL)
	{
		ASSERT(lpszPathName != NULL);
		return CDocument::OnSaveDocument(lpszPathName);
	}

	LPSTORAGE lpOrigStg = NULL;
	if (lpszPathName != NULL)
		m_bSameAsLoad = AfxComparePath(m_strPathName, lpszPathName);

	BOOL bResult = FALSE;
	TRY
	{
		// open new root storage if necessary
		if (lpszPathName != NULL && !m_bSameAsLoad)
		{
			// temporarily detach current storage
			lpOrigStg = m_lpRootStg;
			m_lpRootStg = NULL;

			LPSTORAGE lpStorage;
			SCODE sc = ::StgCreateDocfile(T2COLE(lpszPathName),
				STGM_READWRITE|STGM_TRANSACTED|STGM_SHARE_DENY_WRITE|STGM_CREATE,
				0, &lpStorage);
			if (sc != S_OK)
				AfxThrowOleException(sc);

			ASSERT(lpStorage != NULL);
			m_lpRootStg = lpStorage;
		}
		ASSERT(m_lpRootStg != NULL);

		// use helper to save to root storage
		SaveToStorage();

		if (lpszPathName != NULL)
		{
			// commit each of the items
			CommitItems(m_bRemember && !m_bSameAsLoad);

			// mark document as clean if remembering the storage
			if (m_bRemember)
				SetModifiedFlag(FALSE);

			// remember correct storage or release save copy as storage
			if (!m_bSameAsLoad)
			{
				if (m_bRemember)
				{
					// Save As case -- m_stgRoot is new storage, forget old storage
					lpOrigStg->Release();
				}
				else
				{
					// Save Copy As case -- m_stgRoot should hook up to m_stgOrig.
					m_lpRootStg->Release();
					m_lpRootStg = lpOrigStg;
				}
			}
		}

		bResult = TRUE;
	}
	CATCH_ALL(e)
	{
		if (lpOrigStg != NULL)
		{
			// save as failed: abort new storage, and re-attach original
			RELEASE(m_lpRootStg);
			m_lpRootStg = lpOrigStg;
		}

		if (lpszPathName == NULL)
		{
			THROW_LAST();
			ASSERT(FALSE);  // not reached
		}

		TRY
		{
			ReportSaveLoadException(lpszPathName, e,
				TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
		}
		END_TRY
		DELETE_EXCEPTION(e);
	}
	END_CATCH_ALL

	// cleanup
	m_bSameAsLoad = TRUE;
	m_bRemember = TRUE;

	return bResult;
}

void COleDocument::OnCloseDocument()
{
	// close the document without deleting the memory
	BOOL bAutoDelete = m_bAutoDelete;
	m_bAutoDelete = FALSE;
	CDocument::OnCloseDocument();

	// release storage since document has been closed
	RELEASE(m_lpRootStg);

	// delete the document if necessary
	if (bAutoDelete)
		delete this;
}

/////////////////////////////////////////////////////////////////////////////
// Helpers for saving to IStorage based files
//  (these are used in the 'docfile' implementation as well as for servers)

void COleDocument::SaveToStorage(CObject* pObject)
{
	ASSERT(m_lpRootStg != NULL);

	// create Contents stream
	COleStreamFile file;
	CFileException fe;
	if (!file.CreateStream(m_lpRootStg, _T("Contents"),
			CFile::modeReadWrite|CFile::shareExclusive|CFile::modeCreate, &fe))
	{
		if (fe.m_cause == CFileException::fileNotFound)
			AfxThrowArchiveException(CArchiveException::badSchema);
		else
			AfxThrowFileException(fe.m_cause, fe.m_lOsError);
	}

	// save to Contents stream
	CArchive saveArchive(&file, CArchive::store | CArchive::bNoFlushOnDelete);
	saveArchive.m_pDocument = this;
	saveArchive.m_bForceFlat = FALSE;

	TRY
	{
		// save the contents
		if (pObject != NULL)
			pObject->Serialize(saveArchive);
		else
			Serialize(saveArchive);
		saveArchive.Close();
		file.Close();

		// commit the root storage
		SCODE sc = m_lpRootStg->Commit(STGC_ONLYIFCURRENT);
		if (sc != S_OK)
			AfxThrowOleException(sc);
	}
	CATCH_ALL(e)
	{
		file.Abort();   // will not throw an exception
		CommitItems(FALSE); // abort save in progress
		NO_CPP_EXCEPTION(saveArchive.Abort());
		THROW_LAST();
	}
	END_CATCH_ALL
}

void COleDocument::LoadFromStorage()
{
	ASSERT(m_lpRootStg != NULL);

	// open Contents stream
	COleStreamFile file;
	CFileException fe;
	if (!file.OpenStream(m_lpRootStg, _T("Contents"),
			CFile::modeRead|CFile::shareExclusive, &fe) &&
		!file.CreateStream(m_lpRootStg, _T("Contents"),
			CFile::modeRead|CFile::shareExclusive|CFile::modeCreate, &fe))
	{
		if (fe.m_cause == CFileException::fileNotFound)
			AfxThrowArchiveException(CArchiveException::badSchema);
		else
			AfxThrowFileException(fe.m_cause, fe.m_lOsError);
	}

	// load it with CArchive (loads from Contents stream)
	CArchive loadArchive(&file, CArchive::load | CArchive::bNoFlushOnDelete);
	loadArchive.m_pDocument = this;
	loadArchive.m_bForceFlat = FALSE;

	TRY
	{
		if (file.GetLength() != 0)
			Serialize(loadArchive);     // load main contents
		loadArchive.Close();
		file.Close();
	}
	CATCH_ALL(e)
	{
		file.Abort();   // will not throw an exception
		DeleteContents();   // removed failed contents
		NO_CPP_EXCEPTION(loadArchive.Abort());
		THROW_LAST();
	}
	END_CATCH_ALL
}

/////////////////////////////////////////////////////////////////////////////
// COleDocument diagnostics

#ifdef _DEBUG
void COleDocument::AssertValid() const
{
	CDocument::AssertValid();

	ASSERT(m_ptd == NULL || AfxIsValidAddress(m_ptd, (size_t)m_ptd->tdSize, FALSE));
	ASSERT_VALID(&m_docItemList);
	ASSERT(!m_bEmbedded || m_strPathName.IsEmpty());
}

void COleDocument::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);

	dc << "with " << m_docItemList.GetCount() << " doc items";
	dc << "\nm_dwNextItemNumber = " << m_dwNextItemNumber;
	dc << "\nm_bLastVisible = " << m_bLastVisible;
	dc << "\nm_bEmbedded = " << m_bEmbedded;
	dc << "\nm_lpRootStg = " << m_lpRootStg;
	dc << "\nm_bSameAsLoad = " << m_bSameAsLoad;
	dc << "\nm_bRemember = " << m_bRemember;
	dc << "\nm_ptd = " << m_ptd;

	dc << "\n";
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDocItem

CDocItem::CDocItem()
{
	m_pDocument = NULL;
}

CDocItem::~CDocItem()
{
	ASSERT(m_pDocument == NULL);    // must be detached from document
}

void CDocItem::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ASSERT_VALID(m_pDocument);
		// nothing to do, there is no data
	}
	else
	{
		// if no document connected yet, attach it from the archive
		if (m_pDocument == NULL)
		{
			COleDocument* pContainerDoc = (COleDocument*)ar.m_pDocument;
			ASSERT_VALID(pContainerDoc);
			ASSERT_KINDOF(COleDocument, pContainerDoc);
			pContainerDoc->AddItem(this);
			ASSERT(pContainerDoc == m_pDocument);
		}
	}
	// perform ASSERT_VALID at the end because COleServerItem::AssertValid
	// checks the validity of the m_pDocument pointer
	ASSERT_VALID(this);
}

BOOL CDocItem::IsBlank() const
{
	// by default, a CDocItem is not blank. COleClientItem is sometimes blank!
	//  (a COleServerItem is blank by default)
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CDocItem diagnostics

#ifdef _DEBUG
void CDocItem::AssertValid() const
{
	CObject::AssertValid();
	if (m_pDocument != NULL)
		m_pDocument->AssertValid();
}

void CDocItem::Dump(CDumpContext& dc) const
{
	CCmdTarget::Dump(dc);

	dc << "m_pDocument = " << (void*)m_pDocument;
	dc << "\n";
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// Inline function declarations expanded out-of-line

#ifndef _AFX_ENABLE_INLINES

// expand inlines for OLE general APIs
static char _szAfxOleInl[] = "afxole.inl";
#undef THIS_FILE
#define THIS_FILE _szAfxOleInl
#define _AFXOLE_INLINE
#include "afxole.inl"

#endif //!_AFX_ENABLE_INLINES

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

IMPLEMENT_SERIAL(CDocItem, CCmdTarget, 0)
IMPLEMENT_DYNAMIC(COleDocument, CDocument)

// These IMPLEMENT_DYNAMICs here for .OBJ granularity reasons.
IMPLEMENT_DYNAMIC(COleClientItem, CDocItem)
IMPLEMENT_DYNAMIC(COleServerItem, CDocItem)

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -