⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cedbase.cpp

📁 在WinCe平台上开发的数据库管理程序,里面有一个可排序列表控件的实现和Excel的CVS文件的读写类
💻 CPP
字号:
/*
 *Copyright (c)2001,北京恒基伟业
 *All rights reserved.
 *
 *文件名称:CEdbase.cpp
 *文件标识:见配置管理计划书
 *摘	要:WinCE数据库类的定义,主要实现WinCE数据库底层API的
 *			封装屏蔽细节操作,使其成为一个整体。
 *
 *
 *当前版本:1.1
 *作	者:钟元欢
 *完成日期:2001 年12 月20 日
 *
 *取代版本:1.0
 *原 作 者:钟元欢
 *完成日期:2001 年12 月16 日
 */
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CEdbase.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCEdbase::CCEdbase()
{
	m_isReady = FALSE;
	m_oidDB = 0;
	m_oidDBase = 0;
	m_pBuff = 0;
	m_hDB = 0;
	m_dwIndex = 0;
}

CCEdbase::~CCEdbase()
{

}

//FUNCTION:从当前的数据卷中打开指定的数据库
//PARAMETERS
//	lpszName:		[in]数据库文件名
//	hwndNotify:		[in]数据库改动后通知哪个窗口
//RETURN:
//	= TRUE			成功
//	= FALSE			失败
BOOL CCEdbase::OpenDB(LPWSTR lpszName, HWND hwndNotify)
{
	CENOTIFYREQUEST  cenr;

	cenr.dwSize = sizeof(cenr);
	cenr.hwnd = hwndNotify;
	cenr.dwFlags = 0;
	cenr.hHeap = 0;
	cenr.dwParam = 0;

	//以第一个字段排序,记录指针不自动移动方式打开数据库
	m_hDB = CeOpenDatabaseEx(&m_guid, &m_oidDBase, 
		lpszName, ID_ORDER_PROP, 0, &cenr);
	
	return m_hDB == INVALID_HANDLE_VALUE ? FALSE : TRUE;	
}

//FUNCTION:创建数据库文件
//PARAMETERS
//	lpszName:		[in]数据库名
//RETURN:
//	= TRUE			成功
//	= FALSE			失败
BOOL CCEdbase::CreateDB(LPTSTR lpszName)
{
	CEDBASEINFO dbi;

	dbi.rgSortSpecs[0].propid = ID_ORDER_PROP;
	dbi.rgSortSpecs[0].dwFlags = 0;
	dbi.dwFlags = CEDB_VALIDCREATE;
	lstrcpy(dbi.szDbaseName, lpszName);
	dbi.dwDbaseType = 0;						//MY_DBASE_TYPE;
	dbi.wNumSortOrder = 1;						// order by field1

	m_oidDBase = CeCreateDatabaseEx(&m_guid, &dbi);
	
	return	m_oidDBase == 0 ? FALSE : TRUE;
}

//FUNCTION:
//	初始化数据库,打开指定的数据卷中的数据库,如果不存在则新建一个并打开
//PARAMETERS
// lpszVolName:	[in]数据卷名
//	lpszDBName:		[in]数据库文件名
//	hwndNotify:		[in]要通告的窗口句柄
//RETURN:
//	= TRUE			成功
//	= FALSE			失败
BOOL CCEdbase::InitDB(LPWSTR lpszVolName,
					  LPWSTR lpszDBName,
					  HWND hwndNotify)
{
	//打开数据卷,如果没有则会新建一个,再打开其中的数据库
	//如果没有则新建并将其打开
	m_isReady = FALSE;

	if(!CeMountDBVol(&m_guid, lpszVolName, OPEN_ALWAYS))
	{
		return FALSE;
	}
	m_oidDBase = 0;
	if(!OpenDB(lpszDBName, hwndNotify))
	{
		if(CreateDB(lpszDBName))
		{
			if(!OpenDB(lpszDBName, hwndNotify))
			{
				return FALSE;
			}
		}
		else
		{
			return FALSE;
		}
	}
	m_isReady = TRUE;
	return TRUE;
}

//FUNCTION:读取当前记录
//PARAMETERS
//	lpcPropID:	[out]读取的属性(字段)个数(CEPROPVAL数组)
//	llpbBuf:	[out]CEPROPVAL数组缓冲区指针
//RETURN:
//	ID_SUCCESSFULLY:	成功
//	ID_NULL_ERROR:		数据库为空
//	ID_READ_ERROR:		读取时失败
//	ID_NO_READY_ERROR:	数据库未初始化
//REMARK:
//	缓冲区由函数内部自动分配,因此用完后请一定用LocalFee()释放内存。
WORD CCEdbase::ReadRecord(LPWORD lpcPropID, LPBYTE * llpbBuf)
{
	DWORD dwRecSize;			//存放返回的记录尺寸
	CEOID tempid;

	if(m_isReady)
	{	
		//数据库为空
		if(m_oidDB == 0)
			return ID_NULL_ERROR;

		m_pBuff = 0;
		//读取当前记录
		tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
			lpcPropID, NULL, &(LPBYTE)m_pBuff, &dwRecSize);
		if(tempid == 0)	
			return ID_READ_ERROR;
		
		m_oidDB = tempid;
		*llpbBuf = (LPBYTE)m_pBuff;

		return ID_SUCCESSFULLY;
	}
	return ID_NO_READY_ERROR;
}

