优化点:仅当窗口在屏幕上可见时才进行绘制

优化点:仅当窗口在屏幕上可见时才进行绘制有这么一个需求有时候你会想执行这样一个任务:当窗口没有被另一个窗口覆盖时,对这个窗口执行某个动作,例如更新一个状态窗口。举个例子,下面是任务栏是

大家好,欢迎来到IT知识分享网。

有这么一个需求

有时候你会想执行这样一个任务:当窗口没有被另一个窗口覆盖时,对这个窗口执行某个动作,例如更新一个状态窗口。

任务栏如何更新时钟

检测一个窗口是否可见的最简单的方法,就是不对它进行检测。举个例子,下面是任务栏是如何更新它的时钟的:

1. 计算距离下一次分钟更新还需要多长时间。

2. 使用步骤[1]中得到的结果来调用[SetTimer]创建一个定时器。

3. 当计时器超时,它会调用[InvalidateRect]并销毁定时器。

4. [WM_PAINT]消息处理例程会绘制当前时间到任务栏的时钟控件上,然后重返步骤[1]。

如果任务栏的时钟由于任务栏本身被设置为自动隐藏,或者它被其他窗口覆盖了而呈现出不可见的状态时,Windows将不会向窗口发送[WM_PAINT]消息,因此,任务栏时钟将会进入空闲状态同时不会消耗任何CPU时间。根据以上的原理,我们可以对我们的程序应用相同的逻辑。

在下面的代码中,我们的程序将会显示当前时间。同时,它还会将时间显示在窗口的标题栏,因此当窗口被覆盖或者最小化时,我们可以借助于观察任务栏来查看窗口的绘制行为。

代码如下:

优化点:仅当窗口在屏幕上可见时才进行绘制

下面的代码是一个定时器的回调函数,当我们希望更新窗口时,这个回调函数将会被调用。它仅仅是销毁定时器并将窗口绘制区域无效化。当窗口下一次恢复可见时,我们会得到一个[WM_PAINT]消息。(如果当窗口立即变得可见时,我们也会立即得到一个[WM_PAINT]消息)

优化点:仅当窗口在屏幕上可见时才进行绘制

最后,我们在WM_PAINT消息处理例程中添加了一些代码,这样每次当我们绘制了一个非空的矩形时,重启定时器。

下面是WM_PAINT消息处理例程:

优化点:仅当窗口在屏幕上可见时才进行绘制

编译并运行这个程序,我们可以观察到时间会正常的更新。当你最小化窗口或者这个窗口被其他窗口覆盖时,时间更新停止了。当你拖动窗口到屏幕底部直到只有标题栏可见时,我们会观察到窗口时间的更新也会停止。为什么呢?因为WM_PAINT消息处理例程是用来绘制客户区的,在这种情况下,客户区已经不在屏幕上了。

当你切换到其他用户或者锁定计算机时,窗口也会停止更新时间,虽然在这种情况下你会看不到任务栏来验证这个说法。但是,你可以使用计算机的扬声器来进行验证:在[PaintContent]中改为调用[MessageBeep]来发出声音,这样每当时间被重新绘制时,你都会听到一次扬声器的响声。当切换到其他用户或者锁定计算机时,我们不会听到这个声音,也即证明了之前我们的说法。

仅绘制我们希望绘制的区域,而不是全部

这种无效区绘制的手法,同样可以被扩展到屏幕上只有一块区域需要绘制的情景:仅仅绘制你希望绘制的区域,然后仅当这个区域是待绘制区域的一部分的时候才重启定时器,而不是绘制整个客户区。

下面是我们需要作出的代码改动:

优化点:仅当窗口在屏幕上可见时才进行绘制

当定时器到期,我们仅仅更新上面定义的区域,而不是整个客户区(作为一个优化措施,我禁用了背景,后面我会提到我为什么这样做)。

优化点:仅当窗口在屏幕上可见时才进行绘制

为了更加清楚的显示这个目标绘制区域,我们高亮的绘制了这个区域并在里面显示时间。通过使用[ETO_OPAQUE]标志,我们同时绘制了前景和背景。因此,我们不需要再让它为我们擦除背景了。

优化点:仅当窗口在屏幕上可见时才进行绘制

最后,在WM_PAINT消息处理例程中的代码需要检查目标绘制区的可见性,而不是使用整个客户区。

优化点:仅当窗口在屏幕上可见时才进行绘制

运行这个程序的时候,我们可以使用一些方法来覆盖窗口或者禁止高亮区域的绘制。我们可以观察到:一旦窗口被覆盖,标题栏就停止更新了。

总结

就像我上面说过的,这项技术对于大多数应用程序来说已经足够了。但是还有另外一种更加复杂(也更加昂贵)的技术,我将会在下周为大家揭秘。

优化点:仅当窗口在屏幕上可见时才进行绘制

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/46431.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信