由于 TranslateMessage() 无条件返回非零,因此我如何判断是否发生了翻译?

and*_*abs 5 winapi input text-services-framework ime

这是《在 Windows 上处理自定义控件中的任意文本输入的正确、现代方法是什么?》的延续。WM_CHAR?注塑机?TSF?

\n\n

因此,在尝试了非 IME 布局(美国英语)、非 TSF IME(Windows XP DDK 中的日语 FAKEIME)和 TSF 文本服务(Windows 7 附带的任何内容)后,看来如果活动输入处理器配置文件不是 TSF 文本服务(即,它是TF_PROFILETYPE_KEYBOARDLAYOUT),我仍然需要处理击键和WM_CHAR消息来进行文本输入。

\n\n

我的问题是我的架构需要一种方式来告知它可以忽略当前的关键消息,因为它已转换为文本输入消息。它不关心这是发生在翻译之前还是之后;它只需要知道这样的翻译将会或已经发生。或者用伪代码术语来说:

\n\n
// if I can suppress WM_CHAR generation and synthesize it myself (including if the translation is just dead keys)\ncase WM_KEYDOWN:\ncase WM_SYSKEYDOWN:\n    if (WillTranslateMessage())\n        InsertChar(GenerateEquivalentChar());\n    else\n        HandleRawKeyEvent();\n    break;\n\n// if I can know if a WM_CHAR was generated (or will be generated; for instance, in the case of dead keys)\ncase WM_KEYDOWN:\ncase WM_SYSKEYDOWN:\n    if (!DidTranslateMessage())\n        HandleRawKeyEvent();\n    break;\ncase WM_CHAR:\ncase WM_SYSCHAR:\n    InsertChar(wParam);\n    break;\n
Run Code Online (Sandbox Code Playgroud)\n\n

处理文本输入(无论是通过键盘还是通过非 TSF IME)的标准方法是让“ -to-”TranslateMessage()进行翻译。然而,有一个问题:MSDN 说WM_KEYDOWNWM_CHAR

\n\n
\n

如果消息是 WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN 或 WM_SYSKEYUP,则无论转换如何,返回值都是非零。

\n
\n\n

这意味着我无法用它来确定是否发生了翻译。

\n\n

在阅读了一些 Michael Kaplan 博客文章后,我想我可以使用ToUnicode()orToUnicodeEx()自己进行转换,从 传递状态数组GetKeyboardState()wine 源代码似乎同意,但它有两种特殊情况,我不确定它们是特定于 wine 的还是也需要在真实的 Windows 上完成:

\n\n
    \n
  • VK_PACKET\xe2\x80\x94WM_CHAR直接从消息中生成一个LPARAM
  • \n
  • VK_PROCESS\xe2\x80\x94 调用一个函数ImmTranslateMessage(),该函数似乎是特定于 wine 的函数或未记录的 imm32.dll 函数;我分不清哪个是真的
  • \n
\n\n

WM_KEYUP酒也与和无关WM_SYSKEYUP;再说一次,我不知道这是否只适用于葡萄酒。

\n\n

但我是否需要在使用 TSF 的程序中担心这些情况?如果我这样做,“官方”的方式是什么?即便如此,我会在WM_KEYUP/上做什么WM_SYSKEYUPToUnicode()我也需要将它们发送给吗?WM_KEYUP如果有的话,我是否需要特别在窗户中捕捉s WM_CHAR

\n\n

或者我是否遗漏了任何 MSDN TSF 示例中都没有的东西,而这些示例将允许我让 TSF 来处理处理器TF_PROFILETYPE_KEYBOARDLAYOUT?我以为 TSF 做了透明的 IME 直通,但我对 FAKEIME 样本的实验表明情况并非如此......?我看到 Firefox 和 Chromium 也会检查TF_PROFILETYPE_KEYBOARDLAYOUT甚至使用ImmGetIMEFileName()来查看键盘布局是否受 IME 支持,但我不知道在这些情况下它们是否真的会自己处理输入......

\n\n

我现在的最低版本是Windows 7。

\n\n

谢谢。

\n\n

更新这个问题的原始版本包括需要了解相关的WM_KEYUP;在第二次查看我在其他平台上的等效代码时,这毕竟是不必要的,除了TranslateMessage();的详细信息之外。我已相应地调整了问题。(在 OS X 上,您甚至不向文本输入系统提供按键释放事件;在 GTK+ 上,您这样做,但插入字符的按键似乎不会影响释放,因此它们无论如何也不会得到处理,至少对于我尝试过的输入法(可能有一些可以...)。)话虽这么说,如果我错过了某些内容,我会添加另一个子问题。

\n

Eri*_*own 2

一般来说,尝试复制 Windows 内部并不是一个好主意。\xc2\xa0 繁琐、容易出错,\xc2\xa0 和\xc2\xa0 可能会\xc2\xa0 更改,恕不另行通知。

\n\n

我具有源访问权限的编辑控件\xc2\xa0,可以在 WM_KEYDOWN 处理程序\xc2\xa0 中选取箭头键(和其他特定键),并将其他所有内容传递给默认处理程序,这将(最终)生成 WM_CHAR 或\xc2\ xa0TSF 输入调用(如果您的控件支持 TSF,它应该支持)。

\n\n

在不涉及 TSF 处理程序的情况下,您仍然需要 WM_CHAR。但是,您始终可以让 WM_CHAR 处理程序调用 ITextStoreACP::InsertTextAtSelection 方法。

\n