3

VisualStudioで記述された非UnicodeのC++アプリケーションがあります。これは、元々、コードページ1252の文字セットを使用するマシン用に記述されたものです。

このアプリケーションは、リソースを読み取った後、一部のファイルでリソース文字列を検索するなど、リソースのコンテンツに対して多くの後処理ステップを実行します。

現在、中国の人々はこのアプリケーションを使い始めており、彼らのマシンはPRCロケールを使用しています(これにより、非Unicodeアプリケーションのデフォルトのコードページがマルチバイト文字セットである936に設定されます)。

CString::LoadString変換を実行するようです。他のファイルで探しているコンテンツが同じではないため、これにより以降の処理が中断されます。

同じことがCMenu::GetMenuStringまたはにも当てはまりCWnd::GetWindowTextます。

iconv残念ながら、ファイルを単純に使用することはできません。 LoadStringGetMenuStringまたは次のGetWindowTextように動作します。

  • コードページ1252で有効な一部の文字は、コードページ936では無効であり(たとえば、î、û、ñ、œ)、疑問符に置き換えられます。
  • コードページ1252で有効な一部の文字は、コードページ936では無効です(例: É)が、代替文字に置き換えられます(É=>é)
  • 一部の文字は両方のコードページに存在しますが、同じ表現ではなく、CP936では2バイトであることがよくあります
  • 一部の文字(すべてのASCII文字を含む)は、両方のコードページで一致します。

リソースコンテンツをロードするこれらの3つの関数は、文字セット変換を実行せずに、バイナリコンテンツをロードするようにしたいと思います。.rcでファイルを変更しようとしましLANGUAGE LANG_INVARIANT, SUBLANG_NEUTRALたが、何も変更されませんでした。

リソースファイルには#pragma code_page(1252);も含まれています。これは安全に削除できますか?そのプラグマは何のためですか?

ご回答ありがとうございます。

4

2 に答える 2

3

多分あなたはBOOLを使うことができますSetThreadLocale( LCID Locale );

MSDN:SetThreadLocaleは、LANGUAGEステートメントを使用してリソースの選択に影響を与えます。このステートメントは、CreateDialog、DialogBox、LoadMenu、LoadString、FindResourceなどの関数に影響します。CP_THREAD_ACPによって示されるコードページを設定しますが、FindResourceExには影響しません。詳細については、コードページ識別子を参照してください。

于 2011-03-01T15:47:09.850 に答える
2

LoadStringの場合、明らかに行うべきことは、Win32 API関数LoadStringW()を直接呼び出すことです。これにより、Unicode文字列が直接提供されます。このようにCStringのCStringW形式を使用する場合でも機能する可能性があります(テストされていません!)

CStringW str;
str.LoadString(...);

メニューとウィンドウ関数は、より多くの問題を引き起こします。Win32 API GetMenuStringW()のUnicode形式を直接呼び出すと機能するはずです。ウィンドウ関数GetWindowText()は本当に厄介なものです。もちろん、Win32関数GetWindowTextW()を呼び出すこともできますが、返されるものは、呼び出すウィンドウにANSIまたはUnicodeウィンドウプロシージャがあるかどうかによって異なります。基になるウィンドウがWindowsコントロールの場合、通常、基になるウィンドウプロシージャにアクセスして直接呼び出すことは可能ですが、見栄えがよくなく、あまり面白くありません。

あなたがそれをどのように使おうとしているのかについてもっと詳しく知るチャンスはありますか?これらの関数を3つのアクセスリソースすべてのようにリストすることは注目に値しますが、それは真実ではありません。LoadString()のみがそれを行います。他の2つは、リソースではなく、実行中のプロセスに存在するメニューまたはウィンドウを直接操作します。

GetWindowTextW()の問題を回避する方法の例として、このプロジェクトのUnicodeEditクラスを見てください。これは、Windows 9Xで動作する必要があるANSIアプリケーションですが、可能であれば編集コントロールからUnicodeテキストを取得できる必要もありました。秘訣は、サブクラス化前のウィンドウプロシージャがUnicodeであるかANSIであるかをクラスが記憶し、Unicodeの場合はGetWindowText()で直接呼び出すことです。必要なものによっては、この種のアプローチが役立つ場合があります。

于 2011-03-01T12:39:54.473 に答える