由于TranslateMessage()无条件返回非零值,因此,在事实发生之前或之后,我如何得知发生了翻译? [英] Since TranslateMessage() returns nonzero unconditionally, how can I tell, either before or after the fact, that a translation has occurred?

查看:127
本文介绍了由于TranslateMessage()无条件返回非零值,因此,在事实发生之前或之后,我如何得知发生了翻译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是因此,在尝试使用非IME布局(美国英语),非TSF IME(来自Windows XP DDK的日语FAKEIME)和TSF文本服务(Windows 7附带的任何功能)之后,如果活动的输入处理器概要文件不是TSF文本服务(即它是TF_PROFILETYPE_KEYBOARDLAYOUT),我仍然必须处理击键和WM_CHAR消息以进行文本输入.

So after experimenting with a non-IME layout (US English), a non-TSF IME (the Japanese FAKEIME from the Windows XP DDK), and a TSF text service (anything that comes with Windows 7), it appears that if the active input processor profile is not a TSF text service (that is, it is a TF_PROFILETYPE_KEYBOARDLAYOUT), I'll still have to handle keystrokes and WM_CHAR messages to do text input.

我的问题是我的体系结构需要一种方法来告知它可以忽略当前的关键消息,因为它已被翻译为文本输入消息.无关紧要是在翻译之前还是之后发生;它只需要知道这样的翻译将会或已经发生.或以伪代码形式:

My problem is that my architecture needs a way to be told that it can ignore the current key message because it was translated into a text input message. It does not care whether this happens before or after the translation; it just needs to know that such a translation will or has happened. Or in pseudocode terms:

// if I can suppress WM_CHAR generation and synthesize it myself (including if the translation is just dead keys)
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
    if (WillTranslateMessage())
        InsertChar(GenerateEquivalentChar());
    else
        HandleRawKeyEvent();
    break;

// if I can know if a WM_CHAR was generated (or will be generated; for instance, in the case of dead keys)
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
    if (!DidTranslateMessage())
        HandleRawKeyEvent();
    break;
case WM_CHAR:
case WM_SYSCHAR:
    InsertChar(wParam);
    break;

从键盘或通过非TSF IME处理文本输入的标准方法是让TranslateMessage()进行WM_KEYDOWNWM_CHAR的翻译.但是,有一个问题:MSDN说

The standard way of handling text input, either from a keyboard or through a non-TSF IME, is to let TranslateMessage() do the WM_KEYDOWN-to-WM_CHAR translation. However, there's a problem: MSDN says

如果消息是WM_KEYDOWN,WM_KEYUP,WM_SYSKEYDOWN或WM_SYSKEYUP,则返回值将为非零值,而与转换无关.

If the message is WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP, the return value is nonzero, regardless of the translation.

这意味着我不能用它来确定翻译是否发生.

which means that I cannot use it to determine if a translation has occurred.

阅读了一些Michael Kaplan博客文章后,我认为我可以使用ToUnicode()ToUnicodeEx()自己进行转换,并从GetKeyboardState()传入状态数组. 葡萄酒源代码似乎已达成共识,但有两种特殊情况,我不确定它们是否特定于葡萄酒或是否需要在实际Windows上完成:

After reading some Michael Kaplan blog posts, I figured I could use ToUnicode() or ToUnicodeEx() to do the conversion myself, passing in the state array from GetKeyboardState(). The wine source code seems to agree, but it has two special cases that I'm not sure if they are wine-specific or need to be done on real Windows as well:

  • VK_PACKET —直接从邮件的LPARAM
  • 中生成WM_CHAR
  • VK_PROCESS —调用函数ImmTranslateMessage(),该函数似乎是特定于Wine的函数或未记录的imm32.dll函数;我不知道哪个是真的
  • VK_PACKET — generates a WM_CHAR directly out of the message's LPARAM
  • VK_PROCESS — calls a function ImmTranslateMessage(), which seems to either be a wine-specific function or an undocumented imm32.dll function; I can't tell which is true

葡萄酒对WM_KEYUPWM_SYSKEYUP也不起作用;再次,我不知道这是否仅适用于葡萄酒.

And wine also does nothing with WM_KEYUP and WM_SYSKEYUP; again, I don't know if this is true for wine only.

但是我什至需要在使用TSF的程序中担心这些情况吗?如果我这样做,这样做的官方"方式是什么?即便如此,我将如何在WM_KEYUP/WM_SYSKEYUP上执行操作;我也需要将它们发送到ToUnicode()吗?

But do I even need to worry about these cases in a program that uses TSF? And if I do, what's the "official" way to do so? And even then, what would I do on WM_KEYUP/WM_SYSKEYUP; do I need to send those to ToUnicode() too? Do I even need to catch WM_KEYUPs in my windows specially if there was a WM_CHAR?

或者我是否缺少任何MSDN TSF示例中没有的东西,这些东西将使TSF能够照顾TF_PROFILETYPE_KEYBOARDLAYOUT处理器?我以为TSF可以进行透明的IME直通,但是我对FAKEIME样本的实验却发现其他情况……?我看到Firefox和Chromium都也在检查TF_PROFILETYPE_KEYBOARDLAYOUT甚至使用ImmGetIMEFileName()来查看键盘布局是否受IME支持,但是我不知道在这种情况下它们是否真正负责输入. ..

Or am I missing something that is not in any of the MSDN TSF samples that will allow me to just have TSF take care of the TF_PROFILETYPE_KEYBOARDLAYOUT processors? I thought TSF did transparent IME passthrough, but my experiment with the FAKEIME sample showed otherwise...? I see both Firefox and Chromium also check for TF_PROFILETYPE_KEYBOARDLAYOUT and even use ImmGetIMEFileName() to see if the keyboard layout is backed by an IME or not, but I don't know if they actually take care of input themselves in these cases...

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

My minimum version right now is Windows 7.

谢谢.

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

UPDATE The original version of this question included needing to know about associated WM_KEYUPs; on second look through my equivalent code on other platforms this won't be necessary after all, except for the details of TranslateMessage(); I've adjusted the question accordingly. (On OS X you don't even give key-release events to the text input system; on GTK+ you do but it seems keypresses that insert characters don't bother with releases and so they don't get handled anyway, at least for the input methods I've tried (there could be some that do...).) That being said, if I missed something, I added another sub-question.

推荐答案

通常,尝试复制Windows内部不是一个好主意.这很繁琐,容易出错,并且可能在不通知的情况下进行更改.

In general, it's not a good idea to try to duplicate Windows internals. It's tedious, error-prone, and likely to change without notice.

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

The edit controls that I have source access to pick off arrow keys (and other specific keys) in the WM_KEYDOWN handler and pass everything else off to the default handler, which will (eventually) generate WM_CHAR or TSF input calls (if your control supports TSF, which it should).

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

You would still need WM_CHAR in the case where there is no TSF handler involved. However, you can always have your WM_CHAR handler call your ITextStoreACP::InsertTextAtSelection method.

这篇关于由于TranslateMessage()无条件返回非零值,因此,在事实发生之前或之后,我如何得知发生了翻译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