<!-- /* 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 ;
}