Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

A comprehensive CE class library to replace ATL and MFC

, 4 Oct 2000
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
kgwince-old.zip
WinCe
BeamEx
app.ico
BeamEx.dsp
BeamEx.dsw
BeamEx.ini
BeamEx.plg
bitmap1.bmp
bmp00001.bmp
bmp00002.bmp
calc.bmp
calc16.bmp
circ_cross.ico
cir_cross.ico
cross_4.ico
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico00005.ico
ico00008.ico
ico00009.ico
ico00010.ico
icon1.ico
icon2.ico
icon4.ico
id_downl.bmp
Install
BeamEx.inf
BeamEx.ini
BeamEx.MIPS_PPCBW.CAB
BeamEx.MIPS_PPCColor.CAB
BeamEx.SH3_PPCColor.CAB
Setup.exe
i_cross.ico
l_cross.ico
magenic.ico
mssccprj.scc
obl_corss.ico
obl_cross.ico
options.bmp
options1.bmp
ping16.bmp
rect_cross.ico
scene_5.ico
scene_6.ico
tri_cross.ico
vssver.scc
CeLib
CeLabel.inl
CeLib.aps
CeLib.dsp
CeLib.dsw
CeLib.old
CeLib.plg
CeLib.vcp
CeMisc.inl
CeProperty.inl
CeTab.inl
CeWnd.inl
mssccprj.scc
vssver.scc
WinLib.dsp
WinLib.dsw
dbView
bitmap1.bmp
bmp00001.bmp
db5.bmp
dbView.aps
DbView.dsp
dbView.dsw
dbView.old
dbView.plg
DbView.vcp
deldb.bp2
deldb5.bmp
delrec.bp2
delrecor.bmp
help16.bmp
help4.bmp
icon1.ico
icon2.ico
Install
dbView.inf
dbView.ini
Setup.exe
magenic.bmp
magenic.ico
mssccprj.scc
vssver.scc
ftpView
appicon.ico
bitmap1.bmp
bitmap2.bmp
bitmap3.bmp
bitmap4.bmp
bmp00001.bmp
bmp00002.bmp
db5.bmp
deldb.bp2
delrec.bp2
FtpView.dsp
ftpView.dsw
FtpView.old
ftpView.plg
FtpView.vcl
FtpView.vcp
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico171.ico
ico35.ico
icon1.ico
icon2.ico
imagelis.bmp
IMAGES.bmp
Install
ftpView.inf
ftpView.ini
Setup.exe
vssver.scc
magenic.bmp
magenic.ico
mssccprj.scc
options.bmp
options1.bmp
seperato.bmp
vssver.scc
Setup
ico101.ico
Setup.aps
Setup.dsp
setup.ico
Setup.plg
WinCe.dsw
WinLib.dsw
kgwince.zip
app.ico
BeamEx.dsp
BeamEx.dsw
BeamEx.ini
BeamEx.plg
BeamEx.vcl
BeamEx.vcp
bitmap1.bmp
bmp00001.bmp
bmp00002.bmp
calc.bmp
calc16.bmp
circ_cross.ico
cir_cross.ico
cross_4.ico
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico00005.ico
ico00008.ico
ico00009.ico
ico00010.ico
icon1.ico
icon2.ico
icon4.ico
id_downl.bmp
BeamEx.inf
BeamEx.ini
Setup.exe
i_cross.ico
l_cross.ico
magenic.ico
mssccprj.scc
obl_corss.ico
obl_cross.ico
options.bmp
options1.bmp
ping16.bmp
rect_cross.ico
scene_5.ico
scene_6.ico
tri_cross.ico
vssver.scc
CeFtp.vcp
CeFtp.vcw
CeLabel.inl
CeLib.aps
CeLib.dsp
CeLib.dsw
CeLib.plg
CeLib.vcl
CeLib.vcp
CeMisc.inl
CeProperty.inl
CeTab.inl
CeWnd.inl
mssccprj.scc
vssver.scc
WinLib.dsp
WinLib.dsw
bitmap1.bmp
bitmap2.bmp
bmp00001.bmp
db5.bmp
DbView.dsp
dbView.dsw
dbView.plg
DbView.vcl
DbView.vcp
deldb.bp2
deldb5.bmp
delrec.bp2
delrecor.bmp
help16.bmp
help4.bmp
icon1.ico
icon2.ico
dbView.inf
dbView.ini
Setup.exe
magenic.bmp
magenic.ico
menu1_5.bmp
mssccprj.scc
vssver.scc
appicon.ico
bitmap1.bmp
bitmap2.bmp
bitmap3.bmp
bitmap4.bmp
bmp00001.bmp
bmp00002.bmp
db5.bmp
deldb.bp2
delrec.bp2
FtpView.dsp
ftpView.dsw
ftpView.plg
FtpView.vcl
FtpView.vcp
FtpView.vcw
help16.bmp
help4.bmp
ico00001.ico
ico00002.ico
ico171.ico
ico35.ico
icon1.ico
icon2.ico
imagelis.bmp
IMAGES.bmp
ftpView.inf
ftpView.ini
Setup.exe
vssver.scc
magenic.bmp
magenic.ico
mssccprj.scc
newmenu.bmp
options.bmp
options1.bmp
rcdata1.bin
seperato.bmp
toolbar1.bmp
vssver.scc
WinCe.dsw
WinCe.vcw
///////////////////////////////////////////////////////////////////////////////
//                                                                             *
///////////////////////////////////////////////////////////////////////////////

