如何在桌面上透明的绘画(大神作品)
以前在写过一个截图小工具<<共享个人写的一个截屏小工具>>, 它的主要原理是保存一幅桌面截图,再把截图画的一个全屏的窗口上, 然后我们在该全屏窗口上进行标注和绘画, 这样从效果上看起来就像我们是直接在桌面上进行截屏和绘画一样了。这种方式实际上也是QQ截屏的方式。
但是不知道你有没有发现,这种方式的截屏也有一个比较致命的缺点:就是一旦进入截屏模式,我们就不能再操作桌面窗口了,有些时候我们可能在做了些标注之后想切换下窗口,做些其他事情,但是这种方式下显然是做不到的, 因为它上面盖了一个顶层全屏窗口。
最近研究了下这方面的东西,发现其实可以通过一个Layered窗口来实现这块效果, 简单说下原理:
1. 启动截屏时建立一个全屏的layered窗口,该窗口通过UpdateLayeredWindow渲染, 所以像素的alpha通道为1, 这样看起来就透明了, 但是鼠标点击时又不会穿透
2. 响应鼠标消息, 在上面画内容(比如矩形,线条等)
这里关键是步骤2,因为GDI对Alpha通道的支持不友好,具体参见<<如何基于纯GDI实现alpha通道的矢量和文字绘制>>, 所以我们一般会引入GDI+或是Direct2D。关于如果用GDI+或是Direct2D实现Layered窗口,这里有篇不错的文章<<Layered Windows with Direct2D>>。
这样我们就实现了在桌面上透明的绘画内容, 这时你可以通过alt+tab切换活动窗口, 可以看到标注的内容依然在上面,因为我们的窗口是Alpha通道为1的透明窗口。另外,我们可以在需要的时候给窗口增加一个WS_EX_TRANSPARENT的属性,这样我们可以实现鼠标穿透, 并且让绘画的内容一直保持在上面。
另外,Win8之后我们可以借助Windows Composition实现更高效的透明窗口,具体参见<<High-Performance Window Layering Using the Windows Composition Engine>>
简单的测试代码:NewAnnotTest.rar
http://www.cppblog.com/weiym/archive/2014/09/22/208379.html