Windows Mobile 平台EDB 数据库的应用与开发
2011年04月26日
  Windows Mobile [b]平台[/b]EDB [b]数据库的应用与开发 [/b]
  程乐乎 1,邹仕洪1,林宇 2,史文勇2
  1.北京邮电大学网络技术研究院,北京(100876)
  2.北京网秦天下科技有限公司,北京(100013)
  E-Mail: clh213@gmail.com
  [b]摘要[/b]:本文阐述了Windows Mobile 平台下EDB 数据库的基本知识和常用的操作函数及数据结构体,在此基础上结合Mobile 系统自身的联系人(contacts)数据库实例,系统介绍了EDB 数据库的创建思路和具体操作,如读取记录、添加记录、删除和查询记录等。另外还深入介绍了EDB 的事务操作和监控EDB 数据库变化的通知机制。
  关键词:智能手机,Windows Mobile,EDB,系统联系人
  1. 引言
  近年来,随着人们对移动办公和娱乐需求的不断提高,传统的以通讯功能为主的手机已经不能适应人们的需求。正是在这种情况下,类似当前PC 的具备通用操作系统的智能手机也就应运而生,这些智能手机的一大特点便是其操作系统不再是各个厂家根据自己的硬件产
  品专门定制,而是采用类似PC 上的Windows 操作系统一样通用的操作系统,该系统的接口对外公开,可以由第三方开发者开发该系统应用,这样配合手机硬件水平的不断提高,使得手机的应用领域大大拓展。随着软硬件性能的提升,智能手机已经不仅仅是一个手机通讯工具,而成为了用户的个人数据和移动办公中心。基于智能手机平台的应用,需要处理大量的用户个人数据和应用数据,因此必需提供数据存储、数据管理和查询的功能,同时对于数据的安全性和完整性也必须提供支持。此外,智能手机设备还可以作为后台信息系统的信息收集、处理和接收终端[1]。
  2. 背景
  2.1. 智能手机简介
  目前市场上出现的智能手机操作系统主要为 Symbian、Windows Mobile、Palm OS 以及Linux 等几种。Windows Mobile(以下简称WM)是在Windows CE 系统基础上为智能移动终端设备设计的操作系统。基于WM 操作系统的智能终端设备分为Smartphone 和Pocket PC 两个大类。其中Smartphone 从外观设计、使用习惯方面来看,其更像一部电话,同时具备一定的数据管理和处理能力。而Pocket PC 的功能更类似于一部个人电脑,有非常强大的数据管理和处理功能,同时Pocket PC 也加入了电话功能,使其成为新的Pocket PC phone[2] 。
  2.2. EDB 数据库简介
  WM 5.0 以前的系统使用的是CEDB 数据库,EDB 是WM 5.0 中的新特性之一。为了改善应用程序的性能和长期可移植性,CEDB 已经被 EDB 所取代。EDB 是一个基于SQL Server CE 的嵌入式数据库引擎,为基于Windows CE 的应用程序提供核心功能。通过使用EDB,开发者能够创建一个对象存储,称为数据库卷(volume),其中可以包含多个数据库。该数据库卷是基于文件的,因此可以很容易被复制和移动[3]。
  EDB 作为CEDB 的更新和增强版本,还支持 事务(transaction) 多用户同时访问
  支持 stream 类型的数据 多种排序方式,多个主属性
  增强的性能,尤其是较大的数据库
  3. EDB 数据库设计
  在 WM 系统中,系统联系人和SIM 卡联系人数据,是以EDB 形式存储的。因此本文结合WM 系统联系人数据库的实际例子,详细介绍EDB 数据库的设计与应用开发。
  3.1. EDB 基本概念
  Volume(数据库卷):用来存储数据库的文件,一个volume 上可以创建多个数据库。例如WM 系统的"\\pim.vol",是用来存储个人信息的卷文件,里面有系统联系人、通话记录、任务、约会等多个数据库。 Database(数据库):每个数据库即一个表。数据库存储在volume 文件内。其中,WM系统的"\\pim.vol"卷文件中,联系人数据库的名字为"Contacts Database"。 Property ID(属性ID):每个数据库包含多个属性,即表的多个字段。属性ID 不仅代表该属性的名字,同时也指定了该属性的数据存储类型(int、string、time……)。 CEOID(对象ID):DWORD 类型,用来代表一个数据库或者数据库中每条记录的唯
  一ID 标识。可以理解为数据库中每条记录存放的位置或者索引。 CEGUID:Globally Unique Identifier(全球唯一标识符),它是一个128 比特(16 字节)的结构。用来标识一个被加载的数据库卷。CEGUID 和CEOID 一起,唯一标识一条记录,或者唯一标识一个数据库。
  EDB 数据库的常用操作步骤为:首先加载一个数据库卷文件,然后打开卷文件中的某个数据库,获取数据库的句柄。此后通过这个打开的数据库句柄,对数据库中的记录进行读写、删除、更新、查找的操作。最后关闭数据库,卸载之前加载的卷文件,结束操作[4]。
  3.2. EDB 常用操作函数
  EDB 提供了丰富的操作API,来支持各种数据库应用。下面列举出一些最常用的API,读者可以通过WM SDK 帮助文档或者MSDN,详细了解这些API 的参数说明和注意事项,同时可以获取更多的EDB 相关API[5]。
  加载或者创建一个数据库卷文件
  BOOL CeMountDBVolEx(PCEGUID pGuid, LPWSTR lpwszDBVol,
  CEVOLUMEOPTIONS* pOptions, DWORD dwFlags );
  卸载数据库卷文件
  BOOL CeUnmountDBVol( PCEGUID pGuid);
  打开一个数据库
  HANDLE CeOpenDatabaseInSession(HANDLE hSession, PCEGUID pGuid, PCEOID poid,
  LPWSTR lpwszName, CESORTORDERSPEC* pSort, DWORD dwFlags,
  CENOTIFYREQUEST* pRequest);
  新建一个数据库
  CEOID CeCreateDatabaseWithProps( PCEGUID pGuid, CEDBASEINFOEX* pInfo,
  DWORD cProps, CEPROPSPEC* prgProps);
  创建或者更新一条数据记录
  CEOID CeWriteRecordProps( HANDLE hDatabase, CEOID oidRecord,
  WORD cPropID, CEPROPVAL* prgPropVal );
  读取一条数据记录
  CEOID CeReadRecordPropsEx( HANDLE hDatabase, DWORD dwFlags, LPWORD
  lpcPropID, CEPROPID* prgPropID, LPBYTE lplpBuffer, LPDWORD
  lpcbBuffer, HANDLE hHeap);
  查找一条记录
  CEOID CeSeekDatabaseEx(HANDLE hDatabase, DWORD dwSeekType, DWORD
  dwValue, WORD wNumVals, LPDWORD lpdwIndex);
  删除一条记录
  BOOL CeDeleteRecord( HANDLE hDatabase, CEOID oidRecord );
  创建一个 session。一个session 用来开始、提交、回滚事务。
  HANDLE CeCreateSession( CEGUID* pGuid );
  开始一个事务
  BOOL CeBeginTransaction( HANDLE hSession, CEISOLATIONLEVEL isoLevel); 提交一个事务
  BOOL CeEndTransaction( HANDLE hSession, BOOL fCommit);
  3.3. 创建和打开数据库
  3.3.1. 打开系统联系人数据库
  第一步,首先加载WM 系统联系人数据库所在的卷文件"\\pim.vol",得到该卷文件的CEGUID。调用方式如下:
  CEGUID g_ceGuidInitDB; // 存储加载的卷文件"\\pim.vol"的GUID
  if(FALSE == CeMountDBVolEx(&g_ceGuidInitDB, L"\\pim.vol", 0, OPEN_ALWAYS ))
  {
  DWORD error = GetLastError();
  }
  如果是需要创建一个新的卷文件,只要把第四个dwFlags 参数设为CREATE_NEW 或者
  CREATE_ALWAYS,然后指定卷文件的绝对路径名就可以了。
  第二步,打开系统联系人数据库"Contacts Database"
  HANDLE g_hContactDB; // 数据库句柄
  CEOID oidContact = 0; // 数据库的CEOID
  g_hContactsDB = CeOpenDatabaseInSession(NULL, &g_ceGuidInitDB, &oidContact,
  L"Contacts DataBase", NULL, CEDB_AUTOINCREMENT, NULL);
  if( INVALID_HANDLE_VALUE == g_hContactDB )
  {
  DWORD error = GetLastError();
  }
  其中, 第六个参数为CEDB_AUTOINCREMENT 标志, 指示每调用一次
  CeReadRecordPropsEx 读取记录,数据库中的当前指针位置会自动增加到下一条记录。也可以把该参数设为0。
  如果成功打开了联系人数据库,返回数据库句柄g_hContactsDB,并且得到的oidContact值为数据库的CEOID。
  3.3.2. 创建新的数据库
  假设某个特定应用,需要对系统联系人进行分组,分组包括"亲人"、"同学"、"朋友"、"商务"等等。则需要创建一个新数据库"ContactsGroupDB",用来存储每个联系人的姓名、电话号码、所属分组。创建该数据库步骤如下:
  第一步,定义各个属性的 PropID
  const CEPROPID GroupIDPropid = MAKELONG(CEVT_UI4, 0); // 分组ID,无符号整型
  const CEPROPID NamePropid = MAKELONG(CEVT_LPWSTR,1); // 姓名,string 类型
  const CEPROPID PhoneNumberPropid = MAKELONG(CEVT_LPWSTR,2); // 电话号码,string
  第二步,填充数据库信息结构CEDBASEINFOEX 和数据库属性结构CEPROPSPEC
  DWORD wProps = 3; // 数据库有三个属性
  CEPROPSPEC propSpec[3];
  memset(propSpec,0,sizeof(CEPROPSPEC)*wProps);
  propSpec[0].wVersion = 1;
  propSpec[0].propid = GroupIDPropid;
  propSpec[0].dwFlags = DB_PROP_NOTNULL; // 分组ID,不能为空
  propSpec[1].wVersion = 1;
  propSpec[1].propid = NamePropid; // 联系人名字,可以为空
  propSpec[2].wVersion = 1;
  propSpec[2].propid = PhonePropid;
  propSpec[2].dwFlags = DB_PROP_NOTNULL; // 联系人号码,不能为空
  // 填充数据库信息结构
  CEDBASEINFOEX ced;
  memset(&ced, 0, sizeof(CEDBASEINFOEX));
  ced.wVersion = CEDBASEINFOEX_VERSION;
  ced.dwSize = sizeof(CEDBASEINFOEX);
  ced.dwFlags = CEDB_VALIDNAME | CEDB_VALIDSORTSPEC;
  // CEDB_VALIDNAME 数据库的名字有效
  // CEDB_VALIDSORTSPEC 数据库排序有效
  wcsncpy(ced.szDbaseName, L"ContactsGroupDB", CEDB_MAXDBASENAMELEN);
  第三步,在上节加载的"\\pim.vol"卷上新建"ContactsGroupDB"数据库
  CEOID oid = CeCreateDatabaseWithProps(&g_ceGuidInitDB, &ced, wProps, propSpec);
  if( 0==oid )
  {
  DWORD error = GetLastError();
  }
  3.4. 数据库操作
  3.4.1. 读取记录
  根据对系统联系人 EDB 数据库记录的分析,可以得到各个属性的属性PropID,下面列举一部分属性ID。读者可以根据读取到的联系人属性记录值,推导出每个联系人属性相应的PropID。
  const DWORD ContactNamePropid = 0x0080001f; // 名 const DWORD ContactSurNamePropid = 0x0084001f; // 姓 const DWORD ContactPhonePropid= 0x0096001f; // 移动电话
  const DWORD ContactHomePhonePropid = 0x0099001f; // 家庭电话
  const DWORD ContactHomePhone2Propid = 0x009a001f; // 家庭电话2
  const DWORD ContactWorkPhonePropid = 0x0097001f; // 工作电话
  const DWORD ContactWorkPhone2Propid = 0x0098001f; // 工作电话2
  通过前文打开的联系人数据库句柄g_hContactsDB,并且也已经知道了各个属性的
  PropID,就可以开始对联系人进行读取了。下面的代码片断,实现读取全部联系人的功能。
  // 首先把数据库位置定位到第一条记录。
  CEOID oid = CeSeekDatabaseEx(g_hContactsDB,CEDB_SEEK_BEGINNING ,0,0,NULL);
  while(oid) // 如果联系人记录存在
  {
  PCEPROPVAL pRecord = NULL; // 存储记录属性的数据结构指针
  PBYTE pStringStore = NULL; // 系统分配的属性存储的内存空间地址
  DWORD dwRecSize; // 内存空间的大小
  WORD wProps; // 读取到的联系人属性的数量
  oid = CeReadRecordPropsEx (g_hContactsDB, CEDB_ALLOWREALLOC,&wProps,
  NULL,&(LPBYTE)pStringStore, &dwRecSize, NULL);
  if(0!=oid) // 读取成功
  {
  pRecord = (PCEPROPVAL)pStringStore;
  for(int i = 0; i guid; // 获得数据库卷的CEGUID
  CEOID dbOid = pCalllogNotification-> oidParent; // 获得记录所在的数据库OID
  CEOID oid = pCalllogNotification->oid; // 获得发生变化的记录OID
  switch ( pCalllogNotification->uType )
  {
  case DB_NOTIFY_RECORD_CREATED: // 新建了一个联系人记录
  {
  // 在这里,通过获得的记录oid,可以读取新建联系人的姓名、号码等属性
  // 处理完之后,需要释放消息
  CeFreeNotification(&edbContactsRequest, pCalllogNotification);
  break;
  }
  case DB_NOTIFY_RECORD_CHANGED: // 修改了一条记录
  case DB_NOTIFY_RECORD_DELETED: // 删除了一条记录
  default:
  // 处理完之后,需要释放消息
  CeFreeNotification(&edbContactsRequest, pCalllogNotification);
  Break;
  }
  return S_OK;
  }
  4. 结束语
  通过上面的实例介绍, 读者可以初步掌握数据库的常用操作技术, 能够根据需要对数据库进行开发应用。数据库开发是比较复杂的问题,要开发使用功能强大、性能稳定的数据库, 需要掌握的知识很多。特别是对数据库进行操作时由于函数参数较多往往嵌套多个结构体, 而且比较复杂, 涉及到很多的结构体和指针变量, 在写代码时要特别注意指针和内存的问题, 要防止内存泄露,指针要及时进行清空。希望本文能对WM 平台的EDB 数据库开发起到抛砖引玉的作用。
  [b]参考文献 [/b]
  [1] 傅曦,齐宇,徐骏.Windows Mobile 手机应用开发[M]. 北京:人民邮电出版社,2005
  [2] 刘彦博,胡砚,马骐.Windows Mobile平台应用与开发[M]. 北京:人民邮电出版社,2006
  [3] Microsoft.MSDN Mobile 专区[OL]. http://msdn.microsoft.com/en-us/windowsmobile/defa ult.aspx,2006
  [4] 田东风.Windows CE 应用程序设计[M].北京:机械工业出版社,2005
  [5] 沈建国,田增山.Windows CE 5.0 EDB数据库的应用与开发[D].北京:电脑编程技巧与维护,2007.10
  Windows Mobile Platform EDB Database
  Application Develop
  Cheng Lehu1, Zou Shihong1, Linyu2, Shi Wenyong2
  1. State Key Lab of Networking and Switching Technology,
  Beijing University of Posts and Telecommunications, Beijing (100876)
  2. Beijing NetQin Tech. Co., Ltd., Beijing (100013)
  Abstract
  This paper first introduced the basic knowledge of Windows Mobile platform's EDB database, and
  common data structure and EDB API. Then, based on Windows Mobile's own Contacts EDB database instance, explain how to develop EDB application, such as create EDB database, reading records, add records, delete records and seek records. This paper also introduced EDB transaction and EDB database notification mechanism in detail. Keywords: Mobile Application, Windows Mobile, EDB, Contacts 作者简介:程乐乎,男,1984年生,硕士研究生,主要研究方向是Windows Mobile 操作系统及其应用编程。

Windows Mobile 平台EDB 数据库的应用与开发相关推荐

  1. 《Windows Mobile平台应用与开发》写作工作顺利进行中

    <Windows Mobile平台应用与开发>(书名暂定)是由微软(中国)公司发起,人民邮电出版社负责出版发行,聚集众多Windows Mobile领域的MVP.开发技术专家和技术讲师共同 ...

  2. 模拟Windows Mobile平台

                                                   模拟Windows Mobile平台 概述 在介绍如何在Windows家族操作系统下模拟基于Windows ...

  3. 基于 Windows Mobile 的 Pocket PC 和 Smartphone 的开发工具简介

    Microsoft Corporation 2003 年 8 月 适用于:     Microsoft® eMbedded Visual Tools 3.0 - 2002 Edition     Mi ...

  4. Windows Mobile下访问Sqlite的Native C++封装

    背景 当前移动设备开发领域,在本地数据存储方面,Sqlite几乎成了事实标准,Andriod (android.database.sqlite),iPhone (SQLite for iPhone S ...

  5. Windows Mobile 5.0 中为开发人员提供的新功能(3)

    Windows Mobile 5.0 中为开发人员提供的新功能(3) Pocket Outlook 增强功能 Pocket Outlook 向用户和应用程序开发人员提供了易于使用的 PIM.将 Poc ...

  6. windows mobile+webservice+mysql

    windows mobile已经没落,但由于公司需要,还要进行一个新平台的学习,symbian,meego,wp7,php一路下来,16个月做了5个平台,学到了皮毛但接触到很多方面和层次的技术知识. ...

  7. Windows Mobile 开发系列文章收藏 - Windows Mobile 6.x

    收集整理一些Windows Mobile 6.x开发相关文章, 文章及相关代码大部分搜集自网络,版权属于原作者! 智能手机      手机词汇      研发手机基本流程 WAP协议分析(1)     ...

  8. VS2008中开发wince windows mobile 手持终端程序(PDA软件)

    VS2008中开发wince windows mobile 手持终端程序(PDA软件) 微软平台开发 wince或windows mobile 移动应用程序 跟.NET桌面开发环境 一样 唯一区别的 ...

  9. Windows Mobile BLOG FAQ 2006.12.13

    实在对不住大家,上次回答问题已经是9月份了,这两个月与其说忙,还不如说是太懒.忙了一年了,到了TechEd之后,忽然觉得有点厌倦,就休息了一阵.不过新年快到了,怎么样也要给大家个交代.希望大家的问题都 ...

最新文章

  1. Top1的3D目标检测方法(已开源)
  2. Teamviewer 远程ssh命令行更改密码启动
  3. 文巾解题 17. 电话号码的字母组合
  4. 什么是OR MAPPING
  5. 大学生创业交流会计算机二级,我校召开第三届“互联网+”大学生创新创业大赛选题交流讨论会...
  6. android刷新时的圆形动画_Android自定义加载圈动画效果
  7. 哈希表添加哈希表(Hash Table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。typedef enum{ HASH_OK, -icoding
  8. JsRender 前端渲染模板常用API学习
  9. string常用函数用法集合
  10. 第3批鸿蒙手机排名,荣耀手机也能升级!第三批鸿蒙手机升级名单大曝光:全球第三稳了...
  11. java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
  12. 中国卷绕装置市场趋势报告、技术动态创新及市场预测
  13. Final Project Proposal ——陈稳霖
  14. Day0205____数据库
  15. Excel之vlookup函数的模糊匹配和精准匹配
  16. System.Activator类
  17. 废旧光盘手工小制作_废旧物手工制作:光盘小制作
  18. html文本输入框代码是什么?如何创建html文本输入框
  19. Project0:小游戏
  20. 【工大SCIR笔记】多方对话研究简述

热门文章

  1. 数据管理简史:从人工到人工智能
  2. #今日论文推荐# 北理工研制机械狗全地形自适应,无需额外视觉感知,可在复杂地形中如履平地
  3. 求数学系或计算机系姓张的学生的信息,数据库原理实验三 - 图文
  4. 别怕,卷积其实很简单
  5. 开源解决方案,随笔记录
  6. 小爱同学控制美的美居中的家电热水器,空调等
  7. 青海电大随学随考计算机,国开电大青海电大语言学概论(6180)随学随考答案 (1).docx...
  8. 狼的故事1:首先是生存
  9. Android-Binder及AIDL基础分析
  10. 应用html5画布Apicss制作,程序设计HTML5 Canvas API