VisualStyle

WindowsAPIボタン作ると、

 Windows95の頃の「クラシックスタイル」で表示されます。

・これを今風のデザインにするには、

次のようにして、「ビジュアルスタイル」を適用させます。↓

 


#pragma comment( lib,”UxTheme.lib”)

// コモンコントロール6.0を使うように指定する。↓ (  マニフェストに書いてリンクさせる )

#pragma comment(linker,”\”/manifestdependency:type=’win32′ \
name=’Microsoft.Windows.Common-Controls’ version=’6.0.0.0′ \
processorArchitecture=’*’ publicKeyToken=’6595b64144ccf1df’ language=’*’\””)

// comctl32.lib  を使う。 ( ヘッダファイルは「Comctl.h」のまま )

// WindowsのバージョンXP以降であれば、Windowsのバージョンと同じスタイル適用される。

#include “Uxtheme.h”

int APIENTRY _tWinMain( 

HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow )
{

 

// 省略

 

// ボタンを作成する。

CButton* p_button1 = new CButton();

p_button1->Init( h_main_window, 0, L”ぼたん”, 0010040 );
p_button1->Show();

 

// ビジュアルスタイルを適用する。

::SetWindowTheme( p_button1->GetWindowHandle(), L”BUTTON”, 0 );

 

// 省略

}


 

引数2は、ウィンドゥクラス名で、下記のページ一覧があります。↓

http://msdn.microsoft.com/en-us/library/windows/desktop/bb773210(v=vs.85).aspx

 

msdnの説明。↓

http://msdn.microsoft.com/ja-jp/library/ms997646.aspx

 

・次のようにして適用することもできます。↓

 


// テーマを開く。

HTHEME h_theme = ::OpenThemeData( p_button1->GetWindowHandle(), L”BUTTON” );


::CloseThemeData( h_theme ); // テーマを閉じる。


 

通常のウィンドゥは、自動的に適用されますので必要ありません。

 

( ※デスクトップの設定画面で、クラシックスタイルに設定していた場合は、適用されません。 )

コメントする

カテゴリー: C++, WinAPI

「ハム太と作るC++ライブラリ0 -構文編-」

まだ執筆中なんですが、

C言語のところはそこそこ書けてるので、

退屈しのぎにどうぞ。↓

 

http://p.booklog.jp/book/74354/read

コメントする

カテゴリー: C++

STL::CBitSet

