在symbian中我们经常会用到视图结构(view-architecture),而且经常要从一个视图切换到另一个视图,比如在一个container中时如果要切换到其他视图,象这样是肯定不行:
YOURCONTAINER.h
CYOURAppUi * appUi;
YOURCONTAINER.cpp
TKeyResponse CYOURContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
if(aKeyEvent.iCode==EKeyDevice3)
{
appUi->ActivateLocalViewL(TUid::Uid(EGameListsViewId));/*next view?*/
return EKeyWasConsumed;
}
..........
}
虽然能编译通过,但是当你在模拟器中实行切换的时候会提示你 Kern-Exec 3 ,你仔细调试时会发现在这个过程中appUi一直都是0x000000,因为你根本就没传进来嘛只是定义了一个变量而已.程序会在
appUi->ActivateLocalViewL(TUid::Uid(EGameListsViewId))
这一步的时候panic中止,提示
Unhandled exception in epoc.exe(eikcore.dll):0xc0000005:Access Violation".
解决办法有两个:
方法一
在view中创建函数SwitchToViewL,然后传给container一个视图的指针或引用,让container通过这个指针或调用来切换:
CYOURview.h:
void SwitchToViewL(TUid aViewId);
CYOURview.cpp:
void CYOURView::SwitchToViewL(TUid aViewId)
{
AppUi()->ActiveateLocalViewL(aViewId);
}
CYOURcontainer.h
CYOURview& iView;
CYOURcontainer.cpp
if(aKeyEvent.iCode==EKeyDevice3)
{
iView.SwitchToViewL(TUid::Uid(EYOURViewId));
return EKeyWasConsumed;
}
详细点如下:
CYOURview.h:
void SwitchToViewL(TUid aViewId);
CYOURview.cpp:
void CMainView::DoActivateL(const TVwsViewId& /*aPrevViewId*/,
TUid /*aCustomMessageId*/,
const TDesC8& /*aCustomMessage*/)
{
ASSERT(iContainer == NULL);
iContainer = CMainViewContainer::NewL(*this,ClientRect());
iContainer->SetMopParent(this);
AppUi()->AddToStackL(*this,iContainer);
}
void CMainView::SwitchToViewL(TUid aViewId)
{
AppUi()->ActivateLocalViewL(aViewId);
}
YOURCONTAINER.h
public:
static CMainViewContainer* NewL(CMainView& aView,const TRect& aRect);
static CMainViewContainer* NewLC(CMainView& aView,const TRect& aRect);
~CMainViewContainer();
private:
void ConstructL(const TRect& aRect);
CMainViewContainer(CMainView& aView);
public:
CMainView& iView; //引用,不要搞错了.(引用没有->,只有 "."运算符)
...............
YOURCONTAINER.cpp
CMainViewContainer* CMainViewContainer::NewL(CMainView& aView,const TRect& aRect)
{
CMainViewContainer* self = CMainViewContainer::NewLC(aView,aRect);
CleanupStack::Pop(self);
return self;
}
CMainViewContainer* CMainViewContainer::NewLC(CMainView& aView,const TRect& aRect)
{
CMainViewContainer* self = new (ELeave) CMainViewContainer(aView);
CleanupStack::PushL(self);
self->ConstructL(aRect);
return self;
}
CMainViewContainer::CMainViewContainer(CMainView& aView):
iView(aView),
CCoeControl(),
MCoeControlObserver(),
MCoeControlContext()
{
}
CMainViewContainer::~CMainViewContainer()
{........................
传个指针进来:
view:
iContainer=new(ELeave) CMainViewContainer;
iContainer->ConstructL(this, ClientRect());
container
CMainView * iView;
void CMainViewContainer::ConstructL(CMainView *aView, const TRect& aRect)
{
iView= aView;
...
}
..........
.
2)据说这个也好用,不过没试.((CAppUi*)iEikonEnv->EikAppUi())->HandleCommandL(ESwitchView3); //没试过哈
最近比较忙,写的也仓促,过半个月左右空闲下来再修改,如果需要的话我发example上来