/*============================================================================ * * File Name: PersistFile.cpp * * Class Tribble * * Description: Implementation of Tribbles IPersistfile * * Author: Roger Hughes * * Date: 16/10/98 * * *==============================================================================*/ #include "stdafx.h" #include "OleCharConv.h" #include "Tribble.h" //IPersistFile HRESULT Tribble::IsDirty(void) { OutputDebugString("Tribble IPersistFile::IsDirty()\n"); return S_FALSE; // alway say that we haven't changed } HRESULT Tribble::Load(LPCOLESTR pszFileName, DWORD dwMode) { OutputDebugString("Tribble IPersistFile::Load(...)\n"); HRESULT hr = S_OK; IStorage * pIStorage = NULL; // First off, open the storage file we've been given // Get hold of an IStorage Interface hr=StgOpenStorage(pszFileName,NULL, STGM_TRANSACTED | STGM_READ, NULL,0, &pIStorage); if(SUCCEEDED(hr)) { // Next we open the stream, // read the name an colour hr = ReadStream(pIStorage,OLESTR("Name"),m_Name); if(SUCCEEDED(hr)) hr = ReadStream(pIStorage,OLESTR("Colour"),m_Colour); // If everythings okay - create a moniker for // this file object and register as running // save the value head so that we can tell the // ROT when close down if(!m_pmkFile) { hr = CreateFileMoniker(pszFileName,&m_pmkFile); if (SUCCEEDED(hr)) { IRunningObjectTable *pROT; hr = GetRunningObjectTable(0, &pROT); if (SUCCEEDED(hr)) { //Register as weak so clients can free us pROT->Register(0,(IUnknown *)(ITribble*)this,m_pmkFile,&m_dwROTFile); pROT->Release(); } // At this point, use IROTView.exe to see this // object in the Running Object Table } } // Finnished with the Storage. pIStorage->Release(); } return hr; } HRESULT Tribble::Save(LPCOLESTR pszFileName, BOOL fRemember) { OutputDebugString("Tribble IPersistFile::Save(...)\n"); HRESULT hr = E_NOTIMPL; if(!fRemember) // Only support new files { IStorage *pIStorage; hr=StgCreateDocfile(pszFileName, STGM_DIRECT | STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &pIStorage); if (SUCCEEDED(hr)) { //Having created the storage we must put the data // some where so we create two streams - // one for name and the other for colour LPSTREAM lpStream = NULL; // Add the "Name" property COleCharConv nm("Name"); hr = pIStorage->CreateStream(nm, STGM_DIRECT | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,0,&lpStream); if(SUCCEEDED(hr)) { ULONG cbWritten; // Having got the stream write the tribbles name // in to it hr = lpStream->Write((void const*)(LPCSTR)m_Name, (ULONG)m_Name.GetLength(),&cbWritten); lpStream->Release(); lpStream = NULL; // Now add the colour property COleCharConv cl("Colour"); hr = pIStorage->CreateStream(cl, STGM_DIRECT | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0,0, &lpStream); if(SUCCEEDED(hr) && (lpStream != NULL)) { ULONG cbWritten; hr = lpStream->Write((void const*)(LPCSTR)m_Colour, (ULONG)m_Colour.GetLength(),&cbWritten); lpStream->Release(); lpStream = NULL; // Put our CLSID into the storage provided // by using the OLE helper API WriteClassStg(). hr = WriteClassStg(pIStorage,CLSID_Tribble); LPOLESTR lpszUserType = NULL; // Use the OLE helper API OleRegGetUserType() // get read our human-readable name from the registry. hr = OleRegGetUserType(CLSID_Tribble,USERCLASSTYPE_FULL,&lpszUserType ); if(SUCCEEDED(hr)) { // Use the OLE helper API WriteFmtUserTypeStg() // get write our human-readable name and // preferred clipboard format into the storage. hr = WriteFmtUserTypeStg(pIStorage,CF_TEXT,lpszUserType); CoTaskMemFree ( lpszUserType ); } } pIStorage->Release(); } } } return hr; } HRESULT Tribble::SaveCompleted(LPCOLESTR pszFileName) { OutputDebugString("Tribble IPersistFile::SaveCompleted\n"); return S_OK; // in ALL cases we return this } HRESULT Tribble::GetCurFile(LPOLESTR *ppszFileName) { OutputDebugString("Tribble IPersistFile::GetCurFile\n"); // return our default - *.tbr *ppszFileName = OLESTR("*.tbr"); return S_OK; } HRESULT Tribble::GetClassID(CLSID *pClassID) { OutputDebugString("Tribble PersistFile::GetClassID\n"); memcpy(pClassID, &CLSID_Tribble,sizeof(CLSID)); //*pClassID = m_ClsId; return S_OK; } //--------------------------------------------------------------------------- // Method: Tribble::ReadStream // Purpose: Helper, given a storage read from it.... //--------------------------------------------------------------------------- HRESULT Tribble::ReadStream(IStorage *pIStorage, OLECHAR *pStreamName, CString &strBuffer) { LPSTREAM lpStream = NULL; HRESULT hr = pIStorage->OpenStream(pStreamName, NULL, STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &lpStream); if(SUCCEEDED(hr)) { char Buffer[256]; // allocate a small buffer ULONG dwCount; hr = lpStream->Read((void *)Buffer,256,&dwCount); if(SUCCEEDED(hr)) { // NULL Terminate (don't bother to check the length) *(Buffer + dwCount) = '\0'; strBuffer = Buffer; } lpStream->Release(); } return hr; } /*============================================================================ * End of File: PersistFile.cpp ==============================================================================*/