Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
本文告诉大家在 WPF 写一个自定义的文本框,如何实现让输入法跟随光标
本文非小白向,本文适合想开发自定义的文本框,从底层开始开发的文本库的伙伴。在开始之前,期望了解了文本库开发的基础知识
本文实现的效果如下
实现
本文的方法参考了 WPF 官方仓库的逻辑,可以在 WPF 仓库的 wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\System\Windows\Documents\ImmComposition.cs
文件看到官方是如何让 TextBox 控件获取输入法焦点,和在输入光标变更时,修改输入法的输入框坐标
先了解一下输入法的相关知识。在 Windows 编程开发里,输入法框架有三套,其中用的最多的是第二套。第二套是采用 IMM 进行对接的。所谓 IMM 就是 Input Method Manager 也就是 输入法管理器
相关的另一个缩写词 IME 则是 Input Method Editor 或者是 Input Method Engine 的缩写,含义是输入法编辑器或输入法引擎
应用程序可以通过 IMM 对接输入法。所用的 win32 的 API 重点是如下几个
- ImmGetContext 获取输入法上下文,用于后续所有的其他函数调用
- ImmAssociateContext 关联输入法和对应的窗口,让输入法了解在哪个窗口输入
- ImmSetCompositionWindow 用来设置输入法的窗口的坐标,也是本文最重要的函数
本文接下来将告诉大家如何一步步实现封装对 IME 输入法调用,在本文最后将会给出所有的源代码
这部分对输入法的逻辑可以封装为一个类,这样上层就可以不关注细节逻辑。如例子代码,放在 IMESupporter 类型里
为了方便文本框的接入,咱再定义一个接口,用于设置文本框需要实现一些方法,用来提供参数给 IMESupporter 使用才能进行接入
///
/// 表示控件支持被输入法
///
interface IIMETextEditor
{
///
/// 获取当前使用的字体名
///
///
string GetFontFamilyName();
///
/// 获取字号大小,单位和 WPF 的 FontSize 相同
///
///
int GetFontSize();
///
/// 获取输入框的左上角的点,用于设置输入法的左上角。此点相对于 所在元素坐标。对大部分控件来说,都应该是 0,0 点
///
///
Point GetTextEditorLeftTop();
///
/// 获取光标的输入左上角的点。此点相对于 所在元素坐标
///
///
Point GetCaretLeftTop();
}
对于如微软拼音等输入法,是支持设置输入法的文本大小和字体。因此就需要文本框提供 GetFontFamilyName 和 GetFontSize 方法
而 GetCaretLeftTop 自然就是用来让输入法跟随的。为了让文本框可以做更多的定制,也需要 GetTextEditorLeftTop 方法,这个方法的返回值对大部分自定义的文本框控件来说,都应该是 0,0 点
在 IMESupporter 类型构造函数,期望传入文本框控件,如此可以解决初始化值和监听的锅
internal class IMESupporter<T> where T : UIElement, IIMETextEditor
{
// ReSharper disable InconsistentNaming
public IMESupporter(T editor)
{
Editor = editor;
// 忽略代码
}
}
为了同时约束传入的文本框控件继承 UIElement 和 IIMETextEditor 接口,用了泛形
在文本框控件 Editor 获取焦点的时候,将需要唤起输入法进行输入。在 Editor 失去焦点的时候,就应该告诉输入法当前不进行输入
public IMESupporter(T editor)
{
Editor = editor;
Editor.GotKeyboardFocus += Editor_GotKeyboardFocus;
Editor.LostKeyboardFocus += Editor_LostKeyboardFocus;
}
private T Editor { get; }
根据 WPF 的约定,对自定义的支持输入法的控件,需要设置 IsInputMethodSuspendedProperty 附加属性,如下面代码
InputMethod.SetIsInputMethodSuspended(editor, true);
在 Editor_GotKeyboardFocus
需要实现的逻辑是调起输入法和设置初始的输入框的坐标。如上文,开始之前,需要先拿到输入法上下文。在拿到输入法上下文之前,可以先获取默认的 IME 类窗口句柄。先获取默认的 IME 类窗口句柄是为了在多进程嵌入窗口时,让微软拼音输入法的输入框跟随输入光标而不是在左上角文章来源:https://www.toymoban.com/news/detail-442773.html
_defaultImeWnd = IMENative.ImmGetDefaultIMEWnd(IntPtr.Zero);
以上的 _defaultImeWnd
是一个字段,在 IMESu文章来源地址https://www.toymoban.com/news/detail-442773.html
到了这里,关于WPF 自定义文本框输入法 IME 跟随光标的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!