Text Services Framework (TSF) menyediakan properti yang mengaitkan metadata dengan rentang teks. Properti ini termasuk, tetapi tidak terbatas pada, menampilkan atribut seperti teks tebal, pengidentifikasi bahasa teks, dan data mentah yang disediakan oleh layanan teks seperti data audio yang terkait dengan teks dari layanan teks ucapan.
Contoh berikut menunjukkan bagaimana properti warna teks hipotetis dengan kemungkinan nilai merah (R), hijau (G), atau biru (B) dapat dilihat.
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Properti dari berbagai jenis dapat tumpang tindih. Misalnya, ambil contoh sebelumnya dan tambahkan atribut teks yang dapat ditebalkan (B) atau miring (I).
ATTRIB:BBBBBBB IIIIIIIIIIII
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Teks "ini" akan ditebalkan, "adalah" akan tebal dan merah, "beberapa" akan ditampilkan secara normal, "berwarna" akan berwarna hijau dan miring dan "teks" akan miring.
Properti dengan tipe yang sama tidak dapat tumpang tindih. Misalnya, situasi berikut tidak diizinkan karena "adalah" dan "berwarna" memiliki nilai tumpang tindih dengan jenis yang sama.
COLOR: GGG GGGG RRR BBBBGGG
COLOR: RR GGGGGGGG
TEXT: this is some colored text
Jenis Properti
TSF mendefinisikan tiga jenis properti yang berbeda.
Jenis properti
Deskripsi
Statis
Objek properti statis menyimpan data properti dengan teks. Ini juga menyimpan rentang informasi teks untuk setiap rentang yang diterapkan properti. ITfReadOnlyProperty::GetType mengembalikan kategori GUID_TFCAT_PROPSTYLE_STATIC.
Statis-Ringkas
Objek properti statis-ringkas identik dengan objek properti statis kecuali properti statis-ringkas tidak menyimpan data rentang. Saat rentang yang dicakup oleh properti statis-ringkas diminta, rentang dibuat untuk setiap grup properti yang berdekatan. Properti statis-ringkas adalah cara paling efisien untuk menyimpan properti berdasarkan per karakter. ITfReadOnlyProperty::GetType mengembalikan kategori GUID_TFCAT_PROPSTYLE_STATICCOMPACT.
Adat
Objek properti kustom menyimpan informasi rentang untuk setiap rentang tempat properti berlaku. Namun, tidak menyimpan data aktual untuk properti . Sebagai gantinya, properti kustom menyimpan objek ITfPropertyStore. Manajer TSF menggunakan objek ini untuk mengakses dan memelihara data properti. ITfReadOnlyProperty::GetType mengembalikan kategori GUID_TFCAT_PROPSTYLE_CUSTOM.
Jika jenis properti tertentu diperlukan, maka ITfContext::GetProperty digunakan. ITfContext::GetProperty memerlukan GUID yang mengidentifikasi properti untuk diperoleh. TSF mendefinisikan sekumpulan pengidentifikasi properti yang telah ditentukan sebelumnya yang digunakan atau layanan teks dapat menentukan pengidentifikasi propertinya sendiri. Jika properti kustom digunakan, penyedia properti harus menerbitkan GUID properti dan format data yang diperoleh.
Misalnya, untuk mendapatkan CLSID bagi pemilik rentang teks, panggil ITfContext::GetProperty untuk mendapatkan objek properti, panggil ITfProperty::FindRange untuk mendapatkan rentang yang sepenuhnya mencakup properti, lalu panggil ITfReadOnlyProperty::GetValue untuk mendapatkan TfGuidAtom yang mewakili CLSID layanan teks yang memiliki teks. Contoh berikut menunjukkan fungsi yang, mengingat konteks, rentang, dan cookie edit, akan mendapatkan CLSID dari layanan teks yang memiliki teks.
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;
}
Seringkali, properti transparan untuk aplikasi dan digunakan oleh satu atau beberapa layanan teks. Untuk mempertahankan data properti, seperti saat menyimpan ke file, aplikasi harus membuat serial data properti saat disimpan dan membatalkan penyaringan data properti saat data dipulihkan. Dalam hal ini, aplikasi tidak boleh tertarik pada properti individual, tetapi harus menghitung semua properti dalam konteks dan menyimpannya.
Saat menyimpan data properti, aplikasi harus melakukan langkah-langkah berikut.
Dapatkan enumerator properti dengan memanggil ITfContext::EnumProperties.
Teruskan aliran input ke ITextStoreACPServices::Unserialize dan NULL untuk pLoader.
Metode pertama lebih disukai karena ini adalah yang paling efisien. Menerapkan metode kedua menyebabkan semua data properti dibaca dari aliran selama panggilan ITextStoreACPServices::Unserialize . Metode pertama menyebabkan data properti dibaca sesuai permintaan di lain waktu.
Ulangi langkah-langkah sebelumnya hingga semua blok properti tidak diserialisasi.
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;
}
Komposisi adalah status input sementara yang memungkinkan layanan teks untuk menentukan baik ke aplikasi maupun pengguna bahwa teks input masih dalam status perubahan.