自定义输入法编辑器 (IME) 要求

这些指南和要求可以帮助你开发自定义输入法编辑器(IME),从而协助用户输入在标准 QWERTY 键盘上难以方便表示的语言文本。

有关 IME 的概述,请参阅输入法编辑器(IME)。

默认 IME

用户可以选择任何活动 IME(设置 -> 时间 - 语言 - 语言 ->> 首选语言 -> 语言包 - 选项) 作为其首选语言的默认 IME。

首选语言设置

在语言选项设置屏幕上为首选语言选择默认键盘。

首选语言键盘

重要

不建议直接写入注册表,以便为自定义 IME 设置默认键盘。

兼容性要求

以下是自定义 IME 的基本兼容性要求。

IME 必须与 Windows 应用兼容

使用 文本服务框架 (TSF) 实现 IME。 以前,可以选择将 输入法管理器(IMM32) 用于输入服务。 现在,系统会阻止使用输入法管理器(IMM32)实现的 IME。

应用启动时,TSF 为用户当前选择的 IME 加载 IME DLL。 加载 IME 时,它受到与应用相同的应用容器限制。 例如,如果应用在其清单中未请求 Internet 访问,则 IME 无法访问 Internet。 此行为可确保 IME 不能违反安全协定。

TSF 是应用与 IME 之间的中介。 TSF 将输入事件传达给 IME,并在用户选择字符后从 IME 接收输入字符。

此行为与以前版本的 Windows 相同,但加载到 Windows 应用中会影响 IME 的潜在功能。

如果你的 IME 需要在 Windows 应用和桌面应用之间提供不同的功能或 UI,请确保 TSF 加载的 DLL 会检查要加载到的应用类型。 在 IME 中调用 ITfThreadMgrEx::GetActiveFlags 方法并检查TF_TMF_IMMERSIVEMODE标志,因此 IME 会根据结果触发不同的应用程序逻辑。

Windows 应用不支持表文本服务 (TTS) IME。

注释

一些用于生成 TTS IME 的工具生成由 Windows 标记为恶意软件的 IME。

IME 必须与系统托盘兼容

没有用于托管 IME 图标的语言栏。 而是在系统托盘上显示一个指示当前输入选项的输入指示器。 输入指示器仅显示 IME 品牌图标以指示当前正在运行的 IME。 此外,还有一个 IME 模式图标,它显示在 IME 品牌图标的左侧,供用户执行最常用的 IME 模式开关,例如打开或关闭 IME。

输入指示器仅针对兼容的 IME 显示 IME 品牌标识和模式标识。 不兼容的 IME 没有系统托盘中显示的品牌图标和模式图标。 相反,输入指示器显示语言缩写而不是 IME 品牌图标。

将 IME 图标存储在 DLL 或 EXE 文件中,而不是独立的.ico文件。 IME 图标的设计必须遵循以下 UI 设计指南部分中所述的准则。

IME 品牌图标

输入指示器通过使用 IME 在系统注册时定义的资源 ID,从 IME DLL 获取 IME 品牌标识图标。

IME 模式图标

某些 IME 可能需要依赖系统托盘上显示的输入指示器来显示 IME 模式图标。 在这种情况下,IME 使用 GUID_LBI_INPUTMODE 将 IME 模式图标传递到输入指示器。

将 IME 模式图标传递到系统托盘上的输入指示器时,IME 模式图标的默认大小为 16x16 像素。 UI 缩放遵循 DPI。

将 IME 模式图标传递给 UAC 上的输入指示器(安全桌面中的用户帐户控制),IME 模式图标的默认大小为 20x20 像素。 UAC 上 IME 模式图标的 UI 缩放遵循 PPI。

IME 必须在应用容器中工作

