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 ;

}

 

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