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

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

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

默认 IME

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

Preferred language setting

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

Preferred language keyboard

重要

建议不要直接写入注册表来设置自定义 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,请确保 DLL(由 TSF 加载)检查其要加载到的应用类型。 在 IME 中调用 ITfThreadMgrEx::GetActiveFlags 方法并检查 TF_TMF_IMMERSIVEMODE 标志,以便 IME 根据结果触发不同的应用程序逻辑。

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

注意

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

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 可以使用云服务器提供即时学习服务。 某些 IME 会在用户键入时即时下载和上传用户输入。 由于应用容器不保证具有 Internet 访问权限,因此可能并不总是允许这样做。
  • 在进程之间共享信息 - IES 可能需要在不同应用容器中的应用之间共享有关用户输入首选项的数据。 使用 Web 服务在应用之间共享数据。

重要

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

IME 和触摸键盘

IME 必须确保其候选窗格的 UI 和其他 UI 元素不会绘制在触摸键盘之下。 触摸键盘显示在高于所有应用的 Z 顺序带区中,且 IME UI 显示在与可使用此 IME UI 的应用相同的 Z 顺序带区中。 这样,触摸键盘便可以重叠并隐藏 IME UI。 在大多数情况下,应用应根据触摸键盘来调整其窗口大小。 如果应用不调整大小,IME 仍可以使用 InputPane API 获取触摸键盘的位置。 IME 查询 Location 属性,或注册处理程序来处理触摸键盘的 Show 和 Hide 事件。 用户每次点击编辑字段时,即使当前已显示触摸键盘,仍会引发 Show 事件。 IME 绘制候选 UI 或其他 UI 之前,可以使用此 API 获取触摸键盘使用的屏幕空间,并重新排列 IME UI 以避免其绘制在触摸键盘之下。

指定首选触摸键盘布局

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

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

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

  • 注音输入
  • 仓颉输入
  • 大易输入

除了经典布局之外,还为朝鲜语、日语、简体中文和繁体中文输入语言各提供一个触控优化布局。

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

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

如果 IME 需要将其中一个经典布局设置为首选布局,IME 只需支持 ITfFnGetPreferredTouchKeyboardLayout 和 ITfFunctionProvider 接口即可,无需执行任何其他操作。 但是,如果 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 搜索集成

通过搜索合约和搜索窗格集成,为用户提供搜索功能。

Search pane and IME suggestions
搜索窗格和 IME 建议

搜索窗格是用户在其所有应用中执行搜索的中心位置。 Windows 为 IME 用户提供了独特的搜索体验,将可兼容的 IME 与 Windows 集成,从而提高搜索效率和可用性。

用户使用与搜索功能兼容的 IME 来键入内容时,有两个主要优势:

  • 实现 IME 与搜索体验之间的无缝交互。 IME 候选项会在搜索框下内联显示,不会遮挡搜索建议。 用户可以使用键盘在搜索框、IME 转换候选项和搜索建议之间无缝导航。
  • 更快地访问应用程序提供的相关结果和建议。 应用有权访问所有当前的转换候选项,以提供更多相关建议。 为了更好地确定搜索建议的优先顺序,按相关性顺序向应用程序提供转换。 用户只需键入拼音而无需转换,即可查找并选择他们想要的结果。

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

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

此外,IME 还会发送应该用于运行当前搜索的候选项。 这些候选项可以与转换候选项相同,也可以针对搜索进行定制。

优质搜索候选项符合以下条件:

  • 无前缀重叠。 例如,“北京”对于“北京大学”是多余的,因为其中一个是另一个的前缀。
  • 无多余候选项。 任何多余的候选项对于搜索都是无用的,因为它不能帮助筛选结果。 例如,任何与“北京大学”匹配的结果也会与“北京”匹配。
  • 无预测候选项(只能转换)。 例如,如果用户键入“be”,IME 能返回候选项“北”,但不能返回“北京大学”。 通常,预测候选项太具有限制性。

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

当支持搜索合约的应用收到查询时,该查询事件包含一个 “queryTextAlternatives”数组,它包含所有已知的备选项,这些备选项从最相关(可能)到最不相关(不可能)依次排列。

