Windows CE下通訊錄數據庫的開發詳細代碼

CEDataBase.h文件

#pragma once

//數據庫類型的枚舉值
//可以對此枚舉進行拓展,但是在響應使用的函數裏都要進行拓展
enum
{
PRO_STRING = 0x00000001,   //字符串類型 TCHAR
PRO_TIME,       //日期型   systime
PRO_NUMBER       //整型    int
};

//////////////////////////////////////////////////////////////////
//說明 Begin:每次使用該數據庫類,只需要修改此處的數據結構

//***定義傳遞記錄的結構體***
typedef struct
{
TCHAR   LinkmanName[20];
TCHAR   MobilePhone1[21];
TCHAR   MobilePhone2[21];
TCHAR OfficePhone[21];
TCHAR HomePhone[21];
TCHAR Company[40];
TCHAR QQ[15];
//char name[20];
}DATA_RECORD,*DATA_pRECORD;

//***數據庫屬性的總個數***
#define PROPERTY_NUM 7

//屬性類型數組
extern DWORD PROPERTY_TYPE_ID[PROPERTY_NUM];

//自定義屬性類型數組
extern DWORD PROPERTY_TYPE[PROPERTY_NUM];

//數據對象在結構體中的位置
extern int PROPERTY_POSITION[PROPERTY_NUM];


//定義數據庫文件名
#define DBFILENAME L"\\My Documents\\contact.vol"
//定義數據庫名
#define DBTABLENAME L"\\contact"

//定義聯繫人姓名字段標識,聯繫人姓名在數據庫中將是唯一型字段
#define PID_NAME  MAKELONG(CEVT_LPWSTR,0)
//定義聯繫人手機號碼1字段標識
#define PID_NUMBER1  MAKELONG(CEVT_LPWSTR,1)
//定義聯繫人手機號碼2字段標識
#define PID_NUMBER2  MAKELONG(CEVT_LPWSTR,2)
//定義聯繫人辦公室電話號碼標識
#define PID_NUMBER3  MAKELONG(CEVT_LPWSTR,3)
//定義聯繫人家庭電話號碼標識
#define PID_NUMBER4  MAKELONG(CEVT_LPWSTR,4)
//定義聯繫人單位名稱標識
#define PID_COMPANYNAME MAKELONG(CEVT_LPWSTR,5)
//定義聯繫人QQ標識
#define PID_QQ   MAKELONG(CEVT_LPWSTR,6)

 


//說明 End:每次使用該數據庫類,只需要修改此處的數據結構
//////////////////////////////////////////////////////////////////


class CEDataBase
{
//屬性
private:
CEGUID   m_ceGuid;       //存儲數據庫文件卷標識(GUID)PCEGUID m_pCeGuid;
CEOID   m_ceOid;       //DWORD型 存儲數據庫對象標識和記錄對象標識,惟一標識數據庫的ID,CeCreateDatabaseEx()返回
HANDLE   m_hDB;        //存儲數據庫句柄,CeOpenDatabaseEx()返回
HANDLE  m_hSession;  //會話句柄

public:
CString   m_DataBase;       //數據庫路徑及卷文件名稱
CString   m_TableName;      //操作的數據表名稱

//操作
public:
CEDataBase(void);
~CEDataBase(void);

public:
BOOL Open(void);            //打開數據庫
BOOL Create(DWORD dwIndex);         //創建數據庫
BOOL Close(void);           //關閉數據庫
BOOL UnmountDBVol(void);          //卸載數據庫卷,僅在打開數據庫完全失敗時使用

DWORD Seek(DWORD dwID);          //移動記錄指針
int   GetRecordCount();          //返回表內的記錄總數
BOOL GetRecord(DWORD dwID,DATA_RECORD *pRecord);    //返回指定ID的記錄結構體指針

BOOL Add(DATA_RECORD *pRecord);        //添加一條記錄
BOOL Delete(DWORD dwIndex);         //刪除某條記錄
BOOL Modify(DWORD dwID,DATA_RECORD * pRecord);    //修改某條記錄

};

 

CEDataBase.cpp文件

 

#include "StdAfx.h"
#include "CEDataBase.h"


//////////////////////////////////////////////////////////////////
//說明 Begin:每次使用該數據庫類,只需要修改此處的數據結構

//***屬性類型數組***
//按照結構體個數依次排列
//MAKELONG第一個參數爲其數據庫中的數據類型
//    第二個參數爲其ID,遞增即可
DWORD PROPERTY_TYPE_ID[PROPERTY_NUM] = {
MAKELONG(CEVT_LPWSTR,1),
MAKELONG(CEVT_LPWSTR,2),
MAKELONG(CEVT_LPWSTR,3),
MAKELONG(CEVT_LPWSTR,4),
MAKELONG(CEVT_LPWSTR,5),
MAKELONG(CEVT_LPWSTR,6),
MAKELONG(CEVT_LPWSTR,7)
};

