/////////////////////////////
// ECCSkelton
// CSTRクラス定義ファイル
// Copyright (c) August, 2022
//        By Ysama
/////////////////////////////
#ifndef	_CSTR_
#define _CSTR_

class CSTR {

	WCHAR*	m_str;

public:
	CSTR();									//コンストラクター（無）
	CSTR(const WCHAR*);						//コンストラクター（文字列）
	CSTR(const CSTR&);						//コンストラクター（CSTR）
	CSTR(const long);						//コンストラクター（整数）
	~CSTR();								//デストラクター
	CSTR& operator = (const WCHAR*);		//operator = (B) ---> = B;
	CSTR& operator = (const CSTR&);			//operator = (B) ---> = B;
	CSTR& operator = (const long);			//operator = (B) ---> = B;
	WCHAR* ToChar() {return m_str;}			//文字列ポインターとして返す
	void Print();							//m_strを印字する
	friend CSTR operator + (const CSTR&, const CSTR&);		//A operator + (B)  --->= A + B;
	friend bool operator == (const CSTR&, const CSTR&);		//A operator == (B) --->= A == B;
	friend bool operator == (const CSTR&, const WCHAR*);	//A operator == (B) --->= A == B;
	friend bool operator != (const CSTR&, const CSTR&);		//A operator == (B) --->= A != B;
	friend bool operator != (const CSTR&, const WCHAR*);	//A operator == (B) --->= A != B;
	bool FromFile(WCHAR*, WCHAR*, HWND);	//ファイルからの読込
	bool FromFile(WCHAR*);					//ファイルからの読込
	bool ToFile(WCHAR*, WCHAR*, HWND);		//ダイアログを使ったUTF-16ファイルへの書き込み
	bool ToFile(WCHAR*);					//UTF-16ファイルへの書き込み
	bool ToUTF8File(WCHAR*, bool);			//UTF-8ファイルへの書き込み（boolはBOM有無のフラグ）
	bool ToSJISFile(WCHAR*);				//SJISファイルへの書き込み
	bool Next(CSTR&);						//m_strの単語を切り取り出す
	bool GetLine(CSTR&);					//この行末まで進む
	bool NextLine();						//次の行頭まで進む
	WCHAR* Find(WCHAR*, WCHAR*);			//文字列の検索
	WCHAR* Replace(WCHAR*, WCHAR*, WCHAR*);		//文字列の置換
	void ReplaceAll(WCHAR*, WCHAR*, WCHAR*);	//文字列の全置換
};

//コンストラクター（無）
CSTR::CSTR() {

	//ワイド文字使用のためロケールの初期化（日本語）
	setlocale(LC_CTYPE, "JPN");
	m_str = new WCHAR[1];
	*m_str = L'\0';
}

//コンストラクター（文字列）
CSTR::CSTR(const WCHAR* string) {

	//ワイド文字使用のためロケールの初期化（日本語）
	setlocale(LC_CTYPE, "JPN");
	m_str = new WCHAR[lstrlenW(string) + 1];
	lstrcpyW(m_str, string);
}

//コンストラクター（CSTR）
CSTR::CSTR(const CSTR& cst) {

	//ワイド文字使用のためロケールの初期化（日本語）
	setlocale(LC_CTYPE, "JPN");
	m_str = new WCHAR[lstrlenW(cst.m_str) + 1];
	lstrcpyW(m_str, cst.m_str);
}

//コンストラクター（整数）
CSTR::CSTR(const long i) {

	//ワイド文字使用のためロケールの初期化（日本語）
	setlocale(LC_CTYPE, "JPN");
	WCHAR sbuff[MAX_PATH / 8];
	wsprintfW(sbuff, L"%d", i);
	m_str = new WCHAR[lstrlenW(sbuff) + 1];
	lstrcpyW(m_str, sbuff);
}

//デストラクター
CSTR::~CSTR() {

	delete [] m_str;
}

//WCHAR文字列の代入
CSTR& CSTR::operator = (const WCHAR* str) {

	delete [] m_str;
	m_str = new WCHAR[lstrlenW(str) + 1];
	lstrcpyW(m_str, str);
	return *this;
}

