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

时间:2022-09-02 19:24:46

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