MFC--自己优化滚动条的双缓冲绘图方法
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--自己优化滚动条的双缓冲绘图方法的更多相关文章
- 【MFC】MFC绘制动态曲线,用双缓冲绘图技术防闪烁
摘自:http://zhy1987819.blog.163.com/blog/static/841427882011614103454335/ MFC绘制动态曲线,用双缓冲绘图技术防闪烁 2011 ...
- MFC双缓冲绘图(2015.09.24)
问题引入: 最近在尝试编写贪吃蛇游戏时遇到这么一个问题:当系统以较快频率向窗口发送WM_PAINT消息时,调用OnPaint()函数在窗口中绘制图形就会发生闪烁现象. 问题分析: 当我们把绘图过程放在 ...
- MFC双缓冲绘图实例
本人之前一直了解双缓冲绘图的基本原理,但是在研究很久之后才大概知道具体的使用过程,本文将详细介绍本人在实际项目中使用双缓冲绘图的案例. 实现功能:主界面显示某张包含人脸的图片,通过dlib detec ...
- mfc双缓冲绘图
1.要求 在界面加载本地图片并显示,每过100ms改变一张图片显示 2.现象 通过定时器控制CImage,Load,Draw,Destroy,会非常的卡顿.因为Load图片时,会是非常大的数据[所有C ...
- 陈灯WGF双缓冲绘图框架
“木丸子童屋”,专售各类儿童玩具,价格优惠,请大家多多支持:http://shop65552598.taobao.com/ WGF(windows graphic foundation)为window ...
- [Qt2D绘图]-06QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题
本篇读书笔记主要记录QPainter的复合模式&&双缓冲绘图&&绘图中的其他问题 大纲: 复合模式 双缓冲绘图 绘图中的其他问题 ...
- C#-gdi绘图,双缓冲绘图,Paint事件的触发
一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1 绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...
- 双缓冲绘图和窗口控件的绘制——ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 .
双缓冲绘图和窗口控件的绘制 ---ATL ActiveX 窗口控件生成向导绘制代码OnDraw的一个错误 cheungmine 我们通常使用ATL COM组件,生成一个带窗口的ActiveX控件,然后 ...
- 简单的 "双缓冲" 绘图的例子(研究一下)
所谓双缓冲就是先画到内存画布(如: TBitmap), 然后再转帖到目的地. 譬如下面小程序: procedure TForm1.FormCreate(Sender: TObject); begin ...
随机推荐
- SpringCloud Eureka Client和Server侧配置及Eureka高可用配置
一.Eureka注册中心和客户端配置Demo. 1.Server端 a.使用Idea创建Spring项目,如下所示: b.相关配置 application.yaml配置文件如下: # eureka本身 ...
- 【HBase】知识小结+HMaster选举、故障恢复、读写流程
1:什么是HBase HBase是一个高可靠性,高性能,面向列,可伸缩的分布式数据库,提供海量数据存储功能,一个结构化的分布式存储系统,不同于一般的关系型数据库,它适合半结构化和非结构化数据存储. 2 ...
- 【Storm】核心组件nimbus、supervisor、worker、executor、task
nimbus 是整个集群的控管核心,负责topology的提交.运行状态监控.任务重新分配等工作. zk就是一个管理者,监控者. 总体描述:nimbus下命令(分配任务),zk监督执行(心跳监控wor ...
- 高性能可扩展mysql 笔记(六) SQL执行计划及分页查询优化、分区键统计
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 常见业务处理 一.使用数据库处理常见业务: 案例: 如何对评论进行分页展示 使用 EXPLAIN 获得s ...
- 利用jieba库画词云
from wordcloud import WordCloud import matplotlib.pyplot as plt import jieba # 生成词云 def create_word_ ...
- Java实现 LeetCode 724 寻找数组的中心索引(暴力)
724. 寻找数组的中心索引 给定一个整数类型的数组 nums,请编写一个能够返回数组"中心索引"的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧 ...
- Java实现 LeetCode 390 消除游戏
390. 消除游戏 给定一个从1 到 n 排序的整数列表. 首先,从左到右,从第一个数字开始,每隔一个数字进行删除,直到列表的末尾. 第二步,在剩下的数字中,从右到左,从倒数第一个数字开始,每隔一个数 ...
- Java实现 LeetCode 275 H指数 II
275. H指数 II 给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照升序排列.编写一个方法,计算出研究者的 h 指数. h 指数的定义: "h 代表"高 ...
- java实现滑动解锁
滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上都一致 ...
- 逐点分析,这样做Web端性能测试
前言: 71%用户希望在手机上打开网页能跟电脑一样快: 5秒钟被认为是用户能忍受的最长响应时间,如果响应时间超过5秒,50%的移动用户会放弃: 33%失望的用户会使用竞品替代: 用户尝试三次出现同样性 ...