//CSTRの代入
CSTR& CSTR::operator = (const CSTR& cst) {

	if(&cst != this) {	//You can't copy yourself
		delete [] m_str;
		m_str = new WCHAR[lstrlenW(cst.m_str) + 1];
		lstrcpyW(m_str, cst.m_str);
	}
	return *this;
}

//整数の代入
CSTR& CSTR::operator = (const long i) {

	WCHAR sbuff[MAX_PATH / 8];
	wsprintfW(sbuff, L"%d", i);
	delete [] m_str;
	m_str = new WCHAR[lstrlenW(sbuff) + 1];
	lstrcpyW(m_str, sbuff);
	return *this;
}

//m_strを印字する
void CSTR::Print() {

	MessageBoxW(NULL, m_str, L"CSTR Message", MB_OK);
}

//追加演算子の定義
CSTR operator + (const CSTR& cst1, const CSTR& cst2) {

	CSTR strw;
	delete [] strw.m_str;
	strw.m_str = new WCHAR[lstrlenW(cst1.m_str) + lstrlenW(cst2.m_str) + 1];
	lstrcpyW(strw.m_str, cst1.m_str);
	lstrcatW(strw.m_str, cst2.m_str);
	return strw;
}

//比較演算子の定義（１）
bool operator == (const CSTR& cst1, const CSTR& cst2) {

	return !lstrcmpW(cst1.m_str, cst2.m_str);
}

//比較演算子の定義（２）
bool operator == (const CSTR& cst, const WCHAR* str) {

	return !lstrcmpW(cst.m_str, str);
}

//比較演算子の定義（３）
bool operator != (const CSTR& cst1, const CSTR& cst2) {

	return lstrcmpW(cst1.m_str, cst2.m_str);
}

//比較演算子の定義（４）
bool operator != (const CSTR& cst, const WCHAR* str) {

	return lstrcmpW(cst.m_str, str);
}

//ファイルからの読込
bool CSTR::FromFile(WCHAR* Filter, WCHAR* FilePath, HWND hWnd = NULL) {

	WCHAR FileName[MAX_PATH];
	WCHAR file_path[MAX_PATH];
	lstrcpyW(file_path, FilePath);	//Default Path
	OPENFILENAMEW ofn;				//オープンファイルダイアログ構造体
	//オープンファイルダイアログでファイル名を取得する
	FileName[0] = NULL;
	ZeroMemory(&ofn, sizeof(ofn));	//ゼロ初期化
	ofn.lStructSize		= sizeof(ofn);
	ofn.hwndOwner		= hWnd;
	ofn.lpstrFilter		= Filter;
	ofn.nFilterIndex	= 1;
	ofn.lpstrFile		= FileName;
	ofn.nMaxFile		= MAX_PATH;
	if(!*FilePath)					//規定値のNULLであれば現在のディレクトリー
		GetCurrentDirectoryW(MAX_PATH, file_path);
	else
		lstrcpyW(file_path, FilePath);
	ofn.lpstrInitialDir = file_path;
	ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
	if(!GetOpenFileNameW(&ofn))	return FALSE;		//読み込み結果
	return FromFile(FileName);
}

