山东大学软件工程应用与实践——WeaselTSF(一)
2021SC@SDUSC
文章目录
- 简单介绍
- WeaselTSF.h
从本篇博客开始分析WeaselTFS这个包中的代码。
简单介绍
WeaselTSF.vcproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the Application Wizard.
WeaselTSF.vcproj是使用应用程序向导生成的VC++项目的主项目文件。它包含生成文件的VisualC++的版本信息,和有关使用应用程序向导选择的平台、配置和项目功能的信息。
WeaselTSF.cpp
This is the main DLL source file.
WeaselTSF.cpp是主DLL源文件。
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file named WeaselTSF.pch and a precompiled types file named StdAfx.obj.
其他标准文件StdAfx.h, StdAfx.cpp,这些文件用于构建WeaselTSF.PCH的预编译头(PCH)文件和StdAfx.obj的预编译类型文件。
WeaselTSF.h
#include <WeaselCommon.h>
#include "Globals.h"
#include "WeaselIPC.h"class CCandidateList;
class CLangBarItemButton;
class CCompartmentEventSink;class WeaselTSF:public ITfTextInputProcessorEx,public ITfThreadMgrEventSink,public ITfTextEditSink,public ITfTextLayoutSink,public ITfKeyEventSink,public ITfCompositionSink,public ITfThreadFocusSink,public ITfActiveLanguageProfileNotifySink,public ITfEditSession
{public:WeaselTSF();~WeaselTSF();/* IUnknown */STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);STDMETHODIMP_(ULONG) AddRef();STDMETHODIMP_(ULONG) Release();/* ITfTextInputProcessor */STDMETHODIMP Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId);STDMETHODIMP Deactivate();/* ITfTextInputProcessorEx */STDMETHODIMP ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags);/* ITfThreadMgrEventSink */STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr *pDocMgr);STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr *pDocMgr);STDMETHODIMP OnSetFocus(ITfDocumentMgr *pDocMgrFocus, ITfDocumentMgr *pDocMgrPrevFocus);STDMETHODIMP OnPushContext(ITfContext *pContext);STDMETHODIMP OnPopContext(ITfContext *pContext);/* ITfTextEditSink */STDMETHODIMP OnEndEdit(ITfContext *pic, TfEditCookie ecReadOnly, ITfEditRecord *pEditRecord);/* ITfTextLayoutSink */STDMETHODIMP OnLayoutChange(ITfContext *pContext, TfLayoutCode lcode, ITfContextView *pContextView);/* ITfKeyEventSink */STDMETHODIMP OnSetFocus(BOOL fForeground);STDMETHODIMP OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten);STDMETHODIMP OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten);STDMETHODIMP OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten);STDMETHODIMP OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pfEaten);STDMETHODIMP OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pfEaten);// ITfThreadFocusSinkSTDMETHODIMP OnSetThreadFocus();STDMETHODIMP OnKillThreadFocus();/* ITfCompositionSink */STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, ITfComposition *pComposition);/* ITfEditSession */STDMETHODIMP DoEditSession(TfEditCookie ec);/* ITfActiveLanguageProfileNotifySink */STDMETHODIMP OnActivated(REFCLSID clsid, REFGUID guidProfile, BOOL isActivated);///* ITfCompartmentEventSink *///STDMETHODIMP OnChange(_In_ REFGUID guid);/* Compartments */BOOL _IsKeyboardDisabled();BOOL _IsKeyboardOpen();HRESULT _SetKeyboardOpen(BOOL fOpen);/* Composition */void _StartComposition(com_ptr<ITfContext> pContext, BOOL fCUASWorkaroundEnabled);void _EndComposition(com_ptr<ITfContext> pContext, BOOL clear);BOOL _ShowInlinePreedit(com_ptr<ITfContext> pContext, const std::shared_ptr<weasel::Context> context);void _UpdateComposition(com_ptr<ITfContext> pContext);BOOL _IsComposing();void _SetComposition(com_ptr<ITfComposition> pComposition);void _SetCompositionPosition(const RECT &rc);BOOL _UpdateCompositionWindow(com_ptr<ITfContext> pContext);void _FinalizeComposition();void _AbortComposition(bool clear = true);/* Language bar */HWND _GetFocusedContextWindow();void _HandleLangBarMenuSelect(UINT wID);/* IPC */void _EnsureServerConnected();/* UI */void _UpdateUI(const weasel::Context & ctx, const weasel::Status & status);void _StartUI();void _EndUI();void _ShowUI();void _HideUI();com_ptr<ITfContext> _GetUIContextDocument();com_ptr<ITfThreadMgr> _GetThreadMgr() { return _pThreadMgr; }private:/* TSF Related */BOOL _InitThreadMgrEventSink();void _UninitThreadMgrEventSink();BOOL _InitTextEditSink(com_ptr<ITfDocumentMgr> pDocMgr);BOOL _InitKeyEventSink();void _UninitKeyEventSink();void _ProcessKeyEvent(WPARAM wParam, LPARAM lParam, BOOL *pfEaten);BOOL _InitPreservedKey();void _UninitPreservedKey();BOOL _InitLanguageBar();void _UninitLanguageBar();void _UpdateLanguageBar(weasel::Status stat);void _ShowLanguageBar(BOOL show);void _EnableLanguageBar(BOOL enable);BOOL _InsertText(com_ptr<ITfContext> pContext, const std::wstring& ext);void _DeleteCandidateList();BOOL _InitCompartment();void _UninitCompartment();HRESULT _HandleCompartment(REFGUID guidCompartment);bool isImmersive() const {return (_activateFlags & TF_TMF_IMMERSIVEMODE) != 0;}com_ptr<ITfThreadMgr> _pThreadMgr;TfClientId _tfClientId;DWORD _dwThreadMgrEventSinkCookie;com_ptr<ITfContext> _pTextEditSinkContext;DWORD _dwTextEditSinkCookie, _dwTextLayoutSinkCookie;BYTE _lpbKeyState[256];BOOL _fTestKeyDownPending, _fTestKeyUpPending;com_ptr<ITfContext> _pEditSessionContext;std::wstring _editSessionText;com_ptr<CCompartmentEventSink> _pKeyboardCompartmentSink;com_ptr<ITfComposition> _pComposition;com_ptr<CLangBarItemButton> _pLangBarButton;com_ptr<CCandidateList> _cand;LONG _cRef; // COM ref count/* CUAS Candidate Window Position Workaround */BOOL _fCUASWorkaroundTested, _fCUASWorkaroundEnabled;/* Weasel Related */weasel::Client m_client;DWORD _activateFlags;/* IME status */weasel::Status _status;
};
这里使用了TSF(Text Services Framework),TSF是文本服务框架的简称,基于TSF的每一个输入法IME都是COM组件。支持TSF的应用程序可以在不用感知文本设备的前提下,接受从不同文本设备(键盘、手写、语音等)来源的文本输入。此外,TSF的一个重要优势是对输入法权限的管控程度远远高于IMM-IME,大大有利于系统的安全性。
输入法广泛使用 IMM32 接口,也发展成熟,XP 开始微软推广 TSF,Vista 操作系统默认开启了 TSF 管理器。但 TSF
一直饱受非议,虽然设计的很通用,但使用 COM 组件、接口隐晦、操作麻烦,而且从输入法角度来说,能做的事情似乎并不比 IMM32
强多少。此外,TSF 文档不全,样例单一,个别输入法功能上(比如输入法窗口管理)甚至比 IMM32 还要弱。TSF
似乎一直不怎么受到输入法开发者待见。直到 Win8 之后,METRO 界面只能使用 TSF 接口,于是主流输入法纷纷实现
TSF,用于处理全屏模式、游戏、以及 METRO。
- TSF 特点
-
使用 COM 组件,扩展性非常好,但上手难度大。
本身着重文字服务,比如手写输入、语音输入,甚至纠错、翻译什么的,都是可以用 TSF 实现。
APP 和 IME 之间有更多信息可以通讯。
IME 相关功能提供不全,如只提供了输入字属性和语言栏修改,输入法窗口均需要自己实现。(因为这一点,主流的纯 TSF 输入法都放弃输入法状态栏)
大部分注册表相关任务(比如注册输入法,注册快捷键)需要自己实现。
输入法文件的本质是个 dll,只要 dll 编译正确,就可以注册进操作系统。而 TSF 输入法,则是一个可注册的,包含 COM 接口的 dll。
COM 是微软的核心接口方案,COM 在 Windows 和 Office 中使用非常广泛,比如看似笨重的 IE 其实在为整个操作系统实现了网页相关的接口。COM 的一大特点是跨进程的,使用 COM 的时候,你不知道对面是跟进程,还是个被操作系统托管的 dll,而 COM 对象而言,也会在不同进程里被使用。
DLL DEF
编译 dll 需要暴露外部接口,暴露的方式就是在编译的时候指定 def 文件。一个 COM 组件的 def 文件至少是这样的:
LIBRARYEXPORTSDllGetClassObject PRIVATEDllCanUnloadNow PRIVATEDllRegisterServer PRIVATEDllUnregisterServer PRIVATE
这个包里的WeaselTFS.def文件即为如此:
其中 DllRegisterServer 和 DllUnregisterServer 是被注册(安装卸载),也就是调用 regsvr32.exe 注册时触发的函数。
而组件实际被调用的时候,DllGetClassObject 会被调用,通常你需要返回一个 ClassFactory,注意引用管理。
DllCanUnloadNow 则是用来计算能否卸载,需要跟引用管理配合。
下篇继续~
山东大学软件工程应用与实践——WeaselTSF(一)相关推荐
- 山东大学软件工程应用与实践——GMSSL开源库(四)——SM9数字签名算法及验证的源代码分析
2021SC@SDUSC 目录 一.引言 二.密钥的生成数字签名与签名验证相关代码 1.判定函数 2.签名的初始化函数 3.签名执行函数 4.真正的签名函数 5.签名验证初始化函数 6.签名验证执行函 ...
- 山东大学软件工程应用与实践——GMSSL开源库(一) ——WINDOWS下GMSSL的安装与编译的超详细保姆级攻略
2021SC@SDUSC GMSSL简介 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全 ...
- <2021SC@SDUSC>博客(5)山东大学软件工程应用与实践JPress代码分析(四)
2021SC@SDUSC 前言 在前面三篇文章中,我对 JPress 项目的基础框架 JFinal 和 JBoot 在使用层面进行了拆解与分析.在接下来的文章中,我将在代码层面对 JPress 项目中 ...
- <2021SC@SDUSC>博客(9)山东大学软件工程应用与实践Jpress代码分析(8)
2021SC@SDUSC Lucene和ElasticSearch 在上一篇博客中提到的Elasticsearch是一个基于Lucene搜索引擎为核心构建的开源,分布式,RESTful搜索服务器.这里 ...
- 山东大学软件工程应用与实践——使用CUDA/GPU技术加速密码运算(第五周)
2021SC@SDUSC 很抱歉由于自身身体原因,本来打算这周对AES算法进行CPU和GPU的实际检测比较分析进行推迟.我决定对于SHA.AES.RSA三个算法在CPU和GPU性能对比放在最后几周. ...
- 山东大学软件工程应用与实践——GMSSL开源库(二)——浅尝SM9
2021SC@SDUSC 概述 为了降低公开密钥系统中密钥和证书管理的复杂性,以色列科学家.RSA算法发明人之一Adi Shamir在1984年提出了标识密码(Identity-Based Crypt ...
- 山东大学软件工程应用与实践——GMSSL开源库(九)——SM9密钥封装与公钥加密的源代码分析
2021SC@SDUSC 文章目录 int SM9_wrap_key(密钥的封装) int SM9_unwrap_key(密钥的解封) int SM9_encrypt(公钥加密算法) int SM9_ ...
- 山东大学软件工程应用与实践——Pig代码综述
2021SC@SDUSC 目录 一.Pig是什么? 二.Pig的特点 三.Pig安装部署 四.组内分工 一.Pig是什么? Pig 是Apache平台下的一个免费开源项目,是MapReduce的一个抽 ...
- 山东大学软件工程应用与实践——GMSSL开源库(十)——重要的大整数
2021SC@SDUSC 文章标题 BIGNUM的结构 大整数的加减法(绝对值加减) 绝对值加减 带符号加减 大整数的乘法 经典乘法 递归和comba乘法 小结 无论是SM2.SM9等国密算法还是以R ...
最新文章
- nature | 基于深度学习方法的虚拟组织染色
- 计算机从加电到系统(Linux)启动完成
- 程序员修炼之道--从小工到专家(一)
- 搭建FastDFS分布式文件存储系统教程
- java 读取Zip文件进行写入
- inventor牙距_滚子链计算基础知识 | Inventor 2018 | Autodesk Knowledge Network
- 在VirtualBox的虚拟机上安装和使用NCS2(intel movidius stick 2)
- MFC控件学习:图片(bmp/png)
- 股市修仙传:群魔乱舞之仙人跳!
- 3D目标检测/点云/遥感数据集汇总
- Android -- 小功能 仿美图秀秀(美颜相机)马赛克功能
- 自考02323《操作系统概论》第一章操作系统简介——思维导图
- liferay6.2 mysql_liferay6.2 集成CKEditor和ckfinder
- 2023年云计算的发展趋势如何?还值得学习就业吗?
- Web|Http协议-请求\响应\数据类型\协议类型总结
- Fluent求解器——湍流参数的设置
- 270亿美元!Salesforce收购Slack,协同办公不再是一门好生意
- 小B从测试小白到测试大牛的过程
- tcpdump 和Wireshark抓包
- centos7盘符 linux_centos7 盘符变动 绑定槽位
热门文章
- 【NEO NEXT社区】高校区块链技术分享会——上海交通大学
- Visual Studio中Git的使用(完全图解)
- 用AS实现微信界面设计
- css3 - 图标元素动画效果4 - 动画延迟
- bashne java_bash脚本中 if 语句 和 for 语句使用方法
- ArcGIS坡度分析(解决坡度分析80-89°高值居多)
- MySQL源代码的海洋中游弋 初探MySQL之SQL执行过程
- python贴吧数据可视化软件_Python数据可视化工具之Pyecharts初体验
- 怎么用html3秒自动跳网页,HTML页面3秒后自动跳转的三种常见方法
- (每日一练c++)组合总和