在 Windows 的自定义控件中处理任意文本输入的正确、现代的方法是什么? WM_CHAR?国际管理公司?交易会?

What is the correct, modern way to handle arbitrary text input in a custom control on Windows? WM_CHAR? IMM? TSF?

我希望能够在自定义 Windows 控件中支持文本输入,就像 EDIT 和 rich edit 控件已经做的那样,但不支持其中任何一个的子class。该控件当前使用 Direct2D 和 DirectWrite 绘制文本,并在 Windows Vista SP1 平台更新或更高版本上运行(如果我决定需要更新,我可能会将其更改为 Windows 7 SP1 平台更新或更新版本Direct2D 和 DirectWrite 功能,假设这些功能在那里或仅在 Windows 8 上可用,但这是一个不同的问题...)

对于它的价值,在 OS X 上我会使用 NSTextInputClient and on GTK+ I would use GtkIMContext。我说的就是这些。

显而易见的选择是使用 WM_CHAR,如果 window class 在 RegisterClassW() 中注册,如果我收集正确,它本身就是 UTF-16,并且因此,无论位置如何,都应该 "just work"。但是,WM_CHAR是由TranslateMessage()生成的,而its documentation表示无法确定是否已生成WM_CHAR,因为TranslateMessage()总是returns 非零。我需要能够确定当前键盘消息是否将由文本系统处理(因此应该被忽略);尤其如此,因为所有非文本键都需要以独立于布局的方式处理(我已经有了)。

我还在 Windows 中看到了 IMM API 和文本服务框架的 7 个示例代码。我不确定一个是否比另一个更好,而且他们似乎都在做同样的事情。是吗?

就 IMM 而言,有许多 WM_IMM_xxx 消息我不确定是否应该忽略,而且我发现的每个参考资料似乎都不同意我是否应该忽略是否应该以 Unicode window 来处理它们...此外,上述知道 IMM 是否处理给定按键事件的问题仍然悬而未决;有办法吗?

TSF 有一个叫做 ACP 的概念,它似乎允许我使用任何我想要的文本存储格式来存储我实际要使用的文本(也就是说,不是正在进行的合成)。这是真的?我希望能够将我的文本存储为带有属性的 UTF-8,在绘图时转换为 UTF-16(用于 DirectWrite)。其他 API 选项也让我这样做吗?

还是我完全走错了路?

一旦我完成所有这些,我将如何opt into the on-screen keyboard

我使用的其他参考资料:

谢谢。

更新 2016 年 11 月 7 日
再次查看 TsfPad 示例后,我注意到它似乎也只使用 WM_CHAR;现在我不确定它是如何使用 TSF 的,除此之外……

TSF API 是 IMM API 的超集。它也比 IMM 更新,并且是当前处理国际文本输入(以及其他输入机制,如手写和语音)的现代方式。

如果您使用 TSF API,文本将通过 API 而不是 windows 消息显示(因此哪个消息的问题无关紧要)。

屏幕键盘是自动处理的,您不必担心。 (TSF 的全部目的是让您的应用独立于输入源。)

TSF 可以支持UTF-8,但是有点蛋疼;您需要将扩展​​字符标记为隐藏。使用 UTF-16 会更好,这是 TSF 的默认设置 API。

我所知道的关于如何向现有编辑控件添加 TSF 支持的最佳示例仍然是我在 July 2007 中写回的文章。

输入 can 仍然通过 WM_CHAR 到达(例如,如果当前输入配置文件是键盘布局),因此您也需要实现它;不过,通常情况下,您可以通过调用 ITextStoreACP::InsertTextAtSelection 实现来处理 WM_CHAR 消息。