某些 IME 函数在应用容器中受到影响。

  • 字典文件 - 通常,IME 具有只读字典文件,用于将用户输入映射到特定字符。 若要从应用容器内部访问这些文件,IME 必须将这些文件放置在 Program Files 或 Windows 目录下。 默认情况下,可以从应用容器读取这些目录,因此 IME 可以访问存储在这些位置的字典文件。 如果 IME 必须将字典文件存储在其他位置,则必须显式管理字典文件的 访问控制列表(ACL),以便允许应用容器进行访问。
  • Internet 更新 - 如果你的 IME 需要使用来自 Internet 的数据更新其字典,则它无法可靠地在应用容器内执行此作,因为 Internet 访问并不总是允许的。 相反,IME 应运行单独的桌面进程,该进程负责使用 Internet 中的数据更新字典文件。
  • 即时学习 - 如果 IME 在具有 Internet 访问权限的应用容器中运行,则 IME 可以与之通信的终结点没有限制。 在这种情况下,IME 可以使用云服务器提供实时学习服务。 某些输入法在用户键入时会即时下载并上传用户的输入内容。 由于在应用容器中不能保证 Internet 访问,因此可能始终不允许这样做。
  • 在进程之间共享信息 - IME 可能需要在不同应用容器中的应用之间共享有关用户输入首选项的数据。 使用 Web 服务在应用之间共享数据。

重要

如果尝试规避应用容器安全规则,则 IME 可能被视为恶意软件并被阻止。

IME 和触摸键盘

IME 必须确保其候选项窗格的用户界面和其他用户界面元素不会被触摸键盘覆盖。 触摸键盘的 z 轴顺序在所有应用程序之上显示,而 IME 用户界面在与其活跃的应用程序相同的 z 轴顺序中显示。 因此,触摸键盘可以重叠并隐藏 IME UI。 在大多数情况下,应用应调整其窗口的大小,以考虑触摸键盘。 如果应用大小不调整,IME 仍可使用 InputPane API 获取触摸键盘的位置。 IME 查询 Location 属性,或者为触摸键盘的“显示”和“隐藏”事件注册处理程序。 用户每次轻触编辑字段时都会引发“显示”事件,即使触摸键盘当前已显示。 IME 可以使用此 API 来获取触摸键盘在 IME 绘制候选(或其他)UI 之前占用的屏幕空间,并重新调整 IME UI 以便避免在触摸键盘下绘制。

指定首选触摸键盘布局

IME 可以指定要使用的触摸键盘布局,并且 IME 可用于触摸优化布局。 此功能仅限于朝鲜语、日语、简体中文和繁体中文输入语言的 IME。

触摸键盘支持七种布局,其中三种是经典布局,其中四种是触摸优化布局。 经典布局的外观和行为类似于物理键盘。

这三种经典布局都用于以不同形式输入繁体中文:

  • 基于拼音的输入
  • 仓颉输入
  • Dayi 输入

除了经典布局,每个朝鲜语、日语、简体中文和繁体中文输入语言都有一个触摸优化布局。

若要使用此功能,IME 必须实现 ITfFnGetPreferredTouchKeyboardLayout 接口,该接口由 IME 使用文本服务框架 ITfFunctionProvider API 导出。

如果 IME 不支持 ITfFnGetPreferredTouchKeyboardLayout 接口,则使用 IME 会导致触摸键盘显示的语言的默认经典布局。

如果你的 IME 需要将其中一个经典布局设置为首选布局,则除了支持 ITfFnGetPreferredTouchKeyboardLayout 和 ITfFunctionProvider 接口之外,IME 端不需要其他工作。 但是,IME 中需要执行其他工作才能使用触摸优化布局,下一部分对此进行介绍。

触摸优化布局

韩语、日语、简体中文和繁体中文输入语言的触摸优化键盘在 IME 开启和关闭模式下显示不同的布局。 触摸键盘上有一个键可将 IME 转换模式设置为“开”或“关”,但键盘的 IME 模式也可能随着编辑控件中的焦点更改而更改。

