/**************************************************************************
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright 1997 Microsoft Corporation. All Rights Reserved.
**************************************************************************/
/**************************************************************************
File: PerStor.cpp
Description: CPersistStorage implementation.
**************************************************************************/
/**************************************************************************
#include statements
**************************************************************************/
#include "PerStor.h"
/**************************************************************************
CPersistStorage::CPersistStorage()
**************************************************************************/
CPersistStorage::CPersistStorage(COleDocument *pOleDoc)
{
OutputDebugString(TEXT("CPersistStorage's constructor\n"));
m_pOleDoc = pOleDoc;
m_pStorage = NULL;
m_pColorStream = NULL;
m_fSameAsLoad = FALSE;
}
/**************************************************************************
CPersistStorage::~CPersistStorage()
**************************************************************************/
CPersistStorage::~CPersistStorage()
{
OutputDebugString(TEXT("CPersistStorage's destructor\n"));
}
/**************************************************************************
CPersistStorage::QueryInterface()
**************************************************************************/
STDMETHODIMP CPersistStorage::QueryInterface(REFIID riid, LPVOID *ppReturn)
{
OutputDebugString(TEXT("CPersistStorage::QueryInterface\n"));
return m_pOleDoc->QueryInterface(riid, ppReturn);
}
/**************************************************************************
CPersistStorage::AddRef()
**************************************************************************/
STDMETHODIMP_(ULONG) CPersistStorage::AddRef()
{
OutputDebugString(TEXT("CPersistStorage::AddRef\n"));
return m_pOleDoc->AddRef();
}
/**************************************************************************
CPersistStorage::Release()
**************************************************************************/
STDMETHODIMP_(ULONG) CPersistStorage::Release()
{
OutputDebugString(TEXT("CPersistStorage::Release\n"));
return m_pOleDoc->Release();
}
/**************************************************************************
CPersistStorage::InitNew()
**************************************************************************/
STDMETHODIMP CPersistStorage::InitNew(LPSTORAGE pStg)
{
OutputDebugString(TEXT("CPersistStorage::InitNew\n"));
// release any streams and storages that may be open
ReleaseStreamsAndStorage();
m_pStorage = pStg;
// AddRef the new Storage
if (m_pStorage)
m_pStorage->AddRef();
CreateStreams(m_pStorage);
return S_OK;
}
/**************************************************************************
CPersistStorage::GetClassID()
**************************************************************************/
STDMETHODIMP CPersistStorage::GetClassID(LPCLSID pClassID)
{
OutputDebugString(TEXT("CPersistStorage::GetClassID\n"));
*pClassID = CLSID_SimpleDocObject;
return S_OK;
}
/**************************************************************************
CPersistStorage::Save()
**************************************************************************/
STDMETHODIMP CPersistStorage::Save(LPSTORAGE pStg, BOOL fSameAsLoad)
{
OutputDebugString(TEXT("CPersistStorage::Save\n"));
m_pOleDoc->m_fNoScribbleMode = TRUE;
// save the data
LPSTREAM pTempColor;
if(!fSameAsLoad)
{
if(!pStg)
return E_FAIL;
CreateStreams(pStg, &pTempColor);
}
else
{
pStg = m_pStorage;
if(!pStg)
return E_FAIL;
pTempColor = m_pColorStream;
pTempColor->AddRef();
}
//write our class ID into the storage
CLSID clsid;
GetClassID(&clsid);
WriteClassStg(pStg, clsid);
ULARGE_INTEGER uli;
uli.LowPart = 0;
uli.HighPart = 0;
pTempColor->SetSize(uli);
LARGE_INTEGER li;
li.LowPart = 0;
li.HighPart = 0;
pTempColor->Seek(li, STREAM_SEEK_SET, NULL);
// write the color to the stream
pTempColor->Write(&m_pOleDoc->m_Color, sizeof(m_pOleDoc->m_Color), NULL);
pTempColor->Release();
m_fSameAsLoad = fSameAsLoad;
m_pOleDoc->m_fDirty = FALSE;
return S_OK;
}
/**************************************************************************
CPersistStorage::SaveCompleted()
**************************************************************************/
STDMETHODIMP CPersistStorage::SaveCompleted(LPSTORAGE pStgNew)
{
OutputDebugString(TEXT("CPersistStorage::SaveCompleted\n"));
if(pStgNew)
{
ReleaseStreamsAndStorage();
m_pStorage = pStgNew;
m_pStorage->AddRef();
OpenStreams(pStgNew);
}
if(pStgNew || m_fSameAsLoad)
{
if(m_pOleDoc->m_fNoScribbleMode)
{
if(m_pOleDoc->m_pOleAdviseHolder)
m_pOleDoc->m_pOleAdviseHolder->SendOnSave();
}
m_fSameAsLoad = FALSE;
}
m_pOleDoc->m_fNoScribbleMode = FALSE;
return S_OK;
}
/**************************************************************************
CPersistStorage::Load()
**************************************************************************/
STDMETHODIMP CPersistStorage::Load(LPSTORAGE pStg)
{
OutputDebugString(TEXT("CPersistStorage::Load\n"));
// remember the storage
if(m_pStorage)
{
m_pStorage->Release();
m_pStorage = NULL;
}
m_pStorage = pStg;
m_pStorage->AddRef();
//read our class ID from the storage
CLSID clsidStg;
ReadClassStg(m_pStorage, &clsidStg);
OpenStreams(m_pStorage);
// read the color
if(FAILED(m_pColorStream->Read(&m_pOleDoc->m_Color, sizeof(m_pOleDoc->m_Color), NULL)))
{
m_pOleDoc->m_Color = DEFAULT_COLOR;
}
m_pOleDoc->m_fDirty = FALSE;
return S_OK;
}
/**************************************************************************
CPersistStorage::IsDirty()
**************************************************************************/
STDMETHODIMP CPersistStorage::IsDirty()
{
OutputDebugString(TEXT("CPersistStorage::IsDirty\n"));
return (m_pOleDoc->m_fDirty ? S_OK : S_FALSE);
}
/**************************************************************************
CPersistStorage::HandsOffStorage()
**************************************************************************/
STDMETHODIMP CPersistStorage::HandsOffStorage()
{
OutputDebugString(TEXT("CPersistStorage::HandsOffStorage\n"));
ReleaseStreamsAndStorage();
return S_OK;
}
/**************************************************************************
CPersistStorage::CreateStreams()
**************************************************************************/
void CPersistStorage::CreateStreams(LPSTORAGE pStg)
{
if(m_pColorStream)
m_pColorStream->Release();
// create a stream to save the color
pStg->CreateStream( OLESTR("Color"),
STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0,
0,
&m_pColorStream);
}
/**************************************************************************
CPersistStorage::CreateStreams()
**************************************************************************/
void CPersistStorage::CreateStreams( LPSTORAGE pStg,
LPSTREAM* ppNewColorStream)
{
LPSTREAM pTempColorStream;
//save the member streams
pTempColorStream = m_pColorStream;
//initialize the streams
m_pColorStream = *ppNewColorStream = NULL;
//create the streams
CreateStreams(pStg);
//copy the new streams
*ppNewColorStream = m_pColorStream;
//restore the member streams
m_pColorStream = pTempColorStream;
}
/**************************************************************************
CPersistStorage::OpenStreams()
**************************************************************************/
void CPersistStorage::OpenStreams(LPSTORAGE pStg)
{
if(m_pColorStream)
m_pColorStream->Release();
// open the color stream
pStg->OpenStream( OLESTR("Color"),
0,
STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
0,
&m_pColorStream);
}
/**************************************************************************
CPersistStorage::ReleaseStreamsAndStorage()
**************************************************************************/
void CPersistStorage::ReleaseStreamsAndStorage()
{
if(m_pColorStream)
{
m_pColorStream->Release();
m_pColorStream = NULL;
}
if(m_pStorage)
{
m_pStorage->Release();
m_pStorage = NULL;
}
}