//ファイルからの読込
bool CSTR::FromFile(WCHAR* FileName) {

	//ファイルを読み込む
	BOOL bSuccess = FALSE;
	HANDLE hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
						OPEN_EXISTING, NULL, NULL);		//ファイルを読込みでオープン
	if(hFile != INVALID_HANDLE_VALUE) {					//オープンできたか
		DWORD dwFileSize = GetFileSize(hFile, NULL);
		if(dwFileSize != 0xFFFFFFFF) {					//-1は(0xFFFFFFFF)エラー
			LPBYTE Buff = new BYTE[dwFileSize + 2]();	//読み込みバッファ（NULL終端分追加）用ポインター
			//"new 配列[]()"でゼロ初期化し、WCHARファイルにも対応できるよう最後の2バイトをNULLにしている
			DWORD dwRead;
			if(ReadFile(hFile, Buff, dwFileSize, &dwRead, NULL)) {
				bSuccess = TRUE; 						//読み込み成功
				//BOM付UTF-16、UTF-32の場合
				if(Buff[0] == 0xFF && Buff[1] == 0xFE) {
					if(Buff[2] | Buff[3]) {				//いずれもNULLではない→UTF-16のBOM
						delete [] m_str;				//元の文字列を廃棄
						//BOM以降のデータをm_strに収納する
						m_str = new WCHAR[dwFileSize / sizeof(WCHAR)];
						//正確には"new WCHAR[(dwFileSize + 2 <NULL> - 2 <BOM>) / sizeof(WCHAR)]
						CopyMemory(m_str, Buff + 2, dwFileSize - 2);	//BOMを除外
					}
					else {								//Buff[2]とBuff[3])がいずれもNULL（UTF-32またはUTF-16でNULLのみ）
						bSuccess = FALSE;				//BOM付UTF-32の場合、読み込み失敗扱い
					}
				}
				//BOM付UTF-8の場合
				else if(Buff[0] == 0xEF && Buff[1] == 0xBB && Buff[2] == 0xBF) {
					dwRead = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (LPCCH)(Buff + 3), -1, NULL, NULL);
					if(dwRead) {	//UTF-8文字列の場合
						//m_str用メモリーの初期化
						delete [] m_str;
						m_str = new WCHAR[dwRead];
						//UTF8をWCHARへ変換
						MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (LPCCH)(Buff + 3), -1, m_str, dwRead);
					}
					else {			//BOM付UTF-8で変換不能の場合
						bSuccess = FALSE;	//何もせず読み込み失敗扱い
					}
				}
				//UTF-16、32、8、何れのBOMもない場合
				else {
					//先ずBOM無しUTF-8か否かをチェック
					if(dwRead = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (LPCCH)Buff, -1, NULL, NULL)) {
						//m_str用メモリーの初期化
						delete [] m_str;
						m_str = new WCHAR[dwRead];
						//UTF8をWCHARへ変換
						MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, (LPCCH)Buff, -1, m_str, dwRead);
					}
					//次にSift JIS（コードページCP_ACP）か否かをチェック
					else if(dwRead = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, (LPCCH)Buff, -1, NULL, NULL)) {
						//m_str用メモリーの初期化
						delete [] m_str;
						m_str = new WCHAR[dwRead];
						//SJISをWCHARへ変換
						MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, (LPCCH)Buff, -1, m_str, dwRead);
					}
					//BOMが無く、UTF-8またはSJISではない場合、読み込み失敗扱い
					else {
						bSuccess = FALSE;
					}
				}
			}
			delete [] Buff;							//読み込みバッファ解放
		}
		CloseHandle(hFile);							//ファイルのクローズ
	}
	return bSuccess;
}

//ファイルへの書き込み（規定値UTF-16 リトルエンディアン）
bool CSTR::ToFile(WCHAR* Filter, WCHAR* DefExt, HWND hWnd = NULL) {

	WCHAR FileName[MAX_PATH];
	OPENFILENAMEW ofn;				//オープンファイルダイアログ構造体
	//オープンファイルダイアログでファイル名を取得する
	ZeroMemory(&ofn, sizeof(ofn));	//ゼロ初期化
	FileName[0] = NULL;
	ofn.lStructSize		= sizeof(ofn);
	ofn.hwndOwner		= hWnd;
	ofn.lpstrFilter		= Filter;
	ofn.nFilterIndex	= 1;
	ofn.lpstrFile		= FileName;
	ofn.nMaxFile		= MAX_PATH;
	ofn.lpstrInitialDir = L".";
	ofn.lpstrDefExt		= DefExt;	//デフォルトの拡張子
	ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |
				OFN_OVERWRITEPROMPT;
	if(!GetSaveFileNameW(&ofn))	return FALSE;;
	//ファイルを書き込む
	return ToFile(FileName);
}

//ファイルへの書き込み（規定値UTF-16 リトルエンディアン）
bool CSTR::ToFile(WCHAR* FileName) {

	BOOL bSuccess = FALSE;
	HANDLE hFile;
	hFile = CreateFileW(FileName, GENERIC_WRITE, NULL, NULL,	//ファイルを書込みでオープン
						CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile != INVALID_HANDLE_VALUE) {							//オープンできたか
		//バッファから文字列長取得し、NULL終端も加算
		DWORD dwTextLength = (lstrlenW(m_str) + 1) * sizeof(WCHAR);
		DWORD dwWritten;
		//BOMの書き込み - WindowsはIntel系でUTF-16 FF FE（リトルエンディアン）
		BYTE BOM[2] = {0xFF, 0xFE};
		if(WriteFile(hFile, BOM, 2, &dwWritten, NULL)) {
			WriteFile(hFile, m_str, dwTextLength, &dwWritten, NULL);
			bSuccess = (dwTextLength == dwWritten);				//書込み成功
		}
		CloseHandle(hFile);			//ファイルのクローズ
	}
	return bSuccess;
}