//FUNCTION:新增一条记录并定位到新增记录,数据库按关键属性升序排列
//PARAMETERS:
//		cPropID:	[in]数组个数
//		rcPropVal:	[in]CEPROPVAL数组缓冲区指针
//RETURN:
//		ID_SUCCESSFULLY		写入成功
//		ID_NO_KEY_ERROR		关键字为空
//		ID_SAME_KEY_ERROR	存在相同关键字
//		ID_WRITE_ERROR		写入时失败
//		ID_NO_READY_ERROR	数据库没有初始化
WORD CCEdbase::WriteRecord(WORD cPropID, CEPROPVAL *rgPropVal)
{
	WORD i = 0;
	CEOID tempid;
	DWORD tempIndex;
	
	if(m_isReady)
	{	
		//必须有关键属性写入
		while(i < cPropID)
		{	
			if((rgPropVal + i)->propid == ID_ORDER_PROP)
			{
				break;
			}
			i++;
		}
		if(i >= cPropID)
		{
			return ID_NO_KEY_ERROR;
		}
		
		//查找是否有相同的关键属性值,不能有两条相同关键属性值
		//的记录存在
		CeSeekDatabase(m_hDB, CEDB_SEEK_BEGINNING, 0, &tempIndex);
		tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_VALUEFIRSTEQUAL,
			(DWORD)(rgPropVal + i), &tempIndex);
		if(tempid != 0)
		{
			return ID_SAME_KEY_ERROR;
		}
		
		//新增一条记录
		tempid = CeWriteRecordProps(m_hDB, 0, cPropID, rgPropVal);
		if(tempid == 0)
		{
			return ID_WRITE_ERROR;
		}

		//指向新增的记录
		m_oidDB = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, 
			tempid, &m_dwIndex);
				
		return ID_SUCCESSFULLY;
	}
	return ID_NO_READY_ERROR;
}

//FUNCTION:修改当前记录,如果修改了关键属性记录的先后位置会因自动排序而改变,
//		
//PARAMETERS:
//		cPropID:	[in]数组个数
//		rcPropVal:	[in]CEPROPVAL数组缓冲区指针
//RETURN:
//		ID_SUCCESSFULLY		写入成功
//		ID_NO_KEY_ERROR		关键字为空
//		ID_SAME_KEY_ERROR	存在相同关键字
//		ID_WRITE_ERROR		写入时失败
//		ID_NO_READY_ERROR	数据库没有初始化
WORD CCEdbase::ModifyCurRecord(WORD cPropID, CEPROPVAL *rgPropVal)
{
	WORD i = 0;
	CEOID tempid;
	DWORD tempIndex;

	if(m_isReady){
		
		//当前纪录指针为空说明数据库为空
		if(m_oidDB == 0)
		{
			return ID_NULL_ERROR;
		}

		//必须有关键属性写入
		while(i < cPropID)
		{	
			if((rgPropVal + i)->propid == ID_ORDER_PROP)
				break;
			i++;
		}
		if(i >= cPropID)
		{
			return ID_NO_KEY_ERROR;
		}
		
		//查找是否有相同的关键属性(可以与本身相同)
		CeSeekDatabase(m_hDB, CEDB_SEEK_BEGINNING, 0, &tempIndex);
		tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_VALUEFIRSTEQUAL,
			(DWORD)(rgPropVal + i), &tempIndex);
	
		if(tempid != 0 && tempid != m_oidDB)	//数据库已经存在两个
		{										//以上记录有相同的关键属性
			return ID_BAD_DATA_ERROR;			//数据库可能已被破坏
		}										
		//修改当前记录
		tempid = CeWriteRecordProps(m_hDB, m_oidDB, cPropID, rgPropVal);
		if(tempid == 0)
		{
			return ID_WRITE_ERROR;
		}

		//重新指向修改后的记录(记录顺序可能改变)
		m_oidDB = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, 
			tempid, &m_dwIndex);
			
		return ID_SUCCESSFULLY;
	}
	return ID_NO_READY_ERROR;
}


//FUNCTION:删除当前记录
//RETURN:
//		ID_SUCCESSFULLY		写入成功
//		ID_DEL_ERROR		删除时失败
//		ID_NO_READY_ERROR	数据库没有初始化
//REMARK:
//	如果删除成功,后一条记录成为当前记录。如果没有后一条记录,当前记录
//	是最后一条记录。如果数据库删空时。当前记录为空。
WORD CCEdbase::DelRecord()
{
	CEOID tempid;
	DWORD tempIndex;

	if(m_isReady)
	{	
		//当前数据库是否为空
		if(m_oidDB == 0)
		{
			return ID_NULL_ERROR;
		}

		//得到后面一条记录的id
		tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CURRENT, 1, &tempIndex);
		
		//删除当前记录
		if(!CeDeleteRecord(m_hDB, m_oidDB))
		{
			return ID_DEL_ERROR;
		}

		//新的当前记录是下一条记录或最后一条记录
		if(tempid == 0)
		{
			tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_END, 0, &m_dwIndex);
		}
		else
		{
			tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, tempid, &m_dwIndex);
		}

		//当没有后继记录又没有最后一条记录说明数据库已经删空
		m_oidDB = tempid;

		return ID_SUCCESSFULLY;
	}
	return ID_NO_READY_ERROR;
}

