使用输入面板自动完成

在 Windows Vista 中,平板电脑输入面板集成了新的自动完成功能,使应用程序的自动完成列表能够在输入面板中识别用户的墨迹时实时更新。 此外,应用程序的自动完成列表定位在输入面板用户的方便位置。 如果没有输入面板自动完成,将自动完成功能与输入面板一起使用是一个困难的过程,要求用户一次插入一个字符并移动输入面板,以便访问自动完成建议。 通过集成,自动完成是一个功能强大的工具,适用于平板电脑用户,可加快并增加使用输入面板输入文本的便利性。

包含 ie 自动完成列表的输入面板

有三个选项可用于应用程序如何利用输入面板自动完成集成。 包含使用 Shell 自动完成功能生成的应用程序 (通过 IAutoComplete 接口) 或.NET Framework自动完成 (通过 AutoCompleteMode 枚举) 接收输入面板自动完成集成,而无需更改代码。 包含自定义自动完成文本字段的应用程序可以使用输入面板自动完成 API 来获取相同的功能。

在所有情况下,都可以对应用程序的自动完成列表进行这些修改,而无需复制或修改应用程序用于生成自动完成列表的 UI 或预测逻辑。 自动完成列表仍然是应用程序绘制的所有者,并且自动完成列表的内容与直接在编辑字段中键入文本的内容相同。

Windows Vista 操作系统或更高版本支持输入面板自动完成集成。 输入面板自动完成集成内置于从 Windows Vista 开始的 Shell 自动完成和从 .NET Framework 版本 3.0 开始的Windows 窗体开发中。 虽然 IAutoCompleteAutoCompleteMode 都在早期版本的 Windows 上运行,但 Microsoft Windows XP 平板电脑版或早期操作系统不支持输入面板自动完成集成。 如果在早期版本的 Tablet PC 上运行输入面板自动完成,应用程序还原预集成行为。

将应用程序自动完成列表与输入面板集成的原因

应用程序的“自动完成”列表的集成为将文本输入到包含“自动完成”功能的文本字段中的用户提供了最大的轻松和快速的输入。 此外,包含输入面板自动完成集成的应用程序会立即出现,就好像它是在开发时考虑到了平板电脑,使应用程序对平板电脑用户更具吸引力。

输入面板和自动完成列表如何在不集成的情况下交互

使用输入面板将文本输入到包含自动完成列表但未与输入面板集成的文本字段中:

  1. 用户将焦点放在文本字段中,并打开输入面板。
  2. 用户写入一两个字符。
  3. 用户点击“ 插入”。 输入面板将文本输入到应用程序的文本字段中。 此时将显示应用程序的“自动完成”列表,并且很可能部分或完全被输入面板遮盖。
  4. 用户拖动输入面板以发现应用程序的自动完成列表。
  5. 假设“自动完成”列表中包含正确的条目,则用户现在可以选择该条目;否则,用户必须重复步骤 2 和 3。

这显然是一个繁琐的过程。 用户对自动完成列表应如何工作的期望被破折,并且他们执行任务的能力会受到影响。

输入面板和自动完成列表交互如何通过集成改进

使用输入面板将文本输入到包含与输入面板集成的自动完成列表的文本字段中:

  1. 用户将焦点放在文本字段中,并打开输入面板。
  2. 用户写入一两个字符。 当用户写入文本时,应用程序的自动完成列表将直接显示在输入面板的上方或正下方。
  3. 用户从“自动完成”列表中选择条目;条目直接插入到应用程序的文本字段中,或者用户重复步骤 2,直到出现正确的条目。

由于集成,当用户在输入面板中书写时,自动完成列表会显示并更新。 此外,列表的位置是这样既方便用户在写入时访问,又不会被输入面板遮盖。 最后,当用户从自动完成列表中选择某个项时,该项将直接插入到应用程序的文本输入字段中,从而使用户能够绕过从输入面板插入文本的步骤。

包含 Outlook Express 自动完成列表的输入面板

包含输入面板自动完成集成的标准自动完成组件

