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 CPOL
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
#include "stdafx.h"
#include "CeDb.h"

#include <winnls.h>


char* WideToAscii( char* s, const wchar_t* ws )
{
	char* pszSave = (char*) s;
    while (*s++ = (char) *ws++ )
		;

	return (pszSave);
}


bool CeDb::ReadRec(CeDbRecord& rec)
{
	ASSERT(IsOpen());

	if (! rec.m_bLocalAlloc && rec.m_pProps)
		delete[] rec.m_pProps;

	rec.m_pProps = NULL;
	rec.m_cbProps = 0;
	rec.m_bLocalAlloc = true;

	// Getting a record WILL overwrite the old values
	rec.m_wProps = 0;

	// read all properties
	rec.m_oid = ::CeReadRecordProps(
		m_hDb,					// this database
		CEDB_ALLOWREALLOC,		// no realloc
		&rec.m_wProps,			// number of properties in THIS record
		NULL,					// get all columnsfor THIS record
		(BYTE**) &rec.m_pProps,	// the properties values
		&rec.m_cbProps			// size of the allocated space	
	);

	return (rec.m_oid && rec.m_pProps && rec.m_wProps);
}

//
// CEVT_BLOB		A CEBLOB structure. 
// CEVT_FILETIME	A FILETIME structure. 
// CEVT_I2			A 16-bit signed integer. 
// CEVT_I4			A 32-bit signed integer. 
// CEVT_LPWSTR		A null-terminated string. 
// CEVT_UI2			A 16-bit unsigned integer. 
// CEVT_UI4			A 32-bit unsigned integer. 
//
// And beginning in 2.11
// CEVT_BOOL		A boolean value.
// CEVT_R8			A double floating point value.
//

bool CeDbRecord::GetIndexVal(int nProp, SHORT& iProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_I2);
	iProp = m_pProps[nProp].val.iVal;
	return true;
}


bool CeDbRecord::GetIndexVal(int nProp, USHORT& uiProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_UI2);
	uiProp = m_pProps[nProp].val.uiVal;
	return true;
}


bool CeDbRecord::GetIndexVal(int nProp, LONG& lProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_I4);
	lProp = m_pProps[nProp].val.lVal;
	return true;
}


bool CeDbRecord::GetIndexVal(int nProp, ULONG& ulProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_UI4);
	ulProp = m_pProps[nProp].val.ulVal;
	return true;
}


bool CeDbRecord::GetIndexVal(int nProp, FILETIME& ftProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_FILETIME);
	ftProp = m_pProps[nProp].val.filetime;
	return true;
}


#ifdef CEVT_BOOL
#pragma warning(disable: 4800)
bool CeDbRecord::GetIndexVal(int nProp, bool& bProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_BOOL);
	bProp = m_pProps[nProp].val.boolVal;
	return true;
}
#endif

#ifdef CEVT_R8
bool CeDbRecord::GetIndexVal(int nProp, double& dblProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_R8);
	dblProp = m_pProps[nProp].val.dblVal;
	return true;
}
#endif


bool CeDbRecord::GetIndexVal(int nProp, CEBLOB& blobProp) const
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_BLOB);
	return true;
}

inline char HiNibble(BYTE by)	{ return (by >> 4);   }
inline char LoNibble(BYTE by)	{ return (by & 0x0F); }

static CeString GetBlob(DWORD dwSize, BYTE* lpByte)
{
	CeString str;
	LPTSTR lpsz = str.GetBufferSetLength(3 * dwSize);
	for (DWORD ii = 0; ii < dwSize; ii++)
	{
		BYTE byTmp;

		byTmp = HiNibble(*lpByte);
		*lpsz++ = (TCHAR) (byTmp < 0x0A) ? _T('0') + byTmp: _T('A') + (byTmp - 0x0A);

		byTmp = LoNibble(*lpByte);
		*lpsz++ = (TCHAR) (byTmp < 0x0A) ? _T('0') + byTmp: _T('A') + (byTmp - 0x0A);
	
		*lpsz++ = _T(' ');
		lpByte++;
	}
	*lpsz = 0;
	str.ReleaseBuffer();
	return str;
}

