ページ 11

OS環境依存による文字化けについて

Posted: 2014年8月04日(月) 17:58
by lulu
現在あるライブラリを用いて開発を行っております。
そのライブラリではフォントを指定することができます。
基本的にはWindowsの仕様と同じです。
そこではフォント名とキャラセットの両方が行えます。
現在、フォント名Arial、キャラセットSHIFT-JISで設定しています。

このフォントで「°(度)」を表示するとき、日本語OSでは、
システム側で以下のように言語を変更しても正しく表示されます。

コード:

System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
...
Text = (char)0xB0
しかし、英語OSで実行すると「-」と表示されてしまいます。

そこで、キャラセットをANSIにすると、英語OSでは正しく「°」が表示されます。
しかし、日本語OSでは言語を変更してもしなくても
「<(文字の大きさが通常フォントの半分ぐらいなので<ではないかもしれませんが・・・」と表示されてしまいます。

どのような原因が考えられるのでしょうか?
ご回答のほど、よろしくお願いいたします。

Re: OS環境依存による文字化けについて

Posted: 2014年8月04日(月) 23:30
by YuO
えーっと,C# + .NET Framework環境でしょうか。
ソースコードの言語を指定していないのか,C++になっていますが……。
さらに,どのライブラリをどのように使っているかがわからないと,具体的なことは書けませんが……。


以下,ライブラリの関数をDllImportしている前提での一般論です。

CharSet.AnsiでマーシャルされるStringGetACP APIで指定されたコードページでワイド文字列からマルチバイト文字列に変換されます。
なので,特定のエンコーディングを指定したいのであれば,Encoding.GetBytesByteの配列に自分で直してそれを渡した方がよいでしょう。

ちなみに,NT系列のWindows APIはA系の呼び出しは内部でW系のAPIへの呼び出しに変換されます。
このため,A系のAPIを呼び出すことは原則的に避けるべきで,ライブラリもワイド文字列で扱えるのであればワイド文字列で取り扱うべきです。
また,ArialとSHIFTJIS_CHARSETを指定してのCreateFont APIの呼び出しは,ArialがSHIFTJIS_CHARSETを持たないため,SHIFTJIS_CHARSETの方が優先されます。
細かくは,Windows Font Mappingのあたりを参照してください。
オフトピック
Windows 8.1で調べたところ,Arialには
  • ANSI_CHARSET
  • HEBREW_CHARSET
  • ARABIC_CHARSET
  • GREEK_CHARSET
  • TURKISH_CHARSET
  • BALTIC_CHARSET
  • EASTEUROPE_CHARSET
  • RUSSIAN_CHARSET
  • VIETNAMESE_CHARSET
が含まれる模様。
オフトピック
添付のソリューションのうち,マーシャルまわりの調査がConsoleApplication1プロジェクト,Arialの持つCHARSETの調査がConsoleApplication2プロジェクトです。

Re: OS環境依存による文字化けについて

Posted: 2014年8月06日(水) 07:46
by lulu
YuO様

的確なご回答ならびにサンプルソースコードありがとうございました。
仰せのとおりの方法で実装いたしました。

> NT系列のWindows APIはA系の呼び出しは内部でW系のAPIへの呼び出しに変換されます
これは全く知りませんでした。
勉強になります。

今回はこれで解決といたします。
ありがとうございました。