Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Text Services Framework (TSF) olyan tulajdonságokat biztosít, amelyek metaadatokat társítanak egy szövegtartományhoz. Ezek a tulajdonságok többek között olyan attribútumokat tartalmaznak, mint a félkövér szöveg, a szöveg nyelvi azonosítója, valamint a szövegszolgáltatás által biztosított nyers adatok, például a beszédszöveg-szolgáltatás szövegéhez társított hangadatok.
Az alábbi példa bemutatja, hogyan tekinthető meg egy hipotetikus szövegszín tulajdonság, amelynek lehetséges értéke piros (R), zöld (G) vagy kék (B).
COLOR: RR GGGGGGGG
TEXT: this is some colored text
A különböző típusú tulajdonságok átfedésben lehetnek. Vegyük például az előző példát, és adjunk hozzá egy szöveges attribútumot, amely félkövér (B) vagy dőlt (I) lehet.
ATTRIB:BBBBBBB IIIIIIIIIIII
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Az "ez" szöveg félkövér, az "is" félkövér és piros, a "néhány" normál módon jelenik meg, a "színes" zöld és dőlt, a "szöveg" pedig dőlt.
Az azonos típusú tulajdonságok nem fedhetők át. A következő helyzet például nem engedélyezett, mert az "is" és a "színes" azonos típusú átfedésben van.
COLOR: GGG GGGG RRR BBBBGGG
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Tulajdonságtípusok
A TSF három különböző tulajdonságtípust határoz meg.
| Tulajdonságtípus | Leírás |
|---|---|
| Statikus | Egy statikus tulajdonságobjektum szöveggel tárolja a tulajdonságadatokat. Emellett a tulajdonság által érintett tartományok szöveginformációinak tartományát is tárolja. ITfReadOnlyProperty::A GetType a GUID_TFCAT_PROPSTYLE_STATIC kategóriát adja vissza. |
| Static-Compact | A statikus-kompakt tulajdonságobjektumok megegyeznek egy statikus tulajdonságobjektummal, kivéve, ha egy statikus-kompakt tulajdonság nem tárol tartományadatokat. Ha a statikus-kompakt tulajdonság által lefedett tartományt kéri, a rendszer létrehoz egy tartományt a szomszédos tulajdonságok minden csoportjához. A statikus-kompakt tulajdonságok a tulajdonságok karakterenkénti tárolásának leghatékonyabb módja. ITfReadOnlyProperty::A GetType a GUID_TFCAT_PROPSTYLE_STATICCOMPACT kategóriát adja vissza. |
| Szokás | Az egyéni tulajdonságobjektumok az egyes tartományok tartományadatait tárolják, amelyekre a tulajdonság vonatkozik. A tulajdonság tényleges adatait azonban nem tárolja. Ehelyett egy egyéni tulajdonság egy ITfPropertyStore objektumot tárol. A TSF-kezelő ezt az objektumot használja a tulajdonságadatok eléréséhez és karbantartásához. ITfReadOnlyProperty::GetType a GUID_TFCAT_PROPSTYLE_CUSTOM kategóriát adja vissza. |
Tulajdonságok használata
A tulajdonságértékek és attribútumok az ITfReadOnlyProperty interfész használatával szerezhetők be, és az ITfProperty interfész használatával módosulnak.
Ha egy adott tulajdonságtípusra van szükség, akkor ITfContext::GetProperty lesz használva. ITfContext::GetProperty egy GUID- igényel, amely azonosítja a beolvasandó tulajdonságot. A TSF előre definiált tulajdonságazonosítók készletét határozza meg, vagy egy szövegszolgáltatás definiálhatja saját tulajdonságazonosítóit. Egyéni tulajdonság használata esetén a tulajdonságszolgáltatónak közzé kell tennie a tulajdonságot GUID és a kapott adatok formátumát.
Ha például be szeretné szerezni a CLSID- egy szövegtartomány tulajdonosának, hívja meg ITfContext::GetProperty a tulajdonságobjektum beszerzéséhez, hívja meg ITfProperty::FindRange a teljes tulajdonságot lefedő tartomány lekéréséhez, majd hívja meg ITfReadOnlyProperty::GetValue, hogy lekérjen egy TfGuidAtom, amely a szöveget birtokló szövegszolgáltatás CLSID- jelöli. Az alábbi példa egy olyan függvényt mutat be, amely egy kontextus, tartomány és egy szerkesztési cookie alapján a szöveget birtokló szövegszolgáltatás CLSID- fogja beszerezni.
HRESULT GetTextOwner( ITfContext *pContext,
ITfRange *pRange,
TfEditCookie ec,
CLSID *pclsidOwner)
{
HRESULT hr;
ITfProperty *pProp;
*pclsidOwner = GUID_NULL;
hr = pContext->GetProperty(GUID_PROP_TEXTOWNER, &pProp);
if(S_OK == hr)
{
ITfRange *pPropRange;
hr = pProp->FindRange(ec, pRange, &pPropRange, TF_ANCHOR_START);
if(S_OK == hr)
{
VARIANT var;
VariantInit(&var);
hr = pProp->GetValue(ec, pPropRange, &var);
if(S_OK == hr)
{
if(VT_I4 == var.vt)
{
/*
var.lVal is a TfGuidAtom that represents the CLSID of the
text owner. Use ITfCategoryMgr to obtain the CLSID from
the TfGuidAtom.
*/
ITfCategoryMgr *pCatMgr;
hr = CoCreateInstance( CLSID_TF_CategoryMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfCategoryMgr,
(LPVOID*)&pCatMgr);
if(SUCCEEDED(hr))
{
hr = pCatMgr->GetGUID((TfGuidAtom)var.lVal, pclsidOwner);
if(SUCCEEDED(hr))
{
/*
*pclsidOwner now contains the CLSID of the text
service that owns the text at the selection.
*/
}
pCatMgr->Release();
}
}
else
{
//Unrecognized VARIANT type
hr = E_FAIL;
}
VariantClear(&var);
}
pPropRange->Release();
}
pProp->Release();
}
return hr;
}
A tulajdonságok számba vehetők egy IEnumTfProperties felület ITfContext::EnumProperties.
Tulajdonságok állandó tárolása
A tulajdonságok gyakran transzparensek egy alkalmazás számára, és egy vagy több szöveges szolgáltatás használják. A tulajdonságadatok megőrzése érdekében , például egy fájlba való mentéskor az alkalmazásnak szerializálnia kell a tulajdonságadatokat a tároláskor, és az adatok visszaállításakor meg kell szüntetnie a tulajdonságadatok szerializálását. Ebben az esetben az alkalmazásnak nem kell érdekelnie az egyes tulajdonságokat, hanem számba kell vennie az összes tulajdonságot a környezetben, és tárolnia kell őket.
A tulajdonságadatok tárolásakor az alkalmazásnak végre kell hajtania a következő lépéseket.
- Szerezze be a tulajdonság-enumerátort ITfContext::EnumPropertiesmeghívásával.
- Az egyes tulajdonságok számbavétele IEnumTfProperties::Nextmeghívásával.
- Minden tulajdonsághoz szerezze be a tartomány-enumerátort ITfReadOnlyProperty::EnumRangesmeghívásával.
- A tulajdonság minden tartományának számbavétele IEnumTfRanges::Nextmeghívásával.
- A tulajdonság minden tartományához hívja meg az ITextStoreACPServices::Szerializálja a a tulajdonsággal, a tartománnyal, a TF_PERSISTENT_PROPERTY_HEADER_ACP struktúrával és az alkalmazás által implementált streamobjektummal.
- Írja be a TF_PERSISTENT_PROPERTY_HEADER_ACP szerkezet tartalmát az állandó memóriába.
- Írja be a streamobjektum tartalmát az állandó memóriába.
- Folytassa az összes tulajdonság összes tartományának előző lépéseit.
- Az alkalmazásnak valamilyen terminátort kell írnia a streambe, hogy az adatok visszaállításakor egy leállítási pont azonosítható legyen.
HRESULT SaveProperties( ITfContext *pContext,
ITextStoreACPServices *pServices,
TfEditCookie ec,
IStream *pStream)
{
HRESULT hr;
IEnumTfProperties *pEnumProps;
TF_PERSISTENT_PROPERTY_HEADER_ACP PropHeader;
ULONG uWritten;
//Enumerate the properties in the context.
hr = pContext->EnumProperties(&pEnumProps);
if(SUCCEEDED(hr))
{
ITfProperty *pProp;
ULONG uFetched;
while(SUCCEEDED(pEnumProps->Next(1, &pProp, &uFetched)) && uFetched)
{
//Enumerate all the ranges that contain the property.
IEnumTfRanges *pEnumRanges;
hr = pProp->EnumRanges(ec, &pEnumRanges, NULL);
if(SUCCEEDED(hr))
{
IStream *pTempStream;
//Create a temporary stream to write the property data to.
hr = CreateStreamOnHGlobal(NULL, TRUE, &pTempStream);
if(SUCCEEDED(hr))
{
ITfRange *pRange;
while(SUCCEEDED(pEnumRanges->Next(1, &pRange, &uFetched)) && uFetched)
{
LARGE_INTEGER li;
//Reset the temporary stream pointer.
li.QuadPart = 0;
pTempStream->Seek(li, STREAM_SEEK_SET, NULL);
//Get the property header and data for the range.
hr = pServices->Serialize(pProp, pRange, &PropHeader, pTempStream);
/*
Write the property header into the primary stream.
The header also contains the size of the property
data.
*/
hr = pStream->Write(&PropHeader, sizeof(PropHeader), &uWritten);
//Reset the temporary stream pointer.
li.QuadPart = 0;
pTempStream->Seek(li, STREAM_SEEK_SET, NULL);
//Copy the property data from the temporary stream into the primary stream.
ULARGE_INTEGER uli;
uli.QuadPart = PropHeader.cb;
hr = pTempStream->CopyTo(pStream, uli, NULL, NULL);
pRange->Release();
}
pTempStream->Release();
}
pEnumRanges->Release();
}
pProp->Release();
}
pEnumProps->Release();
}
//Write a property header with zero size and guid into the stream as a terminator
ZeroMemory(&PropHeader, sizeof(PropHeader));
hr = pStream->Write(&PropHeader, sizeof(PropHeader), &uWritten);
return hr;
}
ITextStoreACPServices::SzerializáljaITfPropertyStore::Szerializálja
A tulajdonságadatok visszaállításakor az alkalmazásnak végre kell hajtania a következő lépéseket.
Állítsa a streammutatót az első TF_PERSISTENT_PROPERTY_HEADER_ACP szerkezet elejére.
Olvassa el a TF_PERSISTENT_PROPERTY_HEADER_ACP struktúrát.
Hívja meg ITfContext::GetProperty a TF_PERSISTENT_PROPERTY_HEADER_ACP struktúra guidType tagjával.
Az alkalmazás ezen a ponton két dolog egyikét teheti meg.
- Hozzon létre egy ITfPersistentPropertyLoaderACP-példányt objektumot, amelyet az alkalmazásnak implementálnia kell. Ezután hívja meg ITextStoreACPServices::Unserialize a pStreamNULL és az ITfPersistentPropertyLoaderACP mutatóval.
- Adja át a bemeneti adatfolyamot ITextStoreACPServices:: és NULLpLoader.
Az első módszer előnyben részesített, mivel ez a leghatékonyabb. A második metódus implementálásával az összes tulajdonságadat beolvasható a streamből az ITextStoreACPServices::Unserialize hívás során. Az első módszer hatására a tulajdonságadatok később igény szerint beolvashatók.
Ismételje meg az előző lépéseket, amíg az összes tulajdonságblokk nem lesz rendezve.
HRESULT LoadProperties( ITfContext *pContext,
ITextStoreACPServices *pServices,
IStream *pStream)
{
HRESULT hr;
ULONG uRead;
TF_PERSISTENT_PROPERTY_HEADER_ACP PropHeader;
/*
Read each property header and property data from the stream. The
list of properties is terminated by a TF_PERSISTENT_PROPERTY_HEADER_ACP
structure with a cb member of zero.
*/
hr = pStream->Read(&PropHeader, sizeof(PropHeader), &uRead);
while( SUCCEEDED(hr) &&
(sizeof(PropHeader) == uRead) &&
(0 != PropHeader.cb))
{
ITfProperty *pProp;
hr = pContext->GetProperty(PropHeader.guidType, &pProp);
if(SUCCEEDED(hr))
{
/*
Have TSF read the property data from the stream. This call
requests a read-only lock, so be sure it can be granted
or else this method will fail.
*/
CTSFPersistentPropertyLoader *pLoader = new CTSFPersistentPropertyLoader(&PropHeader, pStream);
hr = pServices->Unserialize(pProp, &PropHeader, NULL, pLoader);
pProp->Release();
}
//Read the next header.
hr = pStream->Read(&PropHeader, sizeof(PropHeader), &uRead);
}
return hr;
}