IAutoCompleteAutoCompleteMode 都包含输入面板自动完成的内置集成。 使用这些标准自动完成组件之一的应用程序可以利用输入面板自动完成功能,几乎不需要额外的工作。 此外,虽然输入面板自动完成仅在 Windows Vista 或 Windows 操作系统的新版本上受支持,但使用 Windows Vista 发布之前使用 IAutoComplete 生成的应用程序会在 Windows Vista 上运行时自动获得输入面板自动完成集成。 以下部分包含有关包含输入面板自动完成集成的特定 IAutoComplete 和 AutoCompleteMode 元素的详细信息。

使用输入面板自动完成集成的 Shell 自动完成

使用 IAutoComplete 的应用程序可以免费获得输入面板自动完成集成。 虽然 Shell 自动完成 API 包含在 Windows 2000 及更高版本中,但输入面板自动完成集成仅在 Windows Vista 和更高版本上受支持。 但是,在 Windows Vista 发布之前生成的使用 IAutoComplete 的应用程序在 Windows Vista 上运行时会自动获得输入面板自动完成集成。

若要以这种方式利用 Tablet 自动完成,必须使用自动完成对象 (CLSID_Autocomplete) 。 如果要为 URL 或文件名提供自动完成功能,请使用 SHAutoComplete 函数创建自动完成对象。

除了 IAutoComplete 之外,还可以直接实现 IAutoComplete2IAutoCompleteDropDown,并且仍可自动获取输入面板自动完成集成。

输入面板自动完成与 .NET Framework 应用程序的集成

从 .NET Framework 3.0 开始,Windows 窗体文本框包括“自动完成”。 Windows 窗体文本框“自动完成”是在 Shell 自动完成的基础上构建的,这意味着输入面板自动完成集成也是内置的。 .NET Framework 3.0 在 Windows Vista 之前发布的 Windows 版本上支持较低级别。 但是,由于输入面板自动完成集成仅在 Windows Vista 或更高版本上受支持,因此输入面板自动完成集成仅适用于在 Windows Vista 或更高版本上安装的 .NET Framework 3.0 应用程序中。

希望在 .NET Framework 3.0 中利用输入面板自动完成集成的应用程序必须使用启用了 AutoCompleteMode 属性的 Windows 窗体 TextBox。 除了Windows 窗体自动完成工作之外,无需执行任何其他工作即可利用输入面板自动完成集成。

直接使用输入面板自动完成 API

自定义“自动完成”文本框的开发人员需要直接使用输入面板自动完成 API,以获得输入面板自动完成集成在其应用程序中实现的改进的文本输入体验。 输入面板自动完成 API 作为 Windows Vista 操作系统的一部分包含在平板电脑平台 SDK 1.9 或更高版本中。 输入面板自动完成接口是基于 COM 的接口。