// valid for all types, limited to 256 bytes for Blob
bool CeDbRecord::GetIndexVal(int nProp, CeString& strProp) const
{
	//ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
	{
		strProp.Empty();
		return false;
	}

	switch ( LOWORD(m_pProps[nProp].propid) )
	{
	case CEVT_BLOB:
		strProp = GetBlob(m_pProps[nProp].val.blob.dwCount, m_pProps[nProp].val.blob.lpb);
		break;
	case CEVT_FILETIME:
		{
			SYSTEMTIME st;

			BOOL bSuccess = ::FileTimeToSystemTime(&m_pProps[nProp].val.filetime, &st);
			if (! bSuccess || st.wYear > 9999)
			{
				strProp.Empty();
				return true;
			}

			CeString strTime;

			::GetDateFormat(LOCALE_SYSTEM_DEFAULT, DATE_SHORTDATE,
				&st, NULL, strProp.GetBufferSetLength(32), 32);
			strProp.ReleaseBuffer();

			::GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS,
				&st, NULL, strTime.GetBufferSetLength(32), 32);
			strTime.ReleaseBuffer();

			strProp += _T(" ");
			strProp += strTime;
		}
		break;
	case CEVT_I2:
		strProp = CeString(m_pProps[nProp].val.iVal);
		break;
	case CEVT_I4:
		strProp = CeString(m_pProps[nProp].val.lVal);
		break;
	case CEVT_LPWSTR:
#ifdef UNICODE
		strProp = m_pProps[nProp].val.lpwstr;
#else
		WideToAscii( strProp.GetBufferSetLength( wcslen(m_pProps[nProp].val.lpwstr) ),
			m_pProps[nProp].val.lpwstr );
		strProp.ReleaseBuffer();
#endif
		break;
	case CEVT_UI2:
		strProp = CeString((ULONG)m_pProps[nProp].val.uiVal);
		break;
	case CEVT_UI4:
		strProp = CeString((ULONG)m_pProps[nProp].val.ulVal);
		break;
#ifdef CEVT_BOOL
	case CEVT_BOOL:
		strProp = m_pProps[nProp].val.boolVal ? _T("true"): _T("false");
		break;
#endif
#ifdef CEVT_R8
	case CEVT_R8:
		strProp = CeString(m_pProps[nProp].val.dblVal);
		break;
#endif
	default:
		return false;
	}

	return true;
}


bool CeDbRecord::SetIndexVal(int nProp, SHORT iProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_I2);
	m_pProps[nProp].val.iVal = iProp;
	return true;
}

bool CeDbRecord::SetIndexVal(int nProp, USHORT uiProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_UI2);
	m_pProps[nProp].val.uiVal = uiProp;
	return true;
}

bool CeDbRecord::SetIndexVal(int nProp, LONG lProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_I4);
	m_pProps[nProp].val.lVal = lProp;
	return true;
}

bool CeDbRecord::SetIndexVal(int nProp, ULONG ulProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_UI4);
	m_pProps[nProp].val.ulVal = ulProp;
	return true;
}

bool CeDbRecord::SetIndexVal(int nProp, FILETIME ftProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_FILETIME);
	m_pProps[nProp].val.filetime = ftProp;
	return true;
}

#ifdef CEVT_BOOL
bool CeDbRecord::SetIndexVal(int nProp, bool bProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_BOOL);
	m_pProps[nProp].val.boolVal = bProp;
	return true;
}
#endif

#ifdef CEVT_R8
bool CeDbRecord::SetIndexVal(int nProp, double dblProp)
{
//	ASSERT(nProp < m_wProps && nProp >= 0);
	if (nProp < 0 || nProp >= m_wProps)
		return false;
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_R8);
	m_pProps[nProp].val.dblVal = dblProp;
	return true;
}
#endif


CEPROPVAL* CeDbRecord::DupProps(CEPROPVAL* pPropsOrig, WORD wProps, DWORD cbNewProps)
{
	// allocate a buffer
	CEPROPVAL* pProps = (CEPROPVAL*) new BYTE[cbNewProps];
	ASSERT(NULL != pProps);
	if (NULL == pProps)
		return NULL;

	// assumes structure and pointer are word aligned
	BYTE* pData = (BYTE*) pProps + sizeof CEPROPVAL * wProps;

	for (WORD ii = 0; ii < wProps; ii++)
	{
		// shallow copy, don't require extra memory space to store the value
		pProps[ii] = pPropsOrig[ii];

		// check if deep copy required
		if ( CEVT_BLOB == LOWORD(pPropsOrig[ii].propid) )
		{
			// Note: could be a NULL value
			if (0 == pPropsOrig[ii].val.blob.dwCount || NULL == pProps[ii].val.blob.lpb)
				continue;

			// NOTE: this has to be on a WORD boundry!!!
			DWORD dwLen = pPropsOrig[ii].val.blob.dwCount;
			pProps[ii].val.blob.lpb = pData;

			memcpy( pProps[ii].val.blob.lpb, pPropsOrig[ii].val.blob.lpb, dwLen );

			// required so character indexes are even
			pData += (dwLen + (dwLen % sizeof WORD));
		}
		else if ( CEVT_LPWSTR == LOWORD(pPropsOrig[ii].propid) )
		{
			// Note: could be a NULL value
			if (NULL == pPropsOrig[ii].val.lpwstr)
				continue;

			// note: results are always word alligned
			// since the characters are the size of the word
			DWORD dwLen = (wcslen(pPropsOrig[ii].val.lpwstr) + 1) * sizeof WCHAR;
			pProps[ii].val.lpwstr = (WCHAR *) pData;

			memcpy(pData, pPropsOrig[ii].val.lpwstr, dwLen);

			pData += dwLen;
		}
	}

	return pProps;
}

