MicrosoftのHPには、「言語をUnicodeにする必要がある」等いろいろと書いてあるのですが、「何をしなければいけない」「ここをチェック」等の記載がありません。
何かご存じの方、参考書籍、参考HP等あればお教えください。
【アプリの特徴】
・レジストリの読書有
・Win32API使用(iniファイルの読込等)
・ExcelCOM使用
・GUIは英語
VBの方は多言語で作成したことがないのでわかりませんが...
VCの方でしたら何本か作成したことがあります。
英語版のOSに対応させるのはりソースの編集だけで事足ります。Unicodeビルドにする必要はありません。
一般的には、例えばソースコードの中で
AfxMessageBox(”あいう”);
というように直接文字列を指定している場合は、多言語の開発時にはこれらの文字列をすべて文字列リソースとしてrcファイルなどから読み出すようにします。
今回の場合はもともと「GUIが英語」ということですからソースコードの中で使われている文字列は
AfxMessageBox(”Hello”);
のようにすべて英語だけで日本語が混じらない状態になっていることかと思います。英語だけの単言語対応にする場合はこのままで十分です(日本語がある場合は英語に置換する必要があります)。
iniファイルの中身も同じです。日本語がある場合は英語に置き換えておいてください。
さらにrcファイルの中身を英語にします。この作業はVC++のIDEからもできますが、私は確実性のために直接編集をしています。
rcファイルをテキストエディタで開くと
/////////////////////////////////////////////////////////////////////////////
// 日本語 resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
#ifdef _WIN32
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
#pragma code_page(932)
#endif //_WIN32
というようになっていてコードページが日本語にしていされています。
これを
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
のように書き換えます。さらに
ダイアログリソースなどの
FONT 9, ”MS Pゴシック”, 0, 0, 0x1
を
FONT 8, ”MS Sans Serif”
に変えます。
そしてrcファイル内で定義されている日本語が使われている部分をすべて英語の文字列に置き換えます。
このようにすればrcファイルが英語用になります。これでビルドをかければ英語用のバイナリが生成されます。
ちなみにUnicodeビルドにした場合はWindowsNT系のみで動作するバイナリになります。WindowsNT系は1つのバイナリの中で日本語とハングルが混在ような多言語のアプリケーションを作るときに使うことが多いと思います。今回のように英語Onlyの単言語版にする場合や、日本語と英語やハングルを切り替えて使いたい場合のように切り替え方の多言語バイナリが必要な場合は特にUnicodeビルトにしなくても大丈夫です。
>「・・・Unicodeビルトにしなくても大丈夫です」とあるのですが、これは「atoi」も使用可能と考えてよろしいでしょうか?
Unicodeビルドにしない場合はatoiでも大丈夫です(厳密にはウソですが普通は問題になりません)。
文字列から数値に変換する関数にatoiや_wtoi、_tstoiなどがあります。これらは文字コードの違いによって使い分けます。
たとえばMFCにCStringという文字列クラスがあります。
これは普通の場合はchar*と同等ですよね。ですから
CString strData;
strData = ”123”;
int n = atoi(strData)
で問題なく使用できます。
しかし、Unicodeビルドの場合はエラーになります。Unicodeビルドの場合はCStringはWCHAR*と同等になるからです。そのため
CString strData;
strData = L”123”;
int n = _wtoi(strData)
とします。これでエラーもなく使えるようになります。このときL”123”というのは文字列をUnicode指定する方法で、_wtoiはUnicode文字列(WCHAR*)から数値に変換する関数です。
上のことから分かるようにUnicodeビルドと普通のビルドではソースコードが大きく変わってしまい不便です。
そのためUnicodeビルドにしてもそうでないときでもエラーが起きないようにプログラミングをすることがあります。そのときに_tstoiを利用します。具体的には
CString strData;
strData = _T(”123”);
int n = _tstoi(strData)
こうすると、Unicodeビルドでもそうでないときでもエラーが起きません。_T(””)は文字列をUnicodeビルドのときはWCHAR*として、そうでないときはchar*として扱うものです。_tstoiはUnicodeビルドのときはWCHAR*から数値、そうでないときはatoiと同等の機能を持つ関数です。
このようにatoiと_tstoiを使い分けます。このようなUnicodeビルドとそうでないときに使い分けるべき関数はたくさんあります。atofやatolなんかもそうですし、WindowsNT系で文字列を受け渡す関数の多くはWCHAR*とchar*用とで関数が2種類用意されています。
ちなみにCStringをCStringAとして利用するとUnicodeビルドをしてもchar*として扱うことができますし、同じようにCStringWとすると常にWCHAR*として利用が可能です。
Windowsプログラミングでよく見かけるLPCTSTRというのはCStringと同じでビルドによってchar*とWCHAR*が変わる文字の型です。これはconst TCHARで、TCHARというのはUnicodeビルドのときはWCHAR*になる文字列型になります。
なるほど・・・I18Nの場合は上記対応が必要なのですね。
お手数をお掛けしては・・・と思い、Unicodeビルドを行わなくて良い理由を探していたのですが、見つかりませんでした。以下の資料が一番近いのかな?とも思いますが明記されていません。<http://www.microsoft.com/japan/technet/prodtechnol/winxppro/evaluate/muiovw.mspx>重ね重ね申し訳ありませんが、Unicodeビルドを行わなくて良い理由を教えていただけないでしょうか?
<http://d.hatena.ne.jp/EguTaka/>
ご丁寧な回答、ありがとうございます。
すごく参考になりました。
最後に「・・・Unicodeビルトにしなくても大丈夫です」とあるのですが、これは「atoi」も使用可能と考えてよろしいでしょうか? (出典はわすれましたが、atoi使用禁止、代わりに_ttoiをと記載されている所があったので。)
また、ご返答の内容は、どのようにして学ばれたのでしょうか、重ねてご質問させてください。