EDB是从Windows Mobile 5.0后出现的,提供了比CEDB更好的性能。
要使用EDB,首先就是mount
BOOL CeMountDBVol(
PCEGUID pceguid,
LPWSTR lpszDBVol,
DWORD dwFlags
);
它的第一个参数是一个CEGUID类型的指针,也是一种唯一标识符,一般在开始使用前先用CREATE_SYSTEMGUID来将其清0。第二个参数就是数据库卷的卷名,第三个参数就标志,这个标志位的意义与CreateFile的非常类似,其实EDB也是一种特殊的文件。也可以用CeMountDBVolEx函数来挂载卷。
将卷挂上之后,就可以使用CeCreateDatabaseWithProps函数来创建数据库。它的声明如下:
CEOID CeCreateDatabaseWithProps(
PCEGUID pGuid,
CEDBASEINFOEX* pInfo,
DWORD cProps,
CEPROPSPEC* prgProps
);
第一个参数就是CeMountDBVol的第一个参数传回的CEGUID,第二个参数是重点,里面包含了要创建的数据库的结构,即每个属性列的类型等。第三个参数指示了第四个参数的个数。第四个参数是好像是指定属性列的一些其它信息用的(这个也不清楚)。
CEDBASEINFOEX的定义如下:
typedef struct CEDBASEINFOEX {
WORD wVersion;
WORD wNumSortOrder;
DWORD dwFlags;
WCHAR szDbaseName[CEDB_MAXDBASENAMELEN];
DWORD dwDbaseType;
DWORD dwNumRecords;
DWORD dwSize;
FILETIME ftLastModified;
SORTORDERSPECEX rgSortSpecs[CEDB_MAXSORTORDER];
} CEDBASEINFOEX;
例如这段代码就创建了一个有两个属性列的数据库,第一个属性是名字,第二个属性是年龄。
CEDBASEINFOEX dbInfo = {0};
dbInfo.wVersion = CEDBASEINFOEX_VERSION;
dbInfo.dwFlags = CEDB_VALIDDBFLAGS | CEDB_VALIDNAME | CEDB_VALIDSORTSPEC;
dbInfo.wNumSortOrder = 1;
_tcscpy(dbInfo.szDbaseName, szDbname);
dbInfo.rgSortSpecs[0].wVersion = SORTORDERSPECEX_VERSION;
dbInfo.rgSortSpecs[0].wNumProps = 1;
dbInfo.rgSortSpecs[0].wKeyFlags = 0;
dbInfo.rgSortSpecs[0].rgPropID[0] = PROP_NAME;
dbInfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
dbInfo.rgSortSpecs[1].wVersion = SORTORDERSPECEX_VERSION;
dbInfo.rgSortSpecs[1].wNumProps = 1;
dbInfo.rgSortSpecs[1].wKeyFlags = 0;
dbInfo.rgSortSpecs[1].rgPropID[0] = PROP_AGE;
dbInfo.rgSortSpecs[1].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
CeCreateDatabaseWithProps(&g_VolGuid, &dbInfo, 0, NULL);
因为rgSortSpecs数组被定义为16,所以EDB的属性列最多也就是16。
当创建好数据库之后,就可以打开数据库了,然后才能进行读写数据库。
要打开数据库,先用CeCreateSession创建一个会话,然后用CeOpenDatabaseInSession来得到一个数据库句柄。
写数据库是通过CeWriteRecordProps函数来实现的。
CeWriteRecordProps的定义如下:
CEOID CeWriteRecordProps(
HANDLE hDatabase,
CEOID oidRecord,
WORD cPropID,
CEPROPVAL* prgPropVal
);
若oidRecord为0,则新添加的记录直接追加到最后。最后一个参数是用来填充属性的数据。
要写数据库,示例代码如下:
prop[0].propid = PROP_NAME;
prop[0].val.lpwstr = _T("某某");
prop[0].wFlags = 0;
prop[1].propid = PROP_AGE;
prop[1].val.uiVal = 25;
prop[1].wFlags = 0;
CeWriteRecordProps(hdb, 0, 2, prop);
要想读数据库,只要用CeReadRecordPropsEx函数即可。
它的定义如下:
CEOID CeReadRecordPropsEx(
HANDLE hDatabase,
DWORD dwFlags,
LPWORD lpcPropID,
CEPROPID* prgPropID,
LPBYTE lplpBuffer,
LPDWORD lpcbBuffer,
HANDLE hHeap
);
第三个参数是返回属性列的个数,第四个参数即是用来指定要接收哪些属性列的数据,如果为NULL,则接收所有。第五个参数即是返回的数据。如果第二个参数指定为:CEDB_ALLOWREALLOC的话,则在不必要使用lplpBuffer之前申请空间。最后一个参数就是要使用的堆的句柄。
再操作完之后,要使用CloseHandle关闭数据库的句柄,并且再最后CeUnmountDBVol卸载数据库。
下面贴上简单的代码
- #define EDB
- #include <Windows.h>
- #include <windbase.h>
- #ifndef EDB
- #include <windbase_edb.h>
- #endif
- #define MAKEPROP(n,t) ((n<<16)|CEVT_##t)
- #define PROP_NAME MAKEPROP(10, LPWSTR)
- #define PROP_AGE MAKEPROP(10, UI2)
- CEGUID g_VolGuid;
- LPTSTR szDbname = _T("MyMsgDb");
- LPTSTR szDbVol = _T("Test.edb");
- HANDLE g_hSession;
- BOOL CreateMyDB();
- BOOL WriteMyDB(HANDLE hdb);
- BOOL OpenDB(HANDLE *phDB);
- BOOL ReadMyDB(HANDLE hDb);
- int WINAPI WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
- {
- if (FALSE == CreateMyDB())
- return FALSE;
- HANDLE hDb;
- OpenDB(&hDb);
- //CeSeekDatabaseEx(hDb, CEDB_SEEK_BEGINNING, 0, 0, 0);
- WriteMyDB(hDb);
- CloseHandle(hDb);
- CEOID DBoid = 0;
- hDb = CeOpenDatabaseInSession( g_hSession,
- &g_VolGuid,
- &DBoid,
- szDbname,
- NULL,
- 0,
- NULL);
- CeSeekDatabaseEx(hDb, CEDB_SEEK_BEGINNING, 0, 0, 0);
- ReadMyDB(hDb);
- CloseHandle(hDb);
- return 0;
- }
- BOOL CreateMyDB()
- {
- CREATE_SYSTEMGUID(&g_VolGuid);
- CEDBASEINFOEX dbInfo = {0};
- dbInfo.wVersion = CEDBASEINFOEX_VERSION;
- dbInfo.dwFlags = CEDB_VALIDDBFLAGS | CEDB_VALIDNAME | CEDB_VALIDSORTSPEC;
- dbInfo.wNumSortOrder = 1;
- _tcscpy(dbInfo.szDbaseName, szDbname);
- dbInfo.rgSortSpecs[0].wVersion = SORTORDERSPECEX_VERSION;
- dbInfo.rgSortSpecs[0].wNumProps = 1;
- dbInfo.rgSortSpecs[0].wKeyFlags = 0;
- dbInfo.rgSortSpecs[0].rgPropID[0] = PROP_NAME;
- dbInfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
- dbInfo.rgSortSpecs[1].wVersion = SORTORDERSPECEX_VERSION;
- dbInfo.rgSortSpecs[1].wNumProps = 1;
- dbInfo.rgSortSpecs[1].wKeyFlags = 0;
- dbInfo.rgSortSpecs[1].rgPropID[0] = PROP_AGE;
- dbInfo.rgSortSpecs[1].rgdwFlags[0] = CEDB_SORT_UNKNOWNFIRST;
- if (!CeMountDBVol(&g_VolGuid, szDbVol, CREATE_ALWAYS | EDB_MOUNT_FLAG))
- {
- DWORD dd = GetLastError();
- return FALSE;
- }
- CEOID DBOid = 0;
- if(NULL == (DBOid = CeCreateDatabaseWithProps(&g_VolGuid, &dbInfo, 0, NULL)))
- {
- DWORD dd = GetLastError();
- return FALSE;
- }
- return TRUE;
- }
- BOOL WriteMyDB(HANDLE hdb)
- {
- CEPROPVAL prop[2] = {0};
- prop[0].propid = PROP_NAME;
- prop[0].val.lpwstr = _T("猛哥");
- prop[0].wFlags = 0;
- prop[1].propid = PROP_AGE;
- prop[1].val.uiVal = 24;
- prop[1].wFlags = 0;
- CeWriteRecordProps(hdb, 0, 2, prop);
- prop[0].propid = PROP_NAME;
- prop[0].val.lpwstr = _T("某某");
- prop[0].wFlags = 0;
- prop[1].propid = PROP_AGE;
- prop[1].val.uiVal = 25;
- prop[1].wFlags = 0;
- CeWriteRecordProps(hdb, 0, 2, prop);
- CeFlushDBVol(&g_VolGuid);
- return TRUE;
- }
- BOOL OpenDB(HANDLE *phDB)
- {
- CEOID DBOid=0;
- g_hSession = CeCreateSession(&g_VolGuid);
- *phDB = CeOpenDatabaseInSession( g_hSession,
- &g_VolGuid,
- &DBOid,
- szDbname,
- NULL,
- CEDB_AUTOINCREMENT,
- NULL);
- return TRUE;
- }
- BOOL ReadMyDB(HANDLE hDb)
- {
- CEOID oidRecord = 0;
- WORD wNumProps = 0;
- CEPROPVAL *pRecord = NULL;
- DWORD dwBufSize = 0;
- while (oidRecord = CeReadRecordPropsEx(hDb, CEDB_ALLOWREALLOC, &wNumProps, NULL, (LPBYTE *)&pRecord, &dwBufSize, NULL))
- {
- for (int i = 0; i < wNumProps; i++) {
- switch(pRecord[i].propid)
- {
- case PROP_NAME:
- break;
- case PROP_ID:
- break;
- }
- }
- return TRUE;
- }
(刚学edb,可能会有好多错误,希望大家提出批评指正)