光标跟随是输入法系统最常见的特性。要实现这一特性,需要获取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来侥幸地获取光标位置。

输入法编程之 光标跟随相关推荐

  1. 实现CEGUI中文汉字输入法光标跟随(C/C++源码)

    作者:庄晓立(liigo) 日期:2011年7月20日 原创链接:http://blog.csdn.net/liigo/article/details/6621104 转载请注明出处:http://b ...

  2. idea输入法候选区不跟随光标

    环境: win10 idea 2017.04 搜狗8.6 问题: idea编辑区输入法候选区不跟随光标 解决: 输入法改成必应输入法 不行的话不用你动手 我自砸蛋蛋.(保命狗头..) 转载于:http ...

  3. 提交的JDK输入法光标跟随,被要求予以详细说明

    邮件内容如下: Provide a complete description and explanation of what you are doing, and why it is is the c ...

  4. IME输入法编程心得

     原文链接: IME输入法编程心得 posted @ 2012-11-30 00:42 from [FreedomShe] 自然语言处理的输入法作业成品没有做出来,但不想再在蛋疼的Win32上面耗 ...

  5. IME输入法编程:第一章 Windows9x系统下汉字输入法的基本原理

    IME输入法编程 第一章 Windows9x系统下汉字输入法的基本原理 Windows系统下汉字输入法实际上是将输入的标准ascii字符串按照一定的编码规则转换为汉字或汉字串,进 入到目的地. 由于应 ...

  6. 输入法编程相关资源汇集-欢迎补充

    本文可以任意转载,转载时请务必以超链接形式标明文章原始出处 在这里向一些付出工作的同志们和网站站长抱歉,有些资源是我直接保存的,现在有些网站打不开让我不能够贴上链接了,如果发现有损你们的利益,给我来信 ...

  7. 输入法编程相关资源汇集

    http://www.cnblogs.com/realfun/archive/2005/03/28/127152.aspx 本文可以任意转载,转载时请务必以超链接形式标明文章原始出处 在这里向一些付出 ...

  8. Win32输入法编程技术的分析研究

    作者:新疆大学 巴力登 陆莲芳 [摘要]本文论述了Win32输入法编程技术的基本原理.技术要点及其实现的方法. 并分析研究了基于IMM-IME结构的输入法的构成.接口.设计方法与核心技术问题.  [关 ...

  9. 光标跟随放大镜js特效代码

    下载地址 光标跟随放大镜特效代码 dd:

  10. VC++ 输入法编程

    一直想写一点关于输入法编程的东西,今天终于有点时间,希望对后来者有点帮助.在此要特别感谢"自由拼音"的作者李振春,我刚开始的几个问题都是在他的帮助下才解决. 首先我们需要明白输入法 ...

最新文章

  1. C# WinForm 技巧四:COMBOBOX搜索提示
  2. 只做决定的架构师会成为团队的瓶颈!
  3. yolov5 face 使用踩坑记录
  4. C++ 对TXT 的串并行读写
  5. 在program A里访问program B local class的两种方式
  6. 深度解读OpenYurt:从边缘自治看YurtHub的扩展能力
  7. Android 8.0 学习(22) Android8.0平台Eng版本中显示界面切换闪红框
  8. sqlcheck约束表达式怎么写_creo 5.0 建模实例教程----乌比莫斯之环教程(表达式扫描特征)...
  9. ASP.NET Core的身份认证框架IdentityServer4--(5)自定义用户登录(通过接口登录,无UI版本)...
  10. 怎么把python从c盘移到d盘_如何转移Pycharm的设置或者缓存到其他盘
  11. 个人第1次作业:阅读与准备作业
  12. 密西西比河谷州立大学:Android应用程序开发(五)
  13. NLP教程笔记:BERT 双向语言模型
  14. IBL(二) IBL中Specular 和Diffuse的计算(ReflectProbe 和 LightProbe)
  15. CVPR 2021 结果出炉!最全论文下载及分类汇总(更新中)
  16. ant-design vue input通过那个事件可以获得输入框变化的值_VUE使用百度地图教程
  17. msxml4.dll加载失败、动态链接库例程失败
  18. 【考研英语语法】五种基本句型
  19. Pathos: Nethack Codex 游戏指南
  20. 清华考研复试上机——最大序列和

热门文章

  1. 【UE·蓝图】UE4蓝图MediaPlayer注意事项
  2. 21岁雅虎卖身引发一波怀旧 市值曾高达1250亿美元
  3. 计算机多媒体英语,基于计算机多媒体的英语个性化教学
  4. java 可达性分析算法_垃圾回收:可达性分析算法、生存还是死亡(两次标记)
  5. 阿里云Maven镜像
  6. 【毕业设计】 基于STM32的人体红外测温枪温度采集系统
  7. 采用LM1875组成的各种功放电路
  8. cnc计算机控制,CNC控制器
  9. 白话理解傅里叶变换原理(时域频域)
  10. PDF虚拟打印机(pdfFactory) v5.11 官方版