游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4994|回复: 9

BeginPaint和GetDC有什么区别?

[复制链接]

42

主题

137

帖子

137

积分

注册会员

Rank: 2

积分
137
发表于 2006-8-31 21:39:00 | 显示全部楼层 |阅读模式
这是个windows编程问题。
第一种情况显示出来的字很正常。
case WM_PAINT:
        gdc = BeginPaint (hwnd, &ps);
        TextOut (gdc, 0, 0, s, strlen (s));
        EndPaint (hwnd, &ps);
break;
第二种情况显示的字不停闪烁。
case WM_PAINT:
        gdc = GetDC (hwnd);
        TextOut (gdc, 0, 0, s, strlen (s));
        ReleaseDC (hwnd, gdc);
break;
请教两种函数的作用?

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
发表于 2006-8-31 21:51:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

后面那个会导致系统不段的发WM_PAINT。 具体自己看API说明去。

4

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2006-9-1 15:44:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

BeginPaint() 和EndPaint() 可以删除消息队列中的WM_PAINT消息,并使无效区域有效。
GetDC()和ReleaseDC()并不删除也不能使无效区域有效,因此当程序跳出 WM_PAINT 时 ,无效区域仍然存在。系统就回不断发送WM_PAINT消息,于是程序不断处理WM_PAINT消息。
      

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
发表于 2006-9-1 17:07:00 | 显示全部楼层

Re: BeginPaint和GetDC有什么区别?

相当于BeginPaint、EndPaint会告诉GDI内部,这个窗口需要重画的地方已经重画了,这样WM_PAINT处理完返回给系统后,系统不会再重发WM_PAINT,而GetDC没有告诉系统这个窗口需要重画的地方已经画过,在你把程序返回给系统后,系统一直以为通知你的重画命令你还没有乖乖的执行或者执行出错,所以在消息空闲时,它还会不断地发WM_PAINT催促你画,导致程序卡死。

42

主题

137

帖子

137

积分

注册会员

Rank: 2

积分
137
 楼主| 发表于 2006-9-4 10:58:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

谢谢。什么是无效区域?

42

主题

137

帖子

137

积分

注册会员

Rank: 2

积分
137
 楼主| 发表于 2006-9-4 11:20:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

我在WM_TIMER中让球移动,但在WM_PAINT消息中用GetDC画球时它就不动了,且一直不停地闪,换成BeginPaint就好了。是不是一个WM_PAINT没被删除它就再一直SendMessage (hwnd,..,WM_PAINT)?为什么会不停的产生WM_PAINT呢?

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
发表于 2006-9-4 20:19:00 | 显示全部楼层

Re: Re:BeginPaint和GetDC有什么区别?

euclid: Re:BeginPaint和GetDC有什么区别?

谢谢。什么是无效区域?


无效区域就是指需要重画的区域,无效的意思是:当前内容是旧的,过时的。
假设A是新弹出的一个对话框或被激活的现有对话框,A对话框置于原来的活动对话框B前面,造成对话框B的部分或全部被覆盖,当对话框A移开或关闭后,使对话框B原来被覆盖的地方重新可见。那部分被覆盖的地方就称为无效区域。
只有当一个窗口消息空闲时,系统才会抽空检查一下这个窗口的无效区域是否为非空(WM_PAINT的优先级是最低的。这也就是为什么系统很忙时窗口和桌面往往会出现变白、刷新不了、留拖拽痕迹等现象的原因),如果非空,系统就发送WM_PAINT。所以一定要用BeginPaint、EndPaint把无效区域设为空,否则WM_PAINT将一直被发送。

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
发表于 2006-9-4 20:28:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

为什么WINDOWS要提出无效区域的概念呢?这是为了加速。
因为BeginPaint和EndPaint用到的设备描述符只会在当前的无效区域内绘画,在有效区域内的绘画会自动被过滤,大家都知道,WIN GDI的绘画速度是比较慢的,所以能节省一个象素就节省一个,不用吝啬,这样可以有效加快绘画速度。
可见BeginPaint、EndPaint是比较“被动”的,只在窗口新建时和被摧残时才重画。
而GetDC用于主动绘制,只要你指到哪,它就打到哪。它不加判断就都画上去,无效区域跟它没关系。对话框没被覆盖没被摧残,它很健康,系统没要求它重画,但开发者有些情况下需要它主动重画:比如一个定时换外观的窗口,这时候就要在WM_TIMER处理代码用GetDC。这时候再用BeginPaint、EndPaint的话,会因为无效区域为空,所有绘画操作都将被过滤掉。

42

主题

137

帖子

137

积分

注册会员

Rank: 2

积分
137
 楼主| 发表于 2006-9-4 22:41:00 | 显示全部楼层

Re:BeginPaint和GetDC有什么区别?

哦,真的是这样啊。今天我把WM_TIMER里的GetDC改成BeginPaint后就画不出来了。但是按你这样说,BeginPaint在无效区域里画图,那WM_PAINT里只写一个BeginPaint()和EndPaint()好了?

96

主题

529

帖子

539

积分

高级会员

Rank: 4

积分
539
发表于 2006-9-5 10:42:00 | 显示全部楼层

Re: Re:BeginPaint和GetDC有什么区别?

euclid: Re:BeginPaint和GetDC有什么区别?

哦,真的是这样啊。今天我把WM_TIMER里的GetDC改成BeginPaint后就画不出来了。但是按你这样说,BeginPaint在...


BeginPaint和EndPaint一般只用于WM_PAINT消息处理。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 07:21

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表