Как получить кодовую страницу текущей раскладки клавиатуры?

Мое приложение, не поддерживающее Unicode, должно иметь возможность обрабатывать ввод с клавиатуры Unicode (WM_CHAR и т. Д.), Таким образом получать 8-битный символьный код, а затем внутренне преобразовывать его в Unicode. Требуется 9x-совместимость, поэтому использование большинства API-интерфейсов Unicode недопустимо.

В настоящее время он проверяет язык, возвращаемый PRIMARYLANGID (GetKeyboardLayout (0)), и ищет соответствующую кодовую страницу в жестко запрограммированной таблице. Мне не удалось найти функцию для получения кодовой страницы, используемой для определенного языка или раскладки клавиатуры. Затем преобразование символа / строки можно выполнить с помощью MultiByteToWideChar.

Есть ли способ получить кодовую страницу текущей раскладки клавиатуры? GetACP возвращает системную кодовую страницу по умолчанию, на которую не влияет текущая раскладка клавиатуры.


person Vladimir Panteleev    schedule 18.08.2009    source источник


Ответы (3)


Вот еще один способ сделать это:

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

Несмотря на то, что это старый поток, я потратил большую часть этого утра на поиск метода идентификации кодовой страницы Windows по конкретному идентификатору кодировки (когда текущая раскладка клавиатуры / языковой стандарт НЕ установлен на эту кодировку). Я подумал, что пример кода может быть полезен другим, ищущим подобную информацию.

В моем случае я хотел сопоставить значение кодировки, например 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;
}

Надеюсь, это будет полезно для других!

Джон

person John C    schedule 24.01.2011

У меня была аналогичная проблема с приложением, которое нужно было запускать в 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 - это ЕДИНИЦА, которая инициализируется как

  m_codePage = CP_ACP;

Затем я использую m___codePage в вызовах MultiByteToWideChar () для обработки ключей из WM_CHAR и т. Д.

person DavidK    schedule 18.08.2009
comment
У этого метода есть недостаток: если раскладка клавиатуры по умолчанию не соответствует системной кодовой странице (CP_ACP), то кодовая страница не будет правильной при запуске приложения. - person Vladimir Panteleev; 23.08.2009