在TSF框架中有时候我们需要通过框架上屏一些占位字符来进行定位,这时候我们就需要对预先上屏的字符进行管理,以微软的输入法为例图中红框框选出来的部分就是预先上屏的字符。
在TSF框架中通过ITfRange类来对这个上屏的字符串进行控制。在进行控制的时候我们通过ITfComposition的接口来获取对应的ITfRange实例,在获取对应的实例之后,我们就可以通过ITfRange的对应的接口来进行控制上屏的字符串了。
ITfRange中的几个比较关键的接口说明如下:
//改接口主要负责设置预先上屏的字符串的内容
HRESULT SetText(
[in] TfEditCookie ec, //会话实例
[in] DWORD dwFlags, //是否纠正内容一般设置为TF_IE_CORRECTION
[in] const WCHAR *pchText, //显示的内容
[in] LONG cch //内容的长度
);
//ITfRange通过两个anchor锚来对预先上屏的字符串进行选择和定位
//start-anchor......end-anchor
//ShiftEnd负责对结束的锚点进行移动
HRESULT ShiftEnd(
[in] TfEditCookie ec, //上下文状态
[in] LONG cchReq, //指定移动的偏移量
[out] LONG *pcch, //实际移动的偏移量
[in] const TF_HALTCOND *pHalt //指定移动的条件,一般给定为空就行
);
//ShiftStart负责对开始的锚点进行移动
HRESULT ShiftStart(
[in] TfEditCookie ec,
[in] LONG cchReq,
[out] LONG *pcch,
[in] const TF_HALTCOND *pHalt
);
//如果想要移动预先上屏的字符串中的光标的话,同时移动两个锚点就可以了
//将两个锚点同时移动到某一个位置,该位置可以是
//TF_ANCHOR_START(开头)TF_ANCHOR_END(结束)
HRESULT Collapse(
[in] TfEditCookie ec,
[in] TfAnchor aPos
);
下面介绍如何在TSF输入法框架中添加ITfRange预先上屏的内容。并对其中的光标进行移动。
//TSF框架传递进来的Composition实例
ITfComposition* _pComposition;
//预先上屏的字符串内容的实例
ITfRange* _pCompositionRange;
//获取当前编辑状态的ITfRange
if (SUCCEEDED(_pComposition->GetRange(&_pCompositionRange)))
{
//获取需要显示的文本内容的长度
wchar_t* content = L"ce'shi'shu'ru'fa";
int str_len = _tcslen(content);
wstring output_wstr;
//屏蔽掉音节分割的分割符号
for (int index = 0; index < str_len; ++index)
{
if (content[index] == wchar_t(L'\''))
{
continue;
}
output_wstr.push_back(content[index]);
}
//向ITfRange中添加需要显示的字符
_pCompositionRange->SetText(ec, TF_IE_CORRECTION, output_wstr.c_str(),
output_wstr.length());
//获取当前操作环境中的光标位置
int pos = context->cursor_pos;
//设置光标的偏移位置
int sel_start = pos, sel_end = pos;
//对光标位置进行移动
LONG cch;
TF_SELECTION tfSelection_tmp;
//将初始位置设置到内容开始的地方
pRangeComposition->Collapse(ec, TF_ANCHOR_START);
//根据光标位置对预先上屏的内容中的光标进行移动
pRangeComposition->ShiftEnd(ec, sel_end, &cch, NULL);
pRangeComposition->ShiftStart(ec, sel_start, &cch, NULL);
//将修改设置会TSF框架
tfSelection_tmp.range = pRangeComposition;
tfSelection_tmp.style.ase = TF_AE_NONE;
tfSelection_tmp.style.fInterimChar = FALSE;
context->SetSelection(ec, 1, &tfSelection_tmp);
}