none
MBCSとUNICODEの混在 RRS feed

  • 質問

  • いつもお世話になります。

    MFCを使ったMBCSベースのアプリで一部のテキストボックスをUNICODEで表示させるにはどうすれば良いのでしょうか?

    2012年8月19日 4:31

回答

  • 単純にアプリを Unicode に変更するわけにはいかないのでしょうか?
    といいますのも、
    やりたいことは仰るとおりSHIFT_JISで表せない文字も表示したいのです。

    SHIFT_JIS で表せない文字は MBCS には保持できないので、そのような文字が入る可能性がある箇所では MBCS を使わずに wchar_t ベースのコードに置き換えないといけなくなると思うのです。

    例えば、「𠮟」(口へんに七)は Shift-JIS には対応する文字コードがないですが、こういうのは char のバッファに入れた時点で「??」に化けてしまいます。Unicode に再度戻そうとしても戻ることはありません。
    2012年8月20日 5:28

すべての返信

  • Windows(正確にはNT系)の内部はUnicode化されているので、テキストボックスも普通にUnicodeで表示されると思います。

    具体的にどのようなコードを書き、どのような問題があったのでしょうか?

    2012年8月19日 5:53
  • 説明不足ですみません。

    テキストボックスはダイアログバーに配置しています。

    	CString strMBCS = "文字列";
    
    	int	nLen;
    	WCHAR*	pszUnicode;
    
    	nLen = ::MultiByteToWideChar(CP_THREAD_ACP, 0, strMBCS, -1, NULL,0);
    	pszUnicode = new WCHAR[nLen];
    
    	::MultiByteToWideChar(CP_THREAD_ACP, 0, strMBCS, strMBCS.GetLength()+1, pszUnicode, nLen);
    
    	pBar->SetDlgItemText(IDC_TEXT, pszUnicode);
    
    	delete	pszUnicode;
    
    この様にしたところ、「'WCHAR *' から 'LPCTSTR'に変換できません」というエラーメッセージが出ます。

    2012年8月19日 7:45
  • CString strMBCS = "文字列";

    CStringA strMBCS = "文字列"; もしくは CStringA strMBCS( "文字列" ); です。

    このコードの目的がよくわかりません。一旦MBCSで格納できるのならそのまま表示すればいいと思います。つまりコードで示すなら

    CString str( _T("文字列") );
    pBar->SetDlgItemText(IDC_TEXT, str);

    かな?

    MBCS(日本語ではSHIFT_JIS)で表現できない文字も扱いたいということでしょうか? であれば、直接SetDlgItemText()を呼ぶしかないのかな。

    CStringW strUNICODE( L"SHIFT_JISで表せない文字も含む…というかソースコードがSHIFT_JISならこれでも表現できないが…" );
    ::SetDlgItemTextW( (HWND)pBar, IDC_TEXT, strUNICODE );

    とかでしょうか。

    文字コード変換も文字列変換クラスがあるのでこちらを使ったほうが楽です。コードを見る限り、char / wchar_t / TCHARの区別ができていないように見えます。


    • 編集済み 佐祐理 2012年8月19日 8:26
    2012年8月19日 8:26
  • ::SetDlgItemTextW( (HWND)pBar, IDC_TEXT, strUNICODE );

    早速試したのですが何も表示しません。
    やりたいことは仰るとおりSHIFT_JISで表せない文字も表示したいのです。

    2012年8月19日 10:09
  • そもそも、そのUNICODE文字はきちんと保持できてますか? 気づかないうちにMBCSに変換され化けたりしていませんか?

    2012年8月19日 11:15
  • 保存というのはよくわかりまえんが、タイトルバーには表示されるので変換はできているようです。

    	::MultiByteToWideChar(CP_THREAD_ACP, 0, strMBCS, strMBCS.GetLength()+1, pszUnicode, nLen);
    	SetWindowTextW(pApp->m_pMainWnd->GetSafeHwnd(), pszUnicode);
    	::SetDlgItemTextW( (HWND)pBar, IDC_TEXT, pszUnicode );
    2012年8月20日 1:50
  • 単純にアプリを Unicode に変更するわけにはいかないのでしょうか?
    といいますのも、
    やりたいことは仰るとおりSHIFT_JISで表せない文字も表示したいのです。

    SHIFT_JIS で表せない文字は MBCS には保持できないので、そのような文字が入る可能性がある箇所では MBCS を使わずに wchar_t ベースのコードに置き換えないといけなくなると思うのです。

    例えば、「𠮟」(口へんに七)は Shift-JIS には対応する文字コードがないですが、こういうのは char のバッファに入れた時点で「??」に化けてしまいます。Unicode に再度戻そうとしても戻ることはありません。
    2012年8月20日 5:28
  • 例えば、「𠮟」(口へんに七)は Shift-JIS には対応する文字コードがないですが、こういうのは char のバッファに入れた時点で「??」に化けてしまいます。Unicode に再度戻そうとしても戻ることはありません。

    やはり無理なのですね。

    諦めます。

    有り難うございました。

    2012年8月20日 8:18
  • ですから、このコードだとMBCS形式で格納可能な文字をUnicodeに変換して扱っているだけで、「SHIFT_JISで表せない文字」を扱っているわけではありませんよね。

    先の返信にも書きましたが、コード上でchar / wchar_t / TCHARの区別ができてなく、変なところで文字コード変換をしてしまったり、それが原因で扱えない文字が化けたりしていそうに思います。

    2012年8月20日 14:11
  • xpで試してみました。

    EDITにVisualStyleが適用されている場合は、SetWindowTextWでShift-JISに無い文字を表示できましたが、VisualStyleが無い場合は、だめでした。VisualStyleが無い場合は、ダイアログにCreateWindowWでL"EDIT"を作成するとSetWindowTextWで表示できました。

    ただし、Shift-JISの文字に対応するUnicode文字はVisualStyleが無い場合でもSetWindowTextWで表示できます。

    2012年8月20日 15:27