【问题标题】:Maximum number of characters output from Win32 ToUnicode()/ToAscii()Win32 ToUnicode()/ToAscii() 输出的最大字符数
【发布时间】:2017-07-28 18:39:13
【问题描述】:

Win32 函数 ToUnicode()/ToAscii() 可以输出的最大字符数是多少?

在给定虚拟键码、扫描键码和键盘状态的情况下,它可以输出的内容肯定有一个合理的上限吗?

【问题讨论】:

    标签: windows winapi unicode ascii


    【解决方案1】:

    在我的 Windows 8 机器上,USER32!ToAscii 使用内部缓冲区调用 USER32!ToUnicode,并将 cchBuff 设置为 2。因为 ToAscii 的输出是 LPWORD 而不是 LPSTR,我们不能假设任何关于ToUnicode 的真正限制来自本次调查,但我们知道ToAscii总是会输出WORD。返回值告诉您此 WORD 的 0、1 或 2 个字节是否包含有用数据。

    转到ToUnicode,事情变得有点棘手。如果它返回 0,则没有写入任何内容。如果它返回 1 或 -1,则写入了一个 UCS-2 代码点。然后我们留下了奇怪的2 <= return 表达式。我们可以尝试剖析 MSDN 文档:

    两个或多个字符被写入 pwszBuff 指定的缓冲区。最常见的原因是存储在键盘布局中的死键字符(重音或变音符号)无法与指定的虚拟键组合形成单个字符。但是,缓冲区可能包含比返回值指定的更多的字符。发生这种情况时,任何多余的字符都是无效的,应该被忽略。

    您可以将此解释为“写入了两个或多个字符,但其中只有两个有效”,但返回值应记录为 2 而不是 2 ≤ value

    我认为这句话中有两件事,我们应该消除它所谓的“额外字符”:

    但是,缓冲区可能包含比返回值指定的字符更多的字符。

    这只是意味着该函数可能会在您的缓冲区上超出它实际返回的有效值。证实了这一点:

    发生这种情况时,任何多余的字符都是无效的,应该被忽略。

    这只是给我们留下了不幸的开场白:

    两个或更多字符被写入 pwszBuff 指定的缓冲区。

    我完全可以想象返回值 2,它可以像一个基本字符与一个不作为预组合代码点存在的 diacritic 组合一样简单。

    “或更多”部分可能来自多个来源。如果基本字符被编码为代理对,那么任何额外的变音符号/组合字符都会使您超过 2。基本字符上也可能有多个变音符号/组合字符。甚至可能有一个领先的 LTR/RTL 标记。

    我不知道是否有可能同时满足所有 3 个条件,但我会谨慎行事并指定 10 个左右 WCHAR 的缓冲区。这应该在您可以通过“单次击键”在键盘上产生的限制范围内。

    这绝不是最终答案,但它可能是你能得到的最好答案,除非 Microsoft 有人回应。

    【讨论】:

    • 根据我的经验,ToUnicodeEx() 可以返回超过 2。如果返回值超过 0(即 1、2、3、4 等),则缓冲区包含那么多 wchar_t 代码点。 AFAIU,这没有上限,因为键盘布局很可能设置为响应某些击键而产生连字(任意长的字符串)。
    猜你喜欢
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    相关资源
    最近更新 更多