5.1、GDI图形接口

一、GDI简介
	GDI(GraphicsDevice Interface),即图形设备接口。主要负责系统与绘图程序之间的信息交换,处理所有Windows程序的绘图输出。
	在window操作系统下,绝大多数具备图形界面的应用程序都离不开GDI,我们利用GDI提供的函数就可以方便的在屏幕、打印机等输出设备输出图形,文本等操作。GDI使程序员无需关心硬件设备及驱动,就可以将应用程序的输出转换为硬件设备上的输出。实现程序开发与硬件设备的隔离,大大方便了开发工作。

GDI具有如下特点:
	1. 不允许程序直接访问物理显示硬件,通过称为“设备环境”的抽象接口间接访问显示硬件;
	2. 程序需要与显示硬件(显示器、打印机等) 进行通讯时,必须首先获得与特定窗口相关联的设备环境	3. 用户无需关心具体的物理设备类型;
	4. Windows参考设备环境的数据结构完成数据的输出。

二、GDI工作原理
	结合画图过程来理解GDI的工作原理。画图的过程一般为:绘画者选择合适的绘图工具,应用其绘画技巧完成一幅画。三个要素:绘图者、绘图工具、绘画技巧。
	设备描述表   ->    绘图者,所有绘画过程均需该对象参与
	GDI对象     ->   绘图工具,包括画刷、画笔、字体、位图等
	GDI函数     ->   绘画技巧。用来绘制GDI的基本图形   

三、设备描述表
	要想在输出设备上输出图形或文字,我们先必须获得一个称为设备描述表(DC:Device Context)的对象句柄。以它为参数调用各种GDI函数实现各种文字或图形输出。
	设备描述表保存了绘图操作中共同需要的设置信息。如当前的画刷、画笔、字体等GDI对象属性。
	取得描述表相当于请画家来绘图。windows提供了几种取得设备句柄的方法。当处理一个消息时取得了设备句柄,应在退出窗口函数之前释放。
1、BeginPaint、EndPaint           //BeginPaint里面的DC,是脏区域的DC
2、GetDc、ReleaseDC            //GetDC获得客户区的DC
3、GetWindowDC、ReleaseDC   //GetWindowDc获得整个窗口区域的DC
	上述不同的DC可以形象表示为请不同画家来画图。如画油画、国画等不同画家。

	三DC用于不同场合,同样是绘图,如果用WindowDC,那就从标题栏开始绘,如果是客户区DC,那就从客户区原点开始绘,因为鼠标的坐标,是以客户区为起始点的, 故直接画图时,经常使用GetDC。
	BeginPaint的DC妙用,在于更新一小块区域时,得重画背景,但是背景往往是一块大区域,画背景是个费力不讨好的事,因为画完之后你就污染了其他地方的前景,为了快速,所以就提供了BeginPaint的DC,在这块区域上,你直接画背景,但不污染干净区域的绘图,这是这个DC存在的原因。
        win32上,你可以进一步使用RGN的概念来进行裁剪区的设置, 也可以合并这些区域. 很多手机平台, 采用了同样的原理, 默认使用裁剪区的DC, 是个良好的改进.

四、GDI对象
	GDI对象相当于绘图工具。包括画笔、画刷、位图等。取得设备描述表后,就可以从GDI绘图工具中选入合适的对象。绘图完成后,再把工具放回原处。步骤如下:
	1、准备好GDI对象。如CreatePen、CreateSoldBrush
	2、设备描述表通过SelectObject选入GDI对象
	3、绘图完成后,再通过SelectObject将GDI对象放回原处。
 
五、三种图形输出类型
应用程序可以使用GDI创建三种类型的图形输出:矢量输出、位图图形输出和文本输出。
1、矢量图形输出
  矢量图形输出指的是创建线条和填充图形,包括点、直线、曲线、多边形、扇形和矩形的绘制。

2、位图输出
  位图图形的输出是指位图图形函数以位图形式存储的数据进行操作,它包括各种位图和图标的输出。
  在屏幕上表现为对若干行和列的像素的操作,在打印机上则是若干行和列的点阵的输出。
  位图图形输出的优点是速度很快,它是直接从内存到显存的拷贝操作。缺点是需要额外的内存空间

3、文本输出
  与DOS字符方式下的输出不同,Windows是按图形方式输出的。
  这样,在输出文本时,必须以逻辑坐标为单位计算文本的输出位置,而不是象DOS下以文本行为单位输出文本。这比DOS下的文本输出要难一些。
  按图形方式输出文本给文本输出带来很大的灵活性。用户可以通过调用各种GDI函数,制造出各种文本输出效果,包括加粗、斜体、设置颜色等。
	Windows还提供了一种TrueType(写真字体)。TrueType字体用一组直线和曲线命令及一些参数来描述字体的轮廓。Windows可以通过参数来调整直线的长度和曲线的形状,从而实现对字体的自由缩放。

六、MFC中与GDI有关的类
	设备上下文类,用于设置绘图属性和绘制图形;
	绘图对象类,封装了各种GDI绘图对象,包括画笔、刷子、字体、位图、调色板和区域。

