beginpaint和getdc的区别

上传人:第*** 文档编号:31321671 上传时间:2018-02-06 格式:DOCX 页数:6 大小:24.58KB
返回 下载 相关 举报
beginpaint和getdc的区别_第1页
第1页 / 共6页
beginpaint和getdc的区别_第2页
第2页 / 共6页
beginpaint和getdc的区别_第3页
第3页 / 共6页
beginpaint和getdc的区别_第4页
第4页 / 共6页
beginpaint和getdc的区别_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《beginpaint和getdc的区别》由会员分享,可在线阅读,更多相关《beginpaint和getdc的区别(6页珍藏版)》请在金锄头文库上搜索。

1、2009-04-22 16:30这是个 windows 编程问题。BeginPaint 和 GetDC 的区别 【转第一种情况显示出来的字很正常。*case WM_PAINT:gdc = BeginPaint (hwnd, TextOut (gdc, 0, 0, s, strlen (s);EndPaint (hwnd, break;*第二种情况显示的字不停闪烁。*case WM_PAINT:gdc = GetDC (hwnd);TextOut (gdc, 0, 0, s, strlen (s);ReleaseDC (hwnd, gdc);break;*请教两种函数的作用?BeginPaint

2、() 和 EndPaint() 可以删除消息队列中的 WM_PAINT 消息,并使无效区域有效。GetDC()和 ReleaseDC()并不删除也不能使无效区域有效,因此当程序跳出 WM_PAINT 时 ,无效区域仍然存在。系统就回不断发送 WM_PAINT 消息,于是程序不断处理 WM_PAINT 消息。相当于 BeginPaint、EndPaint 会告诉 GDI 内部,这个窗口需要重画的地方已经重画了,这样 WM_PAINT 处理完返回给系统后,系统不会再重发 WM_PAINT,而 GetDC 没有告诉系统这个窗口需要重画的地方已经画过,在你把程序返回给系统后,系统一直以为通知你的重画命

3、令你还没有乖乖的执行或者执行出错,所以在消息空闲时,它还会不断地发 WM_PAINT 催促你画,导致程序卡死。【无效区域】 : 无效区域就是指需要重画的区域,无效的意思是:当前内容是旧的,过时的。假设 A 是新弹出的一个对话框或被激活的现有对话框,A 对话框置于原来的活动对话框 B 前面,造成对话框 B 的部分或全部被覆盖,当对话框 A 移开或关闭后,使对话框 B 原来被覆盖的地方重新可见。那部分被覆盖的地方就称为无效区域。只有当一个窗口消息空闲时,系统才会抽空检查一下这个窗口的无效区域是否为非空(WM_PAINT 的优先级是最低的。这也就是为什么系统很忙时窗口和桌面往往会出现变白、刷新不了、

4、留拖拽痕迹等现象的原因),如果非空,系统就发送 WM_PAINT。所以一定要用 BeginPaint、EndPaint 把无效区域设为空,否则 WM_PAINT 将一直被发送。为什么 WINDOWS 要提出无效区域的概念?这是为了加速。因为 BeginPaint 和 EndPaint 用到的设备描述符只会在当前的无效区域内绘画,在有效区域内的绘画会自动被过滤,大家都知道,WIN GDI 的绘画速度是比较慢的,所以能节省一个象素就节省一个,不用吝啬,这样可以有效加快绘画速度。可见 BeginPaint、EndPaint 是比较“被动”的,只在窗口新建时和被摧残时才重画。而 GetDC 用于主动绘

5、制,只要你指到哪,它就打到哪。它不加判断就都画上去,无效区域跟它没关系。对话框没被覆盖没被摧残,它很健康,系统没要求它重画,但开发者有些情况下需要它主动重画:比如一个定时换外观的窗口,这时候就要在 WM_TIMER 处理代码用 GetDC。这时候再用 BeginPaint、EndPaint的话,会因为无效区域为空,所有绘画操作都将被过滤掉。*eg:1. PAINTSTRUCT ps;2. HDC hdc = Beginpaint(hwnd, 3. HDC hdcMem = CreateCompatibleDC(hdc); /Create a DC that matches the device

6、4. HANDLE hBmp = LoadImage(g_hInst_MainWnd, MAKEINTRESOURCE(IDB_MAINWND),5. IMAGE_BITMAP, 0, 0, 0);6. HGDIOBJ hOldSel = SelectObject(hdcMem, hBmp); /Select the bitmap into to the compatible 7. /device context8. BITMAP bmp; /Get the bitmap dimensions from the bitmap9. GetObject(hBmp, sizeof(BIMAP), 1

7、0. RECT rc; /Get the window area11. GetClientRect(hwnd, 12. /Copy the bitmap image from the memory DC to the screen DC13. BitBlt(hdc, rc.left, rc.top, bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);14. SelectObject(hdcMem, hOldSel); /Restore original bitmap selection and destroy 15. /the memory D

8、C16. DeleteDC(hdcMem);17. EndPaint(hWnd, 18. return 0;下面是更加详细的介绍/=/TITLE:/ EVC 绘制位图-BeginPaint() 与 GetDC()的区别/AUTHOR:/ norains/DATE:/ Tuesday 29-August-2006/=1.BeginPaint()和 GetDC()在 EVC 中绘制位图比较方便,有不少现成的函数可供调用,我们所要注意的只是 BeginPaint()或 GetDC()的使用即可.因为代码比较简单,所以不做更多解释.这是消息循环函数:LRESULT CALLBACK MainWndPr

9、oc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam).switch(wMsg)case WM_PAINT:OnPaintMainWnd(hWnd,wMsg,wParam,lParam);break;. return DefWindowProc(hWnd,wMsg,wParam,lParam);.响应 WM_PAINT 消息的函数,在这里进行位图的绘制:LRESULT OnPaintMainWnd(HWND hWnd,UINT wMsg,WPARAM wParam,LPARAM lParam)PAINTSTRUCT ps;HDC hdc =

10、 BeginPaint(hWnd,HDC hdcMem = CreateCompatibleDC(hdc);/Create a DC that matches the device HANDLE hBmp= LoadImage(g_hInst_MainWnd,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0); /Load the bitmap/Select the bitmap into to the compatible device contextHGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);BITM

11、AP bmp; /Get the bitmap dimensions from the bitmapGetObject(hBmp,sizeof(BITMAP),RECT rc; /Get the window areaGetClientRect(hWnd,/Copy the bitmap image from the memory DC to the screen DCBitBlt(hdc,rc.left,rc.top,bmp.bmWidth,bmp.bmHeight,hdcMem,0,0,SRCCOPY);SelectObject(hdcMem,hOldSel);/Restore origi

12、nal bitmap selection and destroy the memory/DC DeleteDC(hdcMem);EndPaint(hWnd,return 0;我们都知道 BeginPaint()和 EndPaint()需要配套使用 ,并且这两个函数也只能用在 WM_PAINT 消息的相应函数当中.如果我们在 WM_PAINT 的响应函数中将以上两个绘制函数相应替换为 GetDC()和 ReleaseDC()会有什么结果呢?即:HDC hdc = BeginPaint(hWnd, EndPaint(hWnd, 编译并运行程序,我们发现窗口一片空白,好像没有绘制位图.但其实不尽然,

13、我们采用单步调试,可以发现其实位图已经绘制出来,只不过又被背景颜色抹掉了. 由此可知,如果需要使用 GetDC(),我们对消息循环函数必须要加上对WM_ERASEBKGND 的处理:LRESULT CALLBACK MainWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)switch(wMsg)case WM_PAINT:OnPaintMainWnd(hWnd, wMsg, wParam, lParam);break;case WM_ERASEBKGND : return 0; . return DefWindowProc(hWnd, wMsg, wParam, lParam);只要系统不对 WM_ERASEBKGND 进行默认处理,我们用 GetDC()替代BeginPaint()就可以正常使用.至此我们可以看出 BeginPaint(),EndPaint()和 GetDC(),ReleaseDC()的区别.前一对只能用在 WM_PAINT 响应函数中,并且绘制背景时不会被抹掉; 后一对随处可用,但如果用在 WM_PAINT 响应函数中,那么接下来将会被WM_ERASEBKGND 消息的响应函数的背景绘制给抹掉.2.绘图闪烁问题

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 工程造价

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号