|
ATL/MFC共有版のCStringについて
VC6.0(MFC4.2)まではCStringはMFCの単純な1クラスに過ぎなかったのですが、.net(MFC7.0)以降では、CStringはATL/MFCの共有クラスになりました。
CStringはCStringTというテンプレートクラスが元になっています。これのデータ型を固定してtypedefしたものがCStringになっています。
afxstr.hで次のように定義されています。
typedef ATL::CStringT< wchar_t, StrTraitMFC< wchar_t > > CStringW;
typedef ATL::CStringT< char, StrTraitMFC< char > > CStringA;
typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;
|
これを見ると、MBCS(マルチバイト文字セット、1文字1バイトまたは2バイト)ではCStringA、Unicode文字型(1文字2バイト)ではCStringWを使います(wchar_tは2バイト)。ではCString型のTCHARとは何でしょうか?これはwinnt.hで定義されています。
#ifdef UNICODE // r_winnt
#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPWSTR LPTCH, PTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPUWSTR PUTSTR, LPUTSTR;
typedef LPCUWSTR PCUTSTR, LPCUTSTR;
typedef LPWSTR LP;
#define __TEXT(quote) L##quote // r_winnt
#else /* UNICODE */ // r_winnt
#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
typedef LPSTR LPTCH, PTCH;
typedef LPSTR PTSTR, LPTSTR, PUTSTR, LPUTSTR;
typedef LPCSTR PCTSTR, LPCTSTR, PCUTSTR, LPCUTSTR;
#define __TEXT(quote) quote // r_winnt
#endif /* UNICODE */ // r_winnt
|
これを見ると分かる通り、UNICODEが定義されているとTCHARはWCHAR、定義されていなければTCHARはchar型になります。要するにコンパイルスイッチによってANSI型にもUNICODE型にも変わるようになっているわけです。CStringがテンプレートクラスになったのは、このようにUNICODEに対応するためなんですね。
UNICODEを使用するかどうかは、MFCアプリケーションウィザードで設定します。

.netでMFCアプリケーションを作ると、デフォルトで"ユニコードライブラリを使用する"がチェックされているので、VC6.0から移行するとちょっと戸惑うところですね。
プロジェクトを作成した後で変更したい場合は、プロジェクトの設定で変更できます。

ここでは、
・UNICODE文字セットを使用する
・マルチバイト文字セットを使用する
・設定なし
の3種類から選択できます。「マルチバイト文字セット」というのはSJISなどのように1バイト文字と2バイト文字が混在する文字コードです。MBCSと呼ばれます。MBCSでは文字列はchar型で扱います。なので、2バイト文字の半分でちょん切れたりしないように、プログラマが気をつけなければいけません。
また、リテラル文字列にも同じようなマクロが用意されています。
_Tというマクロは、UNICODEが定義されていれば文字列をUNICODE型(1文字2バイト)に変換します。定義されていなければそのままになります。
プロジェクトがUNICODEの設定になっているときに次のような記述をするとコンパイルエラーになります。
char型からw_char型に変換できないということですね。この場合は_Tマクロをつかえばw_char型に変換されるのでコンパイルが通るようになります。
|