• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ロケールに対応するストリングテーブルの参照について)

ロケールに対応するストリングテーブルの参照について

このQ&Aのポイント
  • ロケールとストリングテーブルについての質問です。開発環境上では正常に動作するが、exe実行時に日本語のストリングが呼び出される現象が発生します。この解決策を教えてください。
  • 開発環境でのストリングテーブルのロケール切り替え時には正常に動作しますが、exe実行時には必ず日本語のストリングが呼び出されてしまいます。解決策をお教えください。
  • ロケールとストリングテーブルの関連でお困りですね。開発環境では正常に動作するが、実際のexeでは日本語のストリングが呼び出されてしまいます。解決策を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.3

文字化けについて、、、 日本OSでリソースから読み取った日本語文字が化けるというのですか? もしそうなら、、、 リソースから読まずに、固定で画面に文字列をセットしても化けるのですか? 画面でなくて、メッセージボックスで表示しても化けますか? 固定で決めうちした文字列で化けて、メッセージボックスでは化けない場合は、 フォームロード時に、最初にフォームのフォント、次にフォームのコントロール類のフォントを変更してあげたら対応できると思います。 おすすめはMSUゴシック そうでなければ、化ける場合をパターン別に細かく書いてもらわないと答えようがありません。。。

natural_aspirate
質問者

お礼

TAGOSAKU7さん、お忙しいところの即レスにもかかわらずお返事遅くなり申し訳ありません。 文字化けに関してですが、前回教えていただいたロジックを実行したときに起こったことなのですが、「日本語」または「ENGLISH」をストリングテーブルから参照しダイアログで表示するとき、開発環境にてシステムロケール=英語(U.S.)だと「ENGLISH」と表示していたところ、exe実行時に「????」などのように表示されてしまうのです。フォントはダイアログmsgbox関数が持つデフォルトのものであると思われます。英語ストリングが選択されていれば「ENGLISH」と正しく表示されることが然りではないでしょうか?ちなみに他の一部のアプリケーションで同様に「?????」と表示されている個所がありました。ちなみにそのときスタートメニューは日本語で表示されてました(当たり前かも) また、実はあれからいろいろ調べていくうちに、実行時に得るロケールはexeを実行するOS自身の言語版に深く依存していることが分かりました。具体的なロジックレベルまで理解している訳ではありませんが、各国語版のOSはそれぞれネイティブの言語(UI Languageというらしいです)を内部的に持ち、その言語に基づいてストリングテーブルの選択を行うということのようです。ロジックでこれを書き換えることは不可能(または相当手間がかかる)らしいです。対応としてはMSDN上ではサテライトDLLを各言語毎に作成し、実行環境毎に個別に呼ぶ方法、他にIPDKというツールがあるようですが、現状ではまったく理解できてないのでここで詳しく述べることができません。こういったツールについてご存知でしたらヤブヘビということもありますね・・・

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.2

調べは限界なので、想像の世界を書き込みます。 SetThreadLocaleは、現在のスレッドに対して、ロケールを設定するようです。OS全体に影響するものではありません。 んで、デバッグ環境とEXEにしてからの実行結果が違う事について、、、 「親」と言う事に注目してみると・・・ ※デバッグ環境    (1)デスクトップ → (2)VB → (3)デバッグ環境で擬似EXE ※EXE    (1)デスクトップ → (2)EXE となります。 スレッドと言う概念を元に考えると、デスクトップは親として扱われないので、最上位の親が、デバッグ環境とEXEでは違うことになります。 VB自身が開発ツールであることと、デバッグ環境とEXE環境の実行結果から、私たちの見えないところで、VB自身が[GetUserDefaultLCID][SetThreadLocale]をコールしている事が想像できます。 だからこそEXEにしたら、それらは自身でコールしてあげないといけないのだと思います。 (想像だらけでスマソ) さらに、、、文字化けですが、、、、 読み込んだ文字をそのままフォームに張って、「文字化けがおきる」と言ってませんか? ストリングテーブルが英語なら、MSGBOXで表示したらうまくいかないですか? そこでうまく表示できたなら、ロケール以前にフォントの問題だと思われます。 それと、その現象が起こるということは、ストリングテーブルのロケール反映ができたとして捕らえておきますね。

natural_aspirate
質問者

お礼

