在<MFC Windows程序设计总结(三)—— 实现透明窗口>和<MFC Windows程序设计总结(四)—— 实现透明窗口【续】>两篇笔记中,分别学习了使用SetLayeredWindowAttributes和UpdateLayeredWindow两种方法来实现透明窗口。本篇笔记对这两个函数的使用进行一下比较。
添加WS_EX_LAYERED属性之后,窗口不会收到WM_PAINT消息了(除非显示调用InvalidateRect之类的函数)。如果调用SetLayeredWindowAttributes函数来实现透明窗口,那窗口又可以收到WM_PAINT和WM_ERASEBKGND这些普通消息了。我们的代码还是像以前一样,在WM_PAINT或WM_ERASEBKGND消息响应函数中画背景就可以了。
使用SetLayeredWindowAttributes函数的优缺点:
(1)使用起来简单直观,通常在OnInitDialog()里面调用SetLayeredWindowAttributes即可。
(2)对于复杂窗口不能对每个像素设置透明度(It does not allow to set per pixel transparency for complex windows)。
(3)绘制窗口的性能相对较低。
与SetLayeredWindowAttributes相比,UpdateLayeredWindow的性能相对较好并且功能更强。
This function does anything you want for a layered window.You can change position, size, look and transparency all in one function call. Also it can use per pixel Alpha information stored in a bitmap to maintain pixel level
transparency.
Note: 二者不要同时使用,如果先调用了SetLayeredWindowAttributes,再调用UpdateLayeredWindow就会出错(errors 0×06)。
如果是使用UpdateLayeredWindow函数来实现透明,那窗口就不会收到WM_PAINT消息了,此时窗口的外观由UpdateLayeredWindow来维护,系统会自动完成窗口的重绘(repaint)工作。
如果是在OnInitDialog()里面给窗口添加WS_EX_LAYERED属性,由于没有WM_PAINT消息,那可以设置一个Timer,在Timer message handler中调用UpdateLayeredWindow来更新分层窗口。如果习惯于在WM_PAINT消息处理函数中画背景,那就不要在OnInitDialog()里面给窗口添加WS_EX_LAYERED属性,而是在WM_PAINT消息处理里面来添加WS_EX_LAYERED属性。
参考资料: