none
マルチバイトアプリでの文字化け RRS feed

  • 質問

  • Winodws10、マルチバイト(shift-jis)のMFCアプリのことです。

    コンボボックスに全角入力で決定をおすと、コンボボックスの内容が文字化けを起こしました。
    「あ」→「」※何も表示されない
    「工事」→「き・こ」

    原因は、「ベータ:ワールドワイド言語サポートでUnicode UTF-8を使用(U)」のチェックボックスがONなっており、
    OFFにすると文字化けしなくなりました。

    これは、次のフローとなるためでしょうか。
    ・全角入力→漢字変換(IME、ATOK)shift-jis→NLSunicode16→utf-8→フォント検索(shift-jis)→文字化け

    ※チェックを外したときフロー
    ・全角入力→漢字変換(IME、ATOK)shift-jis→NLSunicode16→shift-jis→フォント検索(shift-jis)→正常に文字表示

    1.なぜ文字化けが起こるのか?
    2.対象フォント決定のフロー

    が知りたいです。参考となるページ書籍でもあれば教えてください。

    2020年12月22日 5:41

すべての返信

  • まず。。。UTF-8のチェックは、「ベータ」と書かれているのでお分かりと思いますが、正式なものではなく実験的に搭載された機能なので、リファレンスなどはどこにもありません。せいぜいニュース記事にこんなチェックがついたと話題に出ている程度です(メモ帳のUTF-8対応とは異なる話)。

    > 1.なぜ文字化けが起こるのか?

    IME(ATOKに限らない)の内部処理や、OS内の一部の処理で、UTF-8のチェックが反映されない条件があるためです。

    また、ANSIプログラムのリテラル文字列は、ビルド時のANSIの文字コードでリテラル文字列の文字コードを作るため、ビルド条件によって文字コードが確定しないことがありこれも文字化けの原因としておかしな挙動につながる場合があります。

    > 2.対象フォント決定のフロー

    ここでいう対象フォントというのが、文字化けするのが選ばれているフォントに起因していると思っているのであれば異なります。

    UTF-8 の文字列だとして、画面表示(TextOutA)などを送り込んでいるはずなのに、渡している文字列は実際は Shift-JIS の文字コードの文字列であるあるいはその逆というようなパターンになっているために発生します。

    一年以上前ですが、このあたり使えそうかを調査したことがあったのですが、当時の結論はこの設定を有効活用したいならアプリケーションは UNICODE アプリにする必要があり、そのうえで、ANSIテキストのデフォルト扱いの個所のみこの設定を生かすという以外に選択肢はないという結論に至っています。

    IME以前に、リテラル文字列を持っている場合もおかしくなることがわかっていますし、ダイアログボックスのキャプション文字列が一時的にとはいえ、ANSIに変換されてしまいそのタイミングで文字列長がShift-JIS換算していれば正しい文字列長になる長さに切り詰められる(要するに2/3になる)という状況があります。
    そのほか、いくつかのコントロールの表示で、何をどうやってもうまく表示できないなどがあり、このチェックをセットした場合、UNICODEアプリ以外はまともに動かないことがわかっています。

    私の調査範囲では、MS発(中の人ブログを含む)の情報(英語を含む)で、チェックを作ったよ的なもの以外の情報は存在していないと思います。


    とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx

    2020年12月22日 14:29
  • 補足でVisual C++のサポートするMBCS; Multibyte Character Setは2バイト文字を前提としています。例えば_mbbtypeは_MBC_LEAD マルチバイト文字の先頭バイトと_MBC_TRAIL マルチバイト文字の末尾バイトの2種類しかないです。そのため3バイト以上の構成となるUTF-8は原理上サポートできません。

    ちなみにコンパイルオプション /executioncharset:utf-8は付けていますでしょうか? これで動作するようになるとは思いませんが、少なくともShift-JISアプリをUTF-8で動かすのは無理だと思います。

    2020年12月22日 23:14