VC++双缓冲保持背景不擦除之实现
解决这一问题的办法依然是使用双缓冲,和上次不同的上,用于缓冲的内存DC和位图要保持住,而非随用随建。为了解决第一点不足,需要建立一个内存DC和位图,并在OnDraw过程中将其拷贝到前台。这样欧文们作图的时候将图做在内存DC上,然后使窗口刷新,便看到了所做的图了。当窗体移动或被遮挡时,窗口需要重绘,只是把我们的缓冲重新绘制一遍,因此已经画好的线不会被擦除。解决第二的问题的方法主要有两种,一种是设置画笔的模式为异或模式,这样的话在同意位置画两次的话等同于什么都没画。但是这样会牺牲线条本身的颜色属性,如果背景是单一的颜色,自然是看不出来的,但是如果背景颜色丰富,那我们的线条也就随着多姿多彩了;第二种方法是比较好用的脏矩形法,脏矩形法的主要内容就是每次画面的刷新只更新需要更新的那一块区域,这正是Flash采用的方式,效率比较高。在本程序中为简单起见,没有采用完全的脏矩形法,脏矩形始终定义为整个客户区大小。为此,需要重新定义一个新的缓冲区,用来保存即将变脏的矩形,以备之后恢复所用。在响应WM_MOUSEMOVE消息的过程中,先将新缓冲区上的图形还原到旧缓冲区上,这样可以遮挡住上次的线条。再在旧缓冲区上作图,然后刷新窗口,我们便看到了动态效果。不知道这是不是传说中的三缓冲技术呢?
以下是代码的分析:
CBitmap memBakBMP; //新缓冲区内存DC
CDC memBakDC; //新缓冲区用的位图
BOOL bClicked; //判断是否应当作图
CPoint ptBegin; //记录图象开始的位置
CBitmap memBMP; //新缓冲区用的位图
CDC memDC; //旧缓冲区内存DC
响应WM_CREATE消息的时候做初始化工作:
int CNSSDrawerView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -;
memDC.CreateCompatibleDC(NULL);
memBMP.CreateCompatibleBitmap(&memDC,,);
memDC.SelectObject(&memBMP);
memDC.FillSolidRect(,,,,GetDC()->GetBkColor());
memBakDC.CreateCompatibleDC(NULL);
memBakBMP.CreateCompatibleBitmap(&memBakDC,,);
memBakDC.SelectObject(&memBakBMP);
return ;
}
相应的,在响应WM_DESTROY消息的时候,也要做善后工作:
void CNSSDrawerView::OnDestroy()
{
CView::OnDestroy();
memDC.DeleteDC();
memBMP.DeleteObject();
memBakDC.DeleteDC();
memBakBMP.DeleteObject();
}
干预WM_ERASEBKGND消息的响应,这里是最容易忽略的地方,要特别注意
BOOL CNSSDrawerView::OnEraseBkgnd(CDC* pDC)
{
return TRUE; //CView::OnEraseBkgnd(pDC);
}
部分变量在构造函数中初始化:
CNSSDrawerView::CNSSDrawerView()
{
ptBegin = ;
bClicked = FALSE;
}
响应WM_LBUTTONDOWN消息,着是画线的开始:
void CNSSDrawerView::OnLButtonDown(UINT nFlags, CPoint point)
{
ptBegin = point;
bClicked = TRUE;
CRect rect;
GetClientRect(&rect);
memBakDC.BitBlt(,,rect.Width(),rect.Height(),&memDC,,,SRCCOPY);
CView::OnLButtonDown(nFlags, point);
}
相应的,WM_LBUTTONUP消息的响应是画线的结束:
void CNSSDrawerView::OnLButtonUp(UINT nFlags, CPoint point)
{
bClicked = FALSE;
CView::OnLButtonUp(nFlags, point);
}
最主要的部分在响应WM_MOUSEMOVE消息的模块中:
void CNSSDrawerView::OnMouseMove(UINT nFlags, CPoint point)
{
if(bClicked)
{
CRect rect;
GetClientRect(&rect);
memDC.BitBlt(,,rect.Width(),rect.Height(),&memBakDC,,,SRCCOPY);
memDC.MoveTo(ptBegin);
memDC.LineTo(point);
Invalidate();
}
CView::OnMouseMove(nFlags, point);
}
VC++双缓冲保持背景不擦除之实现的更多相关文章
- VC双缓冲画图技术介绍
双缓冲画图,它是一种主要的图形图像画图技术.首先,它在内存中创建一个与屏幕画图区域一致的对象,然后将图形绘制到内存中的这个对象上,最后把这个对象上的图形数据一次性地拷贝并显示到屏幕上. 这样的技术能够 ...
- MFC VC 双缓冲绘图基本原理与实现,详细解释
转自:http://blog.csdn.net/foreverhuylee/article/details/21548107 当然你可以直接搜索到能用的代码,并且基本能满足要求.不过这样总不是学习的态 ...
- VC 绘图,使用双缓冲技术实现
VC 绘图,使用双缓冲技术实现 - Cloud-Datacenter-Renewable Energy-Big Data-Model - 博客频道 - CSDN.NET VC 绘图,使用双缓冲技术实现 ...
- VC++绘图时,利用双缓冲解决屏幕闪烁 转载
最近做中国象棋,绘制界面时遇到些问题,绘图过程中屏幕闪烁,估计都会想到利用双缓冲来解决问题,但查了下网上双缓冲的资料,发现基本是MFC的,转化为VC++后,大概代码如下: void DrawBmp(H ...
- VC使用双缓冲避免绘图闪烁的正确使用方法【转】
使用内存DC绘图,然后实现双缓冲,避免绘图闪烁,这个小技术简单但很有效.但是仍然有很多人说使用了双缓冲,图片却仍然有闪烁,分析了几个这样的例子,发现 其实不是双缓冲的技术问题,而是使用者没有正确理解和 ...
- VC使用双缓冲制作绘图控件
最近用VC做了一个画图的控件.控件在使用的时候遇到点问题.在控件里画了图之后切换到其他页面,等再切换回来的时候,发现控件里画的图都不见了.这是因为VC里面,当缩小.遮挡页面后客户区域就会失效,当再次显 ...
- VC++中双缓冲技术画图
用双缓冲,先在内存中绘制,然后拷贝到屏幕DC,这样就不会出现画出去的情况了,前段时间我也是为这个问题费了不少劲.我把我的一段代码给你看一下: CDC *pDC = m_drawbox.GetDC(); ...
- Win32 GDI 非矩形区域剪裁,双缓冲技术
传统的Win32通过GDI提供图形显示的功能,包括了基本的绘图功能,如画线.方块.椭圆等等,高级功能包括了多边形和Bezier的绘制.这样app就不用关心那些图形学的细节了,有点类似于UNIX上的X- ...
- 【MFC】MFC绘图不闪烁——双缓冲技术
MFC绘图不闪烁——双缓冲技术[转] 2010-04-30 09:33:33| 分类: VC|举报|字号 订阅 [转自:http://blog.163.com/yuanlong_zheng@126/ ...
随机推荐
- YHLMR007 服装PDA验货差异报表
*********************************************************************** * Title : YHLMR007 * * Appli ...
- kernel/Makefile
## Makefile for the linux kernel.## Note! Dependencies are done automagically by 'make dep', which a ...
- linux 启动weblogic的某服务报错
问题如标题所示, 错误信息主要包括: weblogic.store.PersistentStoreException: [Store:280073]The file store"WLS_DI ...
- ajax中返回json数据有"
1.将“转义为\" string table=sb.ToString(); table.Replace("\"","\\\"");
- pt-ioprofile分析查看mysql的真实IO情况
针对IO密集型应用做系统调优的时候,我们通常都需要知道系统cpu 内存 io 网络等系统性能 和 使用率,结合应用本身的访问量,以及 mysql的性能指标来综合分析.比如说:我们将系统压力情况分为 ...
- struts2 的验证框架validation如何返回json数据 以方便ajax交互
struts2 的验证框架validation简单,好用,但是input只能输出到jsp页面通过struts2的标签<s:fielderror />才能取出,(EL应该也可以). 如果使 ...
- 038. asp.netWeb用户控件之六实现日期选择的用户控件
web用户控件的ascx代码: <%@ Control Language="C#" AutoEventWireup="true" CodeFile=&qu ...
- js 实现ActiveXObject("Scripting.Dictionary") 功能
/* 字典 ActiveXObject("Scripting.Dictionary") 项目中用到的ActiveXObject("Scripting.Dictionary ...
- IOS开发-项目实战-点赞功能的实现
实现思路: 1.每一条新闻就是一个cell,在cell上添加点赞按钮. 2.让cell的控制器成为自定义cell的代理,将点击了哪一个cell放在代理方法中传出去. 3.并将这条新闻的ID和当前用户的 ...
- c#读取快递100查询返回的JSON信息
{"message":"ok","nu":"1105016801203","companytype" ...