在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上来 |