//***自定義屬性類型數組***
//按照結構體個數依次排列
DWORD PROPERTY_TYPE[PROPERTY_NUM] = {
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING,
PRO_STRING
};

//***數據對象在結構體中的位置***
int PROPERTY_POSITION[PROPERTY_NUM] = {
0,
20,
20+20
};

//說明 End:每次使用該數據庫類,只需要修改此處的數據結構
//////////////////////////////////////////////////////////////////


//--------------------------------------------------------------------
//【函數介紹】: 構造和析構函數
//     
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】:
//---------------------------------------------------------------------
CEDataBase::CEDataBase(void)
{
 //初始化數據庫句柄
 m_hDB = 0;
 //將數據庫對象標識設置0
 m_ceOid = 0;
 m_DataBase=_T("\\My Documents\\contact.vol");       //數據庫路徑及卷文件名稱
 m_TableName=_T("\\contact");      //操作的數據表名稱

}

CEDataBase::~CEDataBase(void)
{
}

//--------------------------------------------------------------------
//【函數介紹】: UINT CEDataBase::Open(void)
//      打開數據庫,如果返回 ERROR_FILE_NOT_FOUND 表明數據庫不存在,需要Create函數
//      打開成功返回 0
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: 0 爲成功,否則失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Open(void)
{
//掛載數據庫卷,如果存在則打開,不存在,就新建一個
if (!CeMountDBVol(&m_ceGuid,m_DataBase.GetBuffer(),OPEN_ALWAYS))
{
   TRACE(_T("CEDataBase001:打開或新建數據卷失敗\n"));
   return FALSE;
}

//接着打開數據庫
m_hDB = CeOpenDatabaseEx(&m_ceGuid,&m_ceOid,m_TableName.GetBuffer(),NULL,CEDB_AUTOINCREMENT,NULL);
if (m_hDB == INVALID_HANDLE_VALUE)
{
   //如果數據庫不存在,就新建之
   Create(PID_NAME);
}

return TRUE;
}