#ifndef _CESTRING_DEFINED_
#define _CESTRING_DEFINED_

//#include <iostream.h>    // The iostream facilities are not used in the classes
// in this file, but they are used in the code that 
// tests the classes.

#include <string.h>      // This includes the C string functions, e.g.,
#include <stdlib.h>
#include <tchar.h>

#include "CeDebug.h"
#include "CeMisc.h"

#ifdef _WIN32_WCE
extern wchar_t* wce_AsciiToWide( wchar_t* ws, const char* s );
#endif


///////////////////////////////////////////////////////////////////////////////
//
// Reference counted string representation struct
//
///////////////////////////////////////////////////////////////////////////////

struct CeStringRep
{
public:
// Construction/Destruction
	int AddRef()
	{
		ASSERT(! IsBadWritePtr(this, sizeof *this));
		ASSERT(0 != m_nLen);
		::InterlockedIncrement(&m_nRef);
		return m_nRef;
	}
	int Release()
	{
		ASSERT(! IsBadWritePtr(this, sizeof *this));
		ASSERT(0 != m_nLen);
		::InterlockedDecrement(&m_nRef);
		return m_nRef;
	}
	bool IsShared() const { return m_nRef > 1; }
	int GetRefs() const { return m_nRef; }
	TCHAR* GetString() const { return (TCHAR*) (this+1); }
	int GetLength() const { return m_nLen; }

	static CeStringRep* AllocBuf(int nStrLen)
	{
		CeStringRep* pRep = (CeStringRep*) new BYTE[ sizeof(CeStringRep) +
								(nStrLen+1)*sizeof(TCHAR) ];
		pRep->m_nLen = nStrLen;
		pRep->m_nRef = 1;
		pRep->GetString()[nStrLen] = _T('\0');
		return pRep;
	}
	static void FreeBuf(CeStringRep* pStr)
	{
		delete[] (BYTE *) pStr;
	}

	// retrieve the constants for the null string and or the null string representation
	static LPTSTR NullString() { return (LPTSTR) s_lpszCeEmpty; }
	static CeStringRep* NullRep() { return s_cerepNullRep; }

private:
	static CeStringRep* s_cerepNullRep;
	static LPCTSTR s_lpszCeEmpty;
	static int s_rgNullData[];

	long m_nRef;
	long m_nLen;
//	TCHAR m_szString[];	-- implied array to TCHAR
};


///////////////////////////////////////////////////////////////////////////////
//
//          Classes String and StringValue (from pp. 204, 206-207)
//
///////////////////////////////////////////////////////////////////////////////
class CeString							// class to be used by developers
{
public:
// Constructors
	CeString()
		{ Init(); }
	CeString(TCHAR ch)
		{ Construct(&ch, 1); }
	CeString(LPCTSTR lpsz, int nLength)
		{ ASSERT(lpsz != NULL && ! IsBadReadPtr(lpsz, nLength)); Construct(lpsz, nLength); }
#ifdef _WIN32_WCE
	CeString(LPCSTR lpsz, int nLength=0)
		{
			if (nLength == 0)
				nLength = strlen(lpsz);
			ASSERT(lpsz != NULL && ! IsBadReadPtr(lpsz, nLength));
			// allocate a new copy
			CeStringRep* pRep = CeStringRep::AllocBuf(nLength);
			// assign pointer
			m_pStr = pRep->GetString();
			// assign characters
			for (int ii = 0; ii < nLength; ii++)
				m_pStr[ii] = (wchar_t) *lpsz++;
			m_pStr[ii] = 0;
		}
#endif // _WIN32_WCE