日语、简体中文和繁体中文输入语言的触摸优化键盘配有一个或多个按键,IME 使用这些按键来浏览候选页面。 对于日语和简体中文,候选页面键显示在触摸优化布局上。 对于繁体中文,上一个和下一个候选页面分别有独立的键。

按下这些键时,触摸键盘将 调用 SendInput 函数,将以下 Unicode 专用使用区域字符发送到重点应用程序,IME 可以截获并对其执行作:

  • 下一页(0xF003) - 当候选页面键按下日语和简体中文的触摸优化键盘上时发送,或者下一页键在传统中文的触摸优化键盘上按下时发送。
  • 上一页(0xF004) - 当候选页面键与日语和简体中文的触摸优化键盘上的 Shift 键同时按下时发送,或者在传统中文的触摸优化键盘上按下上一页键时发送。

这些字符作为 Unicode 输入发送。 下一段详细介绍了如何在文本服务框架 IME 将接收的关键事件接收器通知期间提取字符信息。 这些字符值未在任何头文件中定义,因此需要在代码中定义它们。

若要截获键盘输入,IME 必须注册为键事件接收器。 对于使用 SendInput 函数生成的 Unicode 输入, ITfKeyEventSink 回调(OnKeyDown 、OnKeyUp、OnTestKeyDown、OnTestKeyUp)的 WPARAM 参数始终包含虚拟密钥VK_PACKET,并且不直接标识字符。

实现以下调用序列以访问字符:

// Keyboard state
BYTE abKbdState[256];
if (!GetKeyboardState(abKbdState))
{
   return 0;
}

// Map virtual key to character code
WCHAR wch;
if (ToUnicode(VK_PACKET, 0, abKbdState, &wch, 1, 0) == 1)
{
   return wch;
}

IME 搜索集成

通过搜索协定为用户提供搜索功能,并与搜索窗格集成。

搜索窗格和 IME 建议
搜索窗格和 IME 建议

搜索窗格是用户跨所有应用执行搜索的中心位置。 对于 IME 用户,Windows 提供独特的搜索体验,使兼容的 IME 与 Windows 集成,以提高效率和可用性。

使用与搜索兼容的 IME 键入的用户将获得两个主要优势:

  • IME 与搜索体验之间的无缝交互。 IME 候选项直接显示在搜索框下,而不会遮挡搜索建议。 用户可以使用键盘在搜索框、IME 转换候选项和搜索建议之间无缝导航。
  • 更快地访问应用程序提供的相关结果和建议。 该应用有权访问所有当前转化候选对象,以提供更相关的建议。 为了更好地确定搜索建议的优先级,应用程序将按相关性顺序分配转换。 用户只需键入拼音即可找到并选择所需的结果,而无需转换。

如果 IME 符合以下条件,则 IME 与集成搜索体验兼容:

在搜索窗格中激活时,兼容的 IME 将置于 UIless 模式下,并且无法显示其 UI。 相反,它会将转换候选项发送到 Windows,后者在内联候选列表控件中显示它们,如上一屏幕截图所示。

此外,IME 发送用于运行当前搜索的候选词。 这些候选项可以与转换候选项相同,也可以为搜索量身定做。

良好的搜索候选项符合以下条件:

  • 无前缀重叠。 例如,“北京大学”和“北京”是冗余的,因为前者包含后者,构成了前缀关系。
  • 没有多余的候选项。 任何冗余候选项对搜索没有用,因为它没有助于筛选结果。 例如,与北京大学匹配的任何结果也与北京匹配。
  • 没有预测候选项,仅转换。 例如,如果用户键入“be”,则输入法可以返回“北”作为候选项,但不能返回“北京大学”。 通常,预测候选项过于限制。

不符合条件的 IME 无法像其他控件那样与搜索显示兼容,因此不能利用 UI 集成和搜索候选项。 应用仅在用户完成撰写后接收查询。

当支持搜索协定的应用收到查询时,查询事件将包含包含所有已知替代项的“queryTextAlternatives”数组,从最相关的(可能)到最不相关的(不太可能)。

