代码之家  ›  专栏  ›  技术社区  ›  Stuart

为什么createAcceleratorTable和translateAccelerator函数有Unicode和ANSI版本?

  •  1
  • Stuart  · 技术社区  · 6 年前

    在我看来 CreateAcceleratorTable 功能或 TranslateAccelerator 函数处理字符串或字符数据,所以我想知道为什么它们都有Unicode和ANSI版本?这就是 ACCEL 数据结构。

    1 回复  |  直到 6 年前
        1
  •  3
  •   raymai97    6 年前

    CreateAcceleratorTable 处理字符数据。

    根据 MSDN documentation of ACCEL structure

    钥匙
    Type:

    加速键。此成员可以是虚拟密钥代码或字符代码。

    字符代码可以不仅仅是一个ascii字符。超出ascii范围,其含义取决于它是ansi还是unicode。

    为什么字符码会超过ascii?我们的键盘不是只有ascii字符吗?好吧,这是我的猜测。想象一下,在ansi默认为shift-jis的日语窗口中,使用假名输入的日本用户(击键可以直接键入///…)按这些假名的快捷键,如 Ctrl+あ .

    至于 TranslateAccelerator ,因为加速器可以是非ascii的,所以也需要翻译 WM_KEYDOWN , WM_SYSKEYDOWN , WM_CHAR WM_SYSCHAR ,在传递到内部实现之前转换为Unicode。

    以下代码是从泄露的Windows2000源代码中摘录的。

    Unicode版本:

    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
    case WM_CHAR:
    case WM_SYSCHAR:
        return NtUserTranslateAccelerator(hwnd, hAccel, lpMsg);
    

    ANSI版本:

    WPARAM wParamT;
    // irrelevant code here...
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
    case WM_CHAR:
    case WM_SYSCHAR:
        wParamT = lpMsg->wParam;
        RtlMBMessageWParamCharToWCS(lpMsg->message, &(lpMsg->wParam));
        iT = NtUserTranslateAccelerator(hwnd, hAccel, lpMsg);
        lpMsg->wParam = wParamT;
        return iT;
    

    源代码 RtlMBMessageWParamCharToWCS 可以是 found here .