//========================================================================
//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);

VC绘制位图--BeginPaint()与GetDC()的区别相关推荐

  1. BeginPaint和GetDC的区别

    BeginPaint和GetDC的区别 代码 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Gr ...

  2. Beginpaint 与 GetDC 的区别

    InvalidateRect是一个函数,该函数向指定的窗体更新区域添加一个矩形,然后窗体跟新区域的这一部分将被重新绘制. BeginPaint.EndPaint是比较"被动"的,只 ...

  3. 用VC++绘制位图按钮

    MFC的CButton类提供Windows按钮控件的功能,从CButton类派生的CBitmapButton类封装了自绘制按钮的功能,使得程序员可以通过在按钮上绘制位图并为这些位图实例化类CBitma ...

  4. BeginPaint和GetDC有什么区别?【转】

    转自:http://hi.baidu.com/d_b_mike/blog/item/ec8820d0fb9127d5572c84a9.html 这是个windows编程问题. 第一种情况显示出来的字很 ...

  5. BeginPaint和GetDC有什么区别

    windows编程问题 第一种情况显示出来的字很正常. case WM_PAINT: gdc = BeginPaint (hwnd, &ps); TextOut (gdc, 0, 0, s, ...

  6. 用VC打开位图程序[转]

    转自http://sophiekudo.blog.hexun.com/10811818_d.html 经过几天的奋战,按照网上的主要步骤,搞出来了一个用VC打开位图的程序,很是兴奋,现在把主要代码发在 ...

  7. 转载:位图和矢量图的区别

    原文链接:位图和矢量图的区别 位图和矢量图是计算机图形中的两大概念,这两种图形都被广泛应用到出版,印刷,互联网[如flash和svg]等各个方面,他们各有优缺点,两者各自的好处几乎是无法相互替代的,所 ...

  8. OpenGL ES:绘制函数glDrawArrays 和 glDrawElements 的区别

    from:https://www.jianshu.com/p/4d02c2cd21ea 写文章注册登录 首页 下载App OpenGL ES:绘制函数glDrawArrays 和 glDrawElem ...

  9. 窗口非客户区绘制位图与设计

    原文:http://www.haogongju.net/art/1891934 首先介绍在指定区域绘制位图 为了能够在指定的区域中输出位图,需要使用设备上下文CDC类的StretchBlt方法.由于我 ...

最新文章

  1. G6实现标签拖动连线画流程图
  2. javascript的Array对象
  3. 《SAP FIORI 开发入门》课程答疑 第二期
  4. 武汉船舶职业技术学院计算机分数线,武汉船舶职业技术学院录取分数线2021是多少分(附历年录取分数线)...
  5. Spring Boot笔记-404错误统一管理
  6. HTML中的父选择器,html – css4中是否有父选择器?
  7. 优麒麟 20.04 LTS 版本发布,UKUI3.0 灵动转身
  8. c语言中最常用的四种数据类型,计算机中有哪几种常见数据类型
  9. MySQL的主从复制与读写分离技术实例(一)主从复制
  10. BIEE回写(BIEE write back)
  11. 如何设置unobtrusive的语言包
  12. 音频soundpool
  13. QQ互联--个人资料提交审核
  14. C++之三大特性 “封装”、“继承”、“多态”
  15. dhl寄件邮编错了_如果从国外邮寄DHL往中国.邮编怎么写?
  16. ToolkitScriptManager与ScriptManager
  17. 专利申请中的期限及期限的延长
  18. nike air max 1 leopard internationaal meest
  19. bzoj1038: [ZJOI2008]瞭望塔
  20. 02 | 安全原则:我们应该如何上手解决安全问题?

热门文章

  1. 算法(第4版) 编写一个静态方法lg(),接受一个整型参数N,返回不大于log2N的最大整数。(不要使用Math库)
  2. 如何PDF转Excel,手机和电脑都能用的方法
  3. 支付宝里面基金的猫腻?为什么计算对不上?
  4. JavaScript 中的事件类型5(读书笔记思维导图)
  5. Minecraft 1.18.1、1.18.2模组开发 02.方块和物品
  6. HTB-Cursed Secret Party
  7. java怎么注释多行注释_java的注释格式和多行注释和单行注释
  8. 蛙蛙推荐:蛙蛙牌关键词提取算法
  9. android go 小米1,小米首款Android Go入门机红米Redmi Go发布,1GB+8GB运存
  10. 最新优秀开源:车牌识别、车型分析、车流统计、违停检测统统行