//UTF-8ファイルへの書き込み（boolはBOM有無のフラグ）
bool CSTR::ToUTF8File(WCHAR* FileName, bool bom = TRUE) {

	BOOL bSuccess = FALSE;
	HANDLE hFile;
	hFile = CreateFileW(FileName, GENERIC_WRITE, NULL, NULL,	//ファイルを書込みでオープン
						CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile != INVALID_HANDLE_VALUE) {		//オープンできたか
		//WCHARをUTF8へ変換した際の文字列長（バイト−NULL終端を含む）を取得
		DWORD dwBuffSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, m_str, -1, NULL, NULL, NULL, NULL);
		if(!dwBuffSize) {
			CloseHandle(hFile);				//ファイルのクローズ
			return FALSE;
		}
		//UTF-8文字列用メモリーの確保
		char* utf8 = new char[dwBuffSize]();
		//WCHAR文字列をUTF8文字列へ変換
		WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, m_str, -1, utf8, dwBuffSize, NULL, NULL);
		//UTF-8文字列の書き込み
		DWORD dwWritten;
		if(bom) {	//BOM有り
			//BOMの書き込み - UTF-8 0xEF 0xBB 0xBF
			BYTE BOM[3] = {0xEF, 0xBB, 0xBF};
			if(WriteFile(hFile, BOM, 3, &dwWritten, NULL)) {
				WriteFile(hFile, utf8, dwBuffSize, &dwWritten, NULL);
				bSuccess = TRUE;	//書込み成功
			}
		}
		else {		//BOM無し
			if(WriteFile(hFile, utf8, dwBuffSize, &dwWritten, NULL))
				bSuccess = TRUE;	//書込み成功
		}
		delete [] utf8;				//UTF-8文字列メモリーの開放
		CloseHandle(hFile);			//ファイルのクローズ
	}
	return bSuccess;
}

//SJISファイルへの書き込み
bool CSTR::ToSJISFile(WCHAR* FileName) {

	BOOL bSuccess = FALSE;
	HANDLE hFile;
	hFile = CreateFileW(FileName, GENERIC_WRITE, NULL, NULL,	//ファイルを書込みでオープン
						CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hFile != INVALID_HANDLE_VALUE) {	//オープンできたか
		//WCHARをSJISへ変換した際の文字列長（バイト−NULL終端を含む）を取得
		DWORD dwBuffSize = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | WC_DEFAULTCHAR, m_str, -1, NULL, NULL, NULL, NULL);
//		DWORD dwBuffSize = WideCharToMultiByte(CP_ACP, WC_ERR_INVALID_CHARS, m_str, -1, NULL, NULL, NULL, NULL);	//第2引数が厳格すぎる
		if(!dwBuffSize) {
/*			DWORD dwError = GetLastError();		//C_ERR_INVALID_CHARSでエラーが発生した時に付加したコード
			switch(dwError) {
			case ERROR_INSUFFICIENT_BUFFER:
				MessageBoxW(0, L"Cause: ERROR_INSUFFICIENT_BUFFER", L"Error", MB_OK | MB_ICONERROR); break;
			case ERROR_INVALID_FLAGS:
				MessageBoxW(0, L"Cause: ERROR_INVALID_FLAGS", L"Error", MB_OK | MB_ICONERROR); break;
			case ERROR_INVALID_PARAMETER:
    	        MessageBoxW(0, L"Cause: ERROR_INVALID_PARAMETER", L"Error", MB_OK | MB_ICONERROR); break;
			default:
				MessageBoxW(0, L"Cause: unknown", L"Error", MB_OK | MB_ICONERROR); break;
			}
*/			CloseHandle(hFile);			//ファイルのクローズ
			return FALSE;
		}
		//SJIS文字列用メモリーの確保
		char* sjis = new char[dwBuffSize]();
		//WCHAR文字列をSJIS文字列へ変換
		WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | WC_DEFAULTCHAR, m_str, -1, sjis, dwBuffSize, NULL, NULL);
		//SJIS文字列の書き込み
		DWORD dwWritten;
		if(WriteFile(hFile, sjis, dwBuffSize, &dwWritten, NULL))
			bSuccess = TRUE;			//書込み成功
		delete [] sjis;					//UTF-8文字列メモリーの開放
		CloseHandle(hFile);				//ファイルのクローズ
	}
	return bSuccess;
}

