zoukankan      html  css  js  c++  java
  • Gdiplus中实现双Buffer绘图

    在编写win32 GUI相关的程序的时候,最直接的方法是使用GDI API进行绘制操作。一般为了图形绘制过程中为避免绘制过程闪动,而多采用双Buffer的做法,具体是先在一个内存DC中线将图像绘制好,然后采用BitBlt函数将该内存DC中绘制好的图像贴到目标DC中(该目标DC即是待绘制窗口的DC)。在内存DC中绘图的时候,需先创建该DC,然后根据需要创建各种Pen,各种Brush,将Pen/Brush选进去,绘制完成之后,再将原来的Pen/Brush选回去,最后执行InvalidateRect函数使窗口中的指定区域无效,触发WM_PAINT消息,在响应WM_PAINT消息中,执行BitBlt函数。

    该过程使用GDI函数形式的API,操作起来不是很方便,好在Windows给我们提供了一个更好的选择,那就是Gdiplus,在提供相同基本功能前提下,C++对象形式的API使用起来更加方便,而且还提供了常见的变换API,让相关的图形绘制操作变得更省心了。

    这里仅介绍在Gdiplus过程中如何实现爱GDI中类似的双Buffer绘图功能,其核心实现是使用Graphics这个对象。先看其构造函数定义,如下

    1 Graphics(hdc) 
    2 Graphics(hdc, hdevice) 
    3 Graphics(hwnd, icm) 
    4 Graphics(image) 

    从其构造函数可以看出,Graphics对象的绘制过程,可以在的DC上进行,可以在窗口上进行,也可以在一个Image对象上进行,形式非常的灵活,此处实现双Buffer绘制即是利用这一灵活性,另外对应还用到的还有Graphics对象的DrawImage方法,该方法可以将一个Image对象,绘制到构造函数所提供的上下文里头去。如此不难看出此处的双Buffer绘制的操作过程如下

    1,新建一个Image对象,命名为men_image,该对象用于在内存中保存绘制结果

    2,新建一个Graphics对象,命名为drawer,构造函数传入mem_image

    3,使用drawer进行各项所需的绘制过程,结果保存到mem_image中

    4,使用InvalidateRect函数是制定窗口中的区域无效,触发WM_PAINT消息

    5,在响应WM_PAINT消息中,使用另外一个Graphics对象,该对象可以是一个临时对象(构造函数传入HDC),或持续存在的对象(构造函数传入HWND),然后利用Graphics::DrawImage,将mem_image对象显示到窗口中。

    如此处理的话,实现了将绘制过层(drawer完成的)与显示过程(响应WM_PAINT过程)相分离,绘制过程不需关心显示过程,各自的功能内聚,降低了耦合,简化了各自内部的实现流程。

     PS: 在VS2010中使用Gdiplus的代码,以下头文件必须放在文件首部,再引用其他头文件,否则编译不过,Faint!

    #include <windows.h>
    #include <gdiplus.h>
  • 相关阅读:
    iphone、UI设计和PKM的混谈
    社保名单核对的难题
    LVDS技术原理和设计简介
    系统级芯片设计语言和验证语言的发展
    芯片封装(Chip Package)类型70种
    数字电平标准 TTL CMOS ECL LVDS CML...
    什么是施密特触发器(Schmitt Trigger)?
    组合逻辑电路中竞争冒险的分析
    ASIC设计流程(ASIC design flow)
    这18条背下来没人敢和你忽悠CPU
  • 原文地址:https://www.cnblogs.com/lanyuliuyun/p/3050577.html
Copyright © 2011-2022 走看看