(1)设备上下文类
  设备上下文类包括CDC和它的派生类CClientDC、CPaintDC、CWindowDC、CMetaFileDC。
  ·CDC是设备上下文类的基类,除了一般的窗口显示外,还用于基于桌面的全屏幕绘制和非屏幕显示的打印机输出。CDC类封装了所有图形输出函数,包括矢量、位图和文本输出。

  ·CClientDC(客户区设备上下文)用于客户区的输出,它在构造函数中封装了GetDC(),在析构函数中封装了ReleaseDC()函数。一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。
   CClientDCdc(this);              //this一般指向本窗口或当前活动视图
   dc.TextOut(10,10,str,str.GetLength());

  ·CPaintDC用于响应窗口重绘消息(WM_PAINT)时的绘图输出。CPaintDC在构造函数中调用BeginPaint()取得设备上下文,在析构函数中调用EndPaint()释放设备上下文。EndPaint()除了释放设备上下文外,还负责从消息队列中清除WM_PAINT消息。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。CPaintDC也只能用在WM_PAINT消息处理之中。

  ·CWindowDC用于窗口客户区和非客户区(包括窗口边框、标题栏、控制按钮等)的绘制。除非要自己绘制窗口边框和按钮(如一些CD播放程序等),否则一般不用它。

	·CMetaFileDC专门用于图元文件的绘制。图元文件记录一组GDI命令,可以通过这一组GDI命令重建图形输出。使用CMetaFileDC时,所有的图形输出命令会自动记录到一个与CMetaFileDC相关的图元文件中。


(2)图形对象类
图形对象类包括CGdiObject、画笔、刷子、字体、位图、调色板、区域等。
  CGdiObject是图形对象类的基类,但该类不能直接为应用程序所使用。
  要使用GDI对象,必须使用它的派生类:画笔、刷子、字体、位图、区域等等。

  使用图形对象要注意两点:
  a.同其他MFC对象一样,GDI对象的创建也要分为两步:第一步,是定义一个GDI绘图对象类的实例;第二步调用该对象的创建方法真正创建对象	b.创建对象:使用该对象,首先要调用CDC::SelectObject()将它选入到设备上下文中,同时保存原来的设置到一个GDI对象指针比如说pOldObject中。在使用完后,再用SelectObject(pOldObject)恢复原来的设置。

画笔(CPen)
  封装GDI画笔,可被选中为设备上下文中当前所用的笔。
  画笔用于绘制对象的边框以及直线和曲线。缺省画笔画一条与一个像素等宽的黑色实线。
  要使用画笔,首先要定义一个画笔(CPen pen;)然后创建画笔。

  创建画笔有两种方法:
  (1)使用CPen::CreatePen(intnPenStyle,int nWidth,DWORD crColor)进行初始化。
  第一个参数是笔的风格。nPenStyle可选值有:PS_SOLID 实线、PS_DOT 虚线等。
  第二个参数是线的宽度,按逻辑单位。若线宽设为0,则不管是什么映射模式下,线宽始终为一个像素。
  第三个参数是线的颜色,可以选16种VGA颜色中的一种。颜色的设置用一个RGB宏(COLORREF RGB(cRed,cGreen,cBlue))来指定。
  (2)创建笔的另一个方法是使用库存对象。
  SelectStockObject可从以下库存笔中选择一个:BLACK_PEN 黑笔N、ULL_PEN 空笔(不画线或边框)、WHITE_PEN 白笔等。

刷子(CBrush)
  封装GDI刷子,可用作设备上下文中当前刷子。
  刷子用来填充一个封闭图形对象(如矩形、椭圆)的内部区域。缺省的刷子将封闭图形的内部填充成全白色。
  可以用以下几种方法创建刷子:
  (1)CreateSolidBrush(DWORD crColor)创建一个实心刷子,用一种颜色填充一个内部区域。
  (2)CreateHatchBrush(int nIndex,DWORD crColor);创建一个带阴影的刷子,nIndex代表一种影线模式。
  (3)用CreatePatternBrush(CBitmap*pBitmap)用一个位图作刷子,一般采用8X8的位图,因为刷子可以看作8X8的小位图。
  (4)同样可以使用SelectStockObject()从库存刷子中选取一个:BLACK_BRUSH 黑色刷子、WHITE_BRUSH 白色刷子、GRAY_BRUSH 灰色刷子等
 
字体(CFont)
  封装了GDI字体对象,用户可以建立一种GDI字体,并使用CFont的成员函数来访问它。
 
位图(CBitmap)
  封装了GDI位图,它提供成员函数装载和操作位图。
 
调色板(CPalette)
  封装GDI调色板,它保存着系统可用的色彩信息,是应用程序和彩色输出设备上下文的接口。

常见的绘图任务
输出文本
  GetTextMetrics(); 返回当前使用字体的尺寸描述,用于进行字体大小计算。
  SetTextColor(int nColor); 设置前景色。
  SetBkColor(int nColor); 设置背景色。
  TextOut:文字输出。
  TabbedTextOut:象TextOut一样显示正文,可以使用制表键Tab。
  ExtTextOut:在指定的矩形中显示正文。可以用该函数删去超出矩形的正文,用正文背景填充矩形,调整字符间隔。
  DrawText:在指定矩形种显示正文,可以使用制表键Tab。在格式化矩形时调整正文左对齐、右对齐或居中;还可以在一个词中断开以适应矩形边界。
 
画点
  SetPixel:在指定坐标处按指定色彩画一点。
 
画线
  MoveToEx将直线起点移动到指定坐标处,LineTo从起点开始画直线到终点处。使用的线型由当前所用画笔指定。
 
画弧
  Arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4);
 
封闭图形
  矩形:Rectangle
  圆角矩形:RoundRect
  椭圆:Ellipse
  饼形图:Pie
  封闭的多边形:Polygon
 
其它绘图函数
  FillRect:用指定颜色填充矩形且不画边线。
  FloodFill:用给定的颜色,利用当前所选的刷子填充显示的底面被一个边线所包围的区域,如多边形区域的填充。
  ExtFloodFill:用给定的颜色,利用当前刷子填充表面被一个边线包围的区域,用户可以有选择地填充一个由指定颜色组成的区域。
  InvertRect:在某一矩形区域内反显现有颜色
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值