snow(圣诞节的礼物)这个程序的思路是什么?

wonaixiaogang 2009-03-17 09:49:09
这个程序的下载地址在这里
http://www.xdowns.com/soft/6/15/2007/Soft_39601.html
原来是一个外国人写的,现在貌似有不少中国版的了。

我也想写一下,但是我想了很久没想出来思路。
我的思路是2个:
1:直接在桌面DC上画雪,雪花由3个白点形成,程序即时画出来。但是,雪花是飘动的,所以要每隔100ms擦除一次,而难点就在于这里。A:不能用InvalidateRect(NULL,NULL,false),就算给第二个参数一个很小的RECT也不行,桌面依然会严重闪烁。B:也不能用:先取一张先前的桌面DC预先保存,然后把这个DC覆盖上当前DC,因为用户时刻都可能切换桌面。C:每画一次雪花,就记录雪花所在点的颜色值,然后在下一次画雪花时把颜色值恢复。这个方法也不行,因为,一个是消耗CPU资源太厉害,另外一旦用户切换桌面,原来雪花所在的颜色值就改变了,不能用了。

2.在桌面之上做一个完全透明的全屏窗体,在这个窗体上画飘动的雪花,这个窗体是鼠标穿透的。但是这个方法问题肯定存在。如何做到此窗体上的雪花不透明,而其他统统透明?会不会这个顶层窗体与其他程序冲突?等等。

啊,真的是没有思路,希望高手帮助。
...全文
116 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wonaixiaogang 2009-03-19
  • 打赏
  • 举报
回复
今天偶然看到了一个VB源码,发现他用的就是我的方法1.的C方法。
这个程序的确没有考虑:用户切换桌面,原来雪花所在的颜色值改变的情况。不过问题不大。
只怪我当时没仔细观察,我还以为那些彩色的斑点是彩色的雪花呢。。。。囧。
至于CPU消耗的问题,看来是我的程序有点毛病。
好了,结贴.
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 allenhiman 的回复:]
动画,最基本的方案是双缓冲。复杂一点也可以是一个多缓冲的缓冲链。意思是提前把下一桢要显示的图形先绘制在后台缓冲里,然后翻转到前台缓冲,前台缓冲变后台,如果是一个链,那逻辑就更复杂些,这种方案可有效抗闪烁。
[/Quote]
推荐
yc_8301 2009-03-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 oyljerry 的回复:]
先把图画到内存中,双缓冲,然后一次bitblt等贴到窗口...防止闪烁等
[/Quote]
顶一下,,,
oyljerry 2009-03-18
  • 打赏
  • 举报
回复
先把图画到内存中,双缓冲,然后一次bitblt等贴到窗口...防止闪烁等
allenhiman 2009-03-18
  • 打赏
  • 举报
回复
动画,最基本的方案是双缓冲。复杂一点也可以是一个多缓冲的缓冲链。意思是提前把下一桢要显示的图形先绘制在后台缓冲里,然后翻转到前台缓冲,前台缓冲变后台,如果是一个链,那逻辑就更复杂些,这种方案可有效抗闪烁。
fandh 2009-03-18
  • 打赏
  • 举报
回复
用双缓冲,先记录背景,然后在背景上画图,最后,将图贴出来!
背景不要轻易改动即可!
M_S_D_N 2009-03-18
  • 打赏
  • 举报
回复
大家去看下楼主提供的那个exe,根本用不着什么双缓冲,是直接获取屏幕DC,直接画上去的,一刷新就没了。。。
allenhiman 2009-03-18
  • 打赏
  • 举报
回复
dx中为了抗闪烁就是用的缓冲链的概念。dx中这是一个很简单的sprite animate程序,大家只是把这种理念告诉你。我记得学d3d时,第一个动画就是搞的 很多鱼在桌面上游泳的例子
fandh 2009-03-18
  • 打赏
  • 举报
回复
http://blog.chinaunix.net/u2/68418/showart_679467.html
http://www.techrss.cn/html/2008/09-27/115936.htm
fandh 2009-03-18
  • 打赏
  • 举报
回复
这种回答问题的人,很敬业,学习一下!
wonaixiaogang 2009-03-18
  • 打赏
  • 举报
回复
也是怨我自己没有说清楚。
你们觉得方法1可行么?
wonaixiaogang 2009-03-18
  • 打赏
  • 举报
回复
你们回答的都是些什么呢?双缓冲?我晕,看清楚我问题的实质好不好?你倒是跟我说说缓冲啥子东西?
我本来就是在内存DC画雪花,然后再贴上桌面DC。
我在别处问了下,这是别人的答案:


☆ 方法一:
初始化。。。。。
1、首先构建一个位图,大小和桌面一样(hBmpDesktop)。
2、使用钩子截获桌面窗口的WM_PAINT消息。

新的WM_PAINT消息。。。。。。
3、调用桌面原来的WM_PAINT,但是将它画到一个位图(hBmpDesktop)里面,而不是画到桌面上。
4、在这个位图上再画上雪花。
5、将这个位图Bitblt到桌面DC上。(复制位图)

这样,由于每次都是桌面窗口自己先画上去“背景”,所以,无论用户怎么操作桌面,雪花的背景始终是应该的桌面。


☆方法二:
1、制作一个透明的窗口,透明度为完全透明,具有总在最前风格。并且定义颜色的掩码(ColorKey)为非雪花的颜色。使得雪花可以画上去而其他颜色透明。
3、相应WM_PAINT消息,先把窗口画上背景(不要用和雪花一样的颜色)。然后画上雪花。
2、相应这个透明窗口的WM_KEYDOWN、WM_MOUSEMOVE等用户操作的消息,并且将这些消息转发到相应该消息的位置的下面那个窗口。

我个人认为方法一比较好,因为方法2你必须使雪花具有某种特定的颜色范围。而且方法2要解决的问题也比较多。因为,如果用户打开了一个程序,比方说“我的电脑”,用户要操作“我的电脑”窗口,那么你的雪花程序必须将消息转发到“我的电脑”而不是桌面。可以通过EnumWindow来枚举窗口,然后根据消息发生时的位置来判断是否位于所枚举的窗口内,如果是就转发到该窗口,如果不是就枚举下一个窗口,如果一直没有枚举到,就发送到桌面。但这样效率不是很高。

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