设备上下文(DC)画刷的妙用

设备上下文(DC)画刷的妙用

作者:BlogUpdater |  时间:2022-09-07 |  浏览:167 |  评论已关闭 条评论

当我们调用GetStockObject(DC_BRUSH),所返回的是一个与设备上下文(Device Context,简称DC)相关联的DC画刷。它和系统颜色画刷有点类似,DC画刷的颜色会动态修改。但它们俩有个区别:系统颜色画刷的颜色会根据系统的颜色动态修改,而DC画刷的颜色是根据你下发的指令来修改。

当你在很短的时间内需要一个纯色颜色画刷的时候,DC画刷是比较方便的,因为它总是存在于系统中,所以你无须自己创建或销毁它。一般情况是,你需要手动创建一个颜色画刷,然后使用它来在DC上绘制,然后销毁。有了DC画刷,你可以直接设置它的颜色,然后开始绘制。但它的有效期比较短,如果有其他人在你的DC上调用SetDCBrushColor的话,则DC画刷的颜色就会被覆盖。实际上,这意味着一旦你将控制权交给其他代码,DC画刷的颜色就可能会发生改变了。(但是请注意,每个 DC 都有自己的DC画刷颜色,因此你只需要担心另一个线程上的某个人会同时修改你的DC,这在我熟悉的任何绘画模型下都不会发生。)

DC画刷在处理WM_CTLCOLOR消息的时候特别好用。处理这个消息的时候,你需要返回一个画刷以绘制控件的背景色。如果你需要一个纯色的颜色画刷,这通常意味着你需要创建一个纯色颜色画刷,然后缓存它到相关联的窗口以保证它的生命周期,然后当窗口销毁时还需要记得销毁它。(有些人会将这个画刷保存为一个静态变量,这通常没有什么大问题,但是一旦创建某个窗口或对话框的两个实例的时候,事情就开始变得糟糕了)

举个例子
现在,让我们使用一个例子来讲解如何自定义一个静态标签控件的颜色。
这个例子对于开发者的你,可能不是那么有意思,它只是演示了如何使用DC画刷的一种用法。
下图中的代码基于我们一直以来使用的例子程序,只是做了一些小的改动:

执行上面的代码,你会看到我们将标签控件的背景色修改成了红色。

这项工作发生在 OnCtlColor 函数内部。 当需要自定义控件颜色时,我们首先将消息转发到 DefWindowProc 函数,以便设置默认的前景和背景文本颜色。(这里不相关,因为我们没有画文字,但原则上是一件好事。)
由于我们想要覆盖背景画刷颜色,我们将DC画笔颜色设置为红色,然后将DC画刷返回。

然后,标签控件使用我们返回的DC画刷并使用它来绘制背景,它会使用红色绘制,因为这是我们设置的颜色。

通常,在自定义背景画笔时,我们必须手动创建一个画刷,然后从WM_CTLCOLORSTATIC消息中返回,然后在父窗口销毁时将其销毁。 但是通过使用DC画刷,我们避免了这些繁琐的工作。

还有一个DC画笔GetStockObject(DC_PEN),其行为方式和DC画刷完全类似,有机会你可以试试。

总结
我一直会对TopomelBox的GDI资源占用比较关注:不能有太多GDI对象绑在进程上。
有了今天的知识点,我倒是可以试一试。如作者所言,它确实比较方便。
果然老祖宗不忽悠我:温故而知新。原来我需要的东西,一直在那,只是它静静地在等待我去发现。

最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《What is the DC brush good for?》

最近我写了个东西
正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。

评论已关闭。