2

非 Unicode アプリケーションは、Unicode キーボード入力 (WM_CHAR/etc.) を処理できる必要があるため、8 ビット文字コードを受け取り、それを内部で Unicode に変換します。9x 互換性が必要なため、ほとんどの Unicode API を使用することはできません。

現在、PRIMARYLANGID(GetKeyboardLayout(0)) によって返された言語を調べ、ハードコードされたテーブルで関連するコード ページを調べます。特定の言語またはキーボード レイアウトで使用されるコード ページを取得する関数が見つかりませんでした。文字/文字列の変換は、MultiByteToWideChar で行うことができます。

現在のキーボード レイアウトのコード ページを取得する方法はありますか? GetACP は、現在のキーボード レイアウトの影響を受けない既定のシステム コード ページを返します。

4

3 に答える 3

3

これは古いスレッドですが、特定の文字セットID(現在のキーボードレイアウト/ロケールがその文字セットに設定されていない場合)を指定して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;
}

これが他の人にも役立つことを願っています!

ジョン

于 2011-01-24T13:06:50.130 に答える
3

これを行う別の方法は次のとおりです。

WORD languageID = LOWORD(GetKeyboardLayout(0));
char szLCData[6+1];
GetLocaleInfoA(MAKELCID(languageID, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE,
               szLCData, _countof(szLCData));
int codepage = atoi(szLCData);
于 2009-08-23T04:08:56.110 に答える
1

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 などからのキーを処理します。

于 2009-08-18T11:58:12.587 に答える