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(一)相关推荐

  1. 山东大学软件工程应用与实践——GMSSL开源库(四)——SM9数字签名算法及验证的源代码分析

    2021SC@SDUSC 目录 一.引言 二.密钥的生成数字签名与签名验证相关代码 1.判定函数 2.签名的初始化函数 3.签名执行函数 4.真正的签名函数 5.签名验证初始化函数 6.签名验证执行函 ...

  2. 山东大学软件工程应用与实践——GMSSL开源库(一) ——WINDOWS下GMSSL的安装与编译的超详细保姆级攻略

    2021SC@SDUSC GMSSL简介 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全 ...

  3. <2021SC@SDUSC>博客(5)山东大学软件工程应用与实践JPress代码分析(四)

    2021SC@SDUSC 前言 在前面三篇文章中,我对 JPress 项目的基础框架 JFinal 和 JBoot 在使用层面进行了拆解与分析.在接下来的文章中,我将在代码层面对 JPress 项目中 ...

  4. <2021SC@SDUSC>博客(9)山东大学软件工程应用与实践Jpress代码分析(8)

    2021SC@SDUSC Lucene和ElasticSearch 在上一篇博客中提到的Elasticsearch是一个基于Lucene搜索引擎为核心构建的开源,分布式,RESTful搜索服务器.这里 ...

  5. 山东大学软件工程应用与实践——使用CUDA/GPU技术加速密码运算(第五周)

    2021SC@SDUSC 很抱歉由于自身身体原因,本来打算这周对AES算法进行CPU和GPU的实际检测比较分析进行推迟.我决定对于SHA.AES.RSA三个算法在CPU和GPU性能对比放在最后几周. ...

  6. 山东大学软件工程应用与实践——GMSSL开源库(二)——浅尝SM9

    2021SC@SDUSC 概述 为了降低公开密钥系统中密钥和证书管理的复杂性,以色列科学家.RSA算法发明人之一Adi Shamir在1984年提出了标识密码(Identity-Based Crypt ...

  7. 山东大学软件工程应用与实践——GMSSL开源库(九)——SM9密钥封装与公钥加密的源代码分析

    2021SC@SDUSC 文章目录 int SM9_wrap_key(密钥的封装) int SM9_unwrap_key(密钥的解封) int SM9_encrypt(公钥加密算法) int SM9_ ...

  8. 山东大学软件工程应用与实践——Pig代码综述

    2021SC@SDUSC 目录 一.Pig是什么? 二.Pig的特点 三.Pig安装部署 四.组内分工 一.Pig是什么? Pig 是Apache平台下的一个免费开源项目,是MapReduce的一个抽 ...

  9. 山东大学软件工程应用与实践——GMSSL开源库(十)——重要的大整数

    2021SC@SDUSC 文章标题 BIGNUM的结构 大整数的加减法(绝对值加减) 绝对值加减 带符号加减 大整数的乘法 经典乘法 递归和comba乘法 小结 无论是SM2.SM9等国密算法还是以R ...

最新文章

  1. nature | 基于深度学习方法的虚拟组织染色
  2. 计算机从加电到系统(Linux)启动完成
  3. 程序员修炼之道--从小工到专家(一)
  4. 搭建FastDFS分布式文件存储系统教程
  5. java 读取Zip文件进行写入
  6. inventor牙距_滚子链计算基础知识 | Inventor 2018 | Autodesk Knowledge Network
  7. 在VirtualBox的虚拟机上安装和使用NCS2(intel movidius stick 2)
  8. MFC控件学习:图片(bmp/png)
  9. 股市修仙传:群魔乱舞之仙人跳!
  10. 3D目标检测/点云/遥感数据集汇总
  11. Android -- 小功能 仿美图秀秀(美颜相机)马赛克功能
  12. 自考02323《操作系统概论》第一章操作系统简介——思维导图
  13. liferay6.2 mysql_liferay6.2 集成CKEditor和ckfinder
  14. 2023年云计算的发展趋势如何?还值得学习就业吗?
  15. Web|Http协议-请求\响应\数据类型\协议类型总结
  16. Fluent求解器——湍流参数的设置
  17. 270亿美元!Salesforce收购Slack,协同办公不再是一门好生意
  18. 小B从测试小白到测试大牛的过程
  19. tcpdump 和Wireshark抓包
  20. centos7盘符 linux_centos7 盘符变动 绑定槽位

热门文章

  1. 【NEO NEXT社区】高校区块链技术分享会——上海交通大学
  2. Visual Studio中Git的使用(完全图解)
  3. 用AS实现微信界面设计
  4. css3 - 图标元素动画效果4 - 动画延迟
  5. bashne java_bash脚本中 if 语句 和 for 语句使用方法
  6. ArcGIS坡度分析(解决坡度分析80-89°高值居多)
  7. MySQL源代码的海洋中游弋 初探MySQL之SQL执行过程
  8. python贴吧数据可视化软件_Python数据可视化工具之Pyecharts初体验
  9. 怎么用html3秒自动跳网页,HTML页面3秒后自动跳转的三种常见方法
  10. (每日一练c++)组合总和