Symbian 名片操作 新手请看

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

#ifndef _CONTACTHAND_H_

#define _CONTACTHAND_H_

 

#include <cntdb.h> //CContactDatabace

#include <cntitem.h>

 

#include <cntfield.h>

#include <cntdef.h>   //TContactItemId ******typedef TInt32 TContactItemId;

#include <cntfldst.h>

#include <e32base.h>

 

class CContactHand : public CBase

    {

public :

    static CContactHand * NewL ();

    static TInt ParseWord ( TAny *);  // 需要再次学习

    ~CContactHand ();

    void AddEmployerL ( TContactItemId aCntId, const TDesC & aCompany); // 写入 公司 属性到名片

    CDesCArray * ReadTextFieldL ( TContactItemId aCntId, TFieldType aType); // 读取

    void AddCardL ( const TDesC & aFirstName, const TDesC & aLastName, const TDesC & aPhone); // 写入名片信息

    void RemoveContactL ( TContactItemId aCntId); // 删除

    CContactIdArray * FindWithCallbackLC ( TFieldType aField, const TDesC & aMatch); // 通过关键字查找

    void MoveContactL ( TContactItemId aCntId, const TDesC & aNewGroup);

private :

    void ConstructL ();

    CContactHand ();

private :

    TCallBack iCallback ;

    CContactDatabase * iCntDb ;

    };

#endif

 

 

#include "contacthand.h"

#include <e32std.h>

void CContactHand::ConstructL ()

{

/*

  * 手机上一般有一个默认的名片数据库

  * 但是我们在处理名片的时候一定要记住假设这个数据库是不存在的

  * 这样做防止特殊的情况使程序崩溃

*/

    TRAPD (error, iCntDb = CContactDatabase :: OpenL ()); // 打开数据库 用宏查错

    if (KErrNotFound)

       iCntDb = CContactDatabase :: CreateL ();     // 没有找到就创建一个数据库

    else

       User :: LeaveIfError (error);

}

CContactHand::CContactHand (): iCallback (& CContactHand ::ParseWord ) // 不明白这个在做什么

    {}

/*

  * 下面的函数只是添加了名片的一项记录,可以修改参数得到完整的记录,

  * 或则自己解析参数的意义,得到完整名片

  */

void CContactHand::AddEmployerL ( TContactItemId aCntId, const TDesC & aCompany)

{

    // 打开这个 ID 的名片,并且 Lock 这个名片防止修改   这里名片已经存在

    CContactItem * item = iCntDb -> OpenContactLX (aCntId);

    CleanupStack :: PushL (item);

    //make a company name field to add to the contact  用一个域来添加名片中的项

    CContactItemField * field = CContactItemField :: NewLC ( KStorageTypeText );

    field-> AddFieldTypeL (KUidContactFieldCompanyName);

    field-> TextStorage ()-> SetTextL (aCompany); // 把记录添加到 Field

   

    item-> AddFieldL (*field); // field 加到 item

    CleanupStack :: PopAndDestroy (field);

   

    iCntDb -> CommitContactL (*item); // 把记录提交

    CleanupStack :: PopAndDestroy (item);

    CleanupStack :: PopAndDestroy (); // 释放 Item 的锁  

}

/*

  * 参数 名片 ID  数据类型

  * 返回 名片所有内容

  * 描述 读取名片所有 Field

  */

CDesCArray * CContactHand::ReadTextFieldL ( TContactItemId aCntId, TFieldType aType)

{

    // 创建描述数组,存储记录

    CDesCArray * result = new ( ELeave ) CDesCArrayFlat (2); // 这个 New 比较奇怪

    CleanupStack :: PushL (result);

   

    // 用数据库引擎读取记录,关心我们感兴趣的部分, EIncludeFields 接受特殊的部分 EMaskHiddenFields 不接受隐藏

    CContactItemViewDef * viewDef = CContactItemViewDef :: NewL ( CContactItemViewDef :: EIncludeFields ,

           CContactItemViewDef :: EMaskHiddenFields );

    viewDef-> AddL (aType); // 不知道语句在做什么

   

    //get the contact item

    CContactItem * item = iCntDb -> ReadContactLC (aCntId,*viewDef);

    //get all the fields

    CContactItemFieldSet & fieldSet = item-> CardFields ();

    // 循环获取信息

    for ( TInt i = 0; i < fieldSet. Count (); i++)

       {

       CContactItemField & field = fieldSet[i];

       if ( KStorageTypeText == field. StorageType ())

           {

           const TPtrC value = field. TextStorage ()-> Text ();

           result-> AppendL (value);

           }

       }

    CleanupStack :: PopAndDestroy (2,viewDef);   // 对象使用 NewLC 或者 LC 结尾的函数创建的对象都会在 Stack 中留下指针

    CleanupStack :: Pop (result);

    return result;

}

