dポイントプレゼントキャンペーン実施中!

MFCのコントロールにUTF-8の文字を表示したい

表題の件ですが、VisualStudio2008において、UTF-8+BOMフォーマットで保存したソースコードにBOMつきUTF-8を入力する方法と、UTF-8文字列をMFCのコントロール(リストコントロールなど)に表示する方法がわかりません。
どなたかご教授いただける方が居られましたら幸いです。

A 回答 (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;
}

この回答への補足

有用なご返答ありがとうございます。
実はいろいろ試したところ、MFCのエディットボックスではUTF8からUTF16へ先に示したコードで処理した文字列が正常に表示できました。なぜかリストコントロールで激しく文字化けします。この理由がわかりません。

補足日時:2010/09/06 11:20
    • good
    • 0
この回答へのお礼

いろいろありがとうございました。とりあえず私にとっては驚愕の事実とともに自己解決いたしました。
なにが驚きかというと、ダイアログでフォントを設定しますが、コントロールの種類によって、同じフォントをつかっていても文字化けするものとしないものがあるということです。
ためしにメイリオをダイアログのフォントに設定しやってみたところ、難なくきれいに表示されました。MSUIGothicだったかなんだか忘れてしまいましたが、少なくとも私が試した中では、エディットボックスとリストコントロールで同じフォントでも文字化けするしないに分かれました!

まっっっっったく知りませんでしたw しかし試してみるものです。

お礼日時:2010/09/06 12:46

後半だけ。


Windowsのコントロールに文字列を取得/表示したりするAPIは
UnicodeもしくはANSI文字列(日本語ならCP932)になります。

よって、UTF-8のコードの配列を渡しても文字化けすることになるでしょう。
よって、UTF-8→Unicode変換する必要があります。

MultiByteToWideChar

というAPIを使えば、変換できます。
http://msdn.microsoft.com/ja-jp/library/cc448053 …
BOMはとらないといけないかもしれませんが。

この回答への補足

ご返答ありがとうございます。その方法は試しました。そうすると確かにデバッグ画面で変数の中身をウォッチすると正常なユニコード文字列が読める形で見れます。ここでは「(ハード)」を用いました。
しかし、これをそのままコントロールの文字列として代入すると文字化けします。今回はリストコントロールのアイテムの文字列として入れています。
以下のことを試したのですが、文字化けしないケースと文字化けするケースがありました。

■エディットボックスから「(ハード)」を入力⇒その値を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;
}

補足日時:2010/09/06 09:44
    • good
    • 0
この回答へのお礼

どうもありがとうございました。
うえに書いたように自己解決しました。結果は私としてはかなりおどろきでしたw
ちなみに環境は

 VisualStudio2008Professional、Win7x64、UNICODEコンパイル

です。

お礼日時:2010/09/06 12:47

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A