|
应用程序在屏幕上的描画一般是使用CWsScreenDevice图形设备来完成,与CWindowGc图形上下文相关联。CONE提供了一个CWindowGc实例作为描画控件的标准图形上下文。它被CCoeEnv创建并且可以使用CCoeControls::SystemGc方法访问。CWindowGc的描画方法在客户端窗口服务器缓冲区上进行缓冲。
描画要么是一个系统初始事务要么是一个应用程序初始事务。系统初始描画在窗口创建的时候被触发,或者当窗口内容因为窗口重叠而失效的时候被触发。对于后一种情况,窗口服务器为每个窗口保持一个无效的区域。如果一个窗口需要重画,窗口服务器发送一个重画事件到拥有无效窗口的应用程序中。CONE然后使用无效区域来建立需要被重画的控件,并且调用它们的Draw方法。这就是为什么每个控件都应该实现Draw方法来重画它们自己。CCoeControl中的Draw的默认为控件为空。下面的代码说明了Draw方法的示例:
void CExampleControl::Draw( const TRect& /*aRect*/ ) const { // Get the system graphics context CWindowGc& gc = SystemGc(); // Set drawing settings gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); gc.SetBrushColor( KRgbRed ); // Draw gc.DrawLine( TPoint(10,10), TPoint(30,10) ); }
Draw方法的TRect参数指明了需要重画的无效区域。然而大多数控件忽略矩形,由于它非常简单并且重新描画整个控件也不是非常慢。
当一个应用程序的数据或者状态改变的时候,需要应用程序初始化描画,并且屏幕需要更新。CCoeControl提供非虚拟DrawNow方法,指明控件将要描画的窗口服务器,调用控件的Draw方法,最后指明完成描画的窗口服务器。CCoeControl还提供了DrawDeferred方法,使窗口无效并且在窗口服务器中触发一个新的重画事件。这两个方法之间的差异是DrawNow强制控件立即重画自己,而DrawDeferred导致一个重画事件将使用低优先级操作。由于CONE使用比重画事件更优先的级别处理用户输入事件,所以任何未定的用户输入事件都将首先处理。但由于需要重画整个控件,故都是很繁重的操作,通常只有改变的部分需要重画,这可以使用下面的代码做到:
void CExampleControl::DrawBitmap( const TPoint& aPoint, const CFbsBitmap* aBitmap ) { // Get the system graphics context and control rectangle CWindowGc& gc = SystemGc(); // Establish drawing rectangle TRect rect = TRect( aPoint, TSize( aBitmap.iWidth, aBitmap.iHeight ) ); // Activate graphics context ActivateGc(); // Invalidate window Window().Invalidate( rect ); Window().BeginRedraw( rect ); // Draw a bitmap gc.DrawBitmap( aPoint, aBitmap ); Window().EndRedraw(); // Deactivate graphics context DeactivateGc(); }
上面的示例代码在aPoint参数定义的位置画一个CFbsBitmap。示例中值得注意的是图形上下文在使用之前需要激活,在描画完成之后失活。还有窗口服务器需要取得客户端即将启动重画的信息,这使用BeginRedraw方法来完成。由于窗口服务器只允许一个应用程序在无效区域中描画,所以需要Invalidate方法。在一个系统初始重画中,CONE激活图形上下文并且调用用于应用程序的BeginRedraw方法。如果窗口已经无效了,那么Invalidate方法就不必被调用了--这就是为什么系统初始需要被首先描画。
上一篇:Win9x/ME下Apache+PHP安装配置
下一篇:Cookie的传递流程及安全问题
|