于双缓冲技术的GDI无闪烁绘图
Abstract: Graphics flickering is an intractable common problem when programming Windows forms applications by using GDI + . On the basis of profound analysis on the model of form redrawing, the essentials of graphics flickering were explained in this paper. Two flickerfree GDI + drawing methods were proposed based on double buffering built in the . NET framework. To take analog clock as an example, it is shown that these two methods are very easytouse and effective. Key words: double buffering; flickerfree drawing; graphics flickering; GDI + ; . NET framework; analog clock
基于双缓冲技术的 GDI + 无闪烁绘图
江建国 ,温少营,张瑞楠
( 辽宁师范大学 数学学院, 辽宁 大连 116029 ) ( * 通信作者电子邮箱 jjgbox@ sina. com)
*
要: 图形闪烁是使用 GDI + 编写 Windows 窗体应用程序时经 常 遇 到的 一 个 问题。 在 深 入 分析 窗 体重 绘 模型 阐述了图形闪烁的本质原因。利用. NET框架 中 内 置 的 双 缓 冲 技术, 提出了 两 种 GDI + 无 闪烁 绘 图方 法。 以 基础上, 模拟时钟程序为例, 说明了这两种方法都非常简便且有效。 关键词: 双缓冲; 无闪烁绘图; 图形闪烁; GDபைடு நூலகம் + ; . NET框架; 模拟时钟 中图分类号: TP391. 41 文献标志码: A
摘
Flickerfree GDI + drawing based on double buffering
JIANG Jianguo , WEN Shaoying, ZHANG Ruinan
( School of Mathematies, Liaoning Normal University, Dalian Liaoning 116029 , China)
0
引言
在编写图形应用程序时, 经常会发现程序所绘制的图形
在屏幕 上 不 停 地 闪 烁, 这是一个比较难以解决的编程问 题
[1 ]
双缓冲 技 术 在 编 程 界 应 用 已 经 有 好 多 年 了 。 在 早 期 Win32 编程年代, 使用 C 语言调用 GDI 编写图形应用程序, 就 为了使用双缓存技术消除 经常会遇到图形闪烁问题 。 那时, 图形闪烁, 往往需要额外编写一些较高技巧的代码; 后来, 随 着面向对象开发技术的成熟与流行, 双缓冲技术在一些面向 [5 ] DirectX[3,6] 对象风格的图形库中得到了支持, 如 OpenGL 、 等图形库。一些面向对象风格的应用程序框架也都为双缓冲 X 窗 口 系 统[8] 、 如 ET + + 、 技术提 供 了 不 同 程 度 的 支 持, [9 - 10 ] [11 - 12 ] [1 , 4 ] MFC 、 Java 、 . NET 等。 [4 ] 虽然 . NET 框架中内置了双缓冲技术 , 但是我们发现, 很多. NET程序员在开发 Windows 窗体应用程序时, 仍不能正 确地使用双缓冲技术消除图形闪烁 。 许多 . NET 程序员还是 这不但增加了实现 使用传统的手工编码方式来实现双缓冲, 难度, 而且有时还会引入其他的一些编程问题 。 造成 . NET 程 序员不正确使用双缓冲技术的主要原因有两个: 一个是没有 正确地理解 Windows 窗 体 重 绘 模 型; 另 一 个 就 是 没 有 掌 握 . NET框架中内置的双缓冲技术 。 本文通过研究 Windows 窗体重绘模型, 以及 . NET 框架中 来探讨如何在 Windows 窗 与双缓冲技术密切相关的一些类, 体应用 程 序 中 使 用 双 缓 冲 技 术 来 消 除 图 形 闪 烁 。 在 分 析 Windows 窗体重绘模型基础上, 阐述引起图形闪烁的本质原 因; 提出两种基于双缓冲技术的 GDI + 无闪烁绘图方法: 一种 是控件默认的双缓冲绘图, 另一种是自定义双缓冲绘图 。 以 模拟时钟为例, 详细地说明如何在实际的项目开发过程中使 用双缓冲技术消除图形闪烁 。
。绘图密集型应用程序, 如动画、 视频游戏等, 往往会导
致其所绘制的图形出现闪烁 。闪烁使图形具有不可接受的外 会严重地影响用户体验 。 观, 有许多 消 除 图 形 闪 烁 的 方 法, 如 增 量 更 新 ( incremental update ) [2] 、页 面 切 换 ( page flipping ) [3] 、双 缓 冲 ( double buffering) [4] 等。每种方法都有其不同的优缺点, 也都有其不 同的适用范围。增量更新的缺点是不适用于难以判断无效区 域的编程场景, 优点是能在某种程度上提高程序运行效率; 页 面切换的缺点是需要显卡硬件的支持, 优点是运行效率最高; 双缓冲的缺点是需要较多的内存, 优点是适用范围广泛。 在 一般编程场景下, 大多数开发人员还是喜欢使用双缓冲技术 来消除图形闪烁。 双缓冲技术的基本思想是不直接在屏幕的显存( 称为前 端缓冲区) 中绘图, 而是先将图形绘制到一块内存( 称为后端 缓冲区) 中, 然后再将后内存中已绘制好的图形复制到显存 中( 见图 1 ) 。由于所有的绘图操作都是在后端缓冲区内完成 的, 而在屏幕上只执行一次呈现图形操作, 因而能消除由多重 绘制所引起的图形闪烁 。
Journal of Computer Applications 计算机应用,2012,32( S2) : 136 - 139 文章编号: 1001 - 9081 ( 2012 ) S2 - 0136 - 04
ISSN 1001-9081 CODEN JYIIDU
2012-12-31 http: / / www. joca. cn
+MFC+GDI双缓冲避免图形闪烁
// TODO: Add your specialized creation code here SetTimer(1,10,NULL); return 0; } 利用定时器直接进行 10 毫秒的屏幕刷新,这样效果会出现不停的闪烁的情况. 解决方法利用双缓冲,首先触发 WM_ERASEBKGND,然后修改返回 TRUE; 定义变量: CBitmap *m_pBitmapOldBackground ; CBitmap m_bitmapBackground ; CDC m_dcBackground; //绘制背景 if(m_dcBackground.GetSafeHdc()== NULL|| (m_bitmapBackground.m_h Object == NULL)) {
MemDC.CreateCompatibleDC(NULL); //这时还不能绘图,因为没有地方画 ^_^ //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的 大小 MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色 MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255)); //绘图 MemDC.MoveTo(……); MemDC.LineTo(……);
} 说到这里可能又有人要说了 , 为什么一个简单图形看起来没有复杂图形那么闪呢? 这是因为复杂图形占的面积大,重画时造成的反差比较大,所以感觉上要闪得厉 害一些,但是闪烁频率要低。 那为什么动画的重画频率高,而看起来却不闪?这里,我就要再次强调了,闪烁 是什么?闪烁就是反差,反差越大,闪烁越厉害。因为动画的连续两个帧之间的 差异很小所以看起来不闪 。 如果不信 , 可以在动画的每一帧中间加一张纯白的帧 , 不闪才怪呢。 2、如何避免闪烁 在知道图形显示闪烁的原因之后,对症下药就好办了。首先当然是去掉 MFC 提 供的背景绘制过程了。实现的方法很多, * 可以在窗口形成时给窗口的注册类的背景刷付 NULL * 也可以在形成以后修改背景 static CBrush brush(RGB(255,0,0)); SetClassLong(this->m_hWnd,GCL_HBRBACKGROUND,(LONG)(HBRU SH)brush); * 要简单也可以重载 OnEraseBkgnd(CDC* pDC)直接返回 TRUE. 这样背景没有了,结果图形显示的确不闪了,但是显示也象前面所说的一样,变 得一团乱。怎么办?这就要用到双缓存的方法了。双缓冲就是除了在屏幕上有图 形进行显示以外,在内存中也有图形在绘制。我们可以把要显示的图形先在内存 中绘制好 , 然后再一次性的将内存中的图形按照一个点一个点地覆盖到屏幕上去 (这个过程非常快,因为是非常规整的内存拷贝)。这样在内存中绘图时,随便 用什么反差大的背景色进行清除都不会闪,因为看不见。当贴到屏幕上时,因为 内存中最终的图形与屏幕显示图形差别很小 (如果没有运动 , 当然就没有差别) , 这样看起来就不会闪。 3、如何实现双缓冲 首先给出实现的程序,然后再解释,同样是在 OnDraw(CDC *pDC)中: CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设备
C#环境下GDI+绘图效率研究
C#环境下GDI+绘图效率研究作者:温铭毅来源:《中国科技博览》2015年第05期[摘要]本文在简单介绍GDI和GDI+的基础上,指出GDI+在绘制动画时效率不足的劣势,并对三种不同的GDI+动画绘图方式进行了详细的阐述;最后实现了一个GDI+界面绘图程序,比较和验证了三种不同方式的绘图性能。
实验表明,使用双缓冲和bitblt结合的方式,可以有效的解决直接绘制方式的闪烁问题,提高绘图效率。
[关键词]GDI+;动态绘图;双缓冲;bitblt中图分类号:P631.84 文献标识码:A 文章编号:1009-914X(2015)05-0134-011.引言GDI是微软公司的著名的二维图形引擎,GDI+则是微软公司为了提高显示效果而推出的一种新型图形引擎。
GDI是Graphics Device Interface的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有Windows程序的图形输出。
GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。
顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,并添加了许多新的功能。
作为图形设备接口的GDI+使得应用程序开发人员在输出屏幕和打印机信息的时候无需考虑具体显示设备的细节,他们只需调用GDI+库输出的类的一些方法即可完成图形操作,真正的绘图工作由这些方法交给特定的设备驱动程序来完成,GDI+使得图形硬件和应用程序相互隔离.从而使开发人员编写设备无关的应用程序变得非常容易。
Microsoft Windows GDI+服务分为以下3个主要部分:(1)二维矢量图形。
矢量图形由图元组成,而图元则由一系列坐标系统的点集组成。
VC中的GDI双缓冲绘图
CBitmap* m_pOldBmp;
ATL程序中,可在atlgdi.h找到基于ATL程序的内存DC:
class CMemoryDC : public CDC { public: // Data members HDC m_hDCOriginal; RECT m_rcPaint; CBitmap m_bmp; HBITMAP m_hBmpOld; // Constructor/destructor CMemoryDC(HDC hDC, RECT& rcPaint) : m_hDCOriginal(hDC), m_hBmpOld(NULL) {
双缓冲绘图原理
普通绘图操作
物理DC绘图 操作 屏幕
双缓冲绘图操作
物理DC绘图 操作 屏幕
内存DC
实现过程
1. 2. 3. 4. 5. 6.
创建兼容DC 创建兼容位图 用兼容DC关联兼容位图 使用兼容DC绘图 将兼容DC拷贝到物理DC上 回收兼容位图和兼容DC,防止资源泄露
实现代码
CPaintDC dc(this);
// 绘图区域 CRect rectClient; GetClientRect(&rectClient);
// 创建兼容DC
CDC dcMem; dcMem.CreateCompatibleDC(&dc); // 创建兼容位图,使兼容DC与之关联,否则兼容DC则是一个1*1的单色位图 CBitmap bitmap;
SetViewportOrg(-m_rcPaint.left, -m_rcPaint.top);
} ~CMemoryDC() {
::BitBlt(m_hDCOriginal, m_rcPaint.left, m_rcPaint.top, m_rcPaint.right - m_rcPaint.left, m_rcPaint.bottom m_rcPaint.top, m_hDC, m_rcPaint.left, m_rcPaint.top, SRCCOPY); SelectBitmap(m_hBmpOld);
一种基于自定义剪切区集合的MFC程序GDI绘图优化方法-浙江中控技术股份有限公司
一种基于自定义剪切区集合的MFC程序GDI绘图优化方法罗幸明,徐伟强浙江中控技术股份有限公司,浙江杭州,310053摘要:传统MFC程序GDI绘图仅考虑屏幕刷新闪烁的优化,而对于绘图内容本身的优化考虑有限。
常规应用下,GDI绘图本身确实不会成为程序的性能瓶颈,但在高分辨率、复杂画面的绘制显示时,这个问题就不得不考虑了。
通常我们会使用系统剪切区进行优化控制,但是实际应用发现当分辨率或者画面复杂度大于一定程度后,该优化的性能提升有限。
鉴于此,本文提出了一种简单可行的基于自定义剪切区集合判断的MFC程序GDI绘图优化方法,可以有效解决高分辨率、复杂画面的GDI绘图性能问题。
关键词:自定义剪切区、MFC、GDI、绘图One Optimizing Design Based On Custom Clipping Region Sets Of MFC Programs Drawing With GDILuo Xingming,Xu WeiqiangZhejiang SUPCON Co.,Ltd, Hangzhou, Zhejiang, 310053Abstract:When drawing with GDI of traditional MFC programs,the most considering things is the screen flashing problems but not drawing itself.Normally drawing performance will not be the choke point,but it really will be when screen resolution is high enough or graphics is complex enough.It is usual to resolve this problem by using system clipping region,but after some industial practice we found that the benefits from this optimizing is limited.Based on this situation,this paper presents a simple effective and practical optimizing design based on custom clipping region sets which can effectivly improve drawing performance of complex graphics in industrial field. Keyword:Custom Clipping Region Sets, MFC, GDI, Drawing基金项目“石化、轨道交通行业分布式综合监控系统(SCADA)研发及应用示范”资助1.GDI概述GDI(Graphics Device Interface)是Windows操作系统的传统图形子系统,负责与设备无关的图形绘制,Win32 API为应用程序提供了丰富的绘图函数和功能,而MFC又对他们进行了C++类的封装。
gdi双缓冲绘图
gdi双缓冲绘图.txt30生命的美丽,永远展现在她的进取之中;就像大树的美丽,是展现在它负势向上高耸入云的蓬勃生机中;像雄鹰的美丽,是展现在它搏风击雨如苍天之魂的翱翔中;像江河的美丽,是展现在它波涛汹涌一泻千里的奔流中。
以下是最简单的双缓冲代码,注释的地方很重要:CRect rect;static BOOL bColor=false;GetClientRect(&rect);CDC dcMem;dcMem.CreateCompatibleDC(pDC); //创建与视图的设备相兼容的内存设备,新的设备不具有与原设备相同的设备属性与背景色.CBitmap bmp;bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom); //创建一个与视图兼容的位图,只有根据原设备来创建位图,才能从设备中获取像素点组成位图,因为双缓冲需要保留原设备中已有的图像,因此需要调用这个方法CBitmap* pOldBmp=dcMem.SelectObject(&bmp); //选择位图,只是修改了设备属性,并没有真正绘图.if(bColor){dcMem.SelectStockObject(WHITE_PEN);}else{dcMem.SelectStockObject(BLACK_PEN);}bColor=!bColor;for(int i=0;i<rect.Width();i++) {dcMem.MoveTo(i,0);dcMem.LineTo(i,rect.bottom);}pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY); //将在内存中绘制好的图像重新显示到视图中,pDC与dcMem不必兼容.dcMem.SelectObject(pOldBmp);pOldBmp->DeleteObject();双缓冲技术绘图当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。
双缓冲
双缓冲图形刷新技术顾名思义是采用双缓存实现的。传统的绘图方式实际上是一种单缓冲。在windows中每一种设备都在内存中有一个设备描述表与其对应,这个设备描述表实际上就是一个内存缓冲区。传统的绘图中我们是将图形绘制在设备描述表缓冲区中,然后由gdi自动的将设备描述表中的图像拷贝到显存中进行显示。这样一个自动的拷贝过程屏蔽了传统的绘图方式是单缓冲的实质,使我们感觉到我们是在直接操纵显存一样。双缓冲图形刷新技术在内存中有两片缓存,除了设备描述表以外还有一个需要手动建立的与设备描述表缓冲区(前端缓冲区)相兼容的后备缓冲区。绘图过程中,首先将图形绘制在后备缓冲区中,然后在手动的将后备缓冲区中的图像拷贝到前端缓冲区中,再由gdi自动将前端缓冲区中的图像拷贝到显存完成图形的显示过程。
//先用背景色将位图清除干净,这里我用的是白色作为背景
//你也可以用自己应该用的颜色
MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
//绘图
MemDC.MoveTo(……);
MemDC.LineTo(……);
//将后备缓冲区中的图形拷贝到前端缓冲区
1、编写一个刷新速度很慢的应用程序,可以设计为通过点击鼠标来进行屏幕刷新。通过该试验可以发现即使屏幕的刷新速度很慢,但是在每次刷新的时候仍然存在屏幕的问题,只是闪烁不是很明显。
2、编写一个刷新速度很快的应用程序,并在程序中应用双缓冲图形刷新技术。通过该试验可以发现虽然屏幕刷新速度很快,但是采用了双缓冲图新刷新技术以后,屏幕不存在闪烁。
CBitmap MemBitmap;
//建立与屏幕设备描述表(前端缓冲区)兼容的内存设备描述表句柄(后备缓冲区)
使用双缓存来解决GDI下的闪烁问题
。 引 言
在 进 行 图 形 图 像 处 理 的 软 件 中 , 般 的 图形 处 理 程 序 需 一 要 大 量 的绘 图操 作 , 要 解 决绘 图 的 效 率 和 效 果 问题 : 者 表 首 前 现 在 性 能 方 面 , 否 有 延 迟 , 个 小 小 的 交 互 操 作 是 否 要 等 上 是 一 几秒才 能看到 结果 ;后者表现 在软件 中 的图像是否 闪烁? 比 如 , O D a 中 加 入 如 下 代 码 就 可 看 到 闪烁 。 在 nr w0
维普资讯
第 2 卷 第 1 期 7 7
VO .ቤተ መጻሕፍቲ ባይዱ7 12
计 算 机 工 程 与 设计
Co u e n ie r ga d De in mp trE gn e i n sg n
20 年 9 06 月
S pt 0 6 e .2 0
N O. 7 1
摘 要 : 图形 图 像 处 理 过 程 中 , 在 当显 示 绘 制 的 图像 时 , 时 会 出现 闪 烁 的 情 况 。本 丈从 窗 口 、 口 、 有 视 坐标 系统 的 基 本 概 念 和 关 系 出 发 , 要 讲 解 了如 何 使 用 双 缓 存 来 解 决 GD 下 的 闪 烁 问题 此 方 法 已经 应 用 于 项 目地 质 资料 解 释 系统 中对 井 曲 线 的 主 I
De l g wi ik r r b e a o t a i t f c e o lm b u n hl p GD1 t o b eb fe i g h d u l u r wi n
HAN — a_ S o S Li I HIHa —U n .
(.Colg f nomainS in e n eh oo y 1 l eo Ifr t ce c dT c n lg ,Not s Unv ri ,Xi n7 0 6 ,Chn ; 2 e o a r Wet ies y h t 10 9 a ia .De at n f pr me t o
使用GDI在窗口上画出一个图片
memhdc = createcompitabledc(dc)
selectobject(memhdc,图片句柄)
BitBlt(hDc,0,0,100,24,memdc,0,0,SRCCOPY)
===============================
Dim img As Long, img_W As Long, img_H As Long
GdipLoadImageFromFile StrPtr("C:\TestImage.png"), img
GdipGetImageWidth img, img_W
GdipGetImageHeight img, img_H
注意咯 第三~第六个参数是原来图片中要截取的部分;第七~第十呢则是画到哪里以及画出来多大的设置。
(4)贴图刷
贴图刷子 跟其它刷子一样 我们需要创建刷子 另外我们需要先初始化图片:)
来看代码:
Dim img As Long, textureBrush As Long
GdipLoadImageFromFile StrPtr("C:\TestImage.png"), img
'GdipDisposeImage img
当然 这里面载入长宽是可选的。
最后呢 别忘记释放Image,否则内存突然没了可不要找我~
(2)来自资源文件:GdipLoadImageFromStream
这个函数主要是用来从资源文件(RES)载入图像的,怎么载入呢?我们来看函数,函数是从Stream载入,但是我们VB6没有集成Stream对象,从RES读取出来(LoadResData)也只是返回Byte()。不过很好,OLE提供了一个函数能够将Byte()变为一个IStream对象——我们需要这个API
C#使用BufferedGraphics实现GDI+双缓冲绘图
使用双缓冲的图形可以减少或消除重绘显示图面时产生的闪烁。
使用双缓冲时,更新的图形首先被绘制到内存的缓冲区中,然后,此缓冲区的内容被迅速写入某些或所有显示的图面中。
显示图形的重写相对简短,这通常可以减少或消除有时在更新图形时出现的闪烁。
使用C# GDI+绘图,实现双缓冲绘图有几种方法,在这篇文章中,将介绍其中的一种——使用BufferedGraphics实现GDI+双缓冲绘图。
下面的代码示例演示如何使用BufferedGraphics对象绘制以下图形,这些图形使用几种类型的缓冲实现。
单击窗体将启动或停止一个计时器,该计时器将引起绘制更新。
绘制更新使您可以观察双缓冲的效果。
右击窗体将循环使用下列绘制模式:∙对于Form,直接绘制到Handle。
∙对使用OptimizedDoubleBuffer控件样式的OnPaint方法进行重写,以进行绘制∙对于不使用OptimizedDoubleBuffer控件样式的窗体方法,重写OnPaint方法以进行绘制。
在每种模式下都将绘制文本,以标识当前模式并描述按下每个鼠标按钮时发生的行为。
using System;using ponentModel;using System.Drawing;using System.Windows.Forms;namespace BufferingExample{public class BufferingExample : Form{private BufferedGraphicsContext context;private BufferedGraphics grafx;private byte bufferingMode;private string[] bufferingModeStrings ={ "Draw to Form without OptimizedDoubleBufferring control style","Draw to Form using OptimizedDoubleBuffering control style","Draw to HDC for form" };private System.Windows.Forms.Timer timer1;private byte count;public BufferingExample() : base(){// Configure the Form for this example.this.Text = "User double buffering";this.MouseDown += newMouseEventHandler(this.MouseDownHandler);this.Resize += new EventHandler(this.OnResize);this.SetStyle( ControlStyles.AllPaintingInWmPaint | erPaint, true );// Configure a timer to draw graphics updates.timer1 = new System.Windows.Forms.Timer();timer1.Interval = 200;timer1.Tick += new EventHandler(this.OnTimer);bufferingMode = 2;count = 0;// Retrieves the BufferedGraphicsContext for the// current application domain.context = BufferedGraphicsManager.Current;// Sets the maximum size for the primary graphics buffer// of the buffered graphics context for the application// domain. Any allocation requests for a buffer larger// than this will create a temporary buffered graphics// context to host the graphics buffer.context.MaximumBuffer = new Size(this.Width+1,this.Height+1);// Allocates a graphics buffer the size of this form// using the pixel format of the Graphics created by// the Form.CreateGraphics() method, which returns a// Graphics object that matches the pixel format of the form.grafx = context.Allocate(this.CreateGraphics(),new Rectangle( 0, 0, this.Width, this.Height ));// Draw the first frame to the buffer.DrawToBuffer(grafx.Graphics);}private void MouseDownHandler(object sender, MouseEventArgs e){if( e.Button == MouseButtons.Right ){// Cycle the buffering mode.if( ++bufferingMode > 2 )bufferingMode = 0;// If the previous buffering mode used// the OptimizedDoubleBuffering ControlStyle,// disable the control style.if( bufferingMode == 1 )this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );// If the current buffering mode uses// the OptimizedDoubleBuffering ControlStyle,// enabke the control style.if( bufferingMode == 2 )this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false );// Cause the background to be cleared and redraw.count = 6;DrawToBuffer(grafx.Graphics);this.Refresh();}else{// Toggle whether the redraw timer is active.if( timer1.Enabled )timer1.Stop();elsetimer1.Start();}}private void OnTimer(object sender, EventArgs e){// Draw randomly positioned ellipses to the buffer.DrawToBuffer(grafx.Graphics);// If in bufferingMode 2, draw to the form's HDC.if( bufferingMode == 2 )// Render the graphics buffer to the form's HDC.grafx.Render(Graphics.FromHwnd(this.Handle));// If in bufferingMode 0 or 1, draw in the paint method.elsethis.Refresh();}private void OnResize(object sender, EventArgs e){// Re-create the graphics buffer for a new window size.context.MaximumBuffer = new Size(this.Width+1,this.Height+1);if( grafx != null ){grafx.Dispose();grafx = null;}grafx = context.Allocate(this.CreateGraphics(),new Rectangle( 0, 0, this.Width, this.Height ));// Cause the background to be cleared and redraw.count = 6;DrawToBuffer(grafx.Graphics);this.Refresh();}private void DrawToBuffer(Graphics g){// Clear the graphics buffer every five updates.if( ++count > 5 ){count = 0;grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);}// Draw randomly positioned and colored ellipses.Random rnd = new Random();for( int i=0; i<20; i++ ){int px = rnd.Next(20,this.Width-40);int py = rnd.Next(20,this.Height-40);g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255),rnd.Next(0,255), rnd.Next(0,255)), 1),px, py, px+rnd.Next(0, this.Width-px-20), py+rnd.Next(0, this.Height-py-20));}// Draw information strings.g.DrawString("Buffering Mode:"+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10);g.DrawString("Right-click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22);g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34);}protected override void OnPaint(PaintEventArgs e){grafx.Render(e.Graphics);}[STAThread]public static void Main(string[] args){Application.Run(new BufferingExample());}}}。
使用双缓存来解决GDI下的闪烁问题
使用双缓存来解决GDI下的闪烁问题
韩丽娜;石昊苏
【期刊名称】《计算机工程与设计》
【年(卷),期】2006(27)17
【摘要】在图形图像处理过程中,当显示绘制的图像时,有时会出现闪烁的情况.本文从窗口、视口、坐标系统的基本概念和关系出发,主要讲解了如何使用双缓存来解决GDI下的闪烁问题.此方法已经应用于项目地质资料解释系统中对井曲线的修改和显示部分,实践证明,这种方法是可行的.
【总页数】3页(P3258-3260)
【作者】韩丽娜;石昊苏
【作者单位】西北大学,信息科学技术学院,陕西,西安,710069;咸阳师范学院,计算机科学系,陕西,咸阳,712100;西北政法学院,信息网络中心,陕西,西安,710063
【正文语种】中文
【中图分类】TP311.11
【相关文献】
1.在GDI+中使用双缓存 [J], 申晓
2.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
3.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
4.VC6.0下使用GDI+为应用程序添色彩 [J], 费之茵
5.基于双缓存技术解决某模拟系统实时显示屏幕闪烁的方法 [J], 董燕;周燕明;崔卫兵
因版权原因,仅展示原文概要,查看原文内容请购买。
