123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851 |
- #ifndef __Persist_h__
- #define __Persist_h__
- #pragma once
- /////////////////////////////////////////////////////////////////////////////
- // Description: Implementation of *IPersistStreamInit::Load*.
- //
- // Initializes an object from the stream where it was previously saved.
- //
- // Note: The *ATL::IPersistStreamInitImpl* class uses this method for its
- // implementation of *IPersistStreamInit::Load*.
- //
- // Parameters:
- // pStm - [in] *IStream* pointer to the stream from which the object should
- // be loaded.
- // pMap - [in] Pointer to the first element of an array of
- // *ATL_PROPMAP_ENTRY* structures, as defined by the ATL property map macros.
- //
- // Return Value:
- //
- // S_OK - The object was successfully loaded.
- // E_OUTOFMEMORY - The object was not loaded due to a lack of memory.
- // E_FAIL - The object was not loaded due to some reason other than a lack
- // of memory.
- //
- // See Also: TCComPropertyClass, *ATL::IPersistStreamInitImpl* „
- HRESULT TCComPropertyClassRoot::TCPersistStreamInit_Load(LPSTREAM pStm,
- ATL_PROPMAP_ENTRY* pMap)
- {
- // Enter the Loading mode for this scope
- CLoadSaveScope loading(this);
- // Ensure that we get a pointer to the outer-most inheritance branch
- T* pT = static_cast<T*>(this);
- IUnknown* pUnk = pT->GetUnknown();
- assert(pMap != NULL);
- HRESULT hr = S_OK;
- DWORD dwVer;
- hr = pStm->Read(&dwVer, sizeof(DWORD), NULL);
- if (dwVer > _ATL_VER)
- return E_FAIL;
- if (FAILED(hr))
- return hr;
- CComPtr<IDispatch> pDispatch;
- const IID* piidOld = NULL;
- for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
- {
- if (pMap[i].szDesc == NULL)
- continue;
- // check if raw data entry
- if (pMap[i].dwSizeData != 0)
- {
- void* pData = (void*) (pMap[i].dwOffsetData + (DWORD)pThis);
- hr = pStm->Read(pData, pMap[i].dwSizeData, NULL);
- if (FAILED(hr))
- return hr;
- continue;
- }
- CComVariant var;
- // Handle safe arrays seperately from general VARTYPE's
- if (S_FALSE == (hr = TCReadSafeArrayFromStream(pStm, var)))
- hr = var.ReadFromStream(pStm);
- if (FAILED(hr))
- break;
- if(pMap[i].piidDispatch != piidOld)
- {
- pDispatch.Release();
- if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistStreamInit_Load(): Failed to get a dispatch ");
- _TRACE_PART("pointer for property #%i, \"%ls\"\n", i, pMap[i].szDesc);
- _TRACE_END
- hr = E_FAIL;
- break;
- }
- piidOld = pMap[i].piidDispatch;
- }
- if (FAILED(CComDispatchDriver::PutProperty(pDispatch, pMap[i].dispid, &var)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistStreamInit_Load(): Invoke failed on DISPID ");
- _TRACE_PART("0x%x, \"%ls\"\n", pMap[i].dispid, pMap[i].szDesc);
- _TRACE_END
- hr = E_FAIL;
- break;
- }
- }
- return hr;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Description: Implementation of *IPersistStreamInit::Save*.
- //
- // Saves an object to the specified stream.
- //
- // Note: The *ATL::IPersistStreamInitImpl* class uses this method for its
- // implementation of *IPersistStreamInit::Save*.
- //
- // Parameters:
- // pStm - [in] *IStream* pointer to the stream into which the object should
- // be saved.
- // fClearDirty - [in] Indicates whether to clear the dirty flag after the
- // save is complete. If *TRUE*, the flag should be cleared. If *FALSE*, the
- // flag should be left unchanged.
- // pMap - [in] Pointer to the first element of an array of
- // *ATL_PROPMAP_ENTRY* structures, as defined by the ATL property map macros.
- //
- // Return Value:
- //
- // S_OK - The object was successfully saved to the stream.
- // STG_E_CANTSAVE - The object could not save itself to the stream. This
- // error could indicate, for example, that the object contains another object
- // that is not serializable to a stream or that an
- // *ISequentialStream::Write* call returned *STG_E_CANTSAVE*.
- // STG_E_MEDIUMFULL - The object could not be saved because there is no
- // space left on the storage device.
- //
- // See Also: TCComPropertyClass, *ATL::IPersistStreamInitImpl* „
- HRESULT TCComPropertyClassRoot::TCPersistStreamInit_Save(LPSTREAM pStm,
- BOOL fClearDirty, ATL_PROPMAP_ENTRY* pMap)
- {
- // Enter the Saving mode for this scope
- CLoadSaveScope saving(this, false);
- // Ensure that we get a pointer to the outer-most inheritance branch
- T* pT = static_cast<T*>(this);
- IUnknown* pUnk = pT->GetUnknown();
- assert(pMap != NULL);
- DWORD dw = _ATL_VER;
- HRESULT hr = pStm->Write(&dw, sizeof(DWORD), NULL);
- if (FAILED(hr))
- return hr;
- CComPtr<IDispatch> pDispatch;
- const IID* piidOld = NULL;
- for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
- {
- if (pMap[i].szDesc == NULL)
- continue;
- // check if raw data entry
- if (pMap[i].dwSizeData != 0)
- {
- void* pData = (void*) (pMap[i].dwOffsetData + (DWORD)pThis);
- hr = pStm->Write(pData, pMap[i].dwSizeData, NULL);
- if (FAILED(hr))
- return hr;
- continue;
- }
- CComVariant var;
- if(pMap[i].piidDispatch != piidOld)
- {
- pDispatch.Release();
- if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistStreamInit_Save(): Failed to get a dispatch ");
- _TRACE_PART("pointer for property #%i, \"%ls\"\n", i, pMap[i].szDesc);
- _TRACE_END
- hr = E_FAIL;
- break;
- }
- piidOld = pMap[i].piidDispatch;
- }
- if (FAILED(CComDispatchDriver::GetProperty(pDispatch, pMap[i].dispid, &var)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistStreamInit_Save(): Invoke failed on DISPID ");
- _TRACE_PART("0x%x, \"%ls\"\n", pMap[i].dispid, pMap[i].szDesc);
- _TRACE_END
- hr = E_FAIL;
- break;
- }
- // Handle safe arrays seperately from general VARTYPE's
- if (S_FALSE == (hr = TCWriteSafeArrayToStream(pStm, var)))
- hr = var.WriteToStream(pStm);
- if (FAILED(hr))
- break;
- }
- if (SUCCEEDED(hr) && fClearDirty)
- SetDirty(FALSE);
- return hr;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Description: Implementation of *IPersistPropertyBag::Load*.
- //
- // This method instructs the object to initialize itself using the properties
- // available in the property bag, notifying the provided error log object
- // when errors occur. All property storage must take place within this method
- // call as the object cannot hold the IPropertyBag pointer.
- //
- // *E_NOTIMPL* is not a valid return code as any object implementing this
- // interface must support the entire functionality of the interface.
- //
- // Note: The *ATL::IPersistPropertyBagImpl* class uses this method for its
- // implementation of *IPersistPropertyBag::Load*.
- //
- // Parameters:
- // pPropBag - [in] Pointer to the caller's *IPropertyBag* interface bag
- // that the object uses to read its properties. Cannot be *NULL*.
- // pErrorLog - [in] Pointer to the caller's *IErrorLog* interface in which
- // the object stores any errors that occur during initialization. Can be
- // *NULL* in which case the caller is not interested in errors.
- // pMap - [in] Pointer to the first element of an array of
- // *ATL_PROPMAP_ENTRY* structures, as defined by the ATL property map macros.
- //
- // Return Value:
- //
- // S_OK - The object successfully initialized itself.
- // E_UNEXPECTED - This method was called after
- // *IPersistPropertyBag::InitNew* has already been called. The two
- // initialization methods are mutually exclusive.
- // E_OUTOFMEMORY - The properties were not loaded due to a lack of memory.
- // E_POINTER - The address in /pPropBag/ is not valid (such as *NULL*) and
- // therefore the object cannot initialize itself.
- // E_FAIL - The object was unable to retrieve a critical property that is
- // necessary for the object's successful operation. The object was therefore
- // unable to initialize itself completely.
- //
- // See Also: TCComPropertyClass, *ATL::IPersistPropertyBagImpl* „
- HRESULT TCComPropertyClassRoot::TCPersistPropertyBag_Load(
- LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog, ATL_PROPMAP_ENTRY* pMap)
- {
- // Enter the Loading mode for this scope
- CLoadSaveScope loading(this);
- // Ensure that we get a pointer to the outer-most inheritance branch
- T* pT = static_cast<T*>(this);
- IUnknown* pUnk = pT->GetUnknown();
- USES_CONVERSION;
- CComPtr<IDispatch> pDispatch;
- const IID* piidOld = NULL;
- for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
- {
- if (pMap[i].szDesc == NULL)
- continue;
- CComVariant var;
- // If raw entry, handle specially
- if (pMap[i].dwSizeData != 0)
- {
- void* pData = (void*) (pMap[i].dwOffsetData + (DWORD)pThis);
- HRESULT hr = pPropBag->Read(pMap[i].szDesc, &var, pErrorLog);
- if (SUCCEEDED(hr))
- {
- // check the type - we only deal with limited set
- switch (pMap[i].vt)
- {
- case VT_UI1:
- case VT_I1:
- *((BYTE*)pData) = var.bVal;
- break;
- case VT_BOOL:
- *((VARIANT_BOOL*)pData) = var.boolVal;
- break;
- case VT_I2: // Added by TC
- case VT_UI2:
- *((short*)pData) = var.iVal;
- break;
- case VT_I4: // Added by TC
- case VT_UI4:
- case VT_INT:
- case VT_UINT:
- *((long*)pData) = var.lVal;
- break;
- /////////////////////////////////////////////////////////////////////
- // The following all added by TC //
- case VT_R4: //
- *((float*)pData) = var.fltVal; //
- break; //
- case VT_R8: //
- *((double*)pData) = var.dblVal; //
- break; //
- case VT_CY: //
- *((CY*)pData) = var.cyVal; //
- break; //
- case VT_DATE: //
- *((DATE*)pData) = var.date; //
- break; //
- case VT_ERROR: //
- *((SCODE*)pData) = var.scode; //
- break; //
- case VT_DECIMAL: //
- *((DECIMAL*)pData) = *var.pdecVal; //
- break; //
- /////////////////////////////////////////////////////////////////////
- // TODO: Implement the following VARIANT types //
- case VT_BSTR: // Tricky: different ways to store a BSTR //
- break; //
- case VT_UNKNOWN: // Tricky: different ways to store a IUnknown* //
- case VT_DISPATCH: // Tricky: different ways to store a IDispatch*//
- continue; //
- case VT_VARIANT: // Tricky: different ways to store a VARIANT //
- continue; //
- case VT_RECORD: // Tricky: how possible? //
- continue; //
- case VT_ARRAY: // Very tricky: Also, caution: OR flag //
- continue; //
- case VT_BYREF: // Shouldn't be TOO tricky. Caution: OR flag //
- continue; //
- /////////////////////////////////////////////////////////////////////
- }
- }
- continue;
- }
- if(pMap[i].piidDispatch != piidOld)
- {
- pDispatch.Release();
- if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Load(): Failed to get a dispatch ");
- _TRACE_PART("pointer for property #%i, \"%ls\"\n", i, pMap[i].szDesc);
- _TRACE_END
- return E_FAIL;
- }
- piidOld = pMap[i].piidDispatch;
- }
- if (FAILED(CComDispatchDriver::GetProperty(pDispatch, pMap[i].dispid, &var)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Load(): Invoke failed on DISPID ");
- _TRACE_PART("0x%x, \"%ls\"\n", pMap[i].dispid, pMap[i].szDesc);
- _TRACE_END
- return E_FAIL;
- }
- if (VT_DISPATCH == V_VT(&var))
- var.Clear();
- HRESULT hr = pPropBag->Read(pMap[i].szDesc, &var, pErrorLog);
- if (FAILED(hr))
- {
- if (hr == E_INVALIDARG)
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Load(): ");
- _TRACE_PART("Property %ls not in Bag\n", pMap[i].szDesc);
- _TRACE_END
- }
- else
- {
- // Many containers return different ERROR values for Member not found
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Load(): Error attempting to read ");
- _TRACE_PART("Property %ls from PropertyBag\n", pMap[i].szDesc);
- _TRACE_END
- }
- continue;
- }
- if (FAILED(CComDispatchDriver::PutProperty(pDispatch, pMap[i].dispid, &var)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Load(): Invoke failed on DISPID ");
- _TRACE_PART("0x%x, \"%ls\"\n", pMap[i].dispid, pMap[i].szDesc);
- _TRACE_END
- return E_FAIL;
- }
- }
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Description: Implementation of *IPersistPropertyBag::Save*.
- //
- // This method instructs the object to save its properties to the specified
- // property bag, optionally clearing the object's dirty flag. The caller can
- // request that the object save all properties or that the object save only
- // those that are known to have changed.
- //
- // *E_NOTIMPL* is not a valid return code as any object implementing this
- // interface must support the entire functionality of the interface.
- //
- // Note: The *ATL::IPersistPropertyBagImpl* class uses this method for its
- // implementation of *IPersistPropertyBag::Save*.
- //
- // Parameters:
- // pPropBag - [in] Pointer to the caller's *IPropertyBag* interface bag
- // that the object uses to write its properties. Cannot be *NULL*.
- // fClearDirty - [in] A flag indicating whether the object should clear its
- // dirty flag when saving is complete. *TRUE* means clear the flag, *FALSE* „
- // means leave the flag unaffected. *FALSE* is used when the caller wishes to
- // do a /Save/ /Copy/ /As/ type of operation.
- // fSaveAllProperties - [in] A flag indicating whether the object should
- // save all its properties (TRUE) or only those that have changed since the
- // last save or initialization (FALSE).
- // pMap - [in] Pointer to the first element of an array of
- // *ATL_PROPMAP_ENTRY* structures, as defined by the ATL property map macros.
- //
- // Return Value:
- //
- // S_OK - The object successfully saved the requested properties itself.
- // E_FAIL - There was a problem saving one of the properties. The object can
- // choose to fail only if a necessary property could not be saved, meaning
- // that the object can assume default property values if a given property is
- // not seen through *IPersistPropertyBag::Load* at some later time.
- // E_POINTER - The address in /pPropBag/ is not valid (such as *NULL*) and
- // therefore the object cannot save itself.
- // STG_E_MEDIUMFULL - The object was not saved because of a lack of space on
- // the disk.
- //
- // See Also: TCComPropertyClass, *ATL::IPersistPropertyBagImpl* „
- HRESULT TCComPropertyClassRoot::TCPersistPropertyBag_Save(
- LPPROPERTYBAG pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties,
- ATL_PROPMAP_ENTRY* pMap)
- {
- // Do nothing if saving only the dirty properties and there are none
- if (!fSaveAllProperties && !GetDirty())
- return S_OK;
- if (pPropBag == NULL)
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Save(): ");
- _TRACE_PART("PropBag pointer passed in was invalid\n");
- _TRACE_END
- return E_POINTER;
- }
- // Enter the Saving mode for this scope
- CLoadSaveScope saving(this, false);
- // Ensure that we get a pointer to the outer-most inheritance branch
- T* pT = static_cast<T*>(this);
- IUnknown* pUnk = pT->GetUnknown();
- CComPtr<IDispatch> pDispatch;
- const IID* piidOld = NULL;
- for(int i = 0; pMap[i].pclsidPropPage != NULL; i++)
- {
- if (pMap[i].szDesc == NULL)
- continue;
- CComVariant var;
- // If raw entry skip it - we don't handle it for property bags just yet
- if (pMap[i].dwSizeData != 0)
- {
- void* pData = (void*) (pMap[i].dwOffsetData + (DWORD)pThis);
- // check the type - we only deal with limited set
- bool bTypeOK = false;
- switch (pMap[i].vt)
- {
- case VT_UI1:
- case VT_I1:
- var.bVal = *((BYTE*)pData);
- bTypeOK = true;
- break;
- case VT_BOOL:
- var.boolVal = *((VARIANT_BOOL*)pData);
- bTypeOK = true;
- break;
- case VT_I2: // Added by TC
- case VT_UI2:
- var.iVal = *((short*)pData);
- bTypeOK = true;
- break;
- case VT_I4: // Added by TC
- case VT_UI4:
- case VT_INT:
- case VT_UINT:
- var.lVal = *((long*)pData);
- bTypeOK = true;
- break;
- /////////////////////////////////////////////////////////////////////
- // The following all added by TC //
- case VT_R4: //
- var.fltVal = *((float*)pData); //
- bTypeOK = true; //
- break; //
- case VT_R8: //
- var.dblVal = *((double*)pData); //
- bTypeOK = true; //
- break; //
- case VT_CY: //
- var.cyVal = *((CY*)pData); //
- bTypeOK = true; //
- break; //
- case VT_DATE: //
- var.date = *((DATE*)pData); //
- bTypeOK = true; //
- break; //
- case VT_ERROR: //
- var.scode = *((SCODE*)pData); //
- bTypeOK = true; //
- break; //
- case VT_DECIMAL: //
- var.pdecVal = ((DECIMAL*)pData); //
- bTypeOK = true; //
- break; //
- /////////////////////////////////////////////////////////////////////
- // TODO: Implement the following VARIANT types //
- case VT_BSTR: // Tricky: different ways to store a BSTR //
- break; //
- case VT_UNKNOWN: // Tricky: different ways to store a IUnknown* //
- case VT_DISPATCH: // Tricky: different ways to store a IDispatch*//
- continue; //
- case VT_VARIANT: // Tricky: different ways to store a VARIANT //
- continue; //
- case VT_RECORD: // Tricky: how possible? //
- continue; //
- case VT_ARRAY: // Very tricky: Also, caution: OR flag //
- continue; //
- case VT_BYREF: // Shouldn't be TOO tricky. Caution: OR flag //
- continue; //
- /////////////////////////////////////////////////////////////////////
- }
- if (bTypeOK)
- {
- var.vt = pMap[i].vt;
- HRESULT hr = pPropBag->Write(pMap[i].szDesc, &var);
- if (FAILED(hr))
- return hr;
- }
- continue;
- }
- if(pMap[i].piidDispatch != piidOld)
- {
- pDispatch.Release();
- if(FAILED(ControlQueryInterface(*pMap[i].piidDispatch, (void**)&pDispatch)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Save(): Failed to get a dispatch ");
- _TRACE_PART("pointer for property #%i, \"%ls\"\n", i, pMap[i].szDesc);
- _TRACE_END
- return E_FAIL;
- }
- piidOld = pMap[i].piidDispatch;
- }
- if (FAILED(CComDispatchDriver::GetProperty(pDispatch, pMap[i].dispid, &var)))
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Save(): Invoke failed on DISPID ");
- _TRACE_PART("0x%x, \"%ls\"\n", pMap[i].dispid, pMap[i].szDesc);
- _TRACE_END
- return E_FAIL;
- }
- if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH)
- {
- if (var.pUnkVal == NULL)
- {
- _TRACE_BEGIN
- _TRACE_PART("TCComPropertyClass<%hs>::", m_pszType);
- _TRACE_PART("IPersistPropertyBag_Save(): ");
- _TRACE_PART("Warning skipping empty IUnknown in Save\n");
- _TRACE_END
- continue;
- }
- }
- HRESULT hr = pPropBag->Write(pMap[i].szDesc, &var);
- if (FAILED(hr))
- return hr;
- }
- if (fClearDirty)
- SetDirty(FALSE);
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // TCPersistStreamInitImpl extends ATL's IPersistStreamInitImpl class to
- // provide an implementation of the *IPersistStreamInit::GetSizeMax* „
- // interface method.
- //
- // Parameters:
- // T - The class derived from TCPersistStreamInitImpl.
- //
- template <class T>
- class ATL_NO_VTABLE TCPersistStreamInitImpl :
- public IPersistStreamInit
- {
- // Group=Types
- public:
- // Declares a type definition to allow derived classes an easier way to
- // refer to the base class.
- typedef TCPersistStreamInitImpl<T> TCPersistStreamInitImplBase;
- // Group=IPersist Interface Methods
- public:
- STDMETHODIMP GetClassID(CLSID *pClassID);
- // Group=IPersistStream Interface Methods
- public:
- STDMETHODIMP IsDirty();
- STDMETHODIMP Load(IStream* pStm);
- STDMETHODIMP Save(IStream* pStm, BOOL fClearDirty);
- STDMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize);
- // Group=IPersistStreamInit Interface Methods
- public:
- STDMETHODIMP InitNew();
- // Group=Implementation
- public:
- HRESULT IPersistStreamInit_Load(IStream* pStm, ATL_PROPMAP_ENTRY* pMap);
- HRESULT IPersistStreamInit_Save(IStream* pStm, BOOL fClearDirty,
- ATL_PROPMAP_ENTRY* pMap);
- };
- /////////////////////////////////////////////////////////////////////////////
- // Group=IPersist Interface Methods
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl::GetClassID(CLSID *pClassID)
- {
- _TRACE0("TCPersistStreamInitImpl::GetClassID\n");
- *pClassID = T::GetObjectCLSID();
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Group=IPersistStream Interface Methods
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl::IsDirty()
- {
- _TRACE0("TCPersistStreamInitImpl::IsDirty\n");
- T* pT = static_cast<T*>(this);
- return (pT->m_bRequiresSave) ? S_OK : S_FALSE;
- }
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl::Load(IStream* pStm)
- {
- _TRACE0("TCPersistStreamInitImpl::Load\n");
- T* pT = static_cast<T*>(this);
- return pT->IPersistStreamInit_Load(pStm, T::GetPropertyMap());
- }
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl::Save(IStream* pStm, BOOL fClearDirty)
- {
- T* pT = static_cast<T*>(this);
- _TRACE0("TCPersistStreamInitImpl::Save\n");
- return pT->IPersistStreamInit_Save(pStm, fClearDirty, T::GetPropertyMap());
- }
- /////////////////////////////////////////////////////////////////////////////
- // Description: Returns the size, in bytes, of the stream needed to save the
- // object.
- //
- // This function implements the *IPersistStreamInit::GetSizeMax* interface
- // method by calling the TCGetPersistStreamSize global function.
- //
- // Parameters:
- // pCbSize - [out] Points to a 64-bit unsigned integer value indicating the
- // size in bytes of the stream needed to save this object.
- //
- // Return Value: *S_OK* indicates that the size was successfully returned.
- //
- // See Also: TCNullStream, CTCNullStream
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl<T>::GetSizeMax(ULARGE_INTEGER* pcbSize)
- {
- // Get the derived class pointer
- T* pThis = static_cast<T*>(this);
- // Determine the max size by writing to a null stream
- HRESULT hr = TCGetPersistStreamSize(pThis->GetUnknown(), pcbSize);
- // Display trace information under _DEBUG builds
- _TRACE_BEGIN
- _TRACE_PART("TCPersistStreamInitImpl<%hs>::GetSizeMax():", TCTypeName(T));
- if (SUCCEEDED(hr))
- _TRACE_PART("%s Counted 0x%08X (%d) bytes\n", szMsg, pcbSize->LowPart,
- pcbSize->LowPart);
- else
- _TRACE_PART("%s Failed, hr = 0x%08X\n", szMsg, hr);
- _TRACE_END
- // Return the last HRESULT
- return hr;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Group=IPersistStreamInit Interface Methods
- template <class T>
- STDMETHODIMP TCPersistStreamInitImpl::InitNew()
- {
- _TRACE0("TCPersistStreamInitImpl::InitNew\n");
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Group=Implementation
- template <class T>
- HRESULT TCPersistStreamInitImpl::IPersistStreamInit_Load(IStream* pStm,
- ATL_PROPMAP_ENTRY* pMap)
- {
- T* pT = static_cast<T*>(this);
- HRESULT hr = pT->TCPersistStreamInit_Load(pStm, pMap);
- if (SUCCEEDED(hr))
- pT->m_bRequiresSave = FALSE;
- return hr;
- }
- template <class T>
- HRESULT TCPersistStreamInitImpl::IPersistStreamInit_Save(IStream* pStm,
- BOOL fClearDirty, ATL_PROPMAP_ENTRY* pMap)
- {
- T* pT = static_cast<T*>(this);
- return pT->TCPersistStreamInit_Save(pStm, fClearDirty, pMap);
- }
- /////////////////////////////////////////////////////////////////////////////
- // TCPersistPropertyBagImpl
- //
- //
- // Parameters:
- // T - The class derived from TCPersistPropertyBagImpl
- //
- template <class T>
- class ATL_NO_VTABLE TCPersistPropertyBagImpl :
- public IPersistPropertyBag
- {
- // IPersist Interface Methods
- public:
- STDMETHODIMP GetClassID(CLSID *pClassID)
- // IPersistPropertyBag Interface Methods
- public:
- STDMETHODIMP InitNew();
- STDMETHODIMP Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog);
- STDMETHODIMP Save(IPropertyBag* pPropBag, BOOL fClearDirty,
- BOOL fSaveAllProperties);
- // Implementation
- public:
- HRESULT IPersistPropertyBag_Load(IPropertyBag* pPropBag,
- IErrorLog* pErrorLog, ATL_PROPMAP_ENTRY* pMap);
- HRESULT IPersistPropertyBag_Save(IPropertyBag* pPropBag, BOOL fClearDirty,
- BOOL fSaveAllProperties, ATL_PROPMAP_ENTRY* pMap);
- };
- /////////////////////////////////////////////////////////////////////////////
- // IPersist Interface Methods
- STDMETHODIMP TCPersistPropertyBagImpl::GetClassID(CLSID *pClassID)
- {
- _TRACE0("IPersistPropertyBagImpl::GetClassID\n");
- *pClassID = T::GetObjectCLSID();
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IPersistPropertyBag Interface Methods
- STDMETHODIMP TCPersistPropertyBagImpl::InitNew()
- {
- _TRACE0("IPersistPropertyBagImpl::InitNew\n");
- return S_OK;
- }
- STDMETHODIMP TCPersistPropertyBagImpl::Load(IPropertyBag* pPropBag,
- IErrorLog* pErrorLog)
- {
- _TRACE0("IPersistPropertyBagImpl::Load\n");
- T* pT = static_cast<T*>(this);
- ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
- ATLASSERT(pMap != NULL);
- return pT->IPersistPropertyBag_Load(pPropBag, pErrorLog, pMap);
- }
- STDMETHODIMP TCPersistPropertyBagImpl::Save(IPropertyBag* pPropBag,
- BOOL fClearDirty, BOOL fSaveAllProperties)
- {
- _TRACE0("IPersistPropertyBagImpl::Save\n");
- T* pT = static_cast<T*>(this);
- ATL_PROPMAP_ENTRY* pMap = T::GetPropertyMap();
- ATLASSERT(pMap != NULL);
- return pT->IPersistPropertyBag_Save(pPropBag, fClearDirty,
- fSaveAllProperties, pMap);
- }
- /////////////////////////////////////////////////////////////////////////////
- // Implementation
- HRESULT TCPersistPropertyBagImpl::IPersistPropertyBag_Load(
- IPropertyBag* pPropBag, IErrorLog* pErrorLog, ATL_PROPMAP_ENTRY* pMap)
- {
- T* pT = static_cast<T*>(this);
- HRESULT hr = pT->TCPersistPropertyBag_Load(pPropBag, pErrorLog, pMap);
- if (SUCCEEDED(hr))
- pT->m_bRequiresSave = FALSE;
- return hr;
- }
- HRESULT TCPersistPropertyBagImpl::IPersistPropertyBag_Save(
- IPropertyBag* pPropBag, BOOL fClearDirty, BOOL fSaveAllProperties,
- ATL_PROPMAP_ENTRY* pMap)
- {
- T* pT = static_cast<T*>(this);
- return pT->TCPersistPropertyBag_Save(pPropBag, fClearDirty,
- fSaveAllProperties, pMap);
- }
- /////////////////////////////////////////////////////////////////////////////
- #endif // !__Persist_h__
|