symbian s60 3rd 横屏竖屏切换

来源:互联网 发布:淘宝客户关系管理标签 编辑:程序博客网 时间:2024/05/29 15:46
设备, 软件 版本:S60 3rd EditionS60 3rd Edition, FP1S60 3rd Edition, FP2详细描述:缺省情况下,程序是根据手机屏幕的当前方向开始启动的。如果要强制程序以横屏或竖屏的模式启动,那我们在CAknAppUi::ConstructL()方法中调用BaseConstructL()时就要传递相应的flag值:定义如下: EAknEnableSkin = EAknEnableSkinFlag, EAppOrientationPortrait = EAppOrientationSpecifiedFlag, EAppOrientationLandscape = EAppOrientationSpecifiedFlag | EAppOrientationLandscapeFlag, EAppOrientationAutomatic = EAppOrientationSpecifiedFlag | EAppOrientationAutomaticFlag, // Since 3.0 EAknDisableHighlightAnimation = EAknDisableHighlightAnimationFlag,使用方式:void CMyAppUi::ConstructL(){BaseConstructL( EAknEnableSkin | EAppOrientationLandscape ); // start in landscape mode...}如果要在程序运行期间改变方向,则需要调用:void CAknAppUiBase::SetOrientationL( TAppUiOrientation aOrientation );例:在HandleCommandL(TInt aCommand)函数中: case ES60ExCmdRotate: { iForcedRotateState = ETrue; if( !ScreenState() ) { SetOrientationL(CAknViewAppUi::EAppUiOrientationPortrait); //竖屏 } else { SetOrientationL(CAknViewAppUi::EAppUiOrientationLandscape); //横屏 } break; }这里的参数为EAppUiOrientationLandscape和EAppUiOrientationPortrait,注意这种情况下的调用就不要再向BaseConstructL()中传递相同的参数了。注意横屏(landscape),前者是横幅,一般多用在风景照,所以叫"landscape"。 竖屏(portrait),后者是直幅,一般多用在肖像上,所以叫"portrait"。 实例代码:S60_Platform_Custom_UI_and_Screen_Rotation_Example_v1_0_en.zip测试机型:nokia 5320 xpressmusic不过在3rd mr模拟器上测试屏幕旋转没效果,这个模拟器不支持旋转,只能手动设置屏幕大小。屏幕旋转需要真机测试。旋转屏幕2.8,3.0 SDK支持屏幕旋转,程序里面可以捕获该消息,然而使UI自定义的改变位置继承的函数为:Container::HandleResourceChange,原先的SizeChange这个函数不会响应在该函数内不要使用AppUi->ClientRect函数来获取工作区范围,数据会有偏差(这个问题郁闷了好久),可以使用TRect rect;AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane,rect );来获取RECT彻底解决Symbian全屏显示问题原文:http://blog.csdn.net/Max__Payne/archive/2009/02/18/3906734.aspx最近总有同行问我Symbian全屏显示的问题,说是参考了网上的方法也无法设置成全屏。其实,归根结底还是不明白Symbian框架的调用机制。这篇文章里我就来彻底研究一下Symbian全屏的机制。首先,我们可以利用Carbide.vs向导建一个项目,名字就叫"TestScreen",选择基于Eikon的传统控件架构。那么在CTestScreenAppUi的二阶构造函数里就有如下代码:void CTestScreenAppUi::ConstructL(){BaseConstructL();iAppContainer = new (ELeave) CTestScreenContainer;iAppContainer->SetMopParent( this );iAppContainer->ConstructL( ClientRect() );AddToStackL(iAppContainer);}这里面有很关键的一句,就是我用红色显示的那段代码。它把当前UI的ClientRect()传递给Container类,我们都知道Container类是控件类,负责整个程序的界面显示,那么 UI传递给Container的这个ClientRect()到底是什么东东呢?我们看看SDK HELP:ClientRect()TRect ClientRect() const;DescriptionGets the area of the screen available to the application for drawing, not including the space that is available for any of the following, where required: non-application areas which should always be displayed, an application status pane, an application button group, an application menu bar, an application title band and an application tool bar.Importantly, the co-ordinates of the rectangle are relative to the whole screen area so, for example, the co-ordinate for the top, left point of the area available for drawing may be (0, 45).Return valueTRect The area of the screen available to the application for drawing.从Description我们可以看到:ClientRect()获得应用程序绘制的有效屏幕区域,但是这个区域不包括那些总是显示的非应用程序区域,比如:应用程序状态面板 (application status pane)、按钮(button group)、应用程序的菜单bar、标题、工具条。而且更重要的是从下面一行可以看出,这个ClientRect()所获得区域的top-left坐标是(0,45)。通过上面的分析我们知道,UI在构造我们的Container时传递一个所谓的"客户矩形区域",这个"客户矩形区域"的top-left坐标是(0,45),从而也就知道如果要让我们的程序全屏显示,那么我们需要改变的是构造Container的时候传递的矩形大小。那么就有如下几种方法:①如果我们知道屏幕尺寸,那么就可以把iAppContainer->ConstructL( );里面的参数改为TRect (0,0,176,208)。②上面的程序不具有适配性,因为我们把屏幕的宽度和高度写死了。我们来看Symbian给我们提供的一个方法ApplicationRect()TRect ApplicationRect() const;DescriptionGets the total area of the screen available to the application. This includes the space that is available for a toolbar, toolband or title band, if the application requires them.Return valueTRect The total area of the screen available to the application.Description写的很明显了,我就不翻译了。这个方法可以获得屏幕的整个尺寸,我们把程序可以改为:iAppContainer->ConstructL( ApplicationRect() );从而实现程序的全屏显示。③第三中方法是最笨的方法了,那就是不改变UI所传递的"客户矩形区域"的大小,传递的仍然是ClientRect()。但是到了Container后再采用"亡羊补牢"的做法!把status pane、menu bar等隐藏起来。而且这种方法也容易出错误,下面是一个同行犯的错误,他在Container类里写入下面代码:void CTestScreenContainer::ConstructL(const TRect& aRect){CreateWindowL();iLabel = new (ELeave) CEikLabel;iLabel->SetContainerWindowL( *this );iLabel->SetTextL( _L("Example View") );iToDoLabel = new (ELeave) CEikLabel;iToDoLabel->SetContainerWindowL( *this );iToDoLabel->SetTextL( _L("Add Your controls/n here") );SetRect(aRect);CEikStatusPane* statusp = iEikonEnv->AppUiFactory()->StatusPane();if(statusp)statusp->MakeVisible(EFalse);iEikonEnv->AppUiFactory()->Cba()->MakeVisible(EFalse);ActivateL();}为了使用CEikStatusPane类要加入头文件#include为了使用CEikButtonGroupContainer类要加入头文件#include其中iEikonEnv->AppUiFactory()是在Symbian中获取UI实例常用的方法,这和MFC是一样,你千万不能new一个CTestScreenAppUi出来,因为他们是由框架调用的,我们并不知道何时调用。但是因为他是在Container类里调用这两个方法,也就是说ClientRect()获取"矩形区域"之后程序才设置status pane、Cba为不可见!所以当然也没什么用,程序仍然无法全屏显示。所以说即使你在UI类里写下面的代码,但因为代码是在获取"矩形区域"之后才设置status pane、Cba为不可见,程序仍然无法全屏显示!void CTestScreenAppUi::ConstructL(){BaseConstructL();iAppContainer = new (ELeave) CTestScreenContainer;iAppContainer->SetMopParent( this );iAppContainer->ConstructL( ClientRect() );//在获取"矩形区域"后设置status pane、Cba为不见CEikStatusPane* statusp = StatusPane();if(statusp)statusp->MakeVisible(EFalse);Cba()->MakeVisible(EFalse);AddToStackL( iAppContainer );}所以千万记住:如果要通过设置status pane、Cba为不可见的方法获得全屏,千万要在获取"矩形区域"之前设置!④上面集中方法都是通过在UI类设置"矩形区域"的大小,或者通过设置status pane、Cba不可见隐式改变"矩形区域"的大小实现全屏的。这里我们介绍一种在Container类里,在UI设置完"矩形区域"后再改变屏幕为全屏显示的方法。void CTestScreenContainer::ConstructL(const TRect& aRect){CreateWindowL();iLabel = new (ELeave) CEikLabel;iLabel->SetContainerWindowL( *this );iLabel->SetTextL( _L("Example View") );iToDoLabel = new (ELeave) CEikLabel;iToDoLabel->SetContainerWindowL( *this );iToDoLabel->SetTextL( _L("Add Your controls/n here") );SetRect(aRect);SetExtentToWholeScreen();ActivateL();}但是要千万记得:SetExtentToWholeScreen()一定要在SetRect(aRect)之后调用才有效果。这点很容易理解,因为如果 SetExtentToWholeScreen()改变屏幕为全屏后,再调用SetRect(aRect)又把屏幕尺寸设置为UI里传递的"矩形区域"的大小了。Dialog全屏实现:RESOURCE DIALOG r_dialog_waitingbox0{ flags = EEikDialogFlagWait |EEikDialogFlagFillAppClientRect //client screen |EEikDialogFlagNoShadow |EEikDialogFlagNoBorder |EEikDialogFlagCbaButtons |EEikDialogFlagNotifyEsc //OkToExitL will catch "exit" event |EEikDialogFlagNoDrag; buttons = R_AVKON_SOFTKEYS_CANCEL;}void CUbWaitingBox::PostLayoutDynInitL(){#if 1 //dialog 全屏的实现 // hide cba buttons CEikButtonGroupContainer* cba = CEikButtonGroupContainer::Current(); cba->MakeVisible(EFalse); // hide status pane CEikStatusPaneBase* statusPane = CEikStatusPane::Current(); statusPane->MakeVisible(EFalse); SetExtentToWholeScreen();#endif CAknDialog::PostLayoutDynInitL();}屏幕相关事件:void CAknAppUi::HandleResourceChangeL( TInt aType );void CAknAppUi::HandleScreenDeviceChangedL();void CAknAppUi::HandleForegroundEventL(TBool aForeground);例如捕捉转屏事件:在appui的HandleResourceChangeL处理HandleResourceChangeL( TInt aType ){CAknAppUi::HandleResourceChangeL( aType );if ( aType==KEikDynamicLayoutVariantSwitch ) {//TODO: handle screen switch}}void CUbiLiveGC_SymbianAppUi::HandleForegroundEventL(TBool aForeground){ TAppUiOrientation aOrientation = Orientation(); if(aOrientation==EAppUiOrientationLandscape){ }}void CUbiLiveGC_SymbianAppUi::HandleScreenDeviceChangedL(){ TAppUiOrientation aOrientation = Orientation(); if(aOrientation==EAppUiOrientationLandscape){ }}
原创粉丝点击