- ベストアンサー
MFCのコントロールにUTF-8の文字を表示したい
MFCのコントロールにUTF-8の文字を表示したい 表題の件ですが、VisualStudio2008において、UTF-8+BOMフォーマットで保存したソースコードにBOMつきUTF-8を入力する方法と、UTF-8文字列をMFCのコントロール(リストコントロールなど)に表示する方法がわかりません。 どなたかご教授いただける方が居られましたら幸いです。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
とりあえず、受信している文字列はちゃんとBOMつきUTF-8の文字列になっていますか? ちなみにこんなコードではうまく変換出来ているようです。 #include <windows.h> #include <string> std::wstring ConvUTF8toUni(std::string utf8str) // BOMをとるため非const { std::wstring unistr; // BOM とり if (utf8str.length() > 3) { if ((unsigned char)utf8str[0] == 0xEF && (unsigned char)utf8str[1] == 0xBB && (unsigned char)utf8str[2] == 0xBF) { utf8str.erase(0, 3); } } int len = ::MultiByteToWideChar(CP_UTF8, 0, utf8str.c_str(), -1, NULL, 0); if (len > 0) { unistr.resize(len); ::MultiByteToWideChar(CP_UTF8, 0, utf8str.c_str(), -1, &unistr[0], len); } return unistr; } int main() { unsigned char utf8[] = { 0xEF, 0xBB, 0xBF, // BOM 0xE3, 0x81, 0x82, // あ 0xE3, 0x81, 0x84, // い 0xE3, 0x81, 0x86, // う 0xE3, 0x81, 0x88, // え 0xE3, 0x81, 0x8A, // お }; std::string utf8str((char*)utf8, _countof(utf8)); std::wstring unistr = ConvUTF8toUni(utf8str); return 0; }
その他の回答 (1)
- bluecampus
- ベストアンサー率66% (138/209)
後半だけ。 Windowsのコントロールに文字列を取得/表示したりするAPIは UnicodeもしくはANSI文字列(日本語ならCP932)になります。 よって、UTF-8のコードの配列を渡しても文字化けすることになるでしょう。 よって、UTF-8→Unicode変換する必要があります。 MultiByteToWideChar というAPIを使えば、変換できます。 http://msdn.microsoft.com/ja-jp/library/cc448053.aspx BOMはとらないといけないかもしれませんが。
お礼
どうもありがとうございました。 うえに書いたように自己解決しました。結果は私としてはかなりおどろきでしたw ちなみに環境は VisualStudio2008Professional、Win7x64、UNICODEコンパイル です。
補足
ご返答ありがとうございます。その方法は試しました。そうすると確かにデバッグ画面で変数の中身をウォッチすると正常なユニコード文字列が読める形で見れます。ここでは「(ハード)」を用いました。 しかし、これをそのままコントロールの文字列として代入すると文字化けします。今回はリストコントロールのアイテムの文字列として入れています。 以下のことを試したのですが、文字化けしないケースと文字化けするケースがありました。 ■エディットボックスから「(ハード)」を入力⇒その値をCStringWに代入⇒リストコントロールのアイテムに設定⇒文字化けしない ■UTF8を使っているWebからの「(ハード)」を受信⇒その値をstd::stringに代入⇒APIで変換⇒wstringに代入⇒リストアイテムのテキスト(LPTSTR=wchar_t*)に代入⇒文字化け という具合です。MFCのコントロールとMFCのAPIやCStringを介してやっている分には問題ないようです。BOMの有無とかでしょうか? マルチバイト文字列からワイド文字列への変換には以下のような関数を用いました。 std::wstring ConvertMultiToWide( std::string const &str ) { int sizeWide = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0 ); if( sizeWide == 0 ) return L""; std::wstring wstr; wstr.resize(sizeWide); ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wstr[0], sizeWide ); return wstr; }
お礼
いろいろありがとうございました。とりあえず私にとっては驚愕の事実とともに自己解決いたしました。 なにが驚きかというと、ダイアログでフォントを設定しますが、コントロールの種類によって、同じフォントをつかっていても文字化けするものとしないものがあるということです。 ためしにメイリオをダイアログのフォントに設定しやってみたところ、難なくきれいに表示されました。MSUIGothicだったかなんだか忘れてしまいましたが、少なくとも私が試した中では、エディットボックスとリストコントロールで同じフォントでも文字化けするしないに分かれました! まっっっっったく知りませんでしたw しかし試してみるものです。
補足
有用なご返答ありがとうございます。 実はいろいろ試したところ、MFCのエディットボックスではUTF8からUTF16へ先に示したコードで処理した文字列が正常に表示できました。なぜかリストコントロールで激しく文字化けします。この理由がわかりません。