提供替代项时,应用应将每个替代项视为查询,并返回与任何替代项匹配的所有结果。 应用的行为应与用户同时发出多个查询一样,实质上是向提供结果的服务发出“或”查询。 出于性能考虑,应用通常会将匹配限制为 5 到 20 个最相关的替代项。

UI 设计指南

所有 IME 都必须遵循 设计和代码 Windows 应用中所述的用户体验准则。

不要使用粘滞窗口

IME 窗口应仅在需要时显示,并且不应一直可见。 当用户不需要键入时,IME 窗口不应显示。 IME 窗口不应是全屏窗口。 IME 窗口不应相互重叠。 窗口应采用 Windows 样式设计,并遵循 UI 缩放。

IME 图标

有两种类型的 IME 图标,品牌图标和模式图标。 所有 IME 图标都必须仅使用黑白颜色进行设计。 新的 IME 图标借用系统托盘图标的字形外观。 此样式的创建旨在让所有语言都能使用它来增强整体统一风格的亲和感,同时又能相互区分出各自的特点。

IME 图标的文件格式为 ICO。 必须提供以下图标大小。

  • 16x16 像素
  • 20x20 像素
  • 24x24 像素
  • 32x32 像素
  • 40x40 像素
  • 48x48 像素

确保所有分辨率中都提供了具有 alpha 通道的 32 位图标。

IME 品牌图标是由一个白色框内的排版字形所定义,字形使用现代字体呈现。 每个语言团队都选择了自己的定义字形。 字形为黑色。 该框的外划为 1 像素,黑色为 50% 不透明度。 “新建”版本由框左上角的圆角定义。

IME 模式图标由现代字体中的白色字形定义,该字形具有 50% 不透明度的黑色 1 像素的外部描边。

图标 Description
繁体中文倉頡输入法的 IME 品牌图标示例。 传统中国更改界的 IME 品牌图标示例。
繁体中文新倉頡输入法品牌图标示例。 示例用于繁体中文仓颉输入法的 IME 品牌图标。
中文模式图标 示例 IME 模式图标。

拥有的窗口

若要显示候选 UI,IME 必须将窗口设置为子窗口,以便可以显示在当前运行的应用程序之上。 使用 ITfContextView::GetWnd 方法检索要拥有的窗口。 如果 GetWnd 返回错误或 NULLHWND,请调用 GetFocus 函数。

if (FAILED(pView->GetWnd(&parentWndHandle)) || (parentWndHandle == nullptr)) { parentWndHandle = GetFocus(); }

IME 候选窗口与光消除图面交互

弹出窗口的关闭方式称为“轻松关闭”,因为用户很容易关闭这种窗口。 若要使 IME 在 Windows 交互模型中正常运行,IME 窗口必须参与光消除模型。

若要参与轻型消除模型,IME 必须使用 NotifyWinEvent 函数或类似函数引发三个新的 Windows 事件。 这些新事件包括:

  • EVENT_OBJECT_IME_SHOW - 当 IME 变为可见时引发此事件。
  • EVENT_OBJECT_IME_HIDE - 隐藏 IME 时引发此事件。
  • EVENT_OBJECT_IME_CHANGE - 当 IME 移动或更改大小时触发此事件。

声明兼容性

IME 通过使用 ITfCategoryMgr::RegisterCategory 注册其 IME 的类别 GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT 来声明其兼容性。

将默认 IME 模式设置为“打开”

我们为 IME 提供更好的 UX。

桌面应用程序的 DPI 缩放支持

增强的 DPI 缩放支持允许查询每个桌面进程的声明的 DPI 感知级别,以确定它是否需要缩放 UI。 在多监视器方案中,Windows 针对每个监视器上的不同 DPI 设置相应地缩放 UI。

