输入法编程之 光标跟随
光标跟随是输入法系统最常见的特性。要实现这一特性,需要获取IME支持程序(最常见如word,notepad等)中插入符号caret的坐标位置。在Windows的IME环境中,可以通过使用IME核心数据结构INPUTCONTEXT的cfCompForm成员来获取IME宿主程序中文本光标位置。cfCompForm具有如下结构:
typedef tagCANDIDATEFORM { //列表窗口信息
//由IMC_GETCANDIDATEPOS和IMC_SETCANDIDATEPOS消息处理
DWORD dwIndex; //列表窗口序号
DWORD dwStyle; //属性:
//=CFS_CANDIDATEPOS 指定显示位置
//=CFS_EXCLUDE 不可显示
//=CFS_DEFAULT 根据需要显示
POINT ptCurrentPos; //坐标位置
REC rcArea; //不可显示区
} CANDIDATEFORM;
其中ptCurrentPos就是我们需要的光标位置,不过因为这是客户区的坐标,需要转化为屏幕坐标才能使用。要使得输入法上下文结构INPUTCONTEXT中已经填入了正确的坐标位置,需要实现WM_IME_NOTIFY消息响应事件。在WM_IME_NOTIFY消息的子消息IMN_SETCOMPOSITIONWINDOW(设置编码窗口消息)被触发时,系统会返回正确的坐标位置。WM_IME_NOTIFY消息响应函数类似如下形式:
/*
* IMENotifyHandle():
*
* Handle WM_IME_NOTIFY messages.
*/
LONG IMENotifyHandle(HIMC hUICurIMC, HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 0L;
LPINPUTCONTEXT lpIMC;
if (!(lpIMC = ImmLockIMC(hUICurIMC)))
return 0L;
switch (wParam)
{
case IMN_CLOSESTATUSWINDOW:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_CLOSESTATUSWINDOW/n");
/// hide the status window
g_pStatus->Hide();
break;
case IMN_OPENSTATUSWINDOW:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_OPENSTATUSWINDOW/n");
/// create the status window, but don't show
g_pStatus->Create(hWnd);
break;
case IMN_OPENCANDIDATE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_OPENCANDIDATE/n");
break;
case IMN_CHANGECANDIDATE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_CHANGECANDIDATE/n");
break;
case IMN_CLOSECANDIDATE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_CLOSECANDIDATE/n");
break;
case IMN_SETCONVERSIONMODE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETCONVERSIONMODE/n");
/// repaint the status window
g_pStatus->Repaint();
break;
case IMN_SETSENTENCEMODE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETSENTENCEMODE/n");
break;
case IMN_SETOPENSTATUS:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETOPENSTATUS/n");
/// repaint the status window
g_pStatus->Repaint();
break;
case IMN_SETCANDIDATEPOS:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETCANDIDATEPOS/n");
break;
case IMN_SETCOMPOSITIONFONT:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONFONT/n");
break;
case IMN_SETCOMPOSITIONWINDOW:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETCOMPOSITIONWINDOW/n");
/// adjust the postion of comp and cand windows
POINT ptSrc;
SIZE szOffset;
HDC hDC;
ptSrc = lpIMC->cfCompForm.ptCurrentPos;
ClientToScreen(lpIMC->hWnd, &ptSrc);
hDC = GetDC(lpIMC->hWnd);
GetTextExtentPoint(hDC,"A",1,&szOffset);
ReleaseDC(lpIMC->hWnd,hDC);
g_ptTopLeft.x = ptSrc.x + szOffset.cx;
g_ptTopLeft.y = ptSrc.y + szOffset.cy;
break;
case IMN_GUIDELINE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_GUIDELINE/n");
break;
case IMN_SETSTATUSWINDOWPOS:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_SETSTATUSWINDOWPOS/n");
break;
case IMN_PRIVATE:
TRACE("UIWnd:WM_IME_NOTIFY:IMN_PRIVATE/n");
break;
default:
break;
}
ImmUnlockIMC(hUICurIMC);
return lRet;
}
其中,需要注意的是要确保获取正确的位置,必须有先发送过WM_IME_STARTCOMPOSITION消息,这个消息一般在刚开始输入新拼音时候发送!关于IME消息处理可以看MSDN相关文档。
即便如此,仍然不能保证在所有程序中,输入法都能正确地体现光标跟随,我遇到的情况是在UtraEdit中,上述代码毫无作用,IMN_SETCOMPOSITIONWINDOW根本就没有被系统触发,这时我只好通过GetCaretPos来侥幸地获取光标位置。
输入法编程之 光标跟随相关推荐
- 实现CEGUI中文汉字输入法光标跟随(C/C++源码)
作者:庄晓立(liigo) 日期:2011年7月20日 原创链接:http://blog.csdn.net/liigo/article/details/6621104 转载请注明出处:http://b ...
- idea输入法候选区不跟随光标
环境: win10 idea 2017.04 搜狗8.6 问题: idea编辑区输入法候选区不跟随光标 解决: 输入法改成必应输入法 不行的话不用你动手 我自砸蛋蛋.(保命狗头..) 转载于:http ...
- 提交的JDK输入法光标跟随,被要求予以详细说明
邮件内容如下: Provide a complete description and explanation of what you are doing, and why it is is the c ...
- IME输入法编程心得
原文链接: IME输入法编程心得 posted @ 2012-11-30 00:42 from [FreedomShe] 自然语言处理的输入法作业成品没有做出来,但不想再在蛋疼的Win32上面耗 ...
- IME输入法编程:第一章 Windows9x系统下汉字输入法的基本原理
IME输入法编程 第一章 Windows9x系统下汉字输入法的基本原理 Windows系统下汉字输入法实际上是将输入的标准ascii字符串按照一定的编码规则转换为汉字或汉字串,进 入到目的地. 由于应 ...
- 输入法编程相关资源汇集-欢迎补充
本文可以任意转载,转载时请务必以超链接形式标明文章原始出处 在这里向一些付出工作的同志们和网站站长抱歉,有些资源是我直接保存的,现在有些网站打不开让我不能够贴上链接了,如果发现有损你们的利益,给我来信 ...
- 输入法编程相关资源汇集
http://www.cnblogs.com/realfun/archive/2005/03/28/127152.aspx 本文可以任意转载,转载时请务必以超链接形式标明文章原始出处 在这里向一些付出 ...
- Win32输入法编程技术的分析研究
作者:新疆大学 巴力登 陆莲芳 [摘要]本文论述了Win32输入法编程技术的基本原理.技术要点及其实现的方法. 并分析研究了基于IMM-IME结构的输入法的构成.接口.设计方法与核心技术问题. [关 ...
- 光标跟随放大镜js特效代码
下载地址 光标跟随放大镜特效代码 dd:
- VC++ 输入法编程
一直想写一点关于输入法编程的东西,今天终于有点时间,希望对后来者有点帮助.在此要特别感谢"自由拼音"的作者李振春,我刚开始的几个问题都是在他的帮助下才解决. 首先我们需要明白输入法 ...
最新文章
- C# WinForm 技巧四:COMBOBOX搜索提示
- 只做决定的架构师会成为团队的瓶颈!
- yolov5 face 使用踩坑记录
- C++ 对TXT 的串并行读写
- 在program A里访问program B local class的两种方式
- 深度解读OpenYurt:从边缘自治看YurtHub的扩展能力
- Android 8.0 学习(22) Android8.0平台Eng版本中显示界面切换闪红框
- sqlcheck约束表达式怎么写_creo 5.0 建模实例教程----乌比莫斯之环教程(表达式扫描特征)...
- ASP.NET Core的身份认证框架IdentityServer4--(5)自定义用户登录(通过接口登录,无UI版本)...
- 怎么把python从c盘移到d盘_如何转移Pycharm的设置或者缓存到其他盘
- 个人第1次作业:阅读与准备作业
- 密西西比河谷州立大学:Android应用程序开发(五)
- NLP教程笔记:BERT 双向语言模型
- IBL(二) IBL中Specular 和Diffuse的计算(ReflectProbe 和 LightProbe)
- CVPR 2021 结果出炉!最全论文下载及分类汇总(更新中)
- ant-design vue input通过那个事件可以获得输入框变化的值_VUE使用百度地图教程
- msxml4.dll加载失败、动态链接库例程失败
- 【考研英语语法】五种基本句型
- Pathos: Nethack Codex 游戏指南
- 清华考研复试上机——最大序列和