您的位置:首页 > 其它

[转]windos mobile系统中从EDB和通过IContact接口取Contact数据的差别

2009-05-19 09:42 501 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