2010-01-09 18:45

MFC--自己优化的双缓冲绘图方法

自己通过尝试,用修改视图坐标的方法, 优化了双缓冲绘图,实现起来并不复杂。

在介绍这个方法前,重新介绍一下窗口和视口的概念.
窗口:就是我们通过拖滚动条所能看到的整个窗口.它是有一部分不能被当前显示的.
视口:就是我们能直接看到的当前显示的窗口,它是窗口的一部分,滚动窗口的视口肯定比窗口小一些,普通窗口的视口大小就是窗口大小.

下面介绍优化方法

网上给出的双缓冲绘图方法多是在内存中绘出一幅和窗口大小相同的位图再导入设备.对于滚动窗口,我前些日子写的日志也给出了方法.这样做,虽然达到了目
的,但是却很大程度上的浪费了内存资源.比如,窗口大小800*600,滚动窗口1600*800.如果只是刷新了1*1的视口区域,将需要在内存中绘
800*600的位图,对于滚动窗口,更是需要1600*800的位图,而只有1*1的区域是有效的.资源浪费了几十万倍.优化的方法就是在内存中只绘一
幅和刷新区域同样大小的位图.

优化步骤:

一.在OnDraw(CDC* pDC)函数中定义相关变量.

刷新区域 CRect rc,

兼容DC CDC memDC,

兼容位图 CBitmap memBmp,

二.调用GetClipBox(&rc)获得刷新区域,注意,获得的区域是以逻辑坐标表示的,不是设备坐标。rc的左上角坐标即兼容DC视口坐标相对逻辑坐标的偏移,将这个坐标设为兼容DC的视口坐标原点,这样不做其它调整就可以按照逻辑坐标在兼容DC里绘图了。这样绘图时将逻辑坐标加上偏移量就是兼容DC的设备坐标.调用CreateCompatibleDC()创建兼容DC,调用
CreateCompatibleBitmap()创建兼容位图,调用SelectObject()导入位图.

三.绘图.先调用FillSolidRect()用指定的颜色刷背景,再判断下要画在图在不在rc范围内,如果不在,不画,画也没有意义,画图.

四.调用BitBlt()导入位图,销毁位图对象,DC.

五.最后,响应 WM_ERASEBKGND 消息,直接返回TRUE,取消刷新背景.

说明:双缓冲绘图本身都具有一定的复杂性,如果所绘的图形并不复杂,使用这种方法不会有明显的效果提升.

很简单吧,给出示例代码,在文档类中保存的矩形对象m_ellipse内画椭圆.

void CTest2View::OnDraw(CDC* pDC)
{
// TODO: add draw code for
native data here
CDC memDC;
CBitmap memBmp;

memDC.CreateCompatibleDC(pDC);//创建兼容DC
CRect rc;

pDC->GetClipBox(&rc);//获得刷新区域
// 创建兼容位图

memBmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());

memDC.SelectObject(&memBmp);//导入位图
//红色背景

memDC.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(255,0,0));

memDC.SetWindowOrg(rc.left, rc.top);
//start画图 这是画一个椭圆的示例代码

CRect ellipse = GetDocument()->m_ellipse;
if( !( (rc.left >
ellipse.right ) //右侧超出
|| (rc.right < ellipse.left
) //左侧超出
|| (rc.top > ellipse.bottom) //下侧超出

|| (rc.bottom< ellipse.top ) )) //上侧超出
{

memDC.Ellipse(&ellipse); //画图
}
//end画图
//导入

pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, rc.left,
rc.top, SRCCOPY);
memBmp.DeleteObject();//销毁位图

memDC.DeleteDC();//销毁DC
}

BOOL CTestView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message
handler code here and/or call

// default
return TRUE;
//
return CView::OnEraseBkgnd(pDC);

MFC--自己优化滚动条的双缓冲绘图方法的更多相关文章

  1. 【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁

    摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁   2011 ...

  2. MFC双缓冲绘图(2015.09.24)

    问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...

  3. MFC双缓冲绘图实例

    本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...

  4. mfc双缓冲绘图

    1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...

  5. 陈灯WGF双缓冲绘图框架

    “木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...

  6. [Qt2D绘图]-06QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题

    本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题   大纲:     复合模式     双缓冲绘图     绘图中的其他问题       ...

  7. C#-gdi绘图,双缓冲绘图,Paint事件的触发

    一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1  绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...

  8. 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .

    双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...

  9. 简单的 "双缓冲" 绘图的例子(研究一下)

    所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如下面小程序: procedure TForm1.FormCreate(Sender: TObject); begin ...

随机推荐

  1. Java实现 LeetCode 260 只出现一次的数字 III(三)

    260. 只出现一次的数字 III 给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次. 找出只出现一次的那两个元素. 示例 : 输入: [1,2,1,3,2,5] 输出 ...

  2. Java实现蓝桥杯勇者斗恶龙

    勇者斗恶龙 你的王国里有一条n个头的恶龙,你希望雇一些骑士把它杀死(即砍掉所有头). 村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙一个直径不超过x的头, 且需要支付x个金币.如何雇佣骑士才 ...

  3. Java实现 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…

    import java.util.Scanner; public class Main{ private static Scanner cin; public static void main(Str ...

  4. java实现金额组合

    某财务部门结账时发现总金额不对头.很可能是从明细上漏掉了某 1 笔或几笔. 如果已知明细账目清单,能通过编程找到漏掉的是哪 1 笔或几笔吗? 如果有多种可能,则输出所有可能的情况. 我们规定:用户输入 ...

  5. Mysql添加索引及索引的优缺点

    一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二.索引的作用? 索引相当于图书上的目录,可以根据目录上的页码快速找到所需的内容,提高 ...

  6. 全面概述Gitee和GitHub生成/添加SSH公钥

    前言 现如今将代码开源已经成为软件开发行业的一种趋势,而现在比较有名的代码托管平台有GItHub.Gitee.Gitlab等相关平台.而我们在使用代码托管平台最为常见的就是如何将自己本地的代码推送到远 ...

  7. sublime配置C++编译环境

    配置C++编译命令 { "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "workin ...

  8. Python 读取和输出到txt

    读txt文件 python常用的读取文件函数有三种read().readline().readlines() read() #一次性读取文本中全部的内容,以字符串的形式返回结果 with open(& ...

  9. Clumsy Keke【模拟+三维数组】

    Clumsy Keke 题目链接(点击) Problem Description Keke is currently studying engineering drawing courses, and ...

  10. postman切换环境

    原文链接:https://www.cnblogs.com/nicole-zhang/p/11498384.html 通常会有多个测试环境,针对同一个接口来说,可能只是域名有变化,此时可以添加postm ...