Windows CE嵌入式高级编程及其实例详解8.docx
《Windows CE嵌入式高级编程及其实例详解8.docx》由会员分享,可在线阅读,更多相关《Windows CE嵌入式高级编程及其实例详解8.docx(104页珍藏版)》请在冰点文库上搜索。
WindowsCE嵌入式高级编程及其实例详解8
第8章WindowsCE基础数据库编程
在软件编程中,数据库始终是很重要的一个部分。
通过数据库,可以非常方便地存储和
【索数据,极大的提高工作效率。
例如要实现一个个人通讯簿的管理,就可以使用数据库,它
’以非常迅速地实现该项功能。
在本章中,将重点介绍WindowsCE自带的数据库系统EDB。
1果需要存储的数据量较小,数据结构相对简单,EDB将会是非常适用的。
本章主要介绍如下内容:
·EDB概述
·EDB操作综合示例
8.1EDB概述
从WindowsCE5.0开始,WindowsCE自带数据库系统就包括了EDB和CEDB。
CEDB
是WindowsCE5.0之前就支持的数据库系统,EDB是WindowsCE5.0之后新增的数据库系统。
EDB可以理解成是对CEDB的升级,新增加了如下功能:
·支持事务处理功能。
·使用计划(schemas)定义数据库结构。
·增加了字段排序功能(支持最多l6个字段排序以及排序字段支持所有字段类型)。
·新增了“流”字段类型。
·多用户访问。
在WindowsCE5.0、WilldowsCE6.0中依旧支持CEDB,关于CEDB方面的知识读者可
以参考《EVC高级编程以及应用开发》一书。
‘
EDB数据库系统支持10种字段数据类型,如表8.1所示。
表8.110种字段数据类型表
数据类型
描述
对应常量
iVal
2个字节有符号整数
CEVTl2
uiVU
2个字节无符号整数
CEVT—Ul2
1Ⅷ
4个字节有符号整数
CEVTl4
ulV.al
4个字节无符号整数
CEVT-_U14
filetime
日期时间结构
CEVljILETIME
lpwstr
以0结构的UNICODE字符串
CEV£LPWSTR
blob
CEBLOB结构,用于存储一些较小的二进制数据
CEVT—.BLOB
BoolVal
布尔值
CEVT—.BOOL
dblVal
8个字节的有符号值
CEVT—.R8
Stream
内存流
CEVT—.STREAM
256WindowsCE嵌入式高级编程及其实例详解(用C++实现)
本节将来介绍EDB的一些重要APl函数,这些APl函数可以实现创建数据库、打开数损
库以及读写记录等功能。
8.1.1装配数据卷
从WindowsCE2.1开始,数据库文件可以存储在卷中而不用直接存储在对象存储库中。
数据库卷是可以存储WindowsCE数据库的特殊格式的文件。
在WindowsCE中,如果想把参
据库存储在文件中,即要使用数据库卷,就必须先装配数据库卷,并且在关闭数据库后,还矗
卸载数据库卷。
装配数据库卷具有两个意思,一是新建数据库卷,二是打开已存在的数据库卷
在WindowsCE中装配数据库卷可以通过CeMountDBVolEx函数来实现,它的定义如下:
传
常
BOOLCeMountDBVolEx(
PCEGUIDpGuid,
LPWSTRlpwszDBVol,
CEVOLUMEOPTIONS+pOptions,
值
描述
CREATE——NEW
创建一个新的数据库卷,如果数据库卷已存在,函数将失败
CREATE——ALWAYS
创建一个新的数据库卷,如果数据库卷已存在,它将覆盖旧卷
OPEN——EXISTING
打开一个数据库卷,如果数据库卷不存在,函数将失败
OPEN——ALWAYS
打开一个数据库卷,如果数据库卷不存在,则创建一个新的数据库卷
TRUNCATE——EXISTING
打开一个数据库卷,并将其截断为0字节大小。
如果数据库卷不存在,
函数将失败
如果函数执行成功,将返回TRUE,还会将参数pGuid设置为某一个值,并且此值可E
差给其他数据库函数使用。
如果函数执行失败,则可以调用GetLastError函数获取错误代
见的错误代码如表8.3所示。
表8-3常见错误代码袭
值
描述
ERROR_INVALID_PARAMETER
表示其中某个参数无效
ERROR——BAD——FORMAT
表示数据库卷来自一个不同的EDB版本
ERROR——FILE.—NOTFOUND
表示参数dwFlags值为TRUNCATE_EXISTING,但是要装载
的数据库卷不存在
翠型荡目勘茸犁簿鞣‘轴SAVA~3V
-3J:
vauD蕈S天VMlv_N丑d0暮蔡s翱I舭p鞣霉乐些辈
鞍貊回娶骠豳
S工SIXa_凡QvⅡⅪlv—H0ⅪⅦ日
驰卫业哥pJoMs∞dzsMd<。
suogdod磉霉当辈
QH0』nSSVrDN0Ⅺ们0ⅪⅪ丑
薜啤磷西昼集犁群
磉即可‘0N1工SIx丑_丑JⅣ3NnⅪ工椠哥sffuld觚p璨霉当辈(z)
朝娶罾瞽檗犁薄骠(I)
QaIN日Q—SSHDDV—Ⅺ0ⅪⅪa
骤辫
哥
擘旃
DWORDdwFlagS;
WCHARszDbaseName[CF.DBMAXDBASENAMELEN];
DWORDdwDbaseType;
DWORDdwNumRecordsj
DWORDdwSize;
FILETIMEftLastModified;
CESORTORDERSPECrgSortSpecs[CEDB_MAXSORTORDER];
}CEDBASEINFOEX;
·字段wVersion:
表示此结构体的版本,此值必须设置为2。
.字段wNumSortOrder:
表示在数据库中能够被激活的排序字段个数,最大值为16。
·字段dwFlags:
表示数据库标志,它的取值为表8-4中值的组合。
表8-4dwFlags参数取值表
值
CEDBVALIDNAME
表示szDbaseName成员有效并且将被使用—
丢忑dw—Db—ase—Typ磊e面两磊酥两丽
表示成员有效并且将被使用
泵磊i:
;面。
。
。
成员有效并且将被使用
覆荔荔丙ii面鬲荔戛号辱罚蜀i西藏据库的压缩状态
该参数应与下面的参数共同使用以设置数据厍的压缩状态—
戛票丽磊丽磊属菊■示柔雨云磊鬲j丽此标记被:
SetDatabaselnfoCeS
表示创建数据库时,不采用压缩方式。
如果此标记被...
菡数使用,新的记录或修改的记录存储时将不被压缩。
默认情况下,
·字段szDbaseN锄e:
表示数据库名称,此字符串最多可以包括SQLCED
MAXDBASENAMELEN个字符。
当使用CeCreateDatabaseWithProps函数时,此威
●
●
●
●
●
必须被设置。
字段dwDbaseType:
表示数据库类型标识。
字段dwNumRecords:
表示数据库中的记录数。
字段dwSize:
EDB中未使用。
字段ftLastModified:
EDB中未使用。
字段略sortspecs[CEDB_MAXSORTORDER]:
排序字段定义,是1个
CESORT。
ORDERSPEC结构体的固定数组,表示只有数组中前N个值有意义,N
:
雾m舻鬻勰茎篙凯帆必须舣这些觏方可往靳写入黼prgPropsEDB
·参数字段描述数组。
在中,必须足义返些子段,力口J仕生叫与八翟循:
参数硼妒rops是指向CEPROPSPEC结构体的数组,CEPROPSPEC结构体的定义如下
搿塑
燮
‰塑
湍憾
肌磁一
酱搿
豳
·字段wVersion:
表示结构体版本,必须设置为l
·字段propid:
表示字段ID,用来表示数据库中的字段。
它是一个32位值,低l61
表示字段的数据类型,高16位是用户定义的值,用来标识字段。
例如定义一个字:
串类型的字段“仓库名称”,则可以定义如下propid值:
#definePID—STORAGENAMEMAKELONG(CEVT—LPWSTR,1)
·字段dwFlags:
表示字段标志,它为表8.5中的值的组合。
.
表8-5成员dwFlags值描述
值
描述’
DB——PROP——NOTNULL
表示此字段不能为空
DB——PROP——COMPRESSED
表示此字段将被压缩。
此标志仅仅可以应用于CEVT_STREAM字段类
型。
如果Stream字段被设置为压缩格式,那么StreamAPl将不能访问,
相反必须使用CeReadRecordPropsEx(EDB)函数来访问
在对数据库进行添加记录、删除记录,查询记录等操作之前,必须先打开数据库。
在之
前曾经介绍过,EDB打开数据库需要基于会话连接来打开数据库,以便系统来维护事务操作。
在EDB中,可以使用CeOpenDatabaselnSession函数打开数据库。
该函数的定义如下:
HANDLECeOpenDatabaseInSession(
HANDLEhSession,
PCEGUIDpGuid,
PCEOIDpoid,
}
l
}
’堑蝉誊甚砚并暮球咨融明翟智邓号回琳
工SⅥl直N。
^&0NNNn—TNOS—aQ丑3
l
磁阜猪专审黜古牲皆。
氲、『/¥蜘彩
卧I工ISNaSNIaSVJ—J湛OS—aq丑3
}
陋j}}崮捶Ⅵ罐‘陋揩辛华督捌
0pⅡQNa3s日a—确0s_HGHD
i
l
骤辨
珥
|jl。
摹华号爵髫辩明中p8擎椠剪Ⅻ{苍鋈一薹茎三
}
山I疆n寻羽百窜警壕妙鸯。
一珈‘璐千些擎
人ⅡXxwvWnl丁确0S—aQ日3
;
刨骢摹华哥珂掰湃粥业些擎
"IVNOIZISOd—ON—ZlIOS-8Qa3
}
1皂率一珈当辈
afl0INl]-工lIOS—HQ丑3
}
摹g髫擗朝口牮捌单霹
0
孓辨
哥
}骤辨剪s6eId^9>1M曾搿争8擎
}
》。
号爵明士9-8擎椠哥碓‘翠斟茸瓣犁群s8BId角M觚秘车·
}。
(9I)d嗍dlxosⅪ,旷Ⅱ31bsK耳¥咨‘磉妙朝猪专茸擗犁群sdoMumNA~猪专·
p。
乙椠蓦蔡蟛硒‘卓硎鞘瞬勒当擎Uo!
sa0AA~硝右·
!
jx丑3丑dsH丑QHol工-Hosd牛-x丑3丑dsH丑aH0.I-Hos{
B
}j[doHdlLHosxⅥprga丑3】s6PTdMp6JGHOMG
}?
[d。
Hd工HosxVpr日Q丑。
】a工doJd6】GIdOHd丑D
}?
paA】aseHMGHOM
5¨
}:
s6它.[d五exMaⅪOM
}!
sdoxdmnNMGHOM
±
£!
u。
TSXaAMGHOM
}}x丑3丑dsH丑a丑。
工Hos一%0na%s;ap。
d五3
}:
土蝉百晕璐骅窃鎏
《t#噼羁Ⅻ3丑dsⅪa①Iol工Ⅺ0s叫群Vosd。
摹华髫揩朝婆呆茸群磉革群VoSd壕霉·
1。
蜘彩骥徘OUmNZsA~dI
}臻霉眵烂·0椠业鹭p!
od嫌霉酱晦。
牲零犁群鞣明妊群联益当擎otuBNz8柚骠霉·
1。
七bp!
od翠黝掣琳碘斟誓艋犁群骠明回娶‘掣辫骠妊群半
}p.mod咄OlLmNZSA~dl群诽琳‘0紧暮蔡p!
od。
浓辫誓胚茸辨壕朗妊群些擎p!
od臻霉·
}。
QIn0明捌群磉些擎p!
nod壕霉·
}0。
崾勘i6^bK‘4¨o!
ssososeqtnefImOOO
1岩疆(HOH)uo!
ssosmBoaO00甲血耳鎏。
铧呜弩艇娶号当擎uo!
ssosq骠霉·
l!
(
}一
^’……Ⅱ一十mⅢM…Ⅱ…~0IIoN丑3
}
}。
SSWldMPGHOMO
},4】。
sd早x丑3adsH丑QH0工Hos
}。
OmeNzsMdIHlLsMdq
l
续表
值
描述
CEDB——SORT——IGNORENONSPACE
仅对字符串有效
CEDB——SORT——IGNORESYMBOLS
仅对字符串有效
CEDB——SORT——IGNOREKANATYPE
不区分Hiragana和Katakana字符。
仅对字符串有效
CEDB——SORT——IGNOREWIDTH
不区分单字节和双字节,只对字符串有效
CEDB——SORT——NONNULL
表示排序字段不能为NULL
DWORDdwSize
DWORDdwParam;
UINTuType;
CEGUIDguid;
CEOIDoid;
}
●
●
●
CEOIDoidParent;
CENOTINOTIFICATION;
字段dwSize表示CENOTIFICATION结构大小。
字段dwParam存储在CENOTIFYREQUEST结构中的dwParam成员值。
字段uType表示发送WM_DBNOTIFICATION消息的类型,它可以设置为表8.8中的
任意值。
262WindowsCE嵌入式高级编程及其实例详解(用c++实现)
表8—8成员uType取值表
值
描述
DB..CEOID_CREATED
创建了一个新的数据库对象
DB——CEOID——DATABASE——DELETED
数据库从数据卷中删除
DB——CEOID——RECORD——DELETED
记录从数据库中删除
DB——CEOID——FILE——DELETED
文件被删除
DB——CEOID——DIRECTORY——DELETED
目录被删除
DB_CEOID_CHANGED
数据库对象被修改,
·参数hSession表示会话对象句柄,此参数可以在打开数据库函数
(CeOpenDatabaselnSession)中获取。
此参数与对应的CeBeginTransaction函数中的
hSession值是一样的。
·参数fCommit表示结束一个事务的两种方法,一种是提交事务,把之前的操作全部
更新到数据库,另一种是回滚事务,把之前的操作全部取消。
参数fCommit值为
TRUE,则提交事务,否则回滚事务。
当fCommit值为TRUE时,所有的数据变化并
不会实际写入到磁盘,此时我们还需调用CeFlushDBVol函数将数据写入磁盘。
若成功结束事务,函数返回TRUE,否则返回FALSE。
8.1.7删除数据库
EDB提供了CeDeleteDatabase函数来删除数据库卷中的数据库,包括删除数据库中的记录。
该函数定义如下:
BOOLCeDeleteDatabase(
264window!
cE嵌入式高级编程及其实例详解(用c++实现)——
—————————————————————_————————————————————————————————。
——一
PCEGUIDpGuid,
CEOIDOid
1;
·参数p伽d表示要删除的数据库所在的数据库卷标识,可由CeMountDbVolEx函数获取。
·参数oid表示要删除的数据库对象标识;0id值必须已经被CeCrea卸撕base晰吐证’mI)s@DB:
函数生成。
成功删除数据库后将返回TRUE,否则返回FALSE。
同样的,可以使用GetLastError函数
获取函数执行错误信息。
8.1.8枚举数据库卷以及数据库。
如果需要了解当前系统中已装配好的数据卷的信息,可以通过重复调厍
CeEnumDBVolumes函数来实现。
CeEnumDBVolumes函数的定义如下:
BOOLCeEnumDBVolumes(
PCEGUIDpGuid,
LPWSTRpwszName,
DWORDcchMaxName
1:
-
·参数pGuid用于标识开始列举的数据库卷guid。
在首次使用时,应该调月
CREATEINVALIDEDBGUID宏将pGuid设置为无效,然后在下一次调用时,直招
调用上一次的pGuid即可,直到函数返回FALSE值,调用GetLastError函数返匡
ERROR—N0—MORE—ITEMS。
·参数pwszName用于存储找到的数据库卷名称。
·参数cchMaxName表示pwszName的长度。
此值应设置足够大,以便能够存l;
pwszName值,此值至少应该设置为CEDB_MAXDBASENAMELEN。
如果函数找到一个已装配的数据库卷,将返回TRUE值,并且将数据库卷的标识和名乖
分别存储到pGuid和pwszName中;反之,则返回FALSE值。
如下代码实现了列举系统中所有已装配的数据库卷的功能:
CEGUIDceguid;
TCHARszvolumeName[CEDB_MAXDBASENAMELEN];
//创建无效的GUID
CREATE—INVALIDEDBGU工D(&ceguid);
//列举已装载的数据库卷
while(CeEnumDBVolumes(&ceguid,szVolumeName,sizeof(szVolumeName)))
{
TRACEfL”Enummountedvolumes:
%s\n”,szVolumeName)j
}
上面介绍了EDB列举已经装载的数据库卷的函数,EDB也提供了一套APl函数来列举;
据库卷中的数据库,CeFindFirstDatabaseEx用于查找第一个数据库并获取一个查找句柄,然J
传递给CeFindNextDatabaseEx函数以继续查找数据库。
此APl函数非常类似于文件查找,一
不过CeFindFirstDatabaseEx函数只是进行搜索,并不返回数据库对象。
CeFindFirstDatabaseEx函数的定义如下:
HANDLECeFindFirstDatabaseEx(
retUrn;
//开始枚举数据库
while((CeOid=CeFindNextDatabaseEx(hEnumDB,NULL))!
。
0)
{
ZeroMemory(&CeObjectInf0,sizeof(CeObjectInfo));
CeObjectInf0.wVersion=2;
//得到数据库信息
if(!
CeOidGetInfoEx2(pGuid,CeOid,&CeObjectInfo))
{
dwError=GetLastError()j
TRACE(L--thelasterror:
%d\n”,dwError)j
//关闭查找旬柄
C10SeHandle(hEnumDB);
e1Se
retUrnj
//判断是数据库类型
if(CeObjectInf0.wObjType==OBJTYPE—DATABASE)
{
TRACEfL”Thenameofthedatabaseis:
%s\n”,
CeObjectInf0.infDatabase.szDbaseName);
)
//关闭查找句柄
CIoseHandle(hEnumDB);
//枚举系统的所有已经装载的数据库卷以及数据库卷中的数据库
voidCEDB—SampleDl9:
:
0nBnClickedBtnEnumVolumes()
{
CEGUIDceguid;
TCHARszVolumeName[CEDB_MAXDBASENAMELEN];
//创建无效的GUID
CREATE—INVAL工DEDBGU工D(&ceguid);
//列举已装载的数据库卷
while(CeEnumDBVolumes(&ceguid,SzVolumeName,CEDB—MAXDBASENAMELEN一1)
{
TRACEfL”Enummountedvolumes:
%S\n”,SzVolumeName);
ZeroMemory(szVolumeName,CEDB_MAXDBASENAMELEN+2);
//列举其中的数据库
EnumDatabasesInVolume(&ceguid);
)
}
/★+★★★+★★★+★★★★★★+★★++★+★★★+★★★★+★+★★++★+++★++★++★+++★+★★++★★+★7
8.1.9查找或移动记录
打开数据库后,如果想读取或写入记录,还必须移动数据库的当前指针。
EDB提供了
CeSeekDatabaseEx函数来查找数据库或移动数据库指针,该函数在查找记录的同时,还设置
了数据库的当前指针。
CeSeekDatabaseEx函数如果查找到了御应的记录,则返回此记录对象
标识,否则返回0值。
0
CeSeekDatabaseEx函数的定义如下:
CEOIDCeSeekDatabaseEx(。
HANDLEhDatabase,i
DWORDdwSeekType,
DWORDdwValue,
WORDwNumValS,
LPDWORDipdwIndex
);
·参数hDatabase:
表示打开的数据库句柄。
·参数dwSeekType.表示查找记录的类型。
dwSeekType参数的取值如表8-9所示。
表8-9dwSeekType参数取值表
值
描述
CEDB—.SEEK_CEOID
根据特定记录对象ID来查找记录
CEDB——SEEK——VALUESMALLER
●
从数据库当前位置开始查找,直到找到的记录小于所指定
的值
CEDB—.SEEK_VALUESMALLEROREQUAL
从数据库当前位置开始查找,直到找到的记录小于或者等于
所指定的值
CEDB——SEEK_VALUEFIRSTEQUAL
从数据库当前位置开始查找,直到找到的记录与所指定的值
相等。
如果没有找到,数据库当前指针将移动数据库尾部,
函数并返回0。
指定的值由CEPROPVAL结构数组存储,参
数dwValue指向此结构地址,wNumVals表示数组个数
CEDB——SEEK_VALUENEXTEQUAL
从数据库当前位置开始查找,直到找到的记录等于所指定的
值。
指定的值由CEPROPVAL结构数组存储,参数dwValue
指向此结构地址
CEDB——SEEK——VALUEGREATER
从数据库当前记录开始查找,直到找到的记录属性值大于所
指定的值。
指定的值由CEPROPVAL结构数组存储,参数
dwValue指向此结构地址
CEDB——SEEK_VALUEGREATEROREQUAL
从数据库当前记录开始查找,直到找到的记录属性值大于或
等于所指定的值。
指定的值由CEPROPVAL结构数组存储,
参数dwValue指向此结构地址
CEDB——SEEK——BEGINNING
从数据库记录首部开始查找第n个记录,n的值由dwValue