How to get the code page of the current keyboard layout?

丶灬走出姿态 提交于 2019-12-06 13:37:55

Here's another way to do it:

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

Although this is an old thread, I just spent most of this morning searching for a method for identifying the Windows codepage given a specific charset ID (when the current keyboard layout/locale is NOT set to that charset). I figured that the sample code might be of use to others looking for similar information.

In my case I wanted to map a charset value such as 161 (Greek) to equivalent Windows codepage, 1253. After a lot of digging I came up with the following:

/*
 * 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;
}

Hope this is useful for others!

John

I've had a similar problem on an application that needed to run on Windows 9X. The solution I eventually came up with was to listen for WM_INPUTLANGCHANGE notifications messages, which are sent to top-level windows when the user changes the input language. In my message procedure I have something like this:

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

where m_codePage is a UNIT that is initialized as

  m_codePage = CP_ACP;

I then use m___codePage in calls to MultiByteToWideChar() to handle keys from WM_CHAR etc.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!