/*

  * 参数 名片的 Fiel 的内容

  * 描述 新建一张名片,并写入相应的内容到相应的 Field

  */

void CContactHand::AddCardL ( const TDesC & aFirstName, const TDesC & aLastName, const TDesC & aPhone)

    {

    // 创建一个名片

    CContactCard * contactCard = CContactCard :: NewLC (); // 注意在栈中留有指针

    // 添加入 firstName

    CContactItemField * firstName = CContactItemField :: NewLC ( KStorageTypeText );

    firstName-> AddFieldTypeL (KUidContactFieldGivenName);

    firstName-> TextStorage ()-> SetTextL (aFirstName); // 数据写入

    contactCard-> AddFieldL (*firstName);

    CleanupStack :: Pop (firstName);

   

    // 添加入 lastName

    CContactItemField * lastName = CContactItemField :: NewLC ( KStorageTypeText );

    lastName-> AddFieldTypeL (KUidContactFieldFamilyName);

    lastName-> TextStorage ()-> SetTextL (aLastName); // 数据写入

    contactCard-> AddFieldL (*lastName);

    CleanupStack :: Pop (lastName);

   

    // 添加入 lastName

    CContactItemField * phone = CContactItemField :: NewLC ( KStorageTypeText );

    phone-> AddFieldTypeL (KUidContactFieldPhoneNumber);

    phone-> TextStorage ()-> SetTextL (aPhone); // 数据写入

    contactCard-> AddFieldL (*phone);

    CleanupStack :: Pop (phone);

   

    // 名片添加到 DB

    iCntDb -> AddNewContactL (*contactCard);  // 参数是 CContactItem 可见 Item Card

    CleanupStack :: PopAndDestroy (contactCard);

    }

/*

  * 参数 关键字字段 关键字值

  * 描述 查找和关键字匹配的结果

  * 高手支招   ******** 大数据库查找可能需要很多时间,可调用异步函数 CContactDatabase::FindInTextDefAsyncL()

  * ***************** 如果结果过大,可以使用相对较小的批处理来获取(比如利用 Clidle

  */

CContactIdArray * CContactHand::FindWithCallbackLC ( TFieldType aField, const TDesC & aMatch)

    {

    // 搜索关键字属于什么字段,需要建立数组

    TContactTextDefItem field(aField);

    CContactTextDef * textDef = CContactTextDef :: NewL ();

    CleanupStack :: PushL (textDef);

    textDef->AppendL(field);

   

    // 一个描述数组来设置搜索

    CDesCArray * match = new ( ELeave ) CDesCArrayFlat (1);

    CleanupStack :: PushL (match);

    match-> AppendL (aMatch);

    CContactIdArray * result = iCntDb -> FindInTextDefLC (*match,textDef, iCallback ); // 查找

    CleanupStack :: Pop (result);

    CleanupStack :: Pop (2,textDef);   //textDef match

    return result;

    }

/*

  * 非常不明白这个函数在干什么

  */

TInt CContactHand::ParseWord ( TAny * aParam)

    {

    SFindInTextDefWordParser * parserStruct = ( SFindInTextDefWordParser *)aParam;  // 强制转换 SFindInTextDefWordParser*

    TPtrC searchString(*(parserStruct-> iSearchString ));

    TInt index = KErrNotFound;

    TInt error = KErrNone;

    while (0 <= (index = searchString. Locate ( ' ' )))

       {

       if (index > 0)

           {

           TRAP (error,parserStruct-> iWordArray -> AppendL (searchString. Left (index))); // 这个在检查什么错误

           if (error != KErrNone)

              return error;

           if (searchString. Length () > index + 1)

              searchString. Set (searchString. Mid (index));

           else

              {

              searchString. Set (KNullDesC);  //_LIT(KNullDesC,"");

              break ;

              }

           }

       else

           searchString. Set (searchString. Mid (1)); //remove first character as it is a space

       }

    if (searchString. Length () > 0)   //the last word

       {

       TRAP (error,parserStruct-> iWordArray -> AppendL (searchString)); // 这个在检查什么错误

       if (error != KErrNone)

           return error;

       }

    return KErrNone;

    }

