2025-11-28 00:35:46 +09:00

280 lines
7.3 KiB
C++

//
// pstore.cpp
//
// CCustomPropertyStore implementation, ITfPropertyStore example.
//
#include "globals.h"
#include "pstore.h"
#include "mark.h"
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CCustomPropertyStore::CCustomPropertyStore()
{
// assign some arbitrary state to this object, for demonstration purposes
_dwState = GetTickCount();
DllAddRef();
_cRef = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CCustomPropertyStore::~CCustomPropertyStore()
{
DllRelease();
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::QueryInterface(REFIID riid, void **ppvObj)
{
if (ppvObj == NULL)
return E_INVALIDARG;
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfPropertyStore))
{
*ppvObj = (ITfPropertyStore *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CCustomPropertyStore::AddRef()
{
return ++_cRef;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CCustomPropertyStore::Release()
{
LONG cr = --_cRef;
assert(_cRef >= 0);
if (_cRef == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// GetType
//
// Returns the GUID of the property this store is assigned to.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::GetType(GUID *pguidType)
{
*pguidType = c_guidCustomProperty;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetDataType
//
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::GetDataType(DWORD *pdwReserved)
{
// this method is reserved, pdwReserved must be set 0
*pdwReserved = 0;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetData
//
// Returns the data held by this store.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::GetData(VARIANT *pvarValue)
{
pvarValue->vt = VT_I4; // dword value for this store
pvarValue->lVal = _dwState;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// OnTextUpdated
//
// Called by TSF when the text covered by this store is modified.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::OnTextUpdated(DWORD dwFlags, ITfRange *pRangeNew, BOOL *pfAccept)
{
// we will throw away this store (give up) anytime the text is modified.
// If we did set pfAccept TRUE, the store would be maintained.
*pfAccept = FALSE;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Shrink
//
// Called when the text covered by this store is truncated.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::Shrink(ITfRange *pRangeNew, BOOL *pfFree)
{
// give up and free this store
*pfFree = TRUE;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Divide
//
// Called when text covered by the store is deleted, such that the store is
// split in two. We have the option of freeing the store, or keeping the
// store which moves to cover just pRangeThis (the leftmost text) in which
// case we must provide a new store for the rightmost text as well.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::Divide(ITfRange *pRangeThis, ITfRange *pRangeNew, ITfPropertyStore **ppPropertyStore)
{
// just give up
// a NULL ppPropertyStore tells TSF to release this store
*ppPropertyStore = NULL;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Clone
//
// Return a new store with a copy of this store's state.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::Clone(ITfPropertyStore **ppCloneOut)
{
CCustomPropertyStore *pClone;
*ppCloneOut = NULL;
if ((pClone = new CCustomPropertyStore) == NULL)
return E_OUTOFMEMORY;
pClone->_dwState = _dwState;
*ppCloneOut = pClone;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetPropertyRangeCreator
//
// Returns the owning text service. Used by TSF during Unserialization.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::GetPropertyRangeCreator(CLSID *pclsid)
{
*pclsid = c_clsidMarkTextService;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Serialize
//
// Copy this store's state to a binary stream. This stream will later be returned
// to this text service to recreate the store in a later session.
//----------------------------------------------------------------------------
STDAPI CCustomPropertyStore::Serialize(IStream *pStream, ULONG *pcb)
{
return pStream->Write(&_dwState, sizeof(_dwState), pcb);
}
//+---------------------------------------------------------------------------
//
// IsStoreSerializable
//
//----------------------------------------------------------------------------
STDAPI CMarkTextService::IsStoreSerializable(REFGUID guidProperty, ITfRange *pRange, ITfPropertyStore *pPropertyStore, BOOL *pfSerializable)
{
// we don't have any complicated logic, we'll let all our custom property values be serialized
*pfSerializable = IsEqualGUID(guidProperty, c_guidCustomProperty);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CreatePropertyStore
//
// Unserializes a custom property.
//----------------------------------------------------------------------------
STDAPI CMarkTextService::CreatePropertyStore(REFGUID guidProperty, ITfRange *pRange, ULONG cb, IStream *pStream, ITfPropertyStore **ppStore)
{
CCustomPropertyStore *pStore;
DWORD dwState;
*ppStore = NULL;
if (!IsEqualGUID(guidProperty, c_guidCustomProperty))
return E_INVALIDARG;
if (cb != sizeof(DWORD))
return E_INVALIDARG;
if ((pStore = new CCustomPropertyStore) == NULL)
return E_OUTOFMEMORY;
if (pStream->Read(&dwState, sizeof(DWORD), &cb) != S_OK || cb != sizeof(DWORD))
{
pStore->Release();
return E_FAIL;
}
pStore->_SetState(dwState);
*ppStore = pStore;
return S_OK;
}