//m_strの単語を切り取り出す
bool CSTR::Next(CSTR& destination) {

	CSTR str;
	delete [] str.m_str;
	str.m_str = new WCHAR[lstrlenW(m_str) + 1];
	WCHAR* ptr = m_str;
	WCHAR* des = str.m_str;
	bool Terminate = TRUE;
	//スペース文字はスキップする
	while(iswspace(*ptr) || *ptr == L'　' || *ptr == L',') {
			ptr++;						//スキップスペース文字
	}
	//非スペース文字を調べる
	while(!iswspace(*ptr)) {			//スペース文字でない
		if(!*ptr) {						//NULL終端ならFALSEを返す
			Terminate = FALSE;
			break;
		}
		else if(*ptr == L'　') {
			break;						//全角"　"なら終了
		}
		else if(*ptr == L',') {
			ptr++;						//','をスキップして次の文字まで進む
			break;						//空白文字扱い
		}
		else if(*ptr == L'"') {
			ptr++;						//'"'をスキップして中身だけ取り出す
			while(*ptr != L'"') {		//'"'なら'"'まで進む
				if(!*ptr) {				//NULL終端ならFALSEを返す
					Terminate = FALSE;
					break;
				}
				*des = *ptr;
				ptr++;	des++;
			}
			ptr++;						//ソースポインターは次の文字へ進める
			break;						//ループを抜けてデスティネーションはNULLが入る
		}
		else if(*ptr == L'/' && *(ptr + 1) == L'*') {
			ptr++;	ptr++;				//"/*〜*/"コメント
			while(!(*ptr == L'*' && *(ptr + 1) == L'/')) {
				if(!*ptr) {				//NULL終端ならFALSEを返す
					Terminate = FALSE;
					break;
				}
				ptr++;
			}
			ptr++;	ptr++;
			//再度スペース文字をスキップする
			while(iswspace(*ptr) || *ptr == L'　' || *ptr == L',') {
				if(!*ptr) {				//NULL終端ならFALSEを返す
					Terminate = FALSE;
					break;
				}
				ptr++;				//スキップスペース文字
			}
			continue;
		}
		else if(*ptr == L'/' && *(ptr + 1) == L'/') {
			while(*ptr != L'\n') {		//"//"コメント
				if(!*ptr) {				//NULL終端ならFALSEを返す
					Terminate = FALSE;
					break;
				}
				ptr++;
			}
			while(iswspace(*ptr) || *ptr == L'　' || *ptr == L',') {
				if(!*ptr) {				//NULL終端ならFALSEを返す
					Terminate = FALSE;
					break;
				}
				ptr++;				//スキップスペース文字
			}
			continue;
		}
		else {
			*des = *ptr;
		}
		ptr++;	des++;
	}
	*des = L'\0';

	destination = str;			//destinationに切り取った文字列を代入
	str = ptr;					//strにm_strより進んだptr以降の文字列を代入
	delete [] m_str;
	m_str = new WCHAR[lstrlenW(str.m_str) + 1];
	lstrcpyW(m_str, str.m_str);	//m_strには切り取った後の文字列が入る
	if(*str.m_str || *destination.m_str)
		Terminate = TRUE;		//残がNULLだけでも切り取った文字列があれば続ける
	else
		Terminate = FALSE;		//NULLだけなら終わり
	return Terminate;			//成功･失敗フラグを返す
}