//FUNCTION:关闭数据库
void CCEdbase::CloseDB()
{
	if(m_isReady && m_hDB !=0 )
	{
		CloseHandle(m_hDB);
	}
	CeUnmountDBVol(&m_guid);
	m_isReady = FALSE;
	return;
}


//FUNCTION:移动记录指针(查找),失败后记录指针位置不变
BOOL CCEdbase::SeekRecord(DWORD dwSeekType, DWORD dwValue)
{
	CEOID tempid;
	DWORD tempIndex;

	if(m_isReady)
	{
		tempid = CeSeekDatabase(m_hDB, dwSeekType, dwValue, &tempIndex);
		if(tempid == 0)
			return FALSE;
		m_oidDB = tempid;
		m_dwIndex = tempIndex;
		return TRUE;
	}
	return FALSE;
}

//FUNCTION:得到当前记录总数
DWORD CCEdbase::GetCurRecrodNum()
{
	CEOIDINFO oidinfo;
	if(m_isReady)
	{
		CeOidGetInfoEx(&m_guid, m_oidDBase, &oidinfo);
		return oidinfo.infDatabase.wNumRecords;
	}
	return 0;
}

//FUNCTION:得到当前记录索引
DWORD CCEdbase::GetCurIndex()
{
	return m_dwIndex;
}

//FUNCTION::
//	查找含有匹配的属性的记录,找到后的记录成为当前记录否则当前记录不变。
//	每条记录都必须包含完全相同的属性
//PARAMETERS:
//	propid:		[in]属性ID
//	val:		[in]属性值
//	bFinNext:	[in] =TRUE从下一条记录开始查找,=FALSE从当前记录开始查找
//RETURN:
//	ID_SUCCESSFULLY:	查找成功
//	ID_NO_READY_ERROR:	数据库没有初始化
//	ID_NULL_ERROR:		数据库为空
//	ID_READ_ERROR:		读失败
//	ID_UNSUPPORT_PROP:	不支的属性类型,当前只支持LPTSTR和DWORD型
//	ID_NO_FOUND:		没有找到
WORD CCEdbase::Seek(CEPROPID propid, CEVALUNION *val, BOOL bFindNext)
{
	DWORD dwRecSize, tempIndex = m_dwIndex;
	CEOID tempid;
	WORD wPropCount = 1;
	CEPROPID key[1];
	PCEPROPVAL pRecord;

	//数据库还没有初始化
	if(!m_isReady)
	{
		return ID_NO_READY_ERROR;
	}
	
	//数据库为空,不进行查询
	if(m_oidDB == 0)
	{
		return ID_NULL_ERROR;
	}
	
	key[0] = propid;
	
	if(bFindNext)
	{
		goto FIND_NEXT;
	}
	
	//读取当前记录
	m_pBuff = 0;
	tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
		&wPropCount, key, &(LPBYTE)m_pBuff, &dwRecSize);
	if(tempid == 0)
	{
		return ID_READ_ERROR;
	}
	
	do{
		pRecord = (PCEPROPVAL)m_pBuff;
		
		//比较属性是否匹配
		if(_tcscmp(pRecord->val.lpwstr, val->lpwstr) == 0)
		{
			m_oidDB = tempid;
			m_dwIndex = tempIndex;
			return ID_SUCCESSFULLY;
		}
		
		LocalFree(m_pBuff);
FIND_NEXT:
		//查找下一条记录
		tempid = CeSeekDatabase(m_hDB, CEDB_SEEK_CURRENT, 1, &tempIndex);
		if(tempid == 0)						//所有的记录都已经查找完毕
		{
			break;
		}
		
		//读取当前记录
		m_pBuff = 0;
		tempid = CeReadRecordProps(m_hDB, CEDB_ALLOWREALLOC,
			&wPropCount, key, &(LPBYTE)m_pBuff, &dwRecSize);
		if(tempid == 0)
		{
			return ID_READ_ERROR;
		}
		
	}while(tempid != 0);
	
	CeSeekDatabase(m_hDB, CEDB_SEEK_CEOID, m_oidDB, &m_dwIndex);
	return ID_NO_FOUND;
}

//删除所有的记录
WORD CCEdbase::ClearAllRecord()
{

	if(!SeekRecord(CEDB_SEEK_BEGINNING, 0))
	{
		return ID_SUCCESSFULLY;
	}

	while(DelRecord() == ID_SUCCESSFULLY)
	{
		;
	}
	
	return ID_SUCCESSFULLY;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -