TSF输入法框架的工作原理

PS:本篇文章是基于网络上的一些文章、微软官方文档以及自己的理解整理而成,若理解有误,还请大家及时提出。

在了解了TSF的强大之后,很容易产生一个疑问,TSF是如何将应用程序和 Text Service 隔离开的呢?这里简单介绍下TSF 的工作原理。

首先需要知道,基于TSF 框架的输入法 实际上是一个COM程序。也就是说,微软为我们提供了很多的虚基类,然后我们需要实现一个COM 程序。

(1)首先要确认,在应用程序和 Text Service 之间进行传递的是一个 text stream(文本流),既然是 text stream, 肯定要有text(可以理解成 text stream 的载体),比如说notepad,word,各种输入框,都可以理解成是一个text。TSF 的处理是首先由应用程序创建一个 Thread Manager,创建方法是通过 CoCreateInstance 创建一个组件对象,对应的,微软提供的接口是 ITfThreadMgr。

(2)创建好Thread Manager 之后,用 Thread Manager 来创建一个 Document Manager(文档管理器),方法是 ITfThreadMgr::CreateDocumentMgr。应用程序会为每一个不同的Document 创建一个 Document Manager

(3)创建 Document Manager 后,用 ITfDocumentMgr 来创建一个 edit context,方法是 ITfDocumentMgr::CreateContext。

实际上,Thread Manager 为每个 Document Manager 都维护了一个 context stack,新创建的context 被压入到了栈中。

那么,Text Service 是如何往context 中写入text stream 的呢?对于这个问题,首先Text Service 要获得一个context。

当 Text Service 获取一个context 时,很容易想到,此时可能有很多个Document Manager,可能有更多的context,到底获取哪一个呢?

(1)首先获取当前处于焦点的Document Manager,采用的方法是ITfThreadMgr::GetFocus,得到一个Document Manager 对象

(2)获取之前得到的 Document Manager 的 context stack 中的栈顶 context,方法是 ITfDocumentMgr::GetTop

至此,应用程序和 Text Service 通过 Thread Manager 创建的某个 context 产生了连接。

那么,TSF 是如何进行 Text Stores(文本存储)呢?这个问题,微软也为我们提供了相应的接口。

比如说,我们可以实现一个TTsfTextStore,可以继承 ITextStoreAcp,这个接口中有一些函数,可以在TTsfTextStore 中实现这些函数,这些函数中就有传递 text stream 的实现。给出一个ITextStoreAcp 中的函数列表:

/* ITextStoreACP Interfaces */

 HRESULT	STDMETHODCALLTYPE 	AdviseSink(REFIID riid, IUnknown* punk, DWORD dwMask);
    HRESULT	STDMETHODCALLTYPE 	UnadviseSink(IUnknown* punk);
    HRESULT	STDMETHODCALLTYPE 	RequestLock(DWORD dwLockFlags, HRESULT* phrSession);
    HRESULT	STDMETHODCALLTYPE 	GetStatus(TS_STATUS* pdcs);
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值