winapi – 在Windows上自定义控件中处理任意文本输入的正确,现代方法是什么? WM_CHAR? IMM? TSF?

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

对于它的价值,在OS X上我会使用NSTextInputClient而在GTK上我会使用GtkIMContext.我正在谈论的就是这些.

显而易见的选择是使用WM_CHAR,如果我正确地收集它,如果窗口类已经注册了RegisterClassW(),则本机为UTF-16,因此无论位置如何都应该“正常工作”.但是,WM_CHAR由TranslateMessage()生成,而its documentation表示无法确定是否已生成WM_CHAR,因为TranslateMessage()始终返回非零值.我需要能够确定当前的键盘消息是否将由文本系统处理(因此应该被忽略);这尤其正确,因为所有非文本键都需要以与布局无关的方式处理(我已经拥有).

我还在Windows 7示例中看到了IMM API和Text Services Framework的代码.我不确定一个人是否比另一个好,他们似乎都做同样的事情.他们呢?

在IMM的情况下,有一些WM_IMM_xxx消息,我不确定我是否应该忽略,并且我发现的每个引用似乎都不同意我是否应该在Unicode窗口中处理它们…此外,上述知道IMM是否处理某个关键事件的问题仍然存在;有办法吗?

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

还是我完全走错了路?

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

我用的其他参考文献:

> http://www.catch22.net/tuts/unicode-text-editing

谢谢.

更新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中写回的文章.

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

点赞