/*

  * 参数 名片的 ID 添加到的组名称

  * 描述 通过组名得到组的 ID (不存在则新建)并加入 ID 的名片

  * 高手支招 ********* 会遇到非原子操作问题:函数执行一半,失败了;需要考虑一种方法让其回滚

  */

void CContactHand::MoveContactL ( TContactItemId aCntId, const TDesC & aNewGroup)

    {

    CContactItem * item = iCntDb -> OpenContactLX (aCntId);

    CleanupStack :: PushL (item);

    // 找到名片属于的组

    TContactItemId groupId = KNullContactId;  // 记录组的 ID

    CContactItem * group = NULL ;           

    if (KUidContactCard == item. Type ())

       {

       CContactCard * card = ( CContactCard *)item;

       // Returns a pointer to a list of contact item IDs which identify the groups to which this

       // contact card belongs

       CContactIdArray * ids = card-> GroupsJoinedLC ();  

       // 个数大于 0 就把第一个数据赋值

       if (0 < ids-> Count ())

           groupId = (*ids)[0]; // 这样的操作可以学习 C 类似   这里如果 Count()>1 可以循环

       CleanupStack :: PopAndDestroy (ids);

       }

    if (KNullContactId != groupId)

       {

       group = iCntDb -> OpenContactLX (groupId);

       CleanupStack :: PushL (group);

       iCntDb -> RemoveContactFromGroupL (*item,*group);

       CleanupStack :: Pop (group);

       CleanupStack :: Pop (); // 解除 group 的锁

       group = NULL ;

       }

    CleanupStack :: Pop (2); //item , 解除 Item 的锁     ?对于 Pop 的用法还是不很清楚

   

    // 查找新的组 没有就新建一个

    groupId = KNullContactId;

    CContactIdArray * groupArrayId = iCntDb -> GetGroupIdListL ();

    if ( NULL != groupArrayId )

       {

       CleanupStack :: PushL (groupArrayId );

       for ( TInt i = 0; i < groupArrayId . Count (); i++)

           {

           group = iCntDb -> ReadContactLC ((*groupArrayId )[i]);

           TPtrC lable = (( CContactGroup *)group)-> GetGroupLabelL ();

           if (aNewGroup. MatchC (lable))

              {

              groupId = (*groupArrayId )[i];

              i = groupArrayId . Count ();   // 相当于 Break 这样做有什么好处

              }

           CleanupStack :: PopAndDestroy (group);

           group = NULL ;

           }

       CleanupStack :: PopAndDestroy (groupArrayId );

       }

    if (groupId == KNullContactId)   // 没有找到相应的组 新建

       {

       group = iCntDb -> CreateContactGroupLC (aNewGroup); // 在栈中留下变量

       groupId = group-> Id ();

       CleanupStack :: PopAndDestroy (group);

       }

    iCntDb -> AddContactToGroupL (aCntId,groupId);   // 把名片 Id 对应的 Item 添加到 groupId 对应的组

    }

 

/*

  * 参数 名片的 ID

  * 描述 删除 ID 位置的名片

  * 改进 函数没有判断没有找到需要删除的名片 也没有返回删除与否

  * 高手支招   ******** 在删除名片后调用 CContactDatabase::CompactL() 可以减小数据库大小,但是不用每次调用

  * ***************** 一般删除几次调整下比较好

  */

void CContactHand::RemoveContactL ( TContactItemId aCntId)

    {

    iCntDb -> DeleteContactL (aCntId);

//  iCntDb->CompactL();

    }

CContactHand::~CContactHand ()

{

    if ( iCntDb )

       delete iCntDb ;

    iCntDb = NULL ;

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章