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 ...
随机推荐
- SpringBoot 集成 Mybatis(三)
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.增加持久化层 <dependency> <groupId>mysql< ...
- Java实现 LeetCode 690 员工的重要性(简易递归)
690. 员工的重要性 给定一个保存员工信息的数据结构,它包含了员工唯一的id,重要度 和 直系下属的id. 比如,员工1是员工2的领导,员工2是员工3的领导.他们相应的重要度为15, 10, 5.那 ...
- Java实现 LeetCode 643 子数组最大平均数 I(滑动窗口)
643. 子数组最大平均数 I 给定 n 个整数,找出平均数最大且长度为 k 的连续子数组,并输出该最大平均数. 示例 1: 输入: [1,12,-5,-6,50,3], k = 4 输出: 12.7 ...
- Java实现 蓝桥杯VIP 算法提高 快速幂
算法提高 快速幂 时间限制:1.0s 内存限制:256.0MB 问题描述 给定A, B, P,求(A^B) mod P. 输入格式 输入共一行. 第一行有三个数,N, M, P. 输出格式 输出共一行 ...
- Java实现 LeetCode 166 分数到小数
166. 分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入 ...
- Java实现 蓝桥杯VIP 算法提高 欧拉函数
算法提高 欧拉函数 时间限制:1.0s 内存限制:512.0MB 说明 2016.4.5 已更新试题,请重新提交自己的程序. 问题描述 给定一个大于1,不超过2000000的正整数n,输出欧拉函数,p ...
- Java实现 洛谷 P1567 统计天数
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...
- java实现第七届蓝桥杯抽签
抽签 抽签 X星球要派出一个5人组成的观察团前往W星. 其中: A国最多可以派出4人. B国最多可以派出2人. C国最多可以派出2人. .... 那么最终派往W星的观察团会有多少种国别的不同组合呢? ...
- 云服务器部署Web项目
接着上一篇整好MySQL数据库了,部署Web项目的重要一步就完成了,接下来就是整Tomcat发布项目了,这个博主用的是宝塔面板,所以,也很简单,直接在宝塔面板软件商店选择对应的Tomcat版本安装就行 ...
- 面试官:说说Redis的Hash底层 我:......(来自阅文的面试题)
redis源码分析系列文章 [Redis源码系列]在Liunx安装和常见API 为什么要从Redis源码分析 String底层实现——动态字符串SDS Redis的双向链表一文全知道 前言 hello ...