由于 IME 在每个应用程序进程的上下文中运行,因此不应为 IME 声明 DPI 感知级别。 这可确保 IME 在当前进程的 DPI 感知级别运行。

若要确保所有 IME UI 元素的缩放与运行进程的 UI 元素一致,必须适当调整以匹配不同的 DPI 值。

注释

为了确保与新的桌面应用程序保持一致性,您的 IME 应支持每个显示器的 DPI 感知,但不应自行声明感知级别。 系统确定每个方案中的相应缩放要求。

有关桌面应用程序的 DPI 缩放支持要求的详细信息,请参阅 高 DPI

IME 安装

如果使用 Microsoft Visual Studio 生成 IME,请使用第三方安装程序(如 Flexera Software 中的 InstallShield)为 IME 创建安装体验。

以下步骤演示如何使用 InstallShield 为 IME DLL 创建安装项目。

  • 安装 Visual Studio。
  • 启动 Visual Studio。
  • “文件 ”菜单上,指向“ 新建 ”并选择“ 项目”。 此时会打开 “新建项目 ”对话框。
  • 在左窗格中,导航到 “模板 > 其他项目类型 > 设置和部署”,单击“ 启用 InstallShield Limited Edition”,然后单击“ 确定”。 按照安装说明进行操作。
  • 重启 Visual Studio。
  • 打开 IME 解决方案(.sln)文件。
  • 在解决方案资源管理器中,右键单击解决方案,指向 “添加”,然后选择“ 新建项目”。 此时会打开“ 添加新项目 ”对话框。
  • 在左侧树视图控件中,导航到 “模板 > 其他项目类型 > InstallShield Limited Edition”。
  • 在中心窗口中,单击 InstallShield Limited Edition 项目
  • 在“ 名称 ”文本框中,键入“SetupIME”,然后单击“ 确定”。
  • “项目助手 ”对话框中,单击“ 应用程序信息”。
  • 请填写您的公司名称和其他信息。
  • 单击 “应用程序文件”。
  • 在左窗格中,右键单击 [INSTALLDIR] 文件夹,然后选择“ 新建文件夹”。 将文件夹命名为“Plugins”。
  • 单击“ 添加文件”。 导航到 IME DLL 并将其添加到 插件 文件夹。 对 IME 字典重复此步骤。
  • 右键单击 IME DLL 并选择 “属性”。 此时将打开“属性”对话框
  • “属性 ”对话框中,单击 “COM 和 .NET 设置 ”选项卡。
  • “注册类型”下,选择 “自我注册 ”,然后单击“ 确定”。
  • 生成解决方案。 IME DLL 已构建完成,InstallShield 创建了一个 setup.exe 文件,使用户能够在 Windows 上安装你的 IME。

若要创建自己的安装体验,请调用 ITfInputProcessorProfileMgr::RegisterProfile 方法,在安装过程中注册 IME。 不要直接写入注册表项。

如果在安装后必须立即使用 IME,请调用 InstallLayoutOrTip ,将 IME 添加到启用用户的输入法,并使用以下 psz 参数格式:

<LangID 1>:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

IME 辅助功能

实现以下约定,使您的 IME 符合辅助功能要求,并与讲述人一起工作。 若要使候选列表易于访问,IME 必须遵循此约定。

  • 候选列表的 UIA_AutomationIdPropertyId 必须等于转换候选项列表的“IME_Candidate_Window”或预测候选列表的“IME_Prediction_Window”。
  • 当候选列表出现和消失时,它会分别引发UIA_MenuOpenedEventIdUIA_MenuClosedEventId类型的事件。
  • 当当前所选候选项发生更改时,候选列表将引发 UIA_SelectionItem_ElementSelectedEventId。 所选元素的属性 UIA_SelectionItemIsSelectedPropertyId 等于 TRUE
  • 候选列表中的每个项目的 UIA_NamePropertyId 必须是候选项的名称。 (可选)可以通过 UIA_HelpTextPropertyId提供其他信息来消除候选人的歧义。