知识大全 delphi 缓冲画图(内存画图)解决画图闪烁问题[2]

Posted

篇首语:也许就是那么一颗不甘服输的心带着我奋斗下去!本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 delphi 缓冲画图(内存画图)解决画图闪烁问题[2]相关的知识,希望对你有一定的参考价值。

  到了mfc里面 由于有了封装 所有的hdc被隐藏在对象中做为隐藏参数传递(就是DC类的this啦~~) 所以我们的关键话题就转变为了怎样得到想要的DC类而已 这个过程其实大同小异的 在消息响应的过程中 WM_PAINT被转变为OnDraw() OnPaint()一系列函数来响应 这些函数一般都有个参数CDC *pDC传入进来 因此在这些函数里面 我们就只需要直接画图就可以了 和以前sdk的方式一样

  但是WM_PAINT消息响应的频度太高了 比如最小化最大化 移动窗体 覆蓋等等都引起重绘 经常的这样画图 很是消耗性能 在有些场合 比如随机作图的场合 每一次就改变 还导致了程序的无法实现 怎么解决后一种问题呢

  ms在msdn的例子里面交给我们document/view的经典解决办法 将图形的数据存储在document类里面 view类只是根据这些数据绘图 比如你要画个圆 只是将圆心和半径存在document里面 view类根据这个里面的数据在屏幕上面重新绘制 那么 我们只需要随机产生一次数据就可以了

  这样还是存在性能的问题 于是我们开始考虑另外的解决方法 我们知道 将内存中的图片原样输出到屏幕是很快的 这也是我们在dos时代经常做的事情 能不能在windows也重新利用呢?答案就是内存缓冲绘图 我们今天的主题

  我们还是回到DC上来 既然DC是绘图对象 我们也就可以自己来在内存里面造一个 让它等于我们想要的图 图(CBitmap)可以存储在document类里面 每一次刷新屏幕都只是将这个图输出到屏幕上面 每一次作图都是在内存里面绘制 保存在document的图里面 必要时还可以将图输出到外存保存 这样既保证了速度 也解决了随机的问题 在复杂作图的情况下对内存的开销也不大(总是一副图片的大小) 这是一个很好的解决办法 现在让我们来实现它们

  我们在document类里面保存一个图片

  CBitmap m_bmpBuf;//这里面保存了我们做的图 存在于内存中

  在view类里面我们需要将这个图拷贝到屏幕上去  位于OnDraw(CDC *pDC)函数中    CDC dcMem;//以下是输出位图的标准操作  CBitmap *pOldBitmap = NULL;  dcMem CreateCompatibleDC(NULL);  pOldBitmap = dcMem SelectObject(&pDoc >m_bmpBuf);  BITMAP bmpinfo;  pDoc >m_bmpBuf GetBitmap(&bmpinfo);  pDC >BitBlt( bmpinfo bmWidth bmpinfo bmHeight &dcMem SRCCOPY);  dcMem SelectObject(pOldBitmap);  dcMem DeleteDC();

  在我们需要画图的函数里面 我们完成绘图工作

  CBmpDrawDoc *pDoc = GetDocument(); //得到document中的bitmap对象   CDC *pDC = GetDC();  CDC dcMem;  dcMem CreateCompatibleDC(NULL);//这里我们就在内存中虚拟建造了DC  pDoc >m_bmpBuf DeleteObject();  pDoc >m_bmpBuf CreateCompatibleBitmap(pDC );//依附DC创建bitmapCBitmap *pOldBitmap = dcMem SelectObject(&pDoc >m_bmpBuf);//我们调入了我们bitmap目标

  dcMem FillSolidRect( RGB( ));//这些时绘图操作 随便你^_^  dcMem TextOut( Hello world! );  dcMem Rectangle( );  dcMem FillSolidRect( RGB( ));

  pDC >BitBlt( &dcMem SRCCOPY);//第一次拷贝到屏幕  dcMem SelectObject(pOldBitmap);  dcMem DeleteDC();

  全部的过程就是这样 很简单吧 以此为例子还可以实现 个缓冲或者多个缓冲等等 视具体情况而定 当然在缓冲区还可以实现很多高级的图形操作 比如透明 合成等等 取决于具体的算法 需要对内存直接操作(其实就是当年dos怎么做 现在还怎么做)

  再来解释一下前面说的为什么不能用全局变量保存DC问题 其实DC也是用句柄来标识的 所以也具有句柄的不确定性 就是只能随用随取 不同时间两次取得的是不同的(使用过文件句柄地话 应该很容易理解的) 那么我们用全局变量保存的DC就没什么意义了 下次使用只是什么也画不出来 (这一点的理解可以这样 DC需要占用一定的内存 那么在频繁的页面调度中 位置难免改变 于是用来标志指针的句柄也就不同了)

cha138/Article/program/Delphi/201311/24798

相关参考

知识大全 勾股定理画图怎么画

初二数学:勾股定理画图怎么画一条边为3,另一条边长为1,这两条边垂直,连线就是√10的线段。因为满足﹙√10﹚=3+1初二数学,关于勾股定理,请画图解释选C解析设BD长为x,则AD为2x。因为CD垂直

知识大全 画图时如何设置线条的粗细

  在用JavaD进行画图时可以非常方便的设置线条的粗细及接头的形状下面是一个简单的例子供大家参考    floatthick=f;//设置画刷的粗细为  BufferedImagebi=newBuf

知识大全 实现鼠标画图的Java程序

实现鼠标画图的Java程序  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    importjav

知识大全 cad画图前怎么设置

cad画图前怎么设置1.设置快捷键定义,包括编辑,修改,标注。2.设置鼠标右键自定义为重复上一命令以及执行操作。3.采用标准A4线框,或自行规定A4线框,标准零件图框,并保存。4.在图层中定义各线条的

画图说明缸胀监测系统的组成。

画图说明缸胀监测系统的组成。参考答案:TSI系统应用两个直流线性差动变压器(LVDT)来测量汽缸相对于基础(固定的)沿轴线的热膨胀。探头的安装如下图所示,探头一般安装在绝对死点的相对端基础上,在这个相

画图说明缸胀监测系统的组成。

画图说明缸胀监测系统的组成。参考答案:TSI系统应用两个直流线性差动变压器(LVDT)来测量汽缸相对于基础(固定的)沿轴线的热膨胀。探头的安装如下图所示,探头一般安装在绝对死点的相对端基础上,在这个相

知识大全 JS实现简单的Canvas画图实例

JS实现简单的Canvas画图实例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!这篇文章介绍了JS

画图论述蒸汽流量扰动下,汽包水位动态特性特点

画图论述蒸汽流量扰动下,汽包水位动态特性特点参考答案:在蒸汽流量阶跃扰动作用下,水位控制对象的动态特性表现为起始阶段带有“虚假水位”的无自平衡能力的特点,如图4-4所示。图4-4蒸汽流量扰动下汽包水位

画图论述蒸汽流量扰动下,汽包水位动态特性特点

画图论述蒸汽流量扰动下,汽包水位动态特性特点参考答案:在蒸汽流量阶跃扰动作用下,水位控制对象的动态特性表现为起始阶段带有“虚假水位”的无自平衡能力的特点,如图4-4所示。图4-4蒸汽流量扰动下汽包水位

知识大全 我是一位数学老师,想知道数学出题目要画图有什么软体

我是一位数学老师,想知道数学出题目要画图有什么软体画的如果是基本的长方形、正方形之类的话可以试试办公软体里面的画图工具,里面基本用的都有我是一位六年级的数学老师,急需奥数试题1.乙两地相距6千米,某人