`
dato0123
  • 浏览: 910775 次
文章分类
社区版块
存档分类
最新评论

VC绘制位图--BeginPaint()与GetDC()的区别

 
阅读更多
//========================================================================
//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);
分享到:
评论

相关推荐

    BeginPaint和GetDC的用法

    BeginPaint和GetDC的用法区别

    用VC++绘制等边三角形的实例方法

    用VC++绘制等边三角形的实例方法 switch(message) { case WM_PAINT: hdc=::BeginPaint(hwnd,&ps); hP=(HPEN)CreatePen(PS_DASH,3,RGB(0,255,0)); hB=(HBRUSH)CreateHatchBrush(HS_CROSS,RGB(255,0,0));...

    易语言GDI绘制进度条

    易语言GDI绘制进度条源码,GDI绘制进度条,进度条,InvalidateRect,ValidateRect,BeginPaint,SaveDC,RestoreDC

    vc数据可视化编程

    该代码是基于vc的数据可视化功能 #include #include LRESULT CALLBACK WangProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE ...

    易语言api绘制文本

    易语言api绘制文本源码,api绘制文本,窗口主程序,窗口回调函数,GetModuleHandle,GetCommandLine,LoadIcon,LoadCursor,RegisterClassEx,CreateWindowEx,ShowWindow,UpdateWindow,BeginPaint,GetClientRect,DrawText,...

    Windows API一日一练TXT版

    Windows API 一日一练(16)BeginPaint 和 EndPaint 函数 -------------------------------34 Windows API 一日一练(17)DialogBox 和 DialogBoxParam 函数------------------36 Windows API 一日一练(18)EndDialog ...

    vc中实现GDI+双缓冲的DBGraphics类

    vc中实现GDI+双缓冲的DBGraphics类 封装好了的GDI+双缓冲类,省去了自己创建位图、释放资源的麻烦,极大地简化了代码。 使用: Gdiplus::DBGraphics g( hWnd ); g.BeginPaint(); //你的绘图代码 g.EndPaint(); ...

    Windows-SDK.zip_TextOut_WIN32 TextOut_XXXXXXXX.

    1、学会使用VC6.0建立一个Win32 Console Application工程程序内容为...Hdc=BeginPaint(hwnd, &ps) //做好绘制准备 TextOut(hDC,1,1"学同学们好!",9) EndPaint(hwnd,&ps) //结束绘制工作 (4)所有运行结果都要有截图

    快速启动器更新开源-易语言

    创建一张位图,同时获得其图形指针,方便对其绘制 那么组件又是如何绘制到窗口上的呢? 在组件基类里保存着这些类成员变量 这些变量保存着组件的同层与子层组件的指针 在最终绘制的过程中,通过递归的方式,完成全部组件...

    DirectDraw-Double-Buffered.rar_directdraw_内存 绘图

    通常在绘图的时候,你都不会直接在BeginPaint或CDC中使用HDC,如果你这样做了,那么当你绘制很多东西的时候,就有可能造成图像的闪烁。双缓冲就是用在这里实现图像的平滑的更新的。 有很多实现的方法,一种是在内存...

    vc++编程最简单的winmain程序

    hdc=GetDC(hwnd); TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训")); ReleaseDC(hwnd,hdc); break; case WM_PAINT: PAINTSTRUCT ps; hdc=BeginPaint(hwnd,&ps); TextOut(hdc,0,...

    [API] 透明提示框

    Declare Function BeginPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long Declare Function EndPaint Lib "user32" (ByVal hwnd As Long, lpPaint As PAINTSTRUCT) As Long Declare ...

    duilib半透明异形窗口_修改WM_PAINT

    UpdateLayeredWindow(...)这个函数是有限制的. 1.当前窗口样式必须是WS_EX_LAYERED,不能是WS_CHILD. 2.所有的WS_CHILD样式的...4.BeginPaint与EndPaint的使用 有问题可到 http://www.yutent.com/article-68.html 留言.

    易语言GDI画CPU动态线

    GDI画CPU动态线,GetBitmapHandleFromResource,子类化子程序,创建网格,时钟周期,绘画,创建时钟,销毁时钟,置时钟周期,API_SetTimer,API_KillTimer,SetWindowLongA,CallWindowProcA,BeginPaint,EndPaint,GetDC,...

    易语言窗口自绘效果

    易语言窗口自绘效果源码,窗口自绘效果,NewProc,画窗体背景,背景边缘柔化,子程序_获取任务栏高度,是否在矩形,SetWindowLongA,CallWindowProcA,GetWindowTextA,BeginPaint,EndPaint,GetDC,GetWindowRect,...

    易语言给你的窗口创建一个虚线选择框

    易语言给你的窗口创建一个虚线选择框源码,ReleaseDC,SelectObject,GetDC,DeleteObject,DrawFocusRect,GetDCEx,SetCapture,ReleaseCapture,CreateCompatibleDC,CreateCompatibleBitmap,BitBlt,DeleteDC,SetWindowLong...

    gdi和gdi+

    ::GetDC(hWnd); ::ReleaseDC(hwnd, hdc); // 第二种 PAINTSTRUCT ps; ::BeginPaint(hwnd, &ps); ::EndPaint(hwnd, &ps); // 第三种 创建兼容内存DC HDC hMemDC = ::CreateCompatibleDC(hDest); ::DeleteDC(hMemDC); ...

    e语言-利用动画框实现自绘组合框

    资源介绍:利用动画框实现自绘组合框资源作者:电视费资源界面:资源下载:

    易语言自绘时钟

    易语言自绘时钟源码,自绘时钟,处理子程序,BeginPaint,DeleteObject,FillRect,CreateSolidBrush,SelectObject,GetStockObject,Ellipse,CreatePen,LineTo,MoveToEx,DrawText,SetTimer,SetWindowLong,CallWindowProc,...

Global site tag (gtag.js) - Google Analytics