#pragma once
#ifndef _STL_BITSET_H_
#define _STL_BITSET_H_
#include <bitset>
using namespace std;
namespace STL
{
// =====================================================
// ビットセットクラスの定義 ( std::bitsetのラッパー )
//・「ビットセット」は、ビットフラグを扱いやすくしたコンテナ。
//   ( ビット操作に慣れた人には、物足りない内容であり、通常ならマクロで事足りる。 )
//・テンプレート引数には、使用するビット数を指定する。
//  ( たとえば、std::bitset<8> とした場合には、8bitフラグとなり、
//    0~7までの8つのビットを、bool型のフラグ変数のように使用することができる。 )
template<typename T>
class /* _EXPORT */ CBitSet
{
protected: // publicでもOK。
// —————————————————-
// データメンバ
std::bitset<T> bits; // ビットセット 本体。
public:
// —————————————————–<OK><テスト済み>
// コンストラクタ
CBitSet(void) : bits()
{
}
// —————————————————–<OK><テスト済み>
// コンストラクタ
CBitSet( const unsigned __int64 value_ ) : bits( value_ )
{
}
// —————————————————–<OK><テスト済み>
// デストラクタ
~CBitSet(void)
{
}
// —————————————————–<OK><テスト済み>
//【ビットセット】を返す。
   inline std::bitset<T>& GetBitSet(void)
   {
          return bits;
   }
// —————————————————–<OK><テスト済み>
//【ビットセット】を格納する。
   inline void SetBitSet( std::bitset<T>& bits_ )
   {
          bits = bits_;
   }
// —————————————————–<OK><テスト済み>
//【指定indexのビット】を、ONにする。                                  ( set() )
inline std::bitset<T>& SetOnAt( const size_t index_ )
{
                  return bits.set( index_ );
}
// —————————————————–<OK><テスト済み>
//【指定indexのビット】を、OFFにする。                             ( reset() )
inline std::bitset<T>& SetOffAt( const size_t index_ )
{
                  return bits.reset( index_ );
}
// —————————————————–<OK><テスト済み>
//【指定indexのビット】の、フラグ値 ( 0か1 ) を返す。             ( test() )
inline bool GetValue( const size_t index_ )
{
                  return bits.test( index_ );
}
// —————————————————–<OK><テスト済み>
//【指定indexのビット】に、フラグ値 ( 0か1 ) を設定する。         ( set() )
inline std::bitset<T>& SetValue( const size_t index_, const bool value_ )
{
                 return bits.set( index_ );
}
// —————————————————–<OK><テスト済み>
//【すべてのビット】を、OFFにする。                                   ( reset() )
inline std::bitset<T>& SetOffAll(void)
{
                  return bits.reset();
}
// —————————————————–<OK><テスト済み>
//【指定indexのビット】を、反転する。                                   ( flip() )
inline std::bitset<T>& FlipAt( const size_t index_ )
{
                  return bits.flip( index_ );
}
// —————————————————–<OK><テスト済み>
//【すべてのビット】を、反転する。                                         ( flip() )
inline std::bitset<T>& FlipAll(void)
{
                 return bits.flip();
}
// —————————————————–<OK><テスト済み>
//【いずれかのビット】がONなら、TRUEを返す。                     ( any() )
inline bool IsAnyOn(void)
{
                 return bits.any();
}
// —————————————————–<OK><テスト済み>
//【すべてのビット】がONなら、TRUEを返す。                          ( all() )
inline bool IsAllOn(void)
{
                 return bits.all();
}
// —————————————————–<OK><テスト済み>
//【すべてのビット】がOFFなら、TRUEを返す。                    ( none() )
inline bool IsAllOff(void)
{
                  return bits.none();
}
// —————————————————–<OK><テスト済み>
//【ONになっているビットの数】を返す。                            ( count() )
inline size_t GetOnCount(void)
{
                 return bits.count();
}
// —————————————————–<OK><テスト済み>
//【ビットの数】を返す。                                                       ( size() )
inline size_t GetBitCount(void)
{
                 return bits.size();
}
// —————————————————–<OK><テスト済み>
//【符号なし32bit整数値】を返す。                              ( to_ulong() )
inline unsigned int ToUInt32(void)
{
                 return bits.to_ulong();
}
// —————————————————–<OK><テスト済み>
//【符号なし64bit整数値】を返す。                              ( to_ullong() )
inline unsigned __int64 ToUInt64(void)
{
                  return bits.to_ullong();
}
// —————————————————–<OK><テスト済み>
//【文字列】を返す。                     ( to_string() )
// “00101010” といった文字列が返る。
inline std::string ToString(void)
{
                 return bits.to_string();
}
// ————————————————-
// #################################################
// 演算子のオーバーロード
// #################################################
// ————————————————-<OK><テスト済み>
//  指定index_ ビット値を返す。
inline bool operator[]( const size_t index_ )
{
return bits[ index_ ];
}
// ————————————————-<OK><テスト済み>
//  指定index_ 参照を返す。
inline std::bitset::reference operator[]( const size_t index_ )
{
return bits[ index_ ];
}
// ————————————————-<OK><テスト済み>
//  instance = CBitSet
inline CBitSet<T>& operator=( const CBitSet<T>& bits_ )
{
bits = bits_.GetBitSet();
}
// ————————————————-<OK><テスト済み>
//  instance |= CBitSet
inline CBitSet<T>& operator|=( const CBitSet<T>& bits_ )
{
bits |= bits_.GetBitSet();
}
// ————————————————-<OK><テスト済み>
//  instance ^= CBitSet
inline CBitSet<T>& operator^=( const CBitSet<T>& bits_ )
{
bits ^= bits_.GetBitSet();
}
// ————————————————-<OK><テスト済み>
//  ~instance
inline CBitSet<T>& operator~()
{
return ~bits;
}
// ————————————————-<OK><テスト済み>
// instance << shift_bit_count_
inline CBitSet<T> operator<<( const size_t shift_bit_count_ )
{
return ( bits <<  shift_bit_count_);
}
// ————————————————-<OK><テスト済み>
// instance >> shift_bit_count_
inline CBitSet<T> operator>>( const size_t shift_bit_count_ )
{
return ( bits >>  shift_bit_count_);
}
// ————————————————-<OK><テスト済み>
// instance <<= shift_bit_count_
inline CBitSet<T>& operator<<=( const size_t shift_bit_count_ )
{
return ( bits <<= shift_bit_count_);
}
// ————————————————-<OK><テスト済み>
// instance >>= shift_bit_count_
inline CBitSet<T>& operator>>=( const size_t shift_bit_count_ )
{
return ( bits >>= shift_bit_count_);
}
// ————————————————-<OK><テスト済み>
//  bool result = ( instance == CBitSet )
inline bool operator==( CBitSet<T>& bits_ )
{
return ( bits == bits_.GetBitSet() );
}
// ————————————————-<OK><テスト済み>
//  bool result = ( instance != CBitSet )
inline bool operator!=( CBitSet<T>& bits_ )
{
return ( bits != bits_.GetBitSet() );
}
// —————————————————–
}; // end class
}; // end namespace
// —————————————————-
#endif

コメントする

カテゴリー: C++, STL

STL::CStringW

#pragma once

#ifndef _STL_STRINGW_H_
#define _STL_STRINGW_H_
#include <vector>
#include <string>
using namespace std;
namespace STL
{

// ———————————————————————
// NotFound定数 ( 検索した際に、条件に一致する位置が見つからなかった時に返る値。)

#define NotFound 4294967295 // std::wstring::npos
// ———————————————————————
// ワイド文字列クラスの定義 ( std::wstringのラッパー )

//・UTF-16LE ( Unicode文字列。1文字の文字コードは、2byte固定 )

class /*_EXPORT */ CStringW
{

// ————————————————-
// データメンバ

protected:

std::wstring text; // ワイド文字列の本体。

// マルチバイトを使う場合は、ここを std::string にする。

public:

// —————————————————–<OK><テスト済み>
// イテレーター

typedef std::wstring::iterator Iterator; // 通常のイテレーター (ランダムアクセス)

typedef std::wstring::reverse_iterator RevIterator; // 逆順イテレーター (ランダムアクセス)
// ————————————————-
// コンストラクタ

CStringW(void) : text()
{

}

// ————————————————-
// コンストラクタ

CStringW( CStringW& text_ ) : text( text_.GetString() )
{

}

// ————————————————-
// コンストラクタ

CStringW( const std::wstring& text_ ) : text( text_ )
{

}

// ————————————————-<OK><テスト済み>
// コンストラクタ

CStringW( const WCHAR* p_text_ ) : text( p_text_ )
{

}

// ————————————————-<OK><テスト済み>
// デストラクタ

~CStringW(void)
{

}

// ————————————————-<OK><テスト済み>
//【ワイド文字列】を返す。

inline std::wstring& GetString(void)
{
return text;
}

// ————————————————-<OK><テスト済み>
//【ワイド文字列】を変更する。

inline void SetString( std::wstring& text_ )
{
text = text_;
}

// ————————————————-<OK><テスト済み>
//【指定indexの1文字】を返す。 ( at() )

inline WCHAR GetChar( const size_t index_ )
{
return text.at( index_ );
}

// ————————————————-<OK><テスト済み>
//【ポインタ】を返す。 ( c_str() )

// ※返される文字列は、終端に必ずNULL文字が付加されている。
// ・文字数0の場合、p_result[0]は、NULL文字。
// ・p_result[ length ] は、NULL文字。

inline const WCHAR* GetPtr(void)
{
return text.c_str(); // data() と同じ。
}

// —————————————————–<OK><テスト済み>
//【指定indexのイテレータ】を返す。

// ※戻り値のイテレータを、参照にしていないのには理由がある。
// このクラスがローカル変数として宣言された場合、
// スタック領域のアドレスを返してしまうためコケるからである。

inline Iterator GetItr( const size_t index_ )
{
return ( text.begin() + index_ );

}

// ————————————————-
//【文字数】を返す。 ( length() or size() )

// ※終端のNULL文字を含まない。

inline size_t GetLength()
{
return text.length();
}

// ————————————————-
//【最大文字数】を返す。 ( max_size() )

inline size_t GetMaxLength()
{
return text.max_size();
}

// ————————————————-<OK><テスト済み>
//【文字列】を初期化する。 ( assign() )

// ※ std::wstring::value_type は、wchar_t 。

// STL::CStringW text1;
// text1.Init( L”あいうえお”, 3 ); // text1 は、”あいう” で初期化される。

inline std::wstring& Init( const WCHAR* p_text_ )
{
return text.assign( p_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を初期化する。 ( append() )

// STL::CStringW text1;
// text1.Init( L”あいうえお”, 3 ); // text1 は、”あいう” で初期化される。

inline std::wstring& Init( const WCHAR* p_text_ , const size_t length_ )
{
return text.assign( p_text_, length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】で初期化する。 ( append() )

// STL::CStringW text1;
// std::wstring text2( L”かきくけこ” );
// text1.InitByString( text2 ); // text1 は、”かきくけこ” で初期化される。

inline void InitByString( const std::wstring& text_ )
{
text.assign( text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】で初期化する。 ( append() )

// STL::CStringW text1;
// std::wstring text2( L”かきくけこ” );
// text1.InitByString( text2, 1, 2 ); // text1 は、”きく” で初期化される。

inline std::wstring& InitByString(
const std::wstring& text_, // この文字列中の、部分文字列で初期化される。
const size_t start_index_, // 部分文字列の開始位置。
const size_t length_ // 部分文字列の文字数。
)
{
return text.assign( text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定した文字】で初期化する。 ( append() )

// STL::CStringW text1;
// text1.InitByChar( L’あ’, 3 ); // text1 は、”あああ” で初期化される。

inline std::wstring& InitByChar( const WCHAR char_, const size_t count_ )
{
return text.assign( count_, char_ );
}

// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】で初期化する。( ポインタ版 ) ( append() )

// STL::CStringW text1;
// WCHAR src[] = L”かきくけこ”;
// text1.InitByRange( src + 1, src + 3 ); // text1 は、”きく” で初期化される。

inline std::wstring& InitByRange( const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
return text.assign( p_src_start_, p_src_end_ );
}

// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】で初期化する。( イテレータ版 ) ( append() )

// STL::CStringW text1;
// std::wstring src( L”かきくけこ”);
// std::wstring::iterator itr = src.begin();
// text1.InitByRange( itr + 1, itr + 3 ); // text1 は、”きく” で初期化される。

inline std::wstring& InitByRange( const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
return text.assign( src_start_itr_, src_end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】と比較する。 ( compare() )

// ※この比較では、大文字・小文字は区別される。
// ( ( L”Uma” == L”uma” ) は false )

inline bool Compare( const std::wstring& text_ )
{
return ( text.compare( text_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列】を比較する。( compare() )

// 引数1,2で指定された範囲の部分文字列と、指定された文字列を比較する。

inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const std::wstring& text_ // 比較する文字列。
)
{
return ( text.compare( index_, length_, text_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列の指定範囲】を比較する。( compare() )

inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const std::wstring& text_, // 比較する文字列。
const size_t text_offset_, // 比較する部分のオフセット。 ( 指定文字列の )
const size_t text_length_ // 比較する部分の文字数。( 指定文字列の )
)
{
return ( text.compare( index_, length_, text_, text_offset_, text_length_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】と比較する。 ( compare() )

inline bool Compare( const WCHAR* p_text_ )
{
return ( text.compare( p_text_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列】を比較する。( compare() )

inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const WCHAR* p_text_ // 比較する文字列。
)
{
return ( text.compare( index_, length_, p_text_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定範囲】と【指定文字列の指定範囲】を比較する。( compare() )

inline bool Compare(
const size_t index_, // 比較する部分のオフセット。 ( この文字列の )
const size_t length_, // 比較する部分の文字数。( この文字列の )
const WCHAR* p_text_, // 比較する文字列。
const size_t text_length_ // 比較する部分の文字数。( 指定文字列の )
)
{
return ( text.compare( index_, length_, p_text_, text_length_ ) == 0 );
}

// ————————————————-<OK><テスト済み>
//【指定範囲の部分文字列】を切り出して返す。( substr() )

// ※【戻り値】を参照にすると、【ローカルのアドレス】が返る。

inline std::wstring SubString( const size_t start_index_, const size_t length_ )
{
return text.substr( start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )

// ※ std::wstring::value_type は、wchar_t 。

inline std::wstring& Add( const WCHAR* p_text_ )
{
return text.append( p_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )

inline std::wstring& Add( const WCHAR* p_text_ , const size_t length_ )
{
return text.append( p_text_, length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )

inline std::wstring& Add( const std::wstring& text_ )
{
return text.append( text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を追加する。 ( append() )

inline std::wstring& Add( const std::wstring& text_ , const size_t start_index_, const size_t length_ )
{
return text.append( text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【文字】を末尾に追加する。 ( push_back() )

inline void AddChar( const WCHAR char_ )
{
text.push_back( char_ );
}

// ————————————————-<OK><テスト済み>
//【指定した文字】を指定した文字数だけ追加する。 ( append() )

inline std::wstring& AddChar( const WCHAR char_, const size_t count_ )
{
return text.append( count_, char_ );
}

// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】を追加する。( ポインタ版 ) ( append() )

// WCHAR src_text[] = L”かきくけこ”;
// std::wstring added_text = t1.Add( src_text + 1, src_text + 3 ); // “きく” が追加される。

inline std::wstring& Add( const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
return text.append( p_src_start_, p_src_end_ );
}

// ————————————————-<OK><テスト済み>
//【指定範囲の文字列】を追加する。( イテレータ版 ) ( append() )

// std::wstring src_text( L”かきくけこ”);
// std::wstring::iterator itr = src_text.begin();
// std::wstring added_text = t1.Add( itr + 1, itr + 3 ); // “きく” が追加される。

inline std::wstring& Add( const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
return text.append( src_start_itr_, src_end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

inline std::wstring& Insert( const size_t index_, const WCHAR* p_text_ )
{
return text.insert( index_, p_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

// text1.Insert( 1, L”かきくけこ”, 3 ); // 2文字目に、”かきく” が挿入される。( 引数3は、挿入する文字数 )

inline std::wstring& Insert( const size_t index_, const WCHAR* p_text_, const size_t text_length_ )
{
return text.insert( index_, p_text_, text_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

inline std::wstring& Insert( const size_t index_, const std::wstring& text_ )
{
return text.insert( index_, text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

// std::wstring src( L”かきくけこ” );
// text1.InsertByRange( 1, src, 1, 2 ); // 2文字目に、”きく” を挿入する。

inline std::wstring& InsertByRange(
const size_t index_,
const std::wstring& text_,
const size_t text_offset_,
const size_t text_length_
)
{
return text.insert( index_, text_, text_offset_, text_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

// ※【指定したイテレータの指す位置までの文字列】で初期化される。
//
// text1.Insert( text1.GetFirstItr() + 2 ); // 2文字目までの文字列になる。

// ※他のインスタンスのイテレーターを渡すとコケる。
// ※begin()で取得したイテレータをそのまま渡すとコケる。( 1文字目は、begin() + 1 )

//・使い道がよくわからない。おそらく使うことはない。

inline Iterator Insert( Iterator itr_ )
{
return text.insert( itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字】を挿入する。 ( insert() )

//・【イテレータで指定した位置】に、【指定した文字】を挿入する。

inline Iterator InsertByChar( Iterator itr_, WCHAR char_ )
{
return text.insert( itr_, char_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

//・上記に加えて、さらに【挿入する文字数】を指定できる。

inline void InsertByChar( Iterator itr_, WCHAR char_, const size_t count_ )
{
text.insert( itr_, count_, char_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

// text1.InsertByChar( 1, L’か’, 3 );
//
// ・2文字目から、’か’ が 3文字、挿入される。( “あかかかいうえお” )

inline std::wstring& InsertByChar(
const size_t index_,
const WCHAR char_,
const size_t count_
)
{
return text.insert( index_, count_, char_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

inline void InsertByRange( Iterator itr_, const WCHAR* p_src_start_, const WCHAR* p_src_end_ )
{
text.insert( itr_, p_src_start_, p_src_end_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

inline void InsertByRange( Iterator dest_start_itr_, const Iterator src_start_itr_, const Iterator src_end_itr_ )
{
text.insert( dest_start_itr_, src_start_itr_, src_end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を挿入する。 ( insert() )

//・TInputIteratorには、読み取り専用のイテレータ型を指定する。

// STL::stringW t1( L”あいうえお” );
// std::string t2( “かきくけこ” );
// t1.InsertByRange<std::string::iterator>( t1.GetItr(1), t2.begin(), t2.end() );
//
// → “あきいうえお” とはならず、stringの箇所が文字化けしている。
// ( 要するに、挿入は成功したが、文字コードが異なるため、文字化けしている、 )

template<typename TInputIterator>
inline void InsertByRangeEx( Iterator itr_, TInputIterator src_start_itr_, TInputIterator src_end_itr_ )
{
text.insert( itr_, src_start_itr_, src_end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列の指定部分】を削除して返す。 ( erase() )

// text1.RemoveAt( 1, 2 ); // 2文字目以降の2文字が削除される。 ( “あいうえお” → “あえお” )

inline std::wstring& RemoveAt( const size_t index_, const size_t length_ )
{
return text.erase( index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定indexの1文字】を削除し、【次の文字のイテレーター】を返す。( erase() )

// text1.Remove( text1.GetItr( 1 ) ); // 2文字目が削除される。
//
//・2文字目が削除されたので、3文字目が2文字目に移動する。
// 戻り値のイテレーターは、この文字を指している。

inline Iterator RemoveChar( Iterator itr_ )
{
return text.erase( itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列の指定範囲】を削除し、【次の文字のイテレーター】を返す。 ( erase() )

// text1.RemoveByRange( text1.GetItr(1), text1.GetItr(2) ); // 2文字目から3文字目の範囲 ( 2文字目 ) が削除される。

inline Iterator RemoveByRange( Iterator start_itr_, Iterator end_itr_ )
{
return text.erase( start_itr_, end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】をクリアする。 ( clear() )

inline void Clear(void)
{
text.clear();
}

// ————————————————-<OK><テスト済み>
// カラ文字列ならtrueを返す。 ( empty() )

inline bool IsEmpty(void)
{
return text.empty();
}

// ————————————————-<OK><テスト済み>
//【文字列の指定範囲】をコピーする。  ( substr() )

// ※戻り値が参照でないのは、ローカルのアドレスを含んだ参照を返すためである。
// ( 参照にしても動作はするが、コンパイル時に警告が表示される )

inline std::wstring Substring( const size_t index_, const size_t length_ )
{
return text.substr( index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】をコピーする。 (コピーした文字数を返す) ( _Copy_s() )

//・copy()が使いものにならないため、安全性の高い_Copy_s()を使用している。
// ( この手の_s系メソッドで、コピー先とコピー元の要素数を指定しているのは、バッファオーバーランを防止するためである )

inline WCHAR* Copy(void)
{
size_t src_length = text.length(); // コピー元の文字数を取得しておく。

WCHAR* p_dest = new WCHAR[ src_length + 1 ]; // コピー先の文字列バッファを確保する。( +1 は、終端のNULL文字 )

size_t writed_length = text._Copy_s( p_dest, src_length + 1, src_length, 0 ); // コピーする。
//
// p1: コピー先の文字列バッファへのポインタ。
// p2: コピー先の文字列バッファの要素数。( 文字数 )
// p3: コピー元の文字数。
// p4: コピーを開始するオフセット位置。( コピー元のindex )
//
// 戻り値: コピーされた文字数が返る。

p_dest[ src_length ] = NULL; // 終端にNULL文字を入れる。

return p_dest;
}

// ————————————————-<OK><テスト済み>
//【文字列】を交換する。 ( swap() )

inline void Swap( CStringW& text_ )
{
text.swap( text_.GetString() );
}

// ————————————————-<OK><テスト済み>
//【文字数】を変更する。 ( resize() )

// ・追加された要素は、0クリアされている。
// ( “あいうえお” → “あいうえお” )

// ・一般的には、NULL文字までが文字列とみなされるが、
// lengthで返る文字数には、増加分も含まれている。
// ( ただし、NULL文字なので、表示はされない )

inline void Resize( const size_t new_length_ ) // 新しい文字数。
{
text.resize( new_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字数】を変更する。 ( resize() )

// text.ResizeEx( 10, L’無’ ); // → “あいうえお無無無無無”

inline void ResizeEx(
const size_t new_length_, // 新しい文字数。
const WCHAR default_char_ // 新規要素は、この文字で初期化される。
)
{
text.resize( new_length_, default_char_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// 引数1~2の指定範囲を、指定文字列に置き換える。( ※一般的な、「検索→置換」とは別物 )

inline std::wstring& Replace(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR* p_src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( index_, length_, p_src_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

inline std::wstring& Replace(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const std::wstring& src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( index_, length_, src_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), text2 ); // → “あかきくけこうえお”

inline std::wstring& Replace(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const std::wstring& src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// text1.Replace( 1,2, L’■’, 3 ); // → “あ■■■えお”

inline std::wstring& ReplaceByChar(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR src_char_, // 置き換える文字。 (置換元)
const size_t src_char_count_ // 置き換える文字の文字数。(置換元)
)
{
return text.replace( index_, length_, src_char_count_, src_char_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字】に置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L’■’ ); // → “あ■■■うえお”

inline std::wstring& ReplaceByChar(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR src_char_, // 置き換える文字。 (置換元)
const size_t src_char_count_ // 置き換える文字の文字数。(置換元)
)
{
return text.replace( start_itr_, end_itr_, src_char_count_, src_char_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// 指定範囲を、指定文字列の先頭から指定文字数の部分文字列で置き換える。

// STL::CStringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( 1, 2, L”かきくけこ”, 2 ); // → “あかきえお”

inline std::wstring& ReplaceByRange(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const WCHAR* p_src_text_, // 置き換える文字列。 (置換元)
const size_t src_length_ // 置換範囲の文字数。 (置換元)
)
{
return text.replace( index_, length_, p_src_text_, src_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::CStringW text1( L”あいうえお” );
// std::wstring text2( L”かきくけこ” );
// text1.Replace( 1, 2, text2, 1, 2 ); // → “あきくえお”

inline std::wstring& ReplaceByRange(
const size_t index_, // 置換範囲のオフセット位置。 (置換先)
const size_t length_, // 置換範囲の文字数。 (置換先)
const std::wstring& src_text_, // 置き換える文字列。 (置換元)
const size_t src_offset_, // 置換範囲のオフセット位置。 (置換元)
const size_t src_length_ // 置換範囲の文字数。 (置換元)
)
{
return text.replace( index_, length_, src_text_, src_offset_, src_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L”かきくけこ” ); // → “あかきくけこうえお”

inline std::wstring& ReplaceByRange(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_text_ // 置き換える文字列。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_text_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// text1.Replace( text1.GetItr(1), text1.GetItr(2), L”かきくけこ” ); // → “あかきうえお”

inline std::wstring& ReplaceByRange(
const Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
const Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_text_, // 置き換える文字列。 (置換元)
const size_t src_length_ // 置換範囲の先頭からの文字数。(置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_text_, src_length_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW text1( L”あいうえお” );
// WCHAR src[] = L”らりるれろ”;
// t1.ReplaceByRange( t1.GetItr(1), t1.GetItr(2), src + 1, src + 3 ); // → “あらりうえお”

inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const WCHAR* p_src_start_, // 置換範囲の始点ポインタ。 (置換元)
const WCHAR* p_src_end_ // 置換範囲の終点ポインタ。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, p_src_start_, p_src_end_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW t1( L”あいうえお” );
// STL::stringW t2( L”かきくけこ” );
// t1.ReplaceByRange( t1.GetItr(1), t1.GetItr(2), t2.GetItr(1), t2.GetItr(2) ); // → “あきうえお”

inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
const Iterator src_start_itr_, // 置換範囲の始点イテレーター。 (置換元)
const Iterator src_end_itr_ // 置換範囲の終点イテレーター。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_start_itr_, src_end_itr_ );
}

// ————————————————-<OK><テスト済み>
//【文字列】を置換する。 ( replace() )

// STL::stringW t1( L”あいうえお” );
// STL::stringW t2( L”かきくけこ” );
// t1.ReplaceByRange<std::wstring::iterator>( t1.GetItr(1), t1.GetItr(2), t2.GetItr(1), t2.GetItr(2) ); // → “あきうえお”

template<class TInputIterator>
inline std::wstring& ReplaceByRange(
Iterator start_itr_, // 置換範囲の始点イテレーター。 (置換先)
Iterator end_itr_, // 置換範囲の終点イテレーター。 (置換先)
TInputIterator src_start_itr_, // 置換範囲の始点イテレーター。 (置換元)
TInputIterator src_end_itr_ // 置換範囲の終点イテレーター。 (置換元)
)
{
return text.replace( start_itr_, end_itr_, src_start_itr_, src_end_itr_ );
}
// ————————————————-<OK><テスト済み>
//【指定文字】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )

// STL::stringW t1( L”あいうえお” );
//
// size_t result = text1.IndexOf( L’う’, 0 ); // 要素[0]から検索する。
//
// if ( result == wstring::npos ) // 該当indexが無い場合は、trueになる。
// else // 今回は、要素[2]が ‘う’ なので、2 が返る。

inline size_t IndexOf( const WCHAR char_, const size_t start_index_ = 0 )
{
return text.find( char_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )

// size_t result = text1.IndexOf( L”えお”, 0 ); // 3 が返る。

inline size_t IndexOf( const WCHAR* p_text_, const size_t start_index_ = 0 )
{
return text.find( p_text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )

// size_t result = text1.IndexOf( L”えお”, 0, 4 ); // 4文字目まで判定する。( 結果は npos )
//
// ※ 4文字目の要素[3] には、’え’ があるが、
// 5文字目の要素[4] の ‘お’ が範囲外で判定されないため、nposを返す。

inline size_t IndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find( p_text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find() )

inline size_t IndexOf( const std::wstring& text_, const size_t start_index_ = 0 )
{
return text.find( text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )

inline size_t NotIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_first_not_of( char_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )

inline size_t NotIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_first_not_of( p_text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )

inline size_t NotIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_first_not_of( p_text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最初に見つかった箇所の先頭index】を返す。 ( find_first_not_of() )

inline size_t NotIndexOf( const std::wstring& text_, const size_t start_index_ )
{
return text.find_first_not_of( text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )

inline size_t LastIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_last_of( char_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )

inline size_t LastIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_last_of( p_text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )

inline size_t LastIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_last_of( p_text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列】を検索し、【最後に見つかった箇所の先頭index】を返す。 ( find_last_of() )

inline size_t LastIndexOf( const std::wstring& text_, const size_t start_index_ )
{
return text.find_last_of( text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )

inline size_t NotLastIndexOf( const WCHAR char_, const size_t start_index_ )
{
return text.find_last_not_of( char_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )

inline size_t NotLastIndexOf( const WCHAR* p_text_, const size_t start_index_ )
{
return text.find_last_not_of( p_text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )

inline size_t NotLastIndexOf( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.find_last_not_of( p_text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を検索し、【最後に見つかった箇所の先頭index】を返す。( find_last_not_of() )

inline size_t NotLastIndexOf( const std::wstring text_, const size_t start_index_ )
{
return text.find_last_not_of( text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )

inline size_t IndexOf_Reverse( const WCHAR char_, const size_t start_index_ )
{
return text.rfind( char_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )

inline size_t IndexOf_Reverse( const WCHAR* p_text_, const size_t start_index_ )
{
return text.rfind( p_text_, start_index_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )

inline size_t IndexOf_Reverse( const WCHAR* p_text_, const size_t start_index_, const size_t length_ )
{
return text.rfind( p_text_, start_index_, length_ );
}

// ————————————————-<OK><テスト済み>
//【指定文字列以外】を逆順に検索し、【最初に見つかった位置】を返す。( rfind() )

inline size_t IndexOf_Reverse( const std::wstring& text_, const size_t start_index_ )
{
return text.rfind( text_, start_index_ );
}

// —————————————————–<OK><テスト済み>
//【内部的に確保される要素数】を返す。 ( capacity() )

//・未設定の状態だと、要素数が設定されている。

inline size_t GetCapacity(void)
{
return text.capacity();
}

// —————————————————–<OK><テスト済み>
//【内部的に確保される要素数】を変更する。 ( reserve() )

// ※wstringは、内部的にメモリ領域を多めに確保していて、この値は、その際の要素数。
// 多めに見積もっておけば、要素数が拡張された際の、再確保&コピーをしなくて済む。
//
// ・この値は、wstring::capacity()で取得できる。
// ・多すぎる場合は、wstring::shrink_to_fit()で切り詰めることができる。

inline void SetCapacity( const size_t capacity_ )
{
text.reserve( capacity_ );
}

// ————————————————-<OK><テスト済み>
//【先頭のイテレータ】を返す。 ( begin() )

inline Iterator GetFirstItr(void)
{
return text.begin();
}

// ————————————————-<OK><テスト済み>
//【末尾のイテレータ】を返す。 ( end() )

inline Iterator GetLastItr(void)
{
return text.end();
}

// —————————————————–<OK><テスト済み>
// 逆順ループ時の【最初の要素([count-1])のイテレータ】を返す。( rbegin() )

inline RevIterator GetFirstItr_Rev(void)
{
return text.rbegin();
}

// —————————————————–<OK><テスト済み>
// 逆順ループ時の【最後の要素([0])のイテレータ】を返す。( rend() )

inline RevIterator GetLastItr_Rev(void)
{
return text.rend();
}

// ————————————————-
// #################################################
// 演算子のオーバーロード
// #################################################
// ————————————————-
// CString = instance + CString

inline std::wstring& operator+( std::wstring& text_ )
{
text += text_;

return text;
}

// ————————————————-
// instance += CString

inline void operator+=( std::wstring& text_ )
{
text += text_;
}

// ————————————————-
// instance = CString

inline void operator=( std::wstring& text_ )
{
text = text_;
}

// ————————————————-
// bool result = ( instance == CString )

inline bool operator==( std::wstring& text_ )
{
return (text == text_);
}

// ————————————————-
// #################################################
// static 関数
// #################################################
// ————————————————-
//【ワイド文字列】を、【Int32値】に変換して返す。( stol() )

//static inline int ToInt32(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
//return std::stol( text_, start_index_, base_ );
// }

//// ————————————————-
////【ワイド文字列】を、【UInt32値】に変換して返す。( stoul() )

//static inline unsigned int ToUInt32(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoul( text_, start_index_, base_ );
// }

//// ————————————————-
////【ワイド文字列】を、【Int64値】に変換して返す。( stoll() )

//static inline __int64 ToInt64(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoll( text_, start_index_, base_ );
// }

//// ————————————————-
////【ワイド文字列】を、【UInt64値】に変換して返す。( stoull() )

//static inline unsigned __int64 ToUInt64(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0, // オフセット位置。
// const int base_ = 10 // 基数。規定値は10。( 10進数表記 )
// )
// {
// return std::stoull( text_, start_index_, base_ );
// }

//// ————————————————-
////【ワイド文字列】を、【float値】に変換して返す。( stof() )

//static inline float ToFloat(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0 // オフセット位置。
// )
// {
// return std::stof( text_, start_index_ );
// }

//// ————————————————-
////【ワイド文字列】を、【double値】に変換して返す。( stod() )

////・「long double」版のstold()には、「long」が付いているが、doubleと同じ64bit。

//static inline double ToDouble(
// const std::wstring text_, // 変換する文字列。
// const size_t start_index_ = 0 // オフセット位置。
// )
// {
// return std::stod( text_, start_index_ );
// }

//// ————————————————-
////【double値】を、【ワイド文字列】に変換して返す。( to_wstring() )

//static inline std::wstring FromDouble( long double value_ )
// {
// return std::to_wstring( value_ );
// }

//// ————————————————-
////【long long値】を、ワイド文字列に変換して返す。( to_wstring() )

//static inline std::wstring FromInt64( __int64 value_ )
// {
// return std::to_wstring( value_ );
// }

//// ————————————————-
////【unsigned long long】値を、ワイド文字列に変換して返す。( to_wstring() )

//static inline std::wstring FromUInt64( unsigned __int64 value_ )
// {
// return std::to_wstring( value_ );
// }

// ————————————————-

}; // end class

}; // end namespace

// ————————————————-
#endif

コメントする

カテゴリー: C++, STL

文字コードの概要

コンピュータ上で文字列を扱う場合は、

.NetJavaには、stringという基本データ型があります。

// ——————————

// string型の文字列変数「namae」に、文字列を代入する。

string namae = “ハム太”;

// ——————————

ネイティブC/C++で書く場合でも、

STLを使っていい場合なら、std::string クラスがあるし、

MFCを使う場合は、CStringクラスを使えば、同じような事ができます。

しかし、WindowsAPI や、その他のCOMライブラリなどでは

これらのクラスは対応しておらず、直接渡すことはできません。

これらの関数引数には、文字配列を渡す必要があります。

// ————————————–

char multi_text [] = “あいうえお”;          // マルチバイト文字の配列。

wchar_t wide_text[] = L“あいうえお”;  // ワイド文字の配列。

// ————————————–

大きく分けて、この二通りがあるんですが、

SJISで書く場合には、char型 (マルチバイト文字) を使い、

Unicodeで書く場合は、wchar_t 型 (ワイド文字) を使います。

あとで決めたい場合は、TCHAR型を使います。

TCHAR型は、_UNICODE定数が#defineされている場合は

wchar_t として解釈され、そうでない場合は、charとして解釈されます。

// ——————————-

// TCHAR型の定義

#ifdef _UNICODE
typedef wchar_t TCHAR
#elseif
  typedef char TCHAR
#endif

// ——————————-

Cランタイムの関数WindowsAPIの関数も、
文字列を扱うものは、2通り定義されていて、

たとえばMessageBox関数には、

ANSI (の日本語拡張のSJISなど、マルチバイト文字)  に対応した MessageBoxA関数と、

Unicode(のUTF-16などワイド文字)に対応したMessageBoxW関数があり、

単に、「MessageBox」と書いた場合には、

渡された引数によって、切り替わるようになっています。

コンピューターの内部では、文字データは、

文字コード」という番号で、記録されています。

顔文字などで有名な「ASCIIコードセット」は、

英数字基本的な記号しか扱わないため、

1文字のコードを、0~127番までの7bitで記録しています。

( 1バイト固定であるので、「シングルバイト文字」という。
日本語版のasciiには、半角カナ文字があって、

161~223番を使用するため、8bit (1バイト) をフルに使う )

しかし、日本語環境では、ひらがなカタカナに加えて、

膨大な数の漢字を使用するため、

1バイト ( 0~255 ) では到底足りません。

そこで登場するのがマルチバイト文字で、

一般的には、「SJISコードセット」が使用されますが、

( 日本語版のWindowsでは、日本語拡張版の「cp932コードセット」が標準。

つまり、特に指定しない場合は、char配列は、

cp932の文字コードの配列」として解釈されるのです。)

これらのコード体系のデータでは、ASCIIコードに加えて、

2byte以上の文字混在して記録されています。

このマルチバイト文字は、全角文字が使用できる一方で、

—————————————–

1文字おおよそ3バイト使用する。

・何文字目か、わかりにくい。( 判定する手間がかかる )

—————————————–

などの難点もあります。

これに対して、ワイド文字では、

1文字を、おおむね2バイトで記録します。

( 半角文字では、未使用の1バイト0で埋められます。)

このワイド文字は、おもにUnicodeで使用されます。

Unicodeは、世界中の文字を

混在して記録できるようにするために制定された

ワールドワイドなコード体系で、正確には

1文字4バイトで記録している文字もあります。

ただし、これらの文字はまだ、API側で未対応のため、

MessageBoxWに渡しても、文字化けしてしまいます。

( 普段は使わないような難解な漢字なので、無視しても無問題 )

これに対応するためなのか、どうかわかりませんが、

1文字4バイトで記録しているファイルフォーマットがあります。

————————————–

UTF-8」 … マルチバイト文字のUnicode。

UTF-16」… 1文字を2バイトで記録しているUnicode。

UTF-32」 … 1文字を4バイトで記録しているUnicode。 ←コレ

————————————–

テキストファイルの場合は、
先頭に「BOM」(ByteOrderMark) が記録されていて、
テキストエディタなどで読み込まれる際には、これに応じて

どの方式で記録されたデータかを判別して表示しています。

しかし、必ずしもBOMが記録されているとは限らないため、

その場合には、エディタがどのコードセットのデータなのか判別できず

文字化けして表示されてしまいます。

Unicodeは本来、「文字化け」を解消しようとして

制定された統一規格だったのですが、

あとで追加された文字によって、

2バイト ( 0~65535 ) では足りなくなり、

前述の、ファイルへの記録方式のこともあって、

完全な問題解決には至っていません。

UNIXMacではUTF32BEが使用されているようで、

将来的にはUTF32BEで統一されるのかも知りません。

( 「BE」は、「ビックエンディアン」の略。

Windowsは、「LE」(リトルエンディアン)方式でファイルに記録するので、

2バイト以上の値をファイルに書き込んだり読み込む際には、

1バイト単位逆順に並べなおして複合する。)

Windowsでは、SJIS(cp932)が標準であるため、

char配列でSJISを使うことが多かったのですが、

現在では、Unicodeの使用が推奨されています。

ちなみに、wchar_t ( ワイド文字 ) を使用する場合は、

「Unicodeの配列である」と解釈されるようです。

コメントする

カテゴリー: C++, STL

ハム太と作るC++ライブラリ STL編

 

ここまでの内容が本になりました。↓

http://p.booklog.jp/book/74234

 

出版記念パーティーでもしょうかな。^^

文字列は、文字コードと含めて一緒に出します。

一応予告をしておくと、

KFCのコアな部分は後回しにして、

WIC MME MSXML など、オマケ部分から書いていきます。

コメントする

カテゴリー: C++, STL

STL::CAllocator

#pragma once
#ifndef _STL_ALLOCATOR_H_
#define _STL_ALLOCATOR_H_
#include<memory>
using namespace std;
namespace STL
{
// =====================================================
// アロケータ‐クラスの定義 ( std::allocatorのカスタムクラス )
//・ベクターなどのメモリを確保する処理には、汎用化するための処理が含まれている。
//  これをカスタマイズすると、インスタンス化時の実行速度が向上する。
//・効果的なのは、ベクターとデキューだけであり、それ以外のコンテナクラスでは意味が無い。
// 詳細はこちら↓
//http://msdn.microsoft.com/ja-jp/library/vstudio/5fk3e8ek.aspx
// ※要素が存在しないindexやイテレーターを渡した場合はコケる。
//   ( 速度を優先するため、STL側でも範囲判定はあまり行なっていない )
template <typename T>
class /* _EXPORT */ CAllocator : public std::allocator<T>
{
public:
// ————————————————<OK><テスト済み>
// コンストラクタ
CAllocator() : std::allocator<T>::allocator()
{
}
// ————————————————<OK><テスト済み>
// コンストラクタ
CAllocator( const STL::CAllocator<T>& a_ ) : std::allocator<T>::allocator( a_ )
{
}
// ————————————————<OK><テスト済み>
// メモリを動的に確保する。
// n:      確保する数
// hint:   確保する際のヒント ( 使用される保証はない )
// 戻り値: 確保した先頭アドレス
T* allocate( size_t n, const void* hint = 0 ) 
{
       return new T[ sizeof(T) * n ];
       // return (T*) operator new( n * sizeof(T) );
}
// ————————————————<OK><テスト済み>
// メモリを解放する。
    // p: 解放するポインタ
    // n: 開放するサイズ
    void deallocate( T* p, size_t n 
{
      delete [] p;
         // ::operator delete(p);
}
// ————————————————<OK><テスト済み>
// 最長シーケンスの長さを返す。 ( ※max_size() で返される値。これを越えてリサイズはできない )
size_t max_size() const
{
        return (size_t) -1 / sizeof(T);
}
// ————————————————<OK><テスト済み>
// コンストラクタの初期化処理
    //p:    初期化するポインタ
    //val:  初期化する値
   void construct( T* p, const T& val ) 
   {
           new ((void*)p) T(val);
   }
//————————————————<OK><テスト済み>
// デストラクタを呼ぶ。
   void destroy( T* p 
   {
          (p)->~T();
   }
// —————————————————–
}; // end class
// ====================================================
}; // end namespace
// —————————————————-
#endif

コメントする

カテゴリー: C++, STL