bool CeDbRecord::SetIndexVal(int nProp, CEBLOB blobProp)
{
	ASSERT(nProp < m_wProps && nProp >= 0);
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_BLOB);

	if (m_pProps[nProp].val.blob.dwCount < blobProp.dwCount)
	{
		// need to reallocate the ENTIRE record and copy in this one
		// Note: THIS will ONLY work when EXPANDING the allocated memory

		DWORD cbProps = (blobProp.dwCount - m_pProps[nProp].val.blob.dwCount);
		//cbProps += (dwLen % sizeof WORD)

		m_pProps[nProp].val.blob.lpb = blobProp.lpb;
		m_pProps[nProp].val.blob.dwCount = blobProp.dwCount;

		CEPROPVAL* pProps = DupProps(m_pProps, m_wProps, cbProps);
		if (NULL == pProps)
			return false;
		if (m_bLocalAlloc)
			::LocalFree(m_pProps);
		else
			delete[] (BYTE*) m_pProps;
		m_pProps = pProps;
		m_cbProps = cbProps;
		m_bLocalAlloc = false;
	}
	else
	{
		memcpy(m_pProps[nProp].val.blob.lpb, blobProp.lpb, blobProp.dwCount);
		m_pProps[nProp].val.blob.dwCount = blobProp.dwCount;
	}

	return false;
}

bool CeDbRecord::SetIndexVal(int nProp, LPCWSTR lpszProp)
{
	ASSERT(nProp < m_wProps && nProp >= 0);
	ASSERT(LOWORD(m_pProps[nProp].propid) == CEVT_LPWSTR);

	int nOldLen = (m_pProps[nProp].val.lpwstr) ? wcslen(m_pProps[nProp].val.lpwstr) + 2 : 0;
	int nNewLen = wcslen(lpszProp) + 2;
	
	if (nOldLen < nNewLen)
	{
		// need to reallocate the ENTIRE record and copy in this one
		// Note: THIS will ONLY work when EXPANDING the allocated memory

		DWORD cbProps = m_cbProps + (nNewLen - nOldLen) * sizeof WCHAR;

		// set pointer
		m_pProps[nProp].val.lpwstr = (LPWSTR) lpszProp;

		CEPROPVAL* pProps = DupProps(m_pProps, m_wProps, cbProps);
		if (NULL == pProps)
			return false;
		if (m_bLocalAlloc)
			::LocalFree(m_pProps);
		else
			delete[] (BYTE*) m_pProps;
		m_cbProps = cbProps;
		m_pProps = pProps;
		m_bLocalAlloc = false;
	}
	else
		wcscpy(m_pProps[nProp].val.lpwstr, lpszProp);

	return true;
}


bool CeDbRecord::AddProp(WORD wProp, WORD wType)
{
	CEPROPVAL* pProps = NULL;

	if (NULL == m_pProps)
	{
		// append to end
		pProps = (CEPROPVAL*) new BYTE[sizeof CEPROPVAL];
		DWORD dwErr = GetLastError();
		ASSERT(NULL != pProps);
	}
	else
	{
		{
			// enlarge
			pProps = (CEPROPVAL*) new BYTE[m_cbProps + sizeof CEPROPVAL];
			memcpy(pProps, m_pProps, m_cbProps);
		}

		DWORD dwErr = GetLastError();
		ASSERT(NULL != pProps);

		// move data from end
		for (int ii = m_wProps - 1; ii >= 0 ; ii--)
		{
			DWORD dwLen;

			if (CEVT_BLOB == LOWORD(pProps[ii].propid))
			{
				// NOTE: this has to be on a WORD boundry!!!
				dwLen = pProps[ii].val.blob.dwCount;

				if (0 != dwLen && NULL != pProps[ii].val.blob.lpb)
					pProps[ii].val.blob.lpb = (BYTE*) memmove( pProps[ii].val.blob.lpb + sizeof CEPROPVAL, pProps[ii].val.blob.lpb, dwLen);
			}
			else if (CEVT_LPWSTR == LOWORD(pProps[ii].propid))
			{
				// note: results are always word alligned
				// since the characters are the size of the word
				dwLen = pProps[ii].val.lpwstr ? (wcslen(pProps[ii].val.lpwstr) + 1) * sizeof WCHAR: 0;

				if (0 != dwLen)
					pProps[ii].val.lpwstr = (WCHAR*) memmove(pProps[ii].val.lpwstr + sizeof CEPROPVAL, pProps[ii].val.lpwstr, dwLen);
			}
		}
	}

	if (m_bLocalAlloc)
		::LocalFree(m_pProps);
	else
		delete[] (BYTE*) m_pProps;

	m_pProps = pProps;
	m_bLocalAlloc = false;
	m_cbProps += sizeof CEPROPVAL;
	m_wProps++;
	ZeroMemory(&m_pProps[m_wProps-1], sizeof CEPROPVAL);
	m_pProps[m_wProps-1].propid = MAKELPARAM(wType, wProp);

	return true;
}

bool CeDbRecord::RemProp(int nIndex)
{
//	memmove();
//	DupProps();
	return false;
}

bool CeDbRecord::RemProp(WORD wProp)
{
//	int nProp = FindProp(wProp);
//	memmove();
//	DupProps();
	return false;
}



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)

Share

About the Author

Kenny G

United States United States
No Biography provided

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