	CeString(const CeString& strSrc)
	{
		m_pStr = strSrc.m_pStr;
		if (CeStringRep::NullString() != m_pStr)
			GetRep()->AddRef();
	}
	CeString(LPCTSTR lpsz)
	{
		if (lpsz != NULL && HIWORD(lpsz) == NULL)
		{
			Init();
			UINT nID = LOWORD((DWORD)lpsz);
			// Warning: implicit LoadString() failed.
			LoadString(nID, NULL);
		}
		else
			Construct(lpsz);
	}
	CeString(TCHAR ch, int nChar)
	{
		// allocate a new copy
		CeStringRep* pRep = CeStringRep::AllocBuf(nChar);
		// assign pointer
		m_pStr = pRep->GetString();
		// assign characters
		for (int ii = 0; ii < nChar; ii++)
			m_pStr[ii] = ch;
	}
	CeString(HWND hWnd)
	{
		if (! ::IsWindow(hWnd))
			// will now be a null string
			Init();
		else
		{
			int nLen = ::GetWindowTextLength(hWnd);
			if (nLen)
			{
				// allocate a new copy and get the window text
				CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
				m_pStr = pRep->GetString();
				::GetWindowText(hWnd, m_pStr, nLen+1);
			}
			else
				Init();
		}
	}

	CeString(short s, int base=10)				{ Init(); SetShort(s, base); }
	CeString(long l, int base=10)				{ Init(); SetLong(l, base); }
	CeString(unsigned long ul, int base=10)		{ Init(); SetULong(ul, base); }
	CeString(double dbl, int p=3)				{ Init(); SetDouble(dbl, p); }

	virtual ~CeString()							{ Release(); }

public:
// Operators
	const CeString& operator= (const CeString& strSrc);
	const CeString& operator= (LPCTSTR lpsz);
	const CeString& operator= (TCHAR ch)		{ Assign(&ch, 1); return *this;	}
#ifdef _WIN32_WCE
	const CeString& operator= (const char *lps);
#endif

	const CeString& operator+= (const CeString& strSrc)	{ Append(strSrc.m_pStr, strSrc.Length());	return *this; }
	const CeString& operator+= (LPCTSTR lpsz)			{ Append(lpsz, lstrlen(lpsz));	return *this; }
	const CeString& operator+ (const CeString& T);
	const CeString& operator+ (LPCTSTR lpsz);

	bool operator == (LPCTSTR lpsz) const		{ return (Compare(lpsz) == 0);}
	bool operator != (LPCTSTR lpsz) const		{ return (Compare(lpsz) != 0);}
	bool operator <= (LPCTSTR lpsz) const		{ return (Compare(lpsz) <= 0);}
	bool operator <  (LPCTSTR lpsz) const		{ return (Compare(lpsz) <  0);}
	bool operator >= (LPCTSTR lpsz) const		{ return (Compare(lpsz) >= 0);}
	bool operator >  (LPCTSTR lpsz) const		{ return (Compare(lpsz) >  0);}

	operator long()	const						{ return _ttol(m_pStr); }
	operator int() const						{ return _ttoi(m_pStr); }
	operator double() const						{ return _tcstod(m_pStr, NULL); }
	operator LPCTSTR() const					{ return m_pStr; }

	TCHAR operator[](int ii) const				{ CHW_ASSERT(ii >= 0 && ii < Length());  return m_pStr[ii]; }
	// may remove this, it allows internal access
	TCHAR& operator[](int ii)					{ CHW_ASSERT(ii >= 0 && ii < Length()); CopyOnWrite(); return m_pStr[ii]; }

// Attributes
	int Length()  const							{ return GetRep()->GetLength(); }
	int GetLength() const						{ return GetRep()->GetLength(); }

	// for compatability with CString
	int GetAllocLength() const					{ return GetRep()->GetLength(); }
	BOOL IsEmpty() const						{ return (Length() == 0); }

// Operations
	int Compare (LPCTSTR lpsz)       const		{ return _tcscmp (m_pStr, lpsz); }
	int CompareNoCase (LPCTSTR lpsz) const		{ return _tcsicmp (m_pStr, lpsz); }

	void Truncate(int nLen);

	LPCTSTR Find(LPCTSTR lpsz) const			{ return _tcsstr(m_pStr, lpsz); }
	LPCTSTR Find(TCHAR ch) const				{ return _tcschr(m_pStr, ch); }
	int FindIndex(LPCTSTR lpsz) const			{ LPCTSTR pPos = Find(lpsz); return pPos ? pPos - m_pStr: -1; }
	int FindIndex(TCHAR ch) const				{ LPCTSTR pPos = Find(ch); return pPos ? pPos - m_pStr: -1; }
//	LPCTSTR ReverseFind(LPCTSTR lpsz) const		{ return _tcsrstr(m_sz, lpsz); }
	LPCTSTR ReverseFind(TCHAR ch) const			{ return _tcsrchr(m_pStr, ch); }
	int ReverseFindIndex(TCHAR ch) const		{ LPCTSTR pPos = ReverseFind(ch); return pPos ? pPos - m_pStr: -1; }

	LPCTSTR FindOneOf(LPCTSTR lpsz) const		{ int i = _tcscspn(m_pStr, lpsz); return ((m_pStr[i] == 0) ? NULL : &m_pStr[i]); }
	LPCTSTR FindNotOneOf(LPCTSTR lpsz) const	{ int i = _tcsspn(m_pStr, lpsz); return ((m_pStr[i] == 0) ? NULL : &m_pStr[i]); }

	void Format(LPCTSTR szFormat, ...);

	int LoadString(UINT nIDS, HINSTANCE hInst=NULL)
	{
		CopyOnWrite();
	#ifdef _WIN32_WCE
		if (hInst == NULL) hInst = CeGetAppInstance();
		LPCTSTR lpsz = (LPCTSTR) ::LoadString(hInst, nIDS, NULL, 0);
		if (NULL == lpsz)
			return 0;
		else
		{
			int nLen = *(((WORD *)lpsz) - 1);
			return Assign(lpsz, nLen);
		}
	#else
//		error 0
		return 0;
	#endif
	}
	void FormatMessage(DWORD dwSystemErrorID);

	int GetWindowText(HWND hWnd)
	{
		// Note: returns empty string on failure
		Release();

		if (! ::IsWindow(hWnd))
			// will now be a null string
			return 0;

		int nLen = ::GetWindowTextLength(hWnd);
		if (! nLen)
			// will now be a null string
			return 0;

		// allocate a new copy and get the window text
		CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
		m_pStr = pRep->GetString();
		return ::GetWindowText(hWnd, m_pStr, nLen+1);
	}

	void Trim();
	void LTrim();
	void RTrim();

	void Empty()								{ Release();	}
	void MakeUpper()							{ CopyOnWrite(); _tcsupr(m_pStr); }
	void MakeLower()							{ CopyOnWrite(); _tcslwr(m_pStr); }
	void Reverse()								{ CopyOnWrite(); _tcsrev(m_pStr); }

	void Append(LPCTSTR lpsz, int nChars=-1);

	void Set(char ch, int i);
	void Set(char ch);

	void SetShort(short s, int b=10);
	void SetLong(long l, int b=10);
	void SetULong(unsigned long l, int b=10);
	void SetDouble(double dValue, int nPrecision);

	// in testing, use at your own risk...
	LPTSTR GetBuffer(int nMinLen);
	LPTSTR GetBufferSetLength(int nLen);
	void ReleaseBuffer();

	// convenient for testing
//	friend ostream& operator<<(ostream& stream, const String& string);

private:
// Implementation
	LPTSTR m_pStr;

	// initialize to a null pointer
	void Init()					{ m_pStr = CeStringRep::NullString(); }

	// retrieve the string representation structure
	CeStringRep* GetRep() const	{ return ((CeStringRep *) m_pStr) - 1; }

	// release data associated with the pointer, but only if not the null string
	void Release()
	{
		if (m_pStr != CeStringRep::NullString())
		{
			ASSERT(GetRep()->GetRefs() != 0);
			if (GetRep()->Release() <= 0)
				CeStringRep::FreeBuf( GetRep() );

			Init();
		}
	}

	// duplicate the string if others reference it,
	// ASSUMES THERE WAS A PREVIOUS VALUE
	void CopyOnWrite()
	{
		if (0 == GetRep()->GetLength())
			return;

		if (GetRep()->IsShared())
		{
			// allocate a new copy
			CeStringRep* pRep = CeStringRep::AllocBuf(GetRep()->GetLength());
			// copy into string
			memcpy(pRep->GetString(), m_pStr, (GetRep()->GetLength() + 1) * sizeof(TCHAR));
			// release our reference on the old
			GetRep()->Release();
			// assign the new one
			m_pStr = pRep->GetString();
		}
		ASSERT(GetRep()->GetRefs() >= 1);
	}

	int Construct(LPCTSTR lpsz, int nLen=-1)
	{
		// get the length of the string
		if (nLen == -1)
			nLen = lstrlen(lpsz);

		if (nLen == 0)
			// null string
			m_pStr = CeStringRep::NullString();
		else
		{
			// allocate a new copy
			CeStringRep* pRep = CeStringRep::AllocBuf(nLen);
			// assign
			m_pStr = pRep->GetString();
			// copy
			memcpy(m_pStr, lpsz, nLen * sizeof(TCHAR));
		}

		// return the size of the string
		return nLen;
	}

	// allocate and assign a constant string to the string data
	// DOES NOT CHECK FOR OLD VALUE...
	int Assign(LPCTSTR lpsz, int nLen=-1)
	{
		// get rid of the old copy
		Release();
		// construct and return the size of the string
		return Construct(lpsz, nLen);
	}
};


//ostream& operator<<(ostream& stream, const CeString& string)
//{
//	return stream << string.m_pStr;
//}


#endif // _CESTRING_DEFINED_

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Kenny G

United States United States
No Biography provided

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 5 Oct 2000
Article Copyright 2000 by Kenny G
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid