EVC绘制位图--BeginPaint()与GetDC()的区别
来源:互联网 发布:中国和美国的差距知乎 编辑:程序博客网 时间:2024/05/02 04:40
//========================================================================
//TITLE:
// EVC绘制位图--BeginPaint()与GetDC()的区别
//AUTHOR:
// norains
//DATE:
// Tuesday 29-August-2006
//========================================================================
1.BeginPaint()和GetDC()
在EVC中绘制位图比较方便,有不少现成的函数可供调用,我们所要注意的只是BeginPaint()或GetDC()的使用即可.
因为代码比较简单,所以不做更多解释.
这是消息循环函数:
LRESULT CALLBACK MainWndProc(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 = BeginPaint(hWnd,&ps);
//Create a DC that matches the device
HDC hdcMem = CreateCompatibleDC(hdc);
//Load the bitmap
HANDLE hBmp= LoadImage(g_hInst_MainWnd,MAKEINTRESOURCE(IDB_MAINWND),IMAGE_BITMAP,0,0,0);
//Select the bitmap into to the compatible device context
HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
//Get the bitmap dimensions from the bitmap
BITMAP bmp;
GetObject(hBmp,sizeof(BITMAP),&bmp);
//Get the window area
RECT rc;
GetClientRect(hWnd,&rc);
//Copy the bitmap image from the memory DC to the screen DC
BitBlt(hdc,rc.left,rc.top,bmp.bmWidth,bmp.bmHeight,hdcMem,0,0,SRCCOPY);
//Restore original bitmap selection and destroy the memory DC
SelectObject(hdcMem,hOldSel);
DeleteDC(hdcMem);
EndPaint(hWnd,&ps);
return 0;
}
我们都知道BeginPaint()和EndPaint()需要配套使用,并且这两个函数也只能用在WM_PAINT消息的相应函数当中.如果我们在WM_PAINT的响应函数中将以上两个绘制函数相应替换为GetDC()和ReleaseDC()会有什么结果呢?
即:
HDC hdc = BeginPaint(hWnd,&ps); --> HDC hdc = GetDC(hWnd);
EndPaint(hWnd,&ps); --> ReleaseDC(hWnd,hdc);
编译并运行程序,我们发现窗口一片空白,好像没有绘制位图.但其实不尽然,我们采用单步调试,可以发现其实位图已经绘制出来,只不过又被背景颜色抹掉了.由此可知,如果需要使用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.绘图闪烁问题
有时候我们大量绘制屏幕时,可能会出现屏幕闪烁问题,这时候可以采用双缓冲的做法.步骤首先是创建一个内存DC,然后往内存DC中绘图,最后把内存DC的内容复制到显示DC中,完成绘制.具体过程并不复杂,结合代码来说明一下.
PS:这段代码也是相应WM_PAINT 消息的.
PAINTSTRUCT ps;
HDC hdc;
//获取屏幕显示DC
hdc = BeginPaint (hWnd, &ps);
//创建内存DC
HDC hdcMem = CreateCompatibleDC(hdc);
//创建一个bmp内存空间
HBITMAP hBmp = CreateCompatibleBitmap(hdc,SCREEN_WIDTH,SCREEN_HEIGHT);
//将bmp内存空间分配给内存DC
HGDIOBJ hOldSel = SelectObject(hdcMem,hBmp);
//这是使用者需要绘制的画面,全部往内存DC绘制
Rectangle(hdcMem,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
DrawMenuButton(hdcMem);
//将内存DC的内容复制到屏幕显示DC中,完成显示
BitBlt(hdc,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,hdcMem,0,0,SRCCOPY);
//清除资源
SelectObject(hdcMem,hOldSel);
DeleteDC(hdcMem);
EndPaint(hWnd,&ps);
- EVC绘制位图--BeginPaint()与GetDC()的区别
- VC绘制位图--BeginPaint()与GetDC()的区别
- 转VC绘制位图--BeginPaint()与GetDC()的区别
- 转VC绘制位图--BeginPaint()与GetDC()的区别
- VC绘制位图--BeginPaint()与GetDC()的区别
- VC绘制位图--BeginPaint()与GetDC()的区别
- VC绘制位图--BeginPaint()与GetDC()的区别
- VC绘制位图--BeginPaint()与GetDC()的区别和双缓冲
- BeginPaint()与GetDC()的区别
- BeginPaint与GetDC的区别
- BeginPaint EndPaint 与GetDC ReleaseDC的区别
- Win32之BeginPaint与GetDC的区别
- BeginPaint EndPaint 与GetDC ReleaseDC的区别
- BeginPaint 和 GetDC 的区别
- BeginPaint和GetDC的区别
- BeginPaint和GetDC的区别
- BeginPaint和GetDC的区别
- BeginPaint和GetDC的区别
- 开始新版梭织CAD底层数据COM组件的封装(2007-03-15)
- 关闭浏览器
- JSON -- 轻量级的数据交换语言
- cURL/libcURL HTTP Location:重新定向绕过安全限制漏洞
- 撰写高效率的.NET程序
- EVC绘制位图--BeginPaint()与GetDC()的区别
- 中途插入其它工作(2007-03-26)
- ArcObject API 开发(一)
- 转:MOSS 2007 Filter webparts ,建立筛选Document Library 的Web Part
- N76 UCWEB 6.7免费下载
- SQL CE 3.5 部署打包的问题
- 筛选法求100以内的素数
- Java:内部非静态类访问外部类成员的方法
- arguments属性