以下部分详细介绍了如何为 C++ 应用程序使用这些接口。 但是,通过使用 COM 互操作,可以在大多数语言(包括 C#)中实现这些 COM 接口。

为了在自定义“自动完成”文本框中实现输入面板自动完成集成,需要两个接口: ITipAutocompleteProvider 接口ITipAutocompleteClient 接口。 这些接口的定义位于 TipAutoComplete.h 和 TipAutoComplete_i.c。

首先,应用程序必须定义并实例化自动完成提供程序类,该类为包含自动完成列表的每个文本输入字段实现 ITipAutocompleteProvider 。 此类管理自动完成集成的应用程序端。 来自输入面板的所有自动完成请求都是通过应用程序的自动完成提供程序从自动完成客户端向应用程序发出的。 应用程序的自动完成提供程序必须同时有权访问应用程序的“自动完成”列表的 HWND 和关联的文本输入字段的 HWIND。 此外,必须实现 ITipAutocompleteProvider 的以下方法:

  • ITipAutocompleteProvider::UpdatePendingText 方法:自动完成客户端使用此方法通知应用程序用户已写入输入面板的文本。 收到此通知后,提供程序负责生成自动完成列表,就像文本已键入到应用程序的文本输入字段中一样。 通过 ITipAutocompleteProvider::UpdatePendingText 方法 传递给自动完成提供程序的字符串仅包含输入面板中当前的文本。 因此,如果文本输入字段中有其他文本,提供商有责任将其正确追加到客户端发送的文本。 ITipAutocompleteProvider::UpdatePendingText 方法传递的字符串应被视为字段中当前所选内容的替代项。 如果没有当前选定内容,则应将其放置在当前插入点的位置。 生成自动完成列表后,提供程序应调用传入 TRUEITipAutocompleteProvider::Show 方法以显示自动完成列表。 应用程序不应缓存对 UpdatePendingText 的 调用,而应将每次对 UpdatePendingText 的附加调用视为取消上一次调用,以避免闪烁过时的自动完成列表 UI。以下示例代码演示了这些做法。

    HRESULT SampleProvider::UpdatePendingText(BSTR bstrPendingText)
    {
       //Discard previously cached pending text from Input Panel
       m_bstrPending.Empty();
        //Store the new pending text from Input Panel as m_bstrPending
    m_bstrPending = bstrPendingText;
    
        //Get the text from the field in two chunks. The characters to
    //the left of the selection and the characters to the right.
    CComBSTR bstrLeftContext = //Text to the left of the selection
            CComBSTR bstrRightContext = //Text to the right of the selection
    
    //Discard previously cached complete text
        m_bstrCompleteText.Empty();
        //Append to the field text from the left of the selection
        //the text from Input Panel and then append to that
        //the field text to the right of the selection
        m_bstrCompleteText.Append(bstrLeftContext);
        m_bstrCompleteText.Append(m_bstrPending);
        m_bstrCompleteText.Append(bstrRigtContext);
    
        //Update the app's AC list based on m_bstrCompleteText
        //...
    
        //Show the updated AC list by calling the provider's Show method
       Show(true);
       return S_OK;
    }
    
  • ITipAutocompleteProvider::Show 方法:此方法从 UpdatePendingText 调用,但也可以随时由自动完成客户端调用。 收到此调用后,自动完成提供程序必须隐藏或显示由 参数指示的自动完成提供程序。 在显示自动完成列表之前,自动完成提供程序应咨询自动完成客户端,了解自动完成列表的位置。 有关定位自动完成列表的详细信息,请参阅本文后面部分。

接下来,应用程序应使用活动模板库 (ATL) CoCreateInstance 函数生成 ITipAutocompleteClient 接口 的实例,并将类 id CLSID_TipAutoCompleteClient 作为进程内服务器,然后将提供程序注册到客户端。 自动完成客户端 ITipAutocompleteClient::AdviseProvider 方法 向客户端注册提供程序,使客户端能够调用应用程序的自动完成提供程序对象。 如果系统上不存在tiptsf.dll, CoCreateInstance 函数将失败并返回 REGDB_E_CLASSNOTREG。 此时,应用程序可以放弃其 ITipAutocompleteProvider 对象,并像输入面板不存在一样继续,因为它不在此类系统上。

应用程序可以选择创建 ITipAutocompleteClient 的一个实例或每个文本字段的一个实例。 第一个选项要求在每次更改焦点时注销并注册提供程序。 有关取消注册自动完成提供程序的详细信息,请参阅本主题后面部分。

定位自动完成列表涉及几个步骤,必须在自动完成提供程序 (应用程序) 和自动完成客户端 (输入面板) 之间进行协调。 在显示自动完成列表之前,无论是由于调用自动完成提供程序的 Show 方法,还是由于用户使用键盘输入文本,提供程序都需要咨询客户端自动完成列表的位置。 提供程序应执行以下步骤:

  • 使用自动完成客户端的 ITipAutocompleteClient::RequestShowUI 方法 确定输入面板是否已准备好显示自动完成列表。 RequestShowUI 采用 HWND 参数,该参数是“自动完成列表”窗口的 HWND,该方法返回 TRUEFALSE 以指示它是否为可显示自动完成列表的状态。 如果客户端返回 FALSE,则提供程序不应尝试显示自动完成列表。

  • 调用 RequestShowUI 以在调用 ITipAutocompleteClient::P referredRects 方法之前设置弹出式自动完成列表窗口句柄。 否则,调用 PreferredRects 时将导致E_INVALIDARG错误。

  • 如果 RequestShowUI 返回 TRUE,提供程序应根据文本输入字段的位置计算自动完成列表的默认屏幕坐标矩形,然后调用自动完成客户端的 ITipAutocompleteClient::P referredRects 方法。 这允许自动完成客户端调整矩形,以避免自动完成列表与输入面板重叠。 PreferredRects 方法采用四个参数:

    • RECT rcACList:自动完成列表的默认屏幕坐标矩形。
    • RECT rcField:相应文本输入字段的屏幕坐标矩形。
    • RECT *prcModifiedACList:自动完成的调整后的屏幕坐标矩形
    • BOOL *pfShowAbove:此参数向提供程序指示 prcModifiedACList 矩形是将自动完成列表置于输入面板上方还是下方。 应用程序可以使用此信息来正确绘制 UI 元素,例如调整手柄大小和滚动条。 提供程序最初应按照 rcACList 相对于文本输入字段定位自动完成列表的方向传递。 如果客户端将 prcModifiedACList 设置为等于 rcACList,则不会更改 pfShowAbove

    使用 prcModifiedACListpfShowAbove out 参数的返回值来定位和显示“自动完成列表”窗口。 如果未使用输入面板, RequestShowUI 始终返回 TRUE且 prcModifiedACList 始终与 rcACList 相同。 pfShowAbove 也保持不变,结果是调用对应用程序行为没有影响。 以下示例代码演示了这些做法。

HRESULT SampleProvider::Show(BOOL fShow)
{
    //Ask the AC client if it is OK to show the Autocomplete list.
    BOOL fAllowShowing = FALSE;
    m_spACClient->RequestShowUI(m_hWndList, &fAllowShowing);

    if (fShow && fAllowingShowing)
        {
            // Create the parameters required to call PreferredRects
            RECT rcField = //Rectangle for app's text field
            RECT rcACList = //Default rectangle for app's AC list
            RECT rcModifiedACList = {0, 0, 0, 0};
            BOOL fShowAbove = TRUE;

//Ask the AC client to modify the position of the AC list
m_spACClient->PreferredRects(&rcACList, &rcField,
&rcModifiedACList, &fShowAbove);

            //Show the Autocomplete UI at the modified preferred rectangle
            //from rcModifiedACList and the directional info provide by
//fShowAbove
            //...
        }
    else
        {
        //Hide the Autocomplete list and clean up
        //...
        }
    return S_OK;
}

当用户选择“自动完成”列表中的项时,除了将所选项文本插入文本输入字段外,提供程序还需要调用客户端的 ITipAutocompleteClient::UserSelection 方法 。 输入面板使用此通知放弃尚未从输入面板插入的所有剩余文本。

最后,当不再需要提供程序时,应通过调用自动完成客户端的 ITipAutocompleteClient::UnadviseProvider 方法 取消与自动完成客户端的链接以取消注册提供程序。 由于以下两个原因之一,可能需要取消注册提供程序:因为与提供程序关联的文本输入字段已被销毁,或者应用程序选择仅创建一个自动完成客户端,而不是每个文本输入字段一个。 在这种情况下,每次焦点从文本字段切换时,都必须取消注册提供程序。

结论

输入面板自动完成集成是一个功能强大的工具,用于改进 Windows 应用程序中的用户体验,包括平板电脑上的自动完成列表。 如果不集成,输入面板用户需要经历一次插入一个字符的文本并重新定位输入面板以使用自动完成的繁琐过程。 通过集成,当用户在输入面板中墨迹书写时,自动完成列表将显示在一个方便的位置,从而提高文本输入的速度和便利性。 在包含基于 Shell 自动完成或.NET Framework 3.0 自动完成构建的自动完成功能的应用程序中,输入面板自动完成集成是一项免费且引人注目的功能。 此外,还提供了一组基于 COM 的简单接口,以便为选择使用自定义自动完成控件的应用程序提供相同的集成体验。

文本输入面板参考