Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Text Services Framework (TSF), meta verileri bir metin aralığıyla ilişkilendiren özellikler sağlar. Bu özellikler kalın metin, metnin dil tanımlayıcısı gibi görüntüleme özniteliklerini ve konuşma metin hizmetindeki metinle ilişkilendirilmiş ses verileri gibi bir metin hizmeti tarafından sağlanan ham verileri içerir ancak bunlarla sınırlı değildir.
Aşağıdaki örnek, olası kırmızı (R), yeşil (G) veya mavi (B) değerlerine sahip varsayımsal bir metin rengi özelliğinin nasıl görüntülendiğini gösterir.
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Farklı türlerin özellikleri çakışabilir. Örneğin, önceki örneği alın ve kalın (B) veya italik (I) olabilecek bir metin özniteliği ekleyin.
ATTRIB:BBBBBBB IIIIIIIIIIII
COLOR: RR GGGGGGGG
TEXT: this is some colored text
"Bu" metni kalın, "is" hem kalın hem de kırmızı, "bazıları" normal olarak görüntülenir, "renkli" yeşil ve italik ve "metin" italik olur.
Aynı türdeki özellikler çakışamaz. Örneğin, "is" ve "renkli" değerleri aynı türdeki çakışan değerlere sahip olduğundan aşağıdaki duruma izin verilmez.
COLOR: GGG GGGG RRR BBBBGGG
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Özellik Türleri
TSF üç farklı özellik türünü tanımlar.
| Özellik türü | Açıklama |
|---|---|
| Duruk | Statik özellik nesnesi, özellik verilerini metinle birlikte depolar. Ayrıca özelliğin uygulandığı her aralık için metin bilgileri aralığını depolar. ITfReadOnlyProperty::GetType, GUID_TFCAT_PROPSTYLE_STATIC kategorisini döndürür. |
| Static-Compact | Statik-kompakt özellik nesnesi, statik-sıkıştırılmış bir özelliğin aralık verilerini depolamaması dışında statik özellik nesnesiyle aynıdır. Statik-kompakt özelliğin kapsadığı aralık istendiğinde, her bitişik özellik grubu için bir aralık oluşturulur. Statik kompakt özellikler, özellikleri karakter temelinde depolamanın en verimli yoludur. ITfReadOnlyProperty::GetType, GUID_TFCAT_PROPSTYLE_STATICCOMPACT kategorisini döndürür. |
| Töre | Özel özellik nesnesi, özelliğin uygulandığı her aralığın aralık bilgilerini depolar. Ancak, özelliği için gerçek verileri depolamaz. Bunun yerine, özel bir özellik bir ITfPropertyStore nesnesini depolar. TSF yöneticisi, özellik verilerine erişmek ve bunları korumak için bu nesneyi kullanır. ITfReadOnlyProperty::GetType, GUID_TFCAT_PROPSTYLE_CUSTOM kategorisini döndürür. |
Özelliklerle Çalışma
Özellik değeri ve öznitelikleri ITfReadOnlyProperty arabirimi kullanılarak alınır ve ITfProperty arabirimi kullanılarak değiştirilir.
Belirli bir özellik türü gerekiyorsa ITfContext::GetProperty kullanılır. ITfContext::GetProperty, elde edilen özelliği tanımlayan bir GUID gerektirir. TSF, kullanılan önceden tanımlanmış özellik tanımlayıcıları kümesini tanımlar veya bir metin hizmeti kendi özellik tanımlayıcılarını tanımlayabilir. Özel bir özellik kullanılırsa, özellik sağlayıcısının GUID ve alınan verilerin biçimini özelliğini yayımlaması gerekir.
Örneğin, bir metin aralığının sahibine CLSID almak için, özellik nesnesini almak için ITfContext::GetProperty çağrısı yapın, özelliği tamamen kapsayan aralığı elde etmek için ITfProperty::FindRange çağrısı yapın, ardından ITfReadOnlyProperty::GetValue'ni çağırarak metnin sahibi olan metin hizmetinin CLSID temsil eden bir TfGuidAtom alın. Aşağıdaki örnekte bağlam, aralık ve düzenleme tanımlama bilgisi verilip metnin sahibi olan metin hizmetinin CLSID edinecek bir işlev gösterilmektedir.
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;
}
Özellikler, ITfContext::EnumProperties'den IEnumTfProperties arabirimi elde edilerek de numaralandırılabilir.
Özelliklerin Kalıcı Depolaması
Genellikle, özellikler bir uygulama için saydamdır ve bir veya daha fazla metin hizmeti tarafından kullanılır. Bir dosyaya kaydederken olduğu gibi özellik verilerini korumak için, bir uygulamanın depolandığında özellik verilerini seri hale getirmesi ve veriler geri yüklendiğinde özellik verilerini seri durumdan çıkarması gerekir. Bu durumda, uygulama tek tek özelliklerle ilgilenmemeli, ancak bağlamdaki tüm özellikleri numaralandırıp depolamalıdır.
Özellik verilerini depolarken, bir uygulama aşağıdaki adımları gerçekleştirmelidir.
- ITfContext::EnumPropertiesçağırarak bir özellik numaralandırıcısı alın.
- IEnumTfProperties::Next çağırarak her özelliği numaralandır.
- Her özellik için, ITfReadOnlyProperty::EnumRangesçağırarak bir aralık numaralandırıcısı alın.
- IEnumTfRanges::Nextçağırarak özelliğindeki her aralığı numaralandırın.
- Özelliğindeki her aralık için ITextStoreACPServices:: özelliği, aralığı, TF_PERSISTENT_PROPERTY_HEADER_ACP yapısı ve uygulama tarafından uygulanan bir akış nesnesiyle seri hale getirin.
- TF_PERSISTENT_PROPERTY_HEADER_ACP yapısının içeriğini kalıcı belleğe yazın.
- Akış nesnesinin içeriğini kalıcı belleğe yazın.
- Tüm özelliklerdeki tüm aralıklar için önceki adımlara devam edin.
- Uygulamanın akışa bir tür sonlandırıcı yazması gerekir, böylece veriler geri yüklendiğinde bir durdurma noktası tanımlanabilir.
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::SerializeITfPropertyStore::Serialize
Özellik verilerini geri yüklerken, bir uygulama aşağıdaki adımları gerçekleştirmelidir.
Akış işaretçisini ilk TF_PERSISTENT_PROPERTY_HEADER_ACP yapısının başlangıcına ayarlayın.
TF_PERSISTENT_PROPERTY_HEADER_ACP yapısını okuyun.
TF_PERSISTENT_PROPERTY_HEADER_ACP yapısının guidType üyesiyle ITfContext::GetProperty çağırın.
Uygulama bu noktada iki işlemden birini yapabilir.
- Uygulamanın uygulaması gereken ITfPersistentPropertyLoaderACP nesnesinin bir örneğini oluşturun. Ardından pStream ve ITfPersistentPropertyLoaderACP işaretçisi için NULL ile ITextStoreACPServices::Unserialize çağrısı yapın.
- giriş akışını ITextStoreACPServices:: seri durumdan çıkarın ve pLoaderiçin NULL geçirin.
en verimli olduğu için ilk yöntem tercih edilir. İkinci yöntemin uygulanması, ITextStoreACPServices::Unserialize çağrısı sırasında tüm özellik verilerinin akıştan okunmasını sağlar. İlk yöntem, özellik verilerinin daha sonra isteğe bağlı olarak okunmasını neden olur.
Tüm özellik blokları seri durumdan çıkarılana kadar önceki adımları yineleyin.
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;
}