Symbian
学习总结
:Eddy,2007.3
//
在
AppUi
类中构造容器
void CHelloAppUi::ConstructL()
{
BaseControl();
iAppContainer = CHelloContainer::NewL(ClientRect());
iAppContainer->SetMopParent(this);
//在容器之间建立父子关系,这样子控件就可以访问父控件或其他子控件,父控件也可以访问子控件
AddToStackL(iAppContainer);
//将Container推入栈顶,可以接收按键事件,如果想让其他容器接受事件,可以通过RemoveFromStack(iAppContainer)将当前容器从栈顶移出,将其他的容器推入栈顶,通过AddToStackL(iAppContainer2)
}
//symbian
编码诀窍
:
1)CleanupStack 机制是可以扩展的.面对所有的Leave事件.
2)对HBufC变量分配内存后,试图删除该变量,删除后要将该变量设为Null.
3)采用自己的TRAP时,不要忽略所有的错误
TRAPD(err.DoSomething());
if(err ==KErrNotFound||err== KErrNone)
{
//DoSomething();
}
else
User::Leave(err);
4)Symbian中构造函数,析构函数不可能发生Leave.
在symbian os中,构造函数将对象实例化,然后调用ConstructL()函数将成员数据实例化.
5)Symbian指针表示所有权的转移,而引用所有权仍然属于原来的所有者.
//CCoeControl
是所有控件的基类
,
在派生类中要实现四个函数
void CHelloAppUi:public CCoeControl
{
void SizeChanged();
void Draw();
int CountComponentControls();
void ComponentControl();
}
//
描述
symbian
下初始框架的函数
,
以下是
symbian
建立工程时产生的所有文件
先描述头文件
,
然后是
CPP
文件
.
假定工程名称为
Hello
//
头文件定义
//CHelloApplication.h
#ifndef HELLOAPPLICATION_H
#define HELLOAPPLICATION_H
#include <aknapp.h>
class CHelloApplication:public CAknApplication
{
public:
TUid AppDllUid() const;
protected:
CApaDocument* CreateDocumentL();
};
#endif
//CHelloDocument.h
#ifndef HELLODOCUMENT_H
#define HELLODOCUMENT_H
#include <akndoc.h>
class CHelloAppUi;
class CEikApplication;
class CHelloDocument:public CAknDocument
{
public:
static CHelloDocument* NewL(CEikApplication& aApp);
static CHelloDocument* NewLC(CEikApplication& aApp);
~CHelloDocument();
CHelloAppUi* CreateAppUiL();
private:
void ConstructL();
CHelloDocument(CEikApplication& aApp);
};
#endif
//CHelloAppUi.h
#ifndef HELLOAPPUI_H
#define HELLOAPPUI_H
#include <aknappui.h>
class CHelloAppView;
class CHelloAppUi:public CAknAppUi
{
public:
void ConstructL();
CHelloAppUi();
~CHelloAppUi();
void HandleCommandL(TInt aCommand);
private:
CHelloAppView* iAppView;
};
#endif
//CHelloAppView.h
#ifndef HELLOAPPVIEW_H
#define HELLOAPPVIEW_H
#include <coecntrl.h>
class CHelloAppView:public CAknAppView
{
public:
static CHelloAppView* NewL(const TRect& aRect);
static CHelloAppView* NewLC(const TRect& aRect);
~CHelloAppView();
void Draw(const TRect& aRect) const;
private:
CHelloAppView();
void ConstructL(const TRect& aRect);
};
#endif
//
具体的类实现
//the definition of CHelloApplication:HelloApplication.cpp
#include "HelloApplication.h"
#include "HelloDOcument.h"
#include <aknapp.h>
const TUid KUidHelloApp = {0x08d5778};
CApaDocument* CHelloApplication::CreateDocumentL() const
{
return (static_cast<CApaDocument*>(CHelloDocument::NewLC(*this)));
}
TUid CHelloApplication::AppDllUid() const
{
return KUidHelloApp;
}
//the definition of CHelloDocument:HelloDocument.cpp
#include "HelloDocument.h"
#include "HelloAppUi.h"
static CHelloDocument* CHelloDocument::NewL(CEikApplication& aApp)
{
CHelloDocument* self = NewLC(aApp);
CleanupStack::Pop(self);
return self;
}
static CHelloDocument* CHelloDocument::NewLC(CEikApplication& aApp)
{
CHelloDocument* self = new(ELeave)CHelloDocument(aApp);
CLeanupStack::PushL(self);
self->ConstructL();
return self;
}
CHelloDocument::~CHelloDocument()
{
}
CHelloDocument::ConstructL()
{
}
CHelloDocument::CHelloDocument(CEikApplication& aApp):CAknDocument(aApp)
{
}
CHelloAppUi* CHelloDocument::CreateAppUiL()
{
return (static_cast<CHelloAppUi*>(new(ELeave)CHelloAppUi));
}
//the definition of CHelloAppUi:HelloAppUi.cpp
#include "HelloAppUi.h"
#include "HelloAppView.h"
#include "Hello.hrh"
#include "Hello.pan"
#include <avkon.hrh>
#include <aknnotewrappers.h>
CHelloAppUi::CHelloAppUi()
{
}
CHelloAppUi::~CHelloAppUi()
{
if(iAppView)
{
iEikonEnv->RemoveFormStackL(iAppView);
delete iAppView;
iAppView = NULL;
}
}
CHelloAppUi::ConstructL()
{
BaseConstructL();
iAppView = CHelloAppView::NewL(const TRect& arect);
AddToStackL(iAppView);
}
void CHelloAppUi::HandleCommandL(TInt aCommand)
{
switch(aCommand)
{
case EEikCmdExit:
case EAknSoftKeyExit:
Exit();
break;
case EHelloCommand1:
{
_LIT(message,"Command1");
CAknInformationNote* informationnote = new(ELeave)CAknInformationNote;
informationNote->ExecuteLD(message);
}
break;
default:
Panic(EHelloBasicUi);
break;
}
}
//the definition of CHelloAppView:HelloAppView.h
#include "HelloAppView.h"
static CHelloAppView* CHelloAppView::NewL(const TRect& aRect)
{
CHelloAppView* self = NewLC(aRect);
CleanupStack::Pop(self);
return self;
}
CHelloAppView::CHelloAppView()
{
}
static CHelloAppView* CHelloAppView::NewLC(const TRect& aRect)
{
CHelloAppView* self = new(ELeave)CHelloAppView;
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CHelloAppView::~CHelloAppView()
{
}
void CHelloAppView::ConstructL(const TRect& aRect)
{
CreateWindowL();
SetRect(aRect);
ActivateL();
//注意函数后面的L千万不要丢掉.
}
void CHelloAppView::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
//SystemGc是CCoeControl的函数,用来获取图形上下文
gc.SetBrushColor(KRgbRed);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
gc.Clear(Rect());
}
//the definition of Hello.hrh
#ifndef HELLO_HRH
#define HELLO_HRH
enum THelloIds
{
EHelloCommand1 = 0x0600
};
#endif
//the definition of Hello.pan
#ifndef HELLO_PAN
#define HELLO_PAN
#endif
//
框架到此描述结束
.
//
容器类
Container
中的内容精要小结
:
在
Container
中显示两个
Label
的方法
:
1)
首先将两个
Label
指针作为
Container
类的私有成员变量
:
private:
CEikLabel* iLabel;
CEikLabel* iToDoLabel;
2)
Container
类中的四个方法
,
否则
Label
控件不会显示
:
void SizeChanged();
//
这个函数没有
const
限制
void Draw(const TRect& aRect) const;
virtual TInt CountComponentControls() const;
virtual CCoeControl* ComponentControl(TInt aIndex) const;
//
虚函数
,
在基类中声明
,
在派生类中定义
,
但是在派生类中不需要
virtual
标示
.
具体的实现函数
:
CCoeControl* CHelloCOntainer::ComponentControl(TInt aIndex) const
{
Switch(aIndex)
{
case 0:
return iLabel;
case 1::
return iToDoLabel;
default:
return NULL;
}
}
TInt CHelloContainer::CountComponentControls( )const
{
return 2;
}
void CHelloContainer::SizeChanged()
{ //
设定控件的位置
iLabel->SetExtent(TPoint(10,10),iLabel->MinimumSize());
iToDoLabel->SetExent(TPoint(10,100),iToDoLabel->MinimumSize());
}
//
注意
:SetExent
函数没有以
L
结尾
.
必须重写这两个方法
,
要不
Label
控件不会显示
void CHelloContainer::Draw( const TRect& aRect) const
{
//
屏幕的显示范围大概是
(0,0)
到
(120,150).
最好不要超出
CWindowsGc& gc = SystemGc();
TRect rect = Rect();
gc.Clear(rect);
gc.SetPenStyle( CGraphicsContext::ENullPen);
gc.SetBrushColor(KRgbRed);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
gc.DrawRect(aRect);
}
Container
中的
ConstructL( )
方法
:
void CHelloContainer::ConstructL()
{
CreateWindowL();
iLabel = new (ELeave) CEikLabel;
iLabel->SetContaierWindowL(*this);//
将不用有窗口的控件与窗口相联
//
表示这两个控件显示在那个窗口上
,
参数是容器
Container
iLabel->SetTextL(_LIT(“iLabel”));
iLabel->SetUnderlining(ETrue);
iToDoLabel = new(ELeave) CEikLabel;
iToDoLabel->SetContainerWindowL(*this);
iToDoLabel->SetTextL(_LIT(“iToDoLabel”));
SetRect(aRect);
ActivateL();
//
激活窗口
,
也就是调用
Draw(),SizeChanged()
函数
,
开始绘制窗口
}
Avkon
视图切换架构详细分析笔记
:2007.3.6
1):
首先与传统的视图架构相比
,
多了
view
视图类
;
一共有五个类
:Application,Document;AppUi;View;Container;
如果程序中有多个视图
,
则
view
与
container
类要成对实现
.
且视图的切换在类
AppUi
的
ConstructL()
函数中
.
通讯录的删除主要通过引擎类
CPbkContactEngine
来实现
,
引擎类的成员
iEngine
也是在
AppUi
的
ConstructL()
函数中定义的
.
主要几个类的作用
:
AppUi:
控制视图类的定义
,
切换
.
以及
Engine
类的定义实现
.
View:AppUi
类与
Container
类之间的桥梁
.
同时包含
Engine
类的引用
.
Container:
容器类主要实现窗口中的控件如
:
列表
,
图标等等
Engine:
成员函数的具体实现
,
通过
view
中的
HandleCommandL()
函数调用
2):
在传统架构中
,iContainer
是作为
AppUi
的私有成员的
.
而在
Avkon
视图切换架构中
:iContainer
是作为
View
类的私有成员的
.
iEngine
是
AppUi
的私有成员
.
3):
在
View
类的
ConstructL()
函数中不能创建
iContainer,
切记
:
在此函数中仅仅传送资源文件
.
4):
在
view
类的
HandleCommandL()
函数中
,
通过按键事件来调用
AppUi
类与
Engine
类中的菜单或者命令等等
.
5):(
个人观点
)
在
Avkon
视图切换架构中
,view
类相当于
AppUi
与
Container
之间的桥梁
.
与此同时通过
view
类来调用
Container
与
Engien
类
,Container
类与传统视图架构中的作用差不多
,
主要是列表的显示以及图形的绘制等等
.
6):
//
在
container.cpp
文件里面
Void CPhoneBkExContainer::ConstructL(const TRect& aRect)
{
CreateWindowL(); //控制窗口关联
SetRect(aRect); //设置窗口范围
//create the list box
iListBox = new (ELeave)CAknDoubleStyleListBox(); //申请空间
iListBox->ConstructL(this,EAknListBoxSelectionList); //调用构造函数
iListBox->SetContainerWindowL(*this); //将列表与窗口相关联
iListBox->CreateScrollBarFrameL(ETrue); //建立滚动条
iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff);
//设置滚动条默认属性
iListBox->SetRect(Rect());//设置滚动条的范围
ActivateL(); //激活窗口
}
//
上面是列表的创建方法
,
下面是
Label
的创建方法
Void CPhoneBkExContainer::ConstructL(const TRect& aRect)
{
HBufC* labelText = StringLoader::LoadLC(R_VIEW2_TEXT);
CreateWindowL();
iLabel = new (ELeave) CEikLabel;
//声请空间
iLabel->SetContainerWindowL(*this); //将图标与窗口相关联
iLabel->SetTextL(*labelText);
//给相应的图标命名
CleanupStack::PopAndDestroy();
SetRect(aRect);
ActivateL();
}
7):
//view.cpp
文件里面
,
创建列表
(listbox)
与图标
(label)
方法基本相似
Void CPhoneBkExView::ConstructL()
{
BaseConstructL(R_PHONEBKEX_VIEW);
}
//
通讯录学习笔记总结
:2007.3.7
//
打开关闭通讯录
CContactDatabase::OpenL()
函数有两个重载函数
L
参数不同
)
无参数
:
打开默认数据库
有参数
:
打开参数指定的数据库
CContactDatabase* contactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactsDb);
TInt numberOfContacts = contactsDb->CountL();
CleanupStack::PopAndDestroy(contactsDb);
//
新建数据库
CContactDatabase::CreateL():
如果数据库存在
,
以
KErrAlreadyExists
退出
CContactDatabase::ReplaceL():
如果数据库已经存在
,
就替换原来的数据库
.
TFileName contactDbFilePath;
CContactDatabase* newDefaultContactDb;
if( CContactDatabase::FindContactFile(contactDbFilePath))//
是否存在默认数据库
{
newDefaultContactDb = CContactDatabse::ReplaceL();
}
else
{
newDefaultContactDb = CContactDatabase::CreateL():
}
CleanupStack::PushL(newDefaultContactDb);
//
此处添加自己的代码
CleanupStack::PopAndDestroy(newDefaultContactDb);
//
遍历通讯录项
通过类
TContactIter
来实现
,
每个函数用通讯录项
ID(TContactItemId)
进行操作
CContactDatabase* contactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactsDb);
TContactIter iter(*contactsDb); //
类似游标
TContactItemId cardId;
while((cardId = iter.NextL())!= KNullContactId)
{
CContactItem* card = contacsDb->ReadContactL(cardId);
CleanupStack::PushL(card);
//
添加自己的代码
contactsDb->CloseContactL(card->Id());
CleanupStack::PopAndDestroy():
}
CleanupStack::PopAndDestroy();
//
导出所有通信项到文件
主要使用
ContactDatabase::ExportSelectedContactsL
函数
RFs fileSession;
User::LeaveIfError(fileSession.Connect());
CleanupClosePushL(fileSession);
CContactDatabae * contactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactsDb);
CContactIdArray* exportContact = CContactIdArray::NewL();//
记录数据项数组
CleanupStack::PushL(exportContact);
RFile file;
File.Replace(fileSession,aFileName,EFileWrite);//
新建文件
CleanupClosePushL(file);
RFileWriteStream outputStream(file);//
声明文件流
CleanupClosePushL(outputStream);
exportContact = iCOntacts;//iContacts
是初始化相应导出的数组
TUid id;
id.iUid =KVersitEntityUidVCard;
contactsDb->ExportSelectedContactsL(id,*exportContact,aWriteStream,
CContactDatabase::EExcludeUid);
CleanupStack::PopAndDestroy(5);
//
删除指定的通讯录项
可以使用类
CPbkContactEngine;
CPbkContactEngine* iPbkContactEngine =CPbkContactEngine::NewL();
//
建立一个默认的通讯录的引擎对象
void CPbkContactEngine::DeleteContactL(TCOntactItemId aContactId,
TBool aImmediateNotify =EFalse);
//
删除函数
iPbkContactEngine->DeleteContactL(id);
//
调用删除函数
iPbkContactEngine->CompressL();
//
将数据库进行压缩
//
新建通讯录项
首先打开数据库
,
然后
: