设为首页 加入收藏

TOP

17.5.4 绘制的更多知识(3)
2013-10-07 01:05:40 来源: 作者: 【 】 浏览:73
Tags:17.5.4 绘制 更多 知识

(5)重绘

现在用户应该发现,理解重绘是如何工作是相当容易的。当窗口服务器得知某一窗口的某一区域无效时,它向拥有窗口的应用程序发送一条重绘的消息,并指定无效区域的限制矩形。该消息由CONE获得,并使用如下代码进行处理。

  

这段代码与我们在 DrawOneTileNow()中所看到的非常相似:需要配套使用 ActivateGC()和BeginRedraw()来正确设置一切。然而,这里CONE不必要调用Invalidate(),因为重绘的全部要点是已经知道某一区域是无效的。事实上,如果CONE真的在矩形上调用了Invalidate(),它可能会扩展无效区域,这将浪费处理时间。

CONE 使用 Draw()来绘制控件,该函数接收限制矩形作为参数。然后,CONE 使用DrawComponents()来绘制这一控件拥有的每个组件。

   

   

CONE 只是重绘与无效矩形相交的每个可见的寄宿组件,然后依次是可见寄宿组件的组件。CONE为每一组件控件适当调整无效区域限制矩形。

CONE也考虑到少见的特殊情形,即有可能在它们自己的矩形之外绘制的控件。 确保使用这里的默认设置:对 ActivateGc()的最初调用为首先绘制的拥有窗口控件进行默认设置;然后,调用ResetGc(),确保组件也是用默认设置绘制。

以上循环不需要绘制接收最初重绘请求的拥有窗口控件的拥有窗口组件。这是因为窗口服务器在任何情况下都会及时地向这样的控件发送一条重绘消息(事实上,如同它以从前到后的 z 次序在一个特殊客户端的所有窗口上发送重绘事件一样,它通常首先发送重绘消息)。

在这里能再次看到寄宿组件是如何提高系统效率的。对于每一个寄宿组件(而不是拥有窗口控件),避免客户端-服务器消息以及“激活”与“开始重绘”调用。所有我们需要的只是一个ResetGc(),它占据窗口服务器客户端缓冲的单个字节。

(6)对无闪烁绘图的支持 作为一个应用程序开发人员,应该注意窗口服务器促进无闪烁绘制的两个方面。

首先,窗口服务器将绘制剪裁到无效区域和传给 BeginRedraw()矩形的相交部分,因为如果绘制代码容易引起闪烁,这种影响将被限制在必须重绘的区域。可以在某些场合利用这一点。假想要实现一个光标移动函数,但不想改变 COandXAppView和 COandXTile的绘制函数。可以编写一个 DrawTwoTilesNow()函数,它接受要绘制的两个方块的(x,y)坐标,让我们只对那两个矩形进行计算,并让它们无效。然后,可以通过调用 COandXAppView 的 DrawNow()在整个棋盘区域激活图形上下文和 BeginRedraw()。窗口服务器将对受影响的两个方块剪裁绘制活动,消除任何其他地方的闪烁。这是一个不甚高明的无闪烁解决办法,但在某些场合,却能起到很重要的作用。

其次,窗口服务器客户端缓冲提供有用的无闪烁支持。首先,它提高整个系统的效率,因而所有任务执行得更快,闪烁也因此减少。同时,它使绘制命令可以批处理,由窗口服务器使用BITGDI 和常量剪裁区域迅速地执行。在实践中,这意味着绘制命令的某些序列执行得相当快,以至于即使程序代码本质上是闪烁的,也没有人会看出问题,特别是在高持续性的LCD显示器上。这里的关键之处在于,把导致闪烁的序列限制为几个连续的绘制命令,这样它们将作为窗口服务器缓冲的一个部分全部被执行。

最后,也是最明显的,寄宿控件的使用在这里也有帮助作用,因为它意味着在控件之间窗口服务器缓冲只包含一个简单的ResetGc()命令,而不是为一个控件重绘和释放图形上下文,它后面紧跟着激活图形上下文和重绘下一个控件的操作。

【责任编辑:董书 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇18.3.1 程序员需求 下一篇17.5.4 绘制的更多知识(2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: