【问题标题】:How to get the code page of the current keyboard layout?如何获取当前键盘布局的代码页?
【发布时间】:2009-08-18 02:32:22
【问题描述】:

我的非 Unicode 应用程序需要能够处理 Unicode 键盘输入(WM_CHAR/等),从而接收 8 位字符代码,然后在内部将其转换为 Unicode。需要 9x 兼容性,因此不能选择使用大多数 Unicode API。

目前它查看 PRIMARYLANGID(GetKeyboardLayout(0)) 返回的语言,并在硬编码表中查找相关代码页。我找不到获取特定语言或键盘布局使用的代码页的函数。然后可以使用 MultiByteToWideChar 转换字符/字符串。

有没有办法获取当前键盘布局的代码页? GetACP 返回默认的系统代码页,不受当前键盘布局的影响。

【问题讨论】:

    标签: windows winapi keyboard-layout codepages


    【解决方案1】:

    这是另一种方法:

    WORD languageID = LOWORD(GetKeyboardLayout(0));
    char szLCData[6+1];
    GetLocaleInfoA(MAKELCID(languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE,
                   szLCData, _countof(szLCData));
    int codepage = atoi(szLCData);
    

    【讨论】:

      【解决方案2】:

      虽然这是一个旧线程,但我今天早上的大部分时间都在寻找一种方法来识别给定特定 charset ID 的 Windows codepage(当当前键盘布局/语言环境未设置为该字符集)。我认为示例代码可能对寻找类似信息的其他人有用。

      在我的例子中,我想将 161(希腊语)等字符集值映射到等效的 Windows 代码页 1253。经过 大量 的挖掘后,我得出了以下结论:

      /*
       * Convert a font charset value (e.g. 161 - Greek) into a Windows codepage (1253 for Greek)
       */
      
      UINT CodepageFromCharset(UINT nCharset)
      {
          UINT nCodepage = CP_ACP;
          CHARSETINFO csi = {0};
      
          // Note, the symbol charset (2, CS_SYMBOL) translates to the symbol codepage (42, CP_SYMBOL).
          // However, this codepage does NOT produce valid character translations so the ANSI charset
          // (ANSI_CHARSET) is used instead. This appears to be a known problem.
          // See this discussion: "More than you ever wanted to know about CP_SYMBOL"
          // (http://www.siao2.com/2005/11/08/490495.aspx)
      
          if (nCharset == SYMBOL_CHARSET) nCharset = 0;
          DWORD* lpdw = (DWORD*)nCharset;
      
          // Non-zero return value indicates success...
          if (TranslateCharsetInfo(lpdw, &csi, TCI_SRCCHARSET) == 0)
          {
              // This should *not* happen but just in case make sure we use a valid default codepage.
          #ifdef _UNICODE
              csi.ciACP = 1200;
          #else
              csi.ciACP = CP_ACP;
          #endif
          }
      
          return csi.ciACP;
      }
      

      希望这对其他人有用!

      约翰

      【讨论】:

        【解决方案3】:

        我在需要在 Windows 9X 上运行的应用程序上遇到了类似的问题。我最终想出的解决方案是监听 WM_INPUTLANGCHANGE 通知消息,当用户更改输入语言时,这些消息会发送到顶级窗口。在我的消息过程中,我有这样的事情:

        case WM_INPUTLANGCHANGE:
          {
            CHARSETINFO cs;
            if (TranslateCharsetInfo((DWORD*)wParam,&cs,TCI_SRCCHARSET))
              m_codePage = cs.ciACP;
            return DefWindowProc(WM_INPUTLANGCHANGE,wParam,lParam);
          }
          break;
        

        其中 m_codePage 是一个初始化为的 UNIT

          m_codePage = CP_ACP;
        

        然后我在调用 MultiByteToWideChar() 时使用 m___codePage 来处理来自 WM_CHAR 等的键。

        【讨论】:

        • 该方法有个缺陷:如果默认键盘布局与系统代码页(CP_ACP)不对应,那么应用程序启动时代码页将不正确。
        猜你喜欢
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 2014-02-24
        • 2013-07-19
        相关资源
        最近更新 更多