906 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			906 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Win32++   Version 7.2
 | 
						|
// Released: 5th AUgust 2011
 | 
						|
//
 | 
						|
//      David Nash
 | 
						|
//      email: dnash@bigpond.net.au
 | 
						|
//      url: https://sourceforge.net/projects/win32-framework
 | 
						|
//
 | 
						|
//
 | 
						|
// Copyright (c) 2005-2011  David Nash
 | 
						|
//
 | 
						|
// Permission is hereby granted, free of charge, to
 | 
						|
// any person obtaining a copy of this software and
 | 
						|
// associated documentation files (the "Software"),
 | 
						|
// to deal in the Software without restriction, including
 | 
						|
// without limitation the rights to use, copy, modify,
 | 
						|
// merge, publish, distribute, sublicense, and/or sell
 | 
						|
// copies of the Software, and to permit persons to whom
 | 
						|
// the Software is furnished to do so, subject to the
 | 
						|
// following conditions:
 | 
						|
//
 | 
						|
// The above copyright notice and this permission notice
 | 
						|
// shall be included in all copies or substantial portions
 | 
						|
// of the Software.
 | 
						|
//
 | 
						|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
 | 
						|
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 | 
						|
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 | 
						|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 | 
						|
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 | 
						|
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 | 
						|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
						|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
 | 
						|
// OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
//
 | 
						|
////////////////////////////////////////////////////////
 | 
						|
 | 
						|
 | 
						|
// Acknowledgements:
 | 
						|
// Thanks to Adam Szulc for his initial CString code.
 | 
						|
 | 
						|
////////////////////////////////////////////////////////
 | 
						|
// cstring.h
 | 
						|
//  Declaration of the cstring.h
 | 
						|
 | 
						|
// This class is intended to provide a simple alternative to the MFC/ATL 
 | 
						|
// CString class that ships with Microsoft compilers. The CString class
 | 
						|
// specified here is compatible with other compilers such as Borland 5.5
 | 
						|
// and MinGW.
 | 
						|
 | 
						|
// Differences between this class and the MFC/ATL CString class
 | 
						|
// ------------------------------------------------------------
 | 
						|
// 1) The constructors for this class accepts only TCHARs. The various text conversion
 | 
						|
//    functions can be used to convert from other character types to TCHARs.
 | 
						|
//
 | 
						|
// 2) This class is not reference counted, so these CStrings should be passed as 
 | 
						|
//    references or const references when used as function arguments. As a result there 
 | 
						|
//    is no need for functions like LockBuffer and UnLockBuffer.
 | 
						|
//
 | 
						|
// 3) The Format functions only accepts POD (Plain Old Data) arguments. It does not
 | 
						|
//    accept arguments which are class or struct objects. In particular it does not
 | 
						|
//    accept CString objects, unless these are cast to LPCTSTR.
 | 
						|
//    This is demonstrates valid and invalid usage:
 | 
						|
//      CString string1(_T("Hello World"));
 | 
						|
//      CString string2;
 | 
						|
//
 | 
						|
//      // This is invalid, and produces undefined behaviour.
 | 
						|
//      string2.Format(_T("String1 is: %s"), string1); // No! you can't do this
 | 
						|
//
 | 
						|
//      // This is ok
 | 
						|
//      string2.Format(_T("String1 is: %s"), (LPCTSTR)string1); // Yes, this is correct
 | 
						|
//
 | 
						|
//    Note: The MFC/ATL CString class uses a non portable hack to make its CString class 
 | 
						|
//          behave like a POD. Other compilers (such as the MinGW compiler) specifically
 | 
						|
//          prohibit the use of non POD types for functions with variable argument lists.
 | 
						|
//
 | 
						|
// 4) This class provides a few additional functions:
 | 
						|
//       b_str			Returns a BSTR string. This an an alternative for casting to BSTR.
 | 
						|
//       c_str			Returns a const TCHAR string. This is an alternative for casting to LPCTSTR.
 | 
						|
//       GetErrorString	Assigns CString to the error string for the specified System Error Code 
 | 
						|
//                      (from ::GetLastErrror() for example).
 | 
						|
//       GetString		Returns a reference to the underlying std::basic_string<TCHAR>. This 
 | 
						|
//						reference can be used to modify the string directly.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#ifndef _WIN32XX_CSTRING_H_
 | 
						|
#define _WIN32XX_CSTRING_H_
 | 
						|
 | 
						|
 | 
						|
#include "wincore.h"
 | 
						|
 | 
						|
 | 
						|
namespace Win32xx
 | 
						|
{
 | 
						|
 | 
						|
	class CString 
 | 
						|
	{
 | 
						|
		// friend functions allow the left hand side to be something other than CString
 | 
						|
		friend CString operator + (const CString& string1, const CString& string2);
 | 
						|
		friend CString operator + (const CString& string, LPCTSTR pszText);	
 | 
						|
		friend CString operator + (const CString& string, TCHAR ch);
 | 
						|
		friend CString operator + (LPCTSTR pszText, const CString& string);
 | 
						|
		friend CString operator + (TCHAR ch, const CString& string);		
 | 
						|
 | 
						|
	public:
 | 
						|
		CString();
 | 
						|
		~CString();
 | 
						|
		CString(const CString& str);
 | 
						|
		CString(LPCTSTR pszText);
 | 
						|
		CString(TCHAR ch, int nLength = 1);
 | 
						|
		CString(LPCTSTR pszText, int nLength);
 | 
						|
 | 
						|
		CString& operator = (const CString& str);
 | 
						|
		CString& operator = (const TCHAR ch);
 | 
						|
		CString& operator = (LPCTSTR pszText);
 | 
						|
		BOOL     operator == (LPCTSTR pszText);
 | 
						|
		BOOL     operator != (LPCTSTR pszText);
 | 
						|
		BOOL	 operator < (LPCTSTR pszText);
 | 
						|
		BOOL	 operator > (LPCTSTR pszText);
 | 
						|
		BOOL	 operator <= (LPCTSTR pszText);
 | 
						|
		BOOL	 operator >= (LPCTSTR pszText);
 | 
						|
				 operator LPCTSTR() const;
 | 
						|
				 operator BSTR() const;
 | 
						|
		TCHAR&   operator [] (int nIndex);
 | 
						|
		CString& operator += (const CString& str);
 | 
						|
 | 
						|
		// Attributes
 | 
						|
		BSTR     b_str() const		{ return T2W(m_str.c_str()); }	// alternative for casting to BSTR
 | 
						|
		LPCTSTR	 c_str() const		{ return m_str.c_str(); }		// alternative for casting to LPCTSTR
 | 
						|
		tString& GetString()		{ return m_str; }				// returns a reference to the underlying std::basic_string<TCHAR>
 | 
						|
		int      GetLength() const	{ return (int)m_str.length(); }		// returns the length in characters
 | 
						|
 | 
						|
		// Operations
 | 
						|
		BSTR     AllocSysString() const;
 | 
						|
		void	 AppendFormat(LPCTSTR pszFormat,...);
 | 
						|
		void	 AppendFormat(UINT nFormatID, ...);
 | 
						|
		int      Compare(LPCTSTR pszText) const;
 | 
						|
		int      CompareNoCase(LPCTSTR pszText) const;
 | 
						|
		int      Delete(int nIndex, int nCount = 1);
 | 
						|
		int		 Find(TCHAR ch, int nIndex = 0 ) const;
 | 
						|
		int      Find(LPCTSTR pszText, int nStart = 0) const;
 | 
						|
		int		 FindOneOf(LPCTSTR pszText) const;
 | 
						|
		void	 Format(UINT nID, ...);
 | 
						|
		void     Format(LPCTSTR pszFormat,...);
 | 
						|
		void     FormatV(LPCTSTR pszFormat, va_list args);
 | 
						|
		void	 FormatMessage(LPCTSTR pszFormat,...);
 | 
						|
		void	 FormatMessageV(LPCTSTR pszFormat, va_list args);
 | 
						|
		TCHAR	 GetAt(int nIndex) const;
 | 
						|
		LPTSTR	 GetBuffer(int nMinBufLength);
 | 
						|
		void	 GetErrorString(DWORD dwError);
 | 
						|
		void     Empty();
 | 
						|
		int      Insert(int nIndex, TCHAR ch);
 | 
						|
		int      Insert(int nIndex, const CString& str);
 | 
						|
		BOOL     IsEmpty() const;
 | 
						|
		CString  Left(int nCount) const;
 | 
						|
		BOOL	 LoadString(UINT nID);
 | 
						|
		void     MakeLower();
 | 
						|
		void	 MakeReverse();
 | 
						|
		void     MakeUpper();
 | 
						|
		CString	 Mid(int nFirst) const;
 | 
						|
		CString  Mid(int nFirst, int nCount) const;
 | 
						|
		void	 ReleaseBuffer( int nNewLength = -1 );
 | 
						|
		int      Remove(LPCTSTR pszText);
 | 
						|
		int      Replace(TCHAR chOld, TCHAR chNew);
 | 
						|
		int      Replace(const LPCTSTR pszOld, LPCTSTR pszNew);
 | 
						|
		int      ReverseFind(LPCTSTR pszText, int nStart = -1) const;
 | 
						|
		CString  Right(int nCount) const;
 | 
						|
		void	 SetAt(int nIndex, TCHAR ch);
 | 
						|
		BSTR	 SetSysString(BSTR* pBstr) const;
 | 
						|
		CString	 SpanExcluding(LPCTSTR pszText) const;
 | 
						|
		CString	 SpanIncluding(LPCTSTR pszText) const;
 | 
						|
		CString	 Tokenize(LPCTSTR pszTokens, int& iStart) const;
 | 
						|
		void	 Trim();
 | 
						|
		void	 TrimLeft();
 | 
						|
		void	 TrimLeft(TCHAR chTarget);
 | 
						|
		void	 TrimLeft(LPCTSTR pszTargets);
 | 
						|
		void	 TrimRight();
 | 
						|
		void	 TrimRight(TCHAR chTarget);
 | 
						|
		void	 TrimRight(LPCTSTR pszTargets);
 | 
						|
		void     Truncate(int nNewLength);
 | 
						|
 | 
						|
#ifndef _WIN32_WCE
 | 
						|
		int      Collate(LPCTSTR pszText) const;
 | 
						|
		int		 CollateNoCase(LPCTSTR pszText) const;
 | 
						|
		BOOL	 GetEnvironmentVariable(LPCTSTR pszVar);
 | 
						|
#endif
 | 
						|
 | 
						|
	private:
 | 
						|
		tString m_str;
 | 
						|
		std::vector<TCHAR> m_buf;
 | 
						|
	};
 | 
						|
 | 
						|
	inline CString::CString()
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString::~CString()
 | 
						|
	{
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString::CString(const CString& str)
 | 
						|
	{
 | 
						|
		m_str.assign(str);
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString::CString(LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		m_str.assign(pszText);
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString::CString(TCHAR ch, int nLength)
 | 
						|
	{
 | 
						|
		m_str.assign(nLength, ch);
 | 
						|
	}
 | 
						|
	
 | 
						|
	inline CString::CString(LPCTSTR pszText, int nLength)
 | 
						|
	{
 | 
						|
		m_str.assign(pszText, nLength);	
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString& CString::operator = (const CString& str)
 | 
						|
	{
 | 
						|
		m_str.assign(str);
 | 
						|
		return *this;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString& CString::operator = (const TCHAR ch)
 | 
						|
	{
 | 
						|
		m_str.assign(1, ch);
 | 
						|
		return *this;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString& CString::operator = (LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		m_str.assign(pszText);
 | 
						|
		return *this;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator == (LPCTSTR pszText)
 | 
						|
	// Returns TRUE if the strings have the same content
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return (0 == Compare(pszText));
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator != (LPCTSTR pszText)
 | 
						|
	// Returns TRUE if the strings have a different content
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
        return Compare(pszText) != 0;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator < (LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return Compare(pszText) < 0;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator > (LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return Compare(pszText) > 0;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator <= (LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return Compare(pszText) <= 0;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::operator >= (LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return Compare(pszText) >= 0;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString::operator LPCTSTR() const
 | 
						|
	{
 | 
						|
		return m_str.c_str();
 | 
						|
	}
 | 
						|
 | 
						|
	inline TCHAR& CString::operator [] (int nIndex)
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		assert(nIndex < GetLength());
 | 
						|
		return m_str[nIndex];
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString& CString::operator += (const CString& str)
 | 
						|
	{
 | 
						|
		m_str.append(str);
 | 
						|
		return *this;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BSTR CString::AllocSysString() const
 | 
						|
	// Allocates a BSTR from the CString content.
 | 
						|
	{
 | 
						|
		return ::SysAllocStringLen(T2W(m_str.c_str()), (UINT)m_str.size());
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::AppendFormat(LPCTSTR pszFormat,...)
 | 
						|
	// Appends formatted data to an the CString content.
 | 
						|
	{
 | 
						|
		CString str;
 | 
						|
		str.Format(pszFormat);
 | 
						|
		m_str.append(str);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::AppendFormat(UINT nFormatID, ...)
 | 
						|
	// Appends formatted data to an the CString content.
 | 
						|
	{
 | 
						|
		CString str1;
 | 
						|
		CString str2;
 | 
						|
		if (str1.LoadString(nFormatID))
 | 
						|
		{
 | 
						|
			str2.Format(str1);
 | 
						|
			m_str.append(str2);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
#ifndef _WIN32_WCE
 | 
						|
	inline int CString::Collate(LPCTSTR pszText) const
 | 
						|
	// Performs a case sensitive comparison of the two strings using locale-specific information.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return _tcscoll(m_str.c_str(), pszText);
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::CollateNoCase(LPCTSTR pszText) const
 | 
						|
	// Performs a case insensitive comparison of the two strings using locale-specific information.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return _tcsicoll(m_str.c_str(), pszText);
 | 
						|
	}
 | 
						|
#endif	// _WIN32_WCE
 | 
						|
 | 
						|
	inline int CString::Compare(LPCTSTR pszText) const
 | 
						|
	// Performs a case sensitive comparison of the two strings.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return m_str.compare(pszText);
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::CompareNoCase(LPCTSTR pszText) const
 | 
						|
	// Performs a case insensitive comparison of the two strings.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return _tcsicmp(m_str.data(), pszText);
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Delete(int nIndex, int nCount /* = 1 */)
 | 
						|
	// Deletes a character or characters from the string.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		assert(nCount >= 0);
 | 
						|
 | 
						|
		m_str.erase(nIndex, nCount);
 | 
						|
		return (int)m_str.size();
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::Empty()
 | 
						|
	// Erases the contents of the string.
 | 
						|
	{
 | 
						|
		m_str.erase();
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Find(TCHAR ch, int nIndex /* = 0 */) const
 | 
						|
	// Finds a character in the string.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		return (int)m_str.find(ch, nIndex);
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Find(LPCTSTR pszText, int nIndex /* = 0 */) const
 | 
						|
	// Finds a substring within the string. 
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		return (int)m_str.find(pszText, nIndex);
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::FindOneOf(LPCTSTR pszText) const
 | 
						|
	// Finds the first matching character from a set.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return (int)m_str.find_first_of(pszText);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::Format(LPCTSTR pszFormat,...)
 | 
						|
	// Formats the string as sprintf does.
 | 
						|
	{
 | 
						|
		va_list args;
 | 
						|
		va_start(args, pszFormat);
 | 
						|
		FormatV(pszFormat, args);
 | 
						|
		va_end(args);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::Format(UINT nID, ...)
 | 
						|
	// Formats the string as sprintf does.
 | 
						|
	{
 | 
						|
		Empty();
 | 
						|
		CString str;
 | 
						|
		if (str.LoadString(nID))
 | 
						|
			Format(str);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::FormatV(LPCTSTR pszFormat, va_list args)
 | 
						|
	// Formats the string using a variable list of arguments.
 | 
						|
	{
 | 
						|
		if (pszFormat)
 | 
						|
		{
 | 
						|
			int nResult = -1, nLength = 256;
 | 
						|
 | 
						|
			// A vector is used to store the TCHAR array
 | 
						|
			std::vector<TCHAR> vBuffer;( nLength+1, _T('\0') );
 | 
						|
 | 
						|
			while (-1 == nResult)
 | 
						|
			{
 | 
						|
				vBuffer.assign( nLength+1, _T('\0') );
 | 
						|
				nResult = _vsntprintf(&vBuffer[0], nLength, pszFormat, args);
 | 
						|
				nLength *= 2;
 | 
						|
			}
 | 
						|
			m_str.assign(&vBuffer[0]);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::FormatMessage(LPCTSTR pszFormat,...)
 | 
						|
	// Formats a message string.
 | 
						|
	{
 | 
						|
		va_list args;
 | 
						|
		va_start(args, pszFormat);
 | 
						|
		FormatMessageV(pszFormat, args);
 | 
						|
		va_end(args);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::FormatMessageV(LPCTSTR pszFormat, va_list args)
 | 
						|
	// Formats a message string using a variable argument list.
 | 
						|
	{
 | 
						|
		LPTSTR pszTemp = 0;
 | 
						|
		if (pszFormat)
 | 
						|
		{
 | 
						|
			DWORD dwResult = ::FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, pszFormat, 0, 0, pszTemp, 0, &args);
 | 
						|
 | 
						|
			if (0 == dwResult || 0 == pszTemp )
 | 
						|
				throw std::bad_alloc();
 | 
						|
 | 
						|
			m_str = pszTemp;
 | 
						|
			LocalFree(pszTemp);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	inline TCHAR CString::GetAt(int nIndex) const
 | 
						|
	// Returns the character at the specified location within the string.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		assert(nIndex < GetLength());
 | 
						|
		return m_str[nIndex];
 | 
						|
	}
 | 
						|
 | 
						|
	inline LPTSTR CString::GetBuffer(int nMinBufLength)
 | 
						|
	// Creates a buffer of nMinBufLength charaters (+1 extra for NULL termination) and returns 
 | 
						|
	// a pointer to this buffer. This buffer can be used by any function which accepts a LPTSTR.
 | 
						|
	// Care must be taken not to exceed the length of the buffer. Use ReleaseBuffer to safely 
 | 
						|
	// copy this buffer back to the CString object.
 | 
						|
	//
 | 
						|
	// Note: The buffer uses a vector. Vectors are required to be contiguous in memory under
 | 
						|
	//       the current standard, whereas std::strings do not have this requirement.
 | 
						|
	{
 | 
						|
		assert (nMinBufLength >= 0);
 | 
						|
		
 | 
						|
		m_buf.assign(nMinBufLength + 1, _T('\0'));
 | 
						|
		tString::iterator it_end;
 | 
						|
 | 
						|
		if (m_str.length() >= (size_t)nMinBufLength)
 | 
						|
		{
 | 
						|
			it_end = m_str.begin();
 | 
						|
			std::advance(it_end, nMinBufLength);
 | 
						|
		}
 | 
						|
		else
 | 
						|
			it_end = m_str.end();
 | 
						|
		
 | 
						|
		std::copy(m_str.begin(), it_end, m_buf.begin());
 | 
						|
 | 
						|
		return &m_buf[0];
 | 
						|
	}
 | 
						|
 | 
						|
#ifndef _WIN32_WCE
 | 
						|
	inline BOOL CString::GetEnvironmentVariable(LPCTSTR pszVar)
 | 
						|
	// Sets the string to the value of the specified environment variable.
 | 
						|
	{
 | 
						|
		assert(pszVar);
 | 
						|
		Empty();
 | 
						|
 | 
						|
		int nLength = ::GetEnvironmentVariable(pszVar, NULL, 0);
 | 
						|
		if (nLength > 0)
 | 
						|
		{
 | 
						|
			std::vector<TCHAR> vBuffer( nLength+1, _T('\0') );
 | 
						|
			::GetEnvironmentVariable(pszVar, &vBuffer[0], nLength);
 | 
						|
			m_str = &vBuffer[0];
 | 
						|
		}
 | 
						|
 | 
						|
		return (BOOL)nLength;
 | 
						|
	}
 | 
						|
#endif // _WIN32_WCE
 | 
						|
 | 
						|
	inline void CString::GetErrorString(DWORD dwError)
 | 
						|
	// Returns the error string for the specified System Error Code (e.g from GetLastErrror).
 | 
						|
	{
 | 
						|
		m_str.erase();
 | 
						|
		
 | 
						|
		if (dwError != 0)
 | 
						|
		{
 | 
						|
			TCHAR* pTemp = 0;
 | 
						|
			DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
 | 
						|
			::FormatMessage(dwFlags, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pTemp, 1, NULL);
 | 
						|
			m_str.assign(pTemp);
 | 
						|
			::LocalFree(pTemp);
 | 
						|
		}
 | 
						|
	}
 | 
						|
	
 | 
						|
	inline int CString::Insert(int nIndex, TCHAR ch)
 | 
						|
	// Inserts a single character or a substring at the given index within the string.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		assert(ch);
 | 
						|
 | 
						|
		m_str.insert(nIndex, &ch, 1);
 | 
						|
		return (int)m_str.size();
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Insert(int nIndex, const CString& str)
 | 
						|
	// Inserts a single character or a substring at the given index within the string.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
 | 
						|
		m_str.insert(nIndex, str);
 | 
						|
		return (int)m_str.size();
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::IsEmpty() const
 | 
						|
	// Returns TRUE if the string is empty
 | 
						|
	{
 | 
						|
		return m_str.empty();
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::Left(int nCount) const
 | 
						|
	// Extracts the left part of a string.
 | 
						|
	{
 | 
						|
		assert(nCount >= 0);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		str.m_str.assign(c_str(), 0, nCount);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BOOL CString::LoadString(UINT nID)
 | 
						|
	// Loads the string from a Windows resource.
 | 
						|
	{
 | 
						|
		assert (GetApp());
 | 
						|
 | 
						|
		int nSize = 64;
 | 
						|
		TCHAR* pTCharArray = 0;
 | 
						|
		std::vector<TCHAR> vString;
 | 
						|
		int nTChars = nSize;
 | 
						|
 | 
						|
		Empty();
 | 
						|
 | 
						|
		// Increase the size of our array in a loop until we load the entire string
 | 
						|
		// The ANSI and _UNICODE versions of LoadString behave differently. This technique works for both.
 | 
						|
		while ( nSize-1 <= nTChars )
 | 
						|
		{
 | 
						|
			nSize = nSize * 4;
 | 
						|
			vString.assign(nSize+1, _T('\0'));
 | 
						|
			pTCharArray = &vString[0];
 | 
						|
			nTChars = ::LoadString (GetApp()->GetResourceHandle(), nID, pTCharArray, nSize);
 | 
						|
		}
 | 
						|
 | 
						|
		if (nTChars > 0)
 | 
						|
			m_str.assign(pTCharArray);
 | 
						|
 | 
						|
		return (nTChars != 0);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::MakeLower()
 | 
						|
	// Converts all the characters in this string to lowercase characters.
 | 
						|
	{
 | 
						|
		std::transform(m_str.begin(), m_str.end(), m_str.begin(), &::tolower);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::MakeReverse()
 | 
						|
	// Reverses the string.
 | 
						|
	{
 | 
						|
		std::reverse(m_str.begin(), m_str.end());
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::MakeUpper()
 | 
						|
	// Converts all the characters in this string to uppercase characters.
 | 
						|
	{
 | 
						|
		std::transform(m_str.begin(), m_str.end(), m_str.begin(), &::toupper);
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::Mid(int nFirst) const
 | 
						|
	// Extracts the middle part of a string.
 | 
						|
	{
 | 
						|
		return Mid(nFirst, GetLength());
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::Mid(int nFirst, int nCount) const
 | 
						|
	// Extracts the middle part of a string.
 | 
						|
	{
 | 
						|
		assert(nFirst >= 0);
 | 
						|
		assert(nCount >= 0);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		str.m_str.assign(c_str(), nFirst, nFirst + nCount);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::ReverseFind(LPCTSTR pszText, int nIndex /* = -1 */) const
 | 
						|
	// Search for a substring within the string, starting from the end.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
		return (int)m_str.rfind(pszText, nIndex);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::SetAt(int nIndex, TCHAR ch)
 | 
						|
	// Sets the character at the specificed position to the specified value.
 | 
						|
	{
 | 
						|
		assert(nIndex >= 0);
 | 
						|
		assert(nIndex < GetLength());
 | 
						|
		m_str[nIndex] = ch;
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::ReleaseBuffer( int nNewLength /*= -1*/ )
 | 
						|
	// This copies the contents of the buffer (acquired by GetBuffer) to this CString,
 | 
						|
	// and releases the contents of the buffer. The default length of -1 copies from the
 | 
						|
	// buffer until a null terminator is reached. If the buffer doesn't contain a null
 | 
						|
	// terminator, you must specify the buffer's length.
 | 
						|
	{
 | 
						|
		assert (nNewLength > 0 || -1 == nNewLength);
 | 
						|
		assert (nNewLength < (int)m_buf.size());
 | 
						|
 | 
						|
		if (-1 == nNewLength)
 | 
						|
			nNewLength = lstrlen(&m_buf[0]);
 | 
						|
		m_str.assign(nNewLength+1, _T('\0'));
 | 
						|
 | 
						|
		std::vector<TCHAR>::iterator it_end = m_buf.begin();
 | 
						|
		std::advance(it_end, nNewLength);
 | 
						|
		
 | 
						|
		std::copy(m_buf.begin(), it_end, m_str.begin());
 | 
						|
		m_buf.clear();
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Remove(LPCTSTR pszText)
 | 
						|
	// Removes each occurrence of the specified substring from the string.
 | 
						|
	{
 | 
						|
		assert(pszText);
 | 
						|
 | 
						|
		int nCount = 0;
 | 
						|
		size_t pos = 0;
 | 
						|
		while ((pos = m_str.find(pszText, pos)) != std::string::npos)
 | 
						|
		{
 | 
						|
			m_str.erase(pos, lstrlen(pszText));
 | 
						|
			++nCount;
 | 
						|
		}
 | 
						|
		return nCount;
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Replace(TCHAR chOld, TCHAR chNew)
 | 
						|
	// Replaces each occurance of the old character with the new character.
 | 
						|
	{
 | 
						|
		int nCount = 0;
 | 
						|
		tString::iterator it = m_str.begin();
 | 
						|
		while (it != m_str.end())
 | 
						|
		{
 | 
						|
			if (*it == chOld)
 | 
						|
			{
 | 
						|
				*it = chNew;
 | 
						|
				++nCount;
 | 
						|
			}
 | 
						|
			++it;
 | 
						|
		}
 | 
						|
		return nCount;
 | 
						|
	}
 | 
						|
 | 
						|
	inline int CString::Replace(LPCTSTR pszOld, LPCTSTR pszNew)
 | 
						|
	// Replaces each occurance of the old substring with the new substring.
 | 
						|
	{
 | 
						|
		assert(pszOld);
 | 
						|
		assert(pszNew);
 | 
						|
 | 
						|
		int nCount = 0;
 | 
						|
		size_t pos = 0;
 | 
						|
		while ((pos = m_str.find(pszOld, pos)) != std::string::npos)
 | 
						|
		{
 | 
						|
			m_str.replace(pos, lstrlen(pszOld), pszNew);
 | 
						|
			pos += lstrlen(pszNew);
 | 
						|
			++nCount;
 | 
						|
		}
 | 
						|
		return nCount;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::Right(int nCount) const
 | 
						|
	// Extracts the right part of a string.
 | 
						|
	{
 | 
						|
		assert(nCount >= 0);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		str.m_str.assign(c_str(), m_str.size() - nCount, nCount);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline BSTR CString::SetSysString(BSTR* pBstr) const
 | 
						|
	// Sets an existing BSTR object to the string.
 | 
						|
	{
 | 
						|
		assert(pBstr);
 | 
						|
 | 
						|
		if ( !::SysReAllocStringLen(pBstr, T2W(m_str.c_str()), (UINT)m_str.length()) )
 | 
						|
			throw std::bad_alloc();
 | 
						|
 | 
						|
		return *pBstr;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::SpanExcluding(LPCTSTR pszText) const
 | 
						|
	// Extracts characters from the string, starting with the first character, 
 | 
						|
	// that are not in the set of characters identified by pszCharSet.
 | 
						|
	{
 | 
						|
		assert (pszText);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		size_t pos = 0;
 | 
						|
 | 
						|
		while ((pos = m_str.find_first_not_of(pszText, pos)) != std::string::npos)
 | 
						|
		{
 | 
						|
			str.m_str.append(1, m_str[pos++]);
 | 
						|
		}
 | 
						|
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::SpanIncluding(LPCTSTR pszText) const
 | 
						|
	// Extracts a substring that contains only the characters in a set.
 | 
						|
	{
 | 
						|
		assert (pszText);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		size_t pos = 0;
 | 
						|
 | 
						|
		while ((pos = m_str.find_first_of(pszText, pos)) != std::string::npos)
 | 
						|
		{
 | 
						|
			str.m_str.append(1, m_str[pos++]);
 | 
						|
		}
 | 
						|
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString CString::Tokenize(LPCTSTR pszTokens, int& iStart) const
 | 
						|
	// Extracts specified tokens in a target string.
 | 
						|
	{
 | 
						|
		assert(pszTokens);
 | 
						|
		assert(iStart >= 0);
 | 
						|
 | 
						|
		CString str;
 | 
						|
		size_t pos1 = m_str.find_first_not_of(pszTokens, iStart);
 | 
						|
		size_t pos2 = m_str.find_first_of(pszTokens, pos1);
 | 
						|
 | 
						|
		iStart = (int)pos2 + 1;
 | 
						|
		if (pos2 == m_str.npos)
 | 
						|
			iStart = -1;
 | 
						|
 | 
						|
		if (pos1 != m_str.npos)
 | 
						|
			str.m_str = m_str.substr(pos1, pos2-pos1);
 | 
						|
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::Trim()
 | 
						|
	// Trims all leading and trailing whitespace characters from the string.
 | 
						|
	{
 | 
						|
		TrimLeft();
 | 
						|
		TrimRight();
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimLeft()
 | 
						|
	// Trims leading whitespace characters from the string.
 | 
						|
	{
 | 
						|
		// This method is supported by the Borland 5.5 compiler
 | 
						|
		tString::iterator iter;
 | 
						|
		for (iter = m_str.begin(); iter < m_str.end(); ++iter)
 | 
						|
		{
 | 
						|
			if (!isspace(*iter))
 | 
						|
				break;
 | 
						|
		}
 | 
						|
 | 
						|
		m_str.erase(m_str.begin(), iter);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimLeft(TCHAR chTarget)
 | 
						|
	// Trims the specified character from the beginning of the string.
 | 
						|
	{
 | 
						|
		m_str.erase(0, m_str.find_first_not_of(chTarget));
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimLeft(LPCTSTR pszTargets)
 | 
						|
	// Trims the specified set of characters from the beginning of the string. 
 | 
						|
	{
 | 
						|
		assert(pszTargets);
 | 
						|
		m_str.erase(0, m_str.find_first_not_of(pszTargets));
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimRight()
 | 
						|
	// Trims trailing whitespace characters from the string.
 | 
						|
	{
 | 
						|
		// This method is supported by the Borland 5.5 compiler
 | 
						|
		tString::reverse_iterator riter;
 | 
						|
		for (riter = m_str.rbegin(); riter < m_str.rend(); ++riter)
 | 
						|
		{
 | 
						|
			if (!isspace(*riter))
 | 
						|
				break;
 | 
						|
		}
 | 
						|
 | 
						|
		m_str.erase(riter.base(), m_str.end());
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimRight(TCHAR chTarget)
 | 
						|
	// Trims the specified character from the end of the string.
 | 
						|
	{
 | 
						|
		size_t pos = m_str.find_last_not_of(chTarget);
 | 
						|
		if (pos != std::string::npos)
 | 
						|
			m_str.erase(++pos);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::TrimRight(LPCTSTR pszTargets)
 | 
						|
	// Trims the specified set of characters from the end of the string.
 | 
						|
	{
 | 
						|
		assert(pszTargets);
 | 
						|
 | 
						|
		size_t pos = m_str.find_last_not_of(pszTargets);
 | 
						|
		if (pos != std::string::npos)
 | 
						|
			m_str.erase(++pos);
 | 
						|
	}
 | 
						|
 | 
						|
	inline void CString::Truncate(int nNewLength)
 | 
						|
	// Reduces the length of the string to the specified amount.
 | 
						|
	{
 | 
						|
		if (nNewLength < GetLength())
 | 
						|
		{
 | 
						|
			assert(nNewLength >= 0);
 | 
						|
			m_str.erase(nNewLength);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	
 | 
						|
	///////////////////////////////////
 | 
						|
	// Global Functions
 | 
						|
	//
 | 
						|
 | 
						|
	// friend functions of CString
 | 
						|
	inline CString operator + (const CString& string1, const CString& string2)
 | 
						|
	{
 | 
						|
		CString str(string1);
 | 
						|
		str.m_str.append(string2.m_str);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
	inline CString operator + (const CString& string, LPCTSTR pszText)
 | 
						|
	{
 | 
						|
		CString str(string);
 | 
						|
		str.m_str.append(pszText);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
	
 | 
						|
	inline CString operator + (const CString& string, TCHAR ch)
 | 
						|
	{
 | 
						|
		CString str(string);
 | 
						|
		str.m_str.append(1, ch);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
	
 | 
						|
	inline CString operator + (LPCTSTR pszText, const CString& string)
 | 
						|
	{
 | 
						|
		CString str(pszText);
 | 
						|
		str.m_str.append(string);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
	
 | 
						|
	inline CString operator + (TCHAR ch, const CString& string)
 | 
						|
	{
 | 
						|
		CString str(ch);
 | 
						|
		str.m_str.append(string);
 | 
						|
		return str;
 | 
						|
	}	
 | 
						|
 | 
						|
	// Global LoadString
 | 
						|
	inline CString LoadString(UINT nID)
 | 
						|
	{
 | 
						|
		CString str;
 | 
						|
		str.LoadString(nID);
 | 
						|
		return str;
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
}	// namespace Win32xx
 | 
						|
 | 
						|
#endif//_WIN32XX_CSTRING_H_
 |