提供备选项后,应用程序应会将每个备选项视为一个查询,并返回与每个备选项匹配的所有结果。 应用的行为应如同用户同时发出了多个查询,本质上是向提供结果的服务发出“or”查询。 出于性能方面的考虑,应用通常会将最相关备选项的匹配结果限制在 5 到 20 个之间。

UI 设计指南

所有 IME 都必须遵循设计 Windows 应用并为其编写代码中所述的用户体验指南。

请勿使用粘滞窗口

IME 窗口应仅在需要时显示,不应始终可见。 当用户不需要键入时,IME 窗口不应显示。 IME 窗口不应为全屏窗口。 IME 窗口不应相互重叠。 窗口应采用 Windows 样式进行设计,并遵循 UI 缩放比例。

IME 图标

IME 图标有两种类型:品牌图标和模式图标。 所有 IME 图标只能采用黑白两色进行设计。 新的 IME 图标借用了系统托盘图标的 Glyphic 外观。 此样式已创建,所有语言都可以使用它来完善相似的外观,同时也能彼此区分。

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

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

确保所有分辨率都提供带 Alpha 通道的 32 位图标。

IME 品牌图标通过一个白色框及其中放置的一个以现代字样呈现的印刷字形来定义。 每个语言团队选择一种定义字形。 字形为黑色。 框的外边框为 1 像素大小,黑色且不透明度为 50%。 “新”版本由框左上角的圆角定义。

IME 模式图标通过一个采用现代字样的白色印刷字形及大小为 1 像素、不透明度为 50% 的黑色外边框来定义。

图标 说明
Example IME brand icon for Traditional Chinese ChangeJie. 繁体中文仓颉 IME 品牌图标示例。
Example IME brand icon for Traditional Chinese New ChangeJie. 繁体中文仓颉 IME 品牌图标示例。
Chinese mode icon 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 注册 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。
  • 在“文件”菜单上,指向“新建”,然后选择“项目”。 此时会打开“新建项目”对话框。
  • 在左窗格中,导航到“其他Project类型>设置和部署的模板>”,单击“启用 InstallShield Limited Edition”,然后单击“确定”。 按照安装说明进行操作。
  • 重启 Visual Studio。
  • 打开 IME 解决方案 (.sln) 文件。
  • 在“解决方案资源管理器”中,右键打击此解决方案,指向“添加”,然后选择“新建项目”。 此时会打开“添加新项目”对话框。
  • 在左侧树视图控件中,导航到“其他Project类型 > InstallShield Limited Edition 的模板>”。
  • 在中间窗口中,单击“InstallShield limited Edition 项目”。
  • 在“名称”文本框中,键入“SetupIME”,然后单击“确定”。
  • 在“项目助手”对话框中,单击“应用程序信息”。
  • 填写公司名称和其他字段。
  • 单击“应用程序文件”。
  • 在左侧窗格中,右键单击“[INSTALLDIR]”文件夹,然后选择“新建文件夹”。 将文件夹命名为“Plugins”。
  • 单击“添加文件”。 导航到 IME DLL,并将其添加到“Plugins”文件夹。 对 IME 字典重复此步骤。
  • 右键单击 IME DLL 并选择“属性”。 此时将打开“属性”对话框。
  • 在“属性”对话框中,单击 COM & .NET 设置选项卡。
  • 在“注册类型”下,选择“自动注册”,然后单击“确定”。
  • 生成解决方案。 IME DLL 已生成,InstallShield 创建了一个 setup.exe 文件,便于用户在 Windows 上安装 IME。

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

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

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

IME 可访问性

实现以下约定,使 IME 符合可访问性要求,并使用“讲述人”。 若要使候选项列表可访问,IME 必须遵循此约定。

  • 候选项列表的 UIA_AutomationIdPropertyId 必须为“IME_Candidate_Window”(转换候选项列表)或“IME_Prediction_Window”(预测候选项列表)。
  • 当候选项列表显示和消失时,它将分别引发 UIA_MenuOpenedEventId 和 UIA_MenuClosedEventId 类型的事件。
  • 当当前所选的候选项发生更改时,候选项列表将引发 UIA_SelectionItem_ElementSelectedEventId。 所选元素的 UIA_SelectionItemIsSelectedPropertyId 属性应为 TRUE。
  • 候选项列表中每个项的 UIA_NamePropertyId 必须是候选项的名称。 (可选)可以通过 UIA_HelpTextPropertyId 提供其他信息,以区分候选项。