1.先简单介绍一下EDB
WM5以前的系统中一般都是使用的CEDB数据库,EDB是WM5中的新特性之一。为了改善应用程序的性能和长期可移植性,CEDB 已经被 EDB 所取代。EDB 利用了 SQL Mobile 使用的存储子系统,并且提供了明显优于 CEDB 的性能(尤其是在与持久存储区一起使用时)。因为 CEDB 提供了与 EDB 完全相同的函数集 ,所有函数都具有相同的名称和参数列表。但是EDB中也包含了CEDB中所没有函数,并且创建方法也不相同了,要比CEDB复杂WM5以前的系统中一般都 是使用的CEDB数据库,EDB是WM5中的新特性之一。为了改善应用程序的性能和长期可移植性,CEDB 已经被 EDB 所取代。EDB 利用了 SQL Mobile 使用的存储子系统,并且提供了明显优于 CEDB 的性能(尤其是在与持久存储区一起使用时)。因为 CEDB 提供了与 EDB 完全相同的函数集 ,所有函数都具有相同的名称和参数列表。但是EDB中也包含了CEDB中所没有函数,并且创建方法也不相同了,要比CEDB复杂。(以上摘自某网页上)。 在WM6.1中,你可以通过FILE VIEWER可以看到微软做MOBILE系统对于联系人,EMAIL等系统创建的EDB数据库。在/WINDOWS里你可以看到PIM.VOL(这个卷里 面存取clog.db,Contacts Database等等数据库), CEMAIL.VOL(主要放了EMAIL,SMS,MSM的库)。
2.介绍一下POOM
POOM是基于微软COM技术的一套针对手机上(PIM)个人信息管理的COM接口库。按个人理解,其实他就是微软写好的一些接口(用来取个人信息的), 接口最深处其实应该最终还是用读取EDB数据库的方法,那为什么用POOM来取联系人的信息会比直接EDB慢呢?请继续读下去你就会发现其中的区别了。
3.具体代码操作取数据
利用poom方法取Contact联系人的方法在我空间也有摘抄,你也可以参考以下网址:
http://blog.csdn.net/durone/archive/2006/06/07/778589.aspx
现在主要讲以下用EDB相关知识怎么取联系人信息:
#define EDB (下次贴)
#pragma comment(lib, "Coredll.lib")
/*!
@brief
open the EDB.
@param[in]DatebaseName the point to the datebase name.
@param[out]ceguid a buffer that is filled with the CEGUID of the mounted database.
@return hr:
NOT NULL if open successed"n
NULL if open failed
*/
HANDLE OpenEDB(TCHAR * DatebaseName,CEGUID ceguid)
{
CREATE_INVALIDGUID(&ceguid);
CEOID oid = 0;
// pim.vol是存放个人信息的卷,有联系人,约会表等等
if(FALSE == CeMountDBVolEx(&ceguid, L"pim.vol", NULL , OPEN_EXISTING ))
{
DWORD dwErr = GetLastError();
CeUnmountDBVol(&ceguid);
return NULL;
}
HANDLE hEDB = NULL;
//打开EDB
hEDB = CeOpenDatabaseInSession(NULL, &ceguid, &oid, DatebaseName,NULL, CEDB_AUTOINCREMENT, NULL);
return hEDB;
}
/*!
@brief
close the EDB.
@param[in]hEDB the handle of the EDB.
@param[in]ceguid a buffer that is filled with the CEGUID of the mounted database.
*/
HRESULT CloseEDB(HANDLE hEDB,CEGUID ceguid)
{
HRESULT hr = E_FAIL;
if(NULL != hEDB)
{
CloseHandle(hEDB); //close the edb
}
if(NULL != &ceguid)
{
CeFlushDBVol(&ceguid);
CeUnmountDBVol(&ceguid);//unload the mount.
}
hr = S_OK;
return hr;
}
//以下这个函数只是用来筛选我的结构体需要的内容,然后保存起来
void GetContactInformationByEDB(CEPROPVAL pDate,
SmartdialContent * pSmart)
{
// SmartdialContent是我自己定义的结构体
switch(pDate.propid)
{
case PIMPR_FIRST_NAME:
wcscat(pSmart->m_szName,pDate.val.lpwstr);
break;
case PIMPR_MIDDLE_NAME:
if(wcslen(pSmart->m_szName) >0)
{
wcscat(pSmart->m_szName,L" ");
}
wcscat(pSmart->m_szName,pDate.val.lpwstr);
break;
case PIMPR_LAST_NAME:
wcscat(pSmart->m_szFamilyName,pDate.val.lpwstr);
break;
case PIMPR_ASSISTANT_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[0],pDate.val.lpwstr);
break;
case PIMPR_MOBILE_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[1],pDate.val.lpwstr);
break;
case PIMPR_BUSINESS_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[2],pDate.val.lpwstr);
break;
case PIMPR_BUSINESS2_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[3],pDate.val.lpwstr);
break;
case PIMPR_HOME_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[4],pDate.val.lpwstr);
break;
case PIMPR_HOME2_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[5],pDate.val.lpwstr);
break;
case PIMPR_COMPANY_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[6],pDate.val.lpwstr);
break;
case PIMPR_PAGER_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[7],pDate.val.lpwstr);
break;
case PIMPR_CAR_TELEPHONE_NUMBER:
wcscpy(pSmart->m_szPhoneNumber[8],pDate.val.lpwstr);
break;
case PIMPR_RADIO_TELEPHONE_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[9],pDate.val.lpwstr);
break;
case PIMPR_BUSINESS_FAX_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[10],pDate.val.lpwstr);
break;
case PIMPR_HOME_FAX_NUMBER:
FiltrateDialerNumber(pDate.val.lpwstr);
wcscpy(pSmart->m_szPhoneNumber[11],pDate.val.lpwstr);
break;
default:
break;
}
}
HRESULT GetContactFromEDB(SMARTDIAL_LIST *pContactList,SMARTDIAL_LIST *pSimList)
{
HRESULT hr = E_FAIL;
CEGUID g_ceguid = {0};
// Contacts Database是存取联系人,其实SIM卡的内容也在里面
HANDLE hEDB=OpenEDB(L"Contacts Database",g_ceguid);
if(NULL == hEDB)
{
return hr;
}
DWORD count=0;
const int MAX_BUF_SIZE = 256;
WORD wNumRecProps = 0; //数据库的一条记录里可读的属性数
LPBYTE lpRecProps = NULL; //读出来的数据的字节指针
PCEPROPVAL pCePropVal = NULL; //存放从每一条记录的结构体
DWORD dwBufLen = MAX_BUF_SIZE;
//将库的游标移动到库的开始点
CEOID ceoid = CeSeekDatabaseEx(hEDB,CEDB_SEEK_BEGINNING,0,0,&count);
//从头部循环读到ENDING,每一次读取,从其中的LPBYTE取出我们需要的内容
while(true)
{
//READ RecordProps,return lpRecProps
ceoid = CeReadRecordProps(hEDB, CEDB_ALLOWREALLOC, &wNumRecProps, NULL, &lpRecProps, &dwBufLen);
if(!ceoid)
{
switch(GetLastError())
{
case ERROR_NO_MORE_ITEMS :
//ASSERT(false);
break;
default:
return hr;
}
break;
}
//将字节内容转换成我们操作的数据结构类型
pCePropVal = (PCEPROPVAL)lpRecProps;
SmartdialContent *pSmart = new SmartdialContent();
pSmart->m_bIndex = FALSE;
pSmart->m_lOid = ceoid;// ceoid是库记录的索引号,也就是关键ID
//刷选一条记录各个属性,如果需要的就保存下来,wNumRecProps表
//示读这条记录总共有多少个属性值是可以读的
for(int j=0;j<wNumRecProps;j++)
{
if(pCePropVal[j].wFlags!=CEDB_PROPNOTFOUND)
{
WCHAR pString[256]={0};
if(LOWORD(pCePropVal[j].propid) == CEVT_UI4 && pCePropVal[j].propid==PIMPR_CONTACT_TYPE)
{
//PIMPR_CONTACTTYPE_DEVICE代表该记录存储在手机
if(PIMPR_CONTACTTYPE_DEVICE == pCePropVal[j].val.uiVal)
{
pSmart->m_iType = OUTLOOK_TYPE;
continue;
}
//PIMPR_CONTACTTYPE_DEVICE代表该记录存储在SIM卡
else if(PIMPR_CONTACTTYPE_SIM == pCePropVal[j].val.uiVal)
{
pSmart->m_iType = SIM_TYPE;
continue;
}
}
if(LOWORD(pCePropVal[j].propid) == CEVT_LPWSTR)
{
//刷选该字符串到我结构体去。
GetContactInformationByEDB(pCePropVal[j],pSmart);
continue;
}
}
}
if(OUTLOOK_TYPE == pSmart->m_iType)
{
pContactList->push_back(pSmart);
}
else
{
//because the sim phone number save in //thePIMPR_MOBILE_TELEPHONE_NUMBER of the database
if(0 < wcslen(pSmart->m_szPhoneNumber[1]))
{
//change the sim phone number place.
wcscpy(pSmart->m_szPhoneNumber[12],pSmart->m_szPhoneNumber[1]);
memset(pSmart->m_szPhoneNumber[1],0x00,sizeof(pSmart->m_szPhoneNumber[1]));
}
pSimList->push_back(pSmart);
}
}//while
if(NULL != LocalFree(lpRecProps)) //realloc the lpRecProps
ASSERT(false);
CloseEDB(hEDB,g_ceguid);
return hr;
}
4.效率比较
假如您手机里有500条联系人,现在是自己通过两种方法测试得出的结论:
POOM方法 EDB方法
时间 3300ms 520ms左右
你可以看出EDB方法比POOM的快很多。
来自:
http://hi.baidu.com/evaletchen/blog/item/fab808366a73c5daa2cc2bf2.html