//--------------------------------------------------------------------
//【函數介紹】: BOOL CEDataBase::Create(DWORD dwIndex)
//     創建數據庫,如果打開沒有成功,則判斷返回值是否爲,是 ERROR_FILE_NOT_FOUND 則創建數據庫
//【入口參數】: dwIndex 爲Define的MAKELONG宏定義的某個屬性的DWORD值
//     
//【出口參數】: (無)
//【返回 值】: TRUE爲創建成功,FALSE爲創建失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Create(DWORD dwIndex)
{
CEDBASEINFO ceDbInfo;

ceDbInfo.dwFlags = CEDB_VALIDNAME | CEDB_VALIDTYPE | CEDB_VALIDSORTSPEC;
wcscpy(ceDbInfo.szDbaseName , m_TableName.GetBuffer());
ceDbInfo.dwDbaseType = 0;
ceDbInfo.wNumSortOrder = 1; //排序索引字段數目,此處暫定爲1個索引

ceDbInfo.rgSortSpecs[0].propid = dwIndex;
ceDbInfo.rgSortSpecs[0].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小寫無關

//此處只要參數允許,最多可以設置4個索引,此處暫定爲1個索引
//ceDbInfo.rgSortSpecs[1].propid = PID_TEL;
//ceDbInfo.rgSortSpecs[1].dwFlags = CEDB_SORT_CASEINSENSITIVE; //升序,且大小寫無關

m_ceOid = CeCreateDatabaseEx(&m_ceGuid,&ceDbInfo);

if (m_ceOid == 0)
{
   TRACE(_T("CEDataBase005:創建數據庫失敗\n"));
   //此處得卸載數據庫卷
   if (!CeUnmountDBVol(&m_ceGuid))
   {
    TRACE(_T("CEDataBase006:卸載數據庫文件卷失敗\n"));
    return FALSE;
   }
   return FALSE;
}

//創建數據庫後,應緊接着打開數據庫
m_hDB = CeOpenDatabaseEx(&m_ceGuid,&m_ceOid,m_TableName.GetBuffer(),NULL,CEDB_AUTOINCREMENT,NULL);
if (m_hDB == INVALID_HANDLE_VALUE)
{
   TRACE(_T("CEDataBase007:打開數據庫失敗\n"));
   //此處得卸載數據庫卷
   if (!CeUnmountDBVol(&m_ceGuid))
   {
    TRACE(_T("CEDataBase008:卸載數據庫文件卷失敗\n"));
    return FALSE;
   }
   return FALSE;
}

return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL CEDataBase::Close(void)
//       關閉數據庫
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: TRUE爲創建成功,FALSE爲創建失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Close(void)
{
//1、關閉數據庫
if (!CloseHandle(m_hDB))
{
   TRACE(_T("CEDataBase002:關閉數據庫失敗\n"));
   return FALSE;
}

//2、將數據庫卷的數據緩衝到永久存儲介質上
if (!CeFlushDBVol(&m_ceGuid))
{
   TRACE(_T("CEDataBase003:緩衝介質失敗\n"));
   return FALSE;
}

//3、卸載數據庫卷
if (!CeUnmountDBVol(&m_ceGuid))
{
   TRACE(_T("CEDataBase004:卸載數據庫文件卷失敗\n"));
   return FALSE;
}

return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL CEDataBase::UnmountDBVol(void)
//       僅供數據庫文件存在,並且打開錯誤的時候卸載使用
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: TRUE爲卸載成功,FALSE爲卸載失敗
//---------------------------------------------------------------------
BOOL CEDataBase::UnmountDBVol(void)
{
//此處得卸載數據庫卷
if (!CeUnmountDBVol(&m_ceGuid))
{
   TRACE(_T("CEDataBase009:卸載數據庫文件卷失敗\n"));
   return FALSE;
}
return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: DWORD CEDataBase::Seek(DWORD dwID)
//       從開始位置移動dwID個數據指針
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: 成功返回不爲零數值
//---------------------------------------------------------------------
DWORD CEDataBase::Seek(DWORD dwID)
{
CEOID ceOid;
DWORD dwIndex;

ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwIndex);

ASSERT(ceOid !=0);

return ceOid;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL GetRecord(DWORD dwID,DATA_RECORD * pRecord);
//       返回指定ID的記錄結構體指針
//   
//【入口參數】: DWORD dwID 指定返回內容的ID
//      
//【出口參數】: DATA_RECORD * pRecord 返回數據的結構體
//【返回 值】: 返回TRUE爲成功,返回FALSE爲失敗
//---------------------------------------------------------------------
BOOL CEDataBase::GetRecord(DWORD dwID,DATA_RECORD *pRecord)
{
CEOID   ceOid;
WORD   wProps = 0;    //查詢數據庫後返回的指定表的屬性個數
DWORD   dwRecSize = 0;
DWORD   dwInSize = 0;

PBYTE   pBuff;
PCEPROPVAL pRecordVal;

char * pRecNew = (char *)pRecord;

//移動記錄指針
ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwRecSize);
ASSERT(ceOid !=0);

pBuff = 0;
ceOid = CeReadRecordProps(m_hDB,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwInSize);
ASSERT(ceOid != 0);

pRecordVal = (PCEPROPVAL)pBuff;

for (int i=0; i<wProps; i++)
{
   //查找當前屬性與之匹配的MAKELONG值在PROPERTY_TYPE_ID數組中的ID
   int iPos = 9999;      //默認9999爲錯誤值,即沒有找到匹配值
   for(int t=0; t<wProps; t++)
   {
    iPos = 9999;
    if(PROPERTY_TYPE_ID[t] == pRecordVal->propid)
    {
     iPos = t;
     break;
    }
   }

   if((iPos == 9999) || (iPos > PROPERTY_NUM) || (iPos < 0))
   {
    TRACE(_T("CEDataBase010:沒有找到匹配的屬性\n"));
    //return FALSE;
   }
   else
   {
    //找到了匹配的屬性,並賦值給結構體
    switch(PROPERTY_TYPE[iPos])
    {
     case PRO_STRING:
     {
      wcscpy((LPWSTR)(pRecNew+PROPERTY_POSITION[i]),pRecordVal->val.lpwstr);
      break;
     }
     case PRO_TIME:
     {
      memcpy((void *)(pRecNew+PROPERTY_POSITION[i]),(void *)&(pRecordVal->val.filetime),sizeof(FILETIME));
      //TRACE1("Sizeof DATA_RECORD = %d \n",sizeof(DATA_RECORD));
      //TRACE1("Sizeof DATA_RECORD = %d \n",sizeof(pRecord->szName));
      //TRACE1("Sizeof FILETIME = %d \n",sizeof(pRecord->ftBirthday));
      //TRACE1("Sizeof FILETIME = %d \n",sizeof(pRecord->szTel));
      break;
     }
     //升級備註:其他數據類型的case在此添加
    }
   }

   pRecordVal++;

}
 
LocalFree(pBuff);

return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: int GetRecordCount();
//       返回表內記錄的個數
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: 返回表內記錄的個數
//---------------------------------------------------------------------
int CEDataBase::GetRecordCount()
{
int iCount;
CEOIDINFO oidinfo;

if (!CeOidGetInfoEx(&m_ceGuid,m_ceOid,&oidinfo))
{
   TRACE(_T("CEDataBase011:獲取信息失敗\n"));
   return -1;
}

iCount = oidinfo.infDatabase.wNumRecords;

return iCount;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL CEDataBase::Delete(DWORD dwIndex)
//       刪除指定ID的記錄
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: 返回TRUE爲成功,返回FALSE爲失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Delete(DWORD dwIndex)
{
if(dwIndex < 0)
   return FALSE;

DWORD dwRet;
CEOID ceOid;

ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwIndex,&dwRet);

ASSERT(ceOid !=0 );

if (!CeDeleteRecord(m_hDB,ceOid))
{
   TRACE(_T("CEDataBase012:數據庫刪除失敗\n"));
   return FALSE;
}

return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL CEDataBase::Add(DATA_RECORD * pRecord)
//       添加單個聯繫人
//【入口參數】: (無)
//
//【出口參數】: (無)
//【返回 值】: 返回TRUE爲成功,返回FALSE爲失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Add(DATA_RECORD *pRecord)
{
CEOID ceOid = 0;
CEPROPVAL *pRecordVal = new CEPROPVAL[PROPERTY_NUM];

//TRACE1("Sizeof CEPROPVAL = %d \n",sizeof(CEPROPVAL));

char * pRecNew = (char *)pRecord;

for(int i=0; i<PROPERTY_NUM; i++)
{
   memset(pRecordVal,0,sizeof(CEPROPVAL));
   pRecordVal->propid = PROPERTY_TYPE_ID[i];

   switch(PROPERTY_TYPE[i])
   {
    case PRO_STRING:
    {
     pRecordVal->val.lpwstr = (wchar_t *)(pRecNew+PROPERTY_POSITION[i]);
     break;
    }
    case PRO_TIME:
    {
     memcpy((void *)&(pRecordVal->val.filetime),(void *)(pRecNew+PROPERTY_POSITION[i]),sizeof(FILETIME));
     break;
    }
    //升級備註:其他數據類型的case在此添加
   }
   pRecordVal++;
}

    pRecordVal = pRecordVal - PROPERTY_NUM;   //(PROPERTY_NUM - 1);
ceOid = CeWriteRecordProps(m_hDB,0,PROPERTY_NUM,pRecordVal);

if (ceOid == 0)
{
   TRACE(_T("CEDataBase013:添加數據失敗\n"));
   return FALSE;
}

return TRUE;
}

//--------------------------------------------------------------------
//【函數介紹】: BOOL Modify(DWORD dwID,DATA_RECORD * pRecord)
//       編輯指定ID的數據內容
//【入口參數】: (無)
//     
//【出口參數】: (無)
//【返回 值】: 返回TRUE爲成功,返回FALSE爲失敗
//---------------------------------------------------------------------
BOOL CEDataBase::Modify(DWORD dwID,DATA_RECORD * pRecord)
{
CEOID ceOid = 0;
CEPROPVAL *pRecordVal = new CEPROPVAL[PROPERTY_NUM];

WORD   wProps = 0;
DWORD   dwRecSize = 0;

char * pRecNew = (char *)pRecord;

///////////////////////////////////////////////////////

ceOid = CeSeekDatabase(m_hDB,CEDB_SEEK_BEGINNING,dwID,&dwRecSize);
ASSERT(ceOid !=0);

for(int i=0; i<PROPERTY_NUM; i++)
{
   memset(pRecordVal,0,sizeof(CEPROPVAL));
   pRecordVal->propid = PROPERTY_TYPE_ID[i];

   switch(PROPERTY_TYPE[i])
   {
    case PRO_STRING:
    {
     pRecordVal->val.lpwstr = (wchar_t *)(pRecNew+PROPERTY_POSITION[i]);
     break;
    }
    case PRO_TIME:
    {
     memcpy((void *)&(pRecordVal->val.filetime),(void *)(pRecNew+PROPERTY_POSITION[i]),sizeof(FILETIME));
     break;
    }
    //升級備註:其他數據類型的case在此添加
   }
   pRecordVal++;
}

    pRecordVal = pRecordVal - PROPERTY_NUM;
ceOid = CeWriteRecordProps(m_hDB,ceOid,PROPERTY_NUM,pRecordVal);

if (ceOid == 0)
{
   TRACE(_T("CEDataBase014:修改數據失敗\n"));
   return FALSE;
}

return TRUE;
}


 

發佈了4 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章