//この行末まで進む
bool CSTR::GetLine(CSTR& destination) {

	bool Terminate = TRUE;
	WCHAR* ptr = m_str;
	WCHAR* des = ptr;
	while(*des && *des != L'\n')
		des++;
	if(!*des) {
		destination = L"";
		Terminate = FALSE;	//文字列の終了サイン
	}
	else {
		*des = L'\0'; des++;				//NULL終端させ、一つ進める
		delete [] destination.m_str;
		destination.m_str = new WCHAR[des - ptr + 1];
		lstrcpyW(destination.m_str, ptr);
		destination.m_str[des - ptr - 1] = L'\n';	//NULLにした'\n'を付加
		destination.m_str[des - ptr] = L'\0';		//NULL終端
	}
	if(Terminate) {					//まだ文字列があれば残りを入れる
		CSTR str = des;
		delete [] m_str;
		m_str = new WCHAR[lstrlenW(str.m_str) + 1];
		lstrcpyW(m_str, str.m_str);	//m_strには切り取った後の文字列が入る
	}
	if(*destination.m_str)			//NULLに出会ったが、
		Terminate = TRUE;			//切り取った文字列があれば続ける
	else
		Terminate = FALSE;			//NULLだけなら終わり
	return Terminate;				//成功･失敗フラグを返す
}

//次の行頭まで進む
bool CSTR::NextLine() {

	WCHAR* ptr = m_str;
	while(*ptr != L'\n') {		//改行コードまで進む
		if(!*ptr) {				//途中でNULL終端したならFALSEを返す
			return FALSE;
		}
		ptr++;
	}
	ptr++;
	CSTR str = ptr;
	delete [] m_str;
	m_str = new WCHAR[lstrlenW(str.m_str) + 1];
	lstrcpyW(m_str, str.m_str);	//m_strには切り取った後の文字列が入る
	return TRUE;				//成功･失敗フラグを返す
}

//文字列の検索
WCHAR* CSTR::Find(WCHAR* ToFind, WCHAR* sp = 0) {

	if(!sp)
		sp = m_str;
	return StrStrW(sp, ToFind);
}

//文字列の置換
WCHAR* CSTR::Replace(WCHAR* ToFind, WCHAR* ToReplace, WCHAR* sp = 0) {

	//CSTRのデータ長、検索文字長、置換文字長を計算する
	int OrgLen = lstrlenW(m_str);
	int ToFindLen = lstrlenW(ToFind);
	int ToReplaceLen = lstrlenW(ToReplace);
	//spの指定が無ければCSTRデータの先頭から検索する
	if(!sp)
		sp = m_str;
	//検索文字列ポインターの取得
	WCHAR* Found_at = StrStrW(sp, ToFind);		//検索文字列が無ければNULLを返す
	//検索文字があれば
	if(Found_at) {
		DWORD dspl = Found_at - m_str;			//Found_atのm_str内の相対位置
		//置換後の文字列データバッファー（NULL終端付）の確保
		WCHAR* buff = new WCHAR[OrgLen - ToFindLen + ToReplaceLen + 1];
		*Found_at = L'\0';						//NULL終端
		lstrcpyW(buff, m_str);					//検索文字列（ToFind）までをbuffにコピー
		lstrcatW(buff, ToReplace);				//検索文字列（ToFind）の代わりに置換文字列をコピー
		lstrcatW(buff, Found_at + ToFindLen);	//検索文字列（ToFind）以降の文字列をコピー
		buff[OrgLen - ToFindLen + ToReplaceLen] = L'\0';	//NULL終端を付ける
		delete [] m_str;						//CSTRデータ（m_str）を削除
		m_str = new WCHAR[OrgLen - ToFindLen + ToReplaceLen + 1];	//新しいデータ領域を確保
		lstrcpyW(m_str, buff);					//置換後のデータをコピー
		Found_at = m_str + dspl;				//Found_atのm_str内の相対位置
		delete [] buff;							//文字列データバッファーを破棄
	}
	return Found_at;	//置換できなかった場合NULL、できた場合置換文字列の先頭ポインター
}

//文字列の全置換
void CSTR::ReplaceAll(WCHAR* ToFind, WCHAR* ToReplace, WCHAR* sp = 0) {

	WCHAR* Next = sp;
	while((Next = Replace(ToFind, ToReplace, Next)))
		Next += lstrlenW(ToReplace);
}

#endif