TAGOSAKU7さん、引続きお付き合い頂き、ありがとうございます。想定とはいえ、処理系作成者(MS)くらいしか核心が分からないことかもしれませんね。実際APIを組み込んでテストしてませんが、現状の知識ではAPIを組み合わせることが最善のようです。しかし、この点についてはMSDNの説明が不十分である可能性もありますので、結論付けは少し時間を頂きたいと思います。後半仰られた文字化けの件ですが、会社PCで再現させたところ(かなり危険かも)原因は日本語の文字コードを変換できなかったために"???"という表示になるようです→前回は言葉が足りませんでした。やはりストリングテーブルのロケール反映は不能でした・・・と、いうことは、手動でのロケール設定は不可能ということかなぁ。それとも英語版OSを用意してテストすべきでしょうかねぇ・・・

すると、全ての回答が全文表示されます。
  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.1

質問者が履歴で挙げた過去スレに答えていた者です。 前回の質問は、 開発環境:US版OS 実行環境:多国(日本語は含まない) という状況でした。 悲しい事にそんな環境が手元にあるわけもなく、 「日本語版での環境で、日本語テーブルを含まない、複数のストリングテーブル」 を対象にした方法を述べたつもりです。 今回の場合は、前回の質問とちょっと違います。 「日本語版での環境で、日本語テーブルを含む、複数のストリングテーブル」 です。 そうであれば、特にリソースをスクリプト化する必要もありません。 手元にサンプルがあったのでサンプルを載せておきます。 ※注意事項----------非常に大事----------- デバッグ環境だと、対応しないので、EXEの状態で試してみてください。 ※注意事項----------非常に大事----------- ちなみに 日本語ロケールID:1041 英語USロケールID:1033 です Project1.vbp(プロジェクト) ├Module1.bas(モジュール) └Test.res(リソース) *****Module1.basの内容***** Option Explicit Public Declare Function GetUserDefaultLCID Lib "KERNEL32" () As Long Public Declare Function SetThreadLocale Lib "KERNEL32" (ByVal Locale As Long) As Long Public Const API_FALSE = &H0& Sub Main()   Dim lngNowLCID As Long   '//現在のロケールID   Dim lngNewLCID As Long   '//入力後のロケールID   Dim strRet   As String  '//インプットボックス戻り      '地域のオプションでセットされているロケールを取得する   lngNowLCID = GetUserDefaultLCID      Do     strRet = InputBox("現在のロケールは[" & lngNowLCID & "]です", _           "ロケールIDを指定してください。", lngNowLCID)          '数値のみ対応     If Not IsNumeric(strRet) Then       Exit Sub     End If     lngNewLCID = CLng(strRet)          '取得したロケールを、現在のスレッドにセット     If API_FALSE = SetThreadLocale(lngNewLCID) Then       'ロケール設定エラー       MsgBox "ロケール設定に失敗", vbCritical Or vbOKOnly     Else       'リソースを読んで表示       MsgBox LoadResString(101), vbInformation Or vbOKOnly     End If   Loop    End Sub *****Test.resの内容***** 構成:日本語テーブル/英語(U.S.)テーブルの計2つのテーブル ID:101 内容:日本語テーブル側の文字列="日本語"/英語(U.S.)テーブル側の文字列="English" それと、、、 >同環境上でロケールを日本語⇔英語切替を行いながらデバッグ実行をしました。 >その際はロケールに対応したストリングが呼び出され、該当した言語で表現されました。 とありますが、おそらくVBは デバッグでは、GetUserDefaultLCID 関数(コンパネで設定されたロケールID) EXEでは、GetSystemDefaultLCID 関数(OSが持っているロケールID) を使用しているからだと、勝手に思っています。(違っていたらゴメソ)

natural_aspirate
質問者

お礼

TAGOSAKU7さん、こんにちは。早速教えていただいたソースを試してみました(自宅でですが、同じ環境なのです)。GetUserDefaultLCIDでは正しく地域のオプションで設定したロケールIDを返しますが、実際ストリングテーブルを切り分けるトリガは別のようですね。ひょっとしてTAGOSAKU7さんはGetUserDefaultLCIDで取得したロケールIDをSetThreadLocaleでシステムに対して再度設定する、ということなんでしょうか?両方の関数の機能を考えると何とかなりそうですね?MSDNには「システムのLCIDを基準にして(GetSystemDefaultLCIDのことでしょうか?)、実行時に自動的に選択されます」とありますが、システムロケールを手動変更すると文字化けしてストリングテーブル以前の問題になっちゃうんですよねぇ・・・ともあれ、長文でのご回答、大変感謝いたします。もし追加情報ありましたら、是非お伝えください。

すると、全ての回答が全文表示されます。

関連するQ&A