《Windows程序设计》读书笔记之五

图形基础

                                                                                    见钱眼开 于 2005-4-16

    图形设备接口(GDI:Graphics Device Interface)是Windows的子系统,负责在显示器和打印机上显示图形。

    GDI由几百个函数调用和一些相关数据类型组成,包含在GDI32.dll动态连接库中。GDI命令通过设备驱动程序访问显示器和打印机设备。GDI支持与设备无关的图形。

    图形输出设备分为两大类:光栅设备和矢量设备。显示器、打印机都是光栅设备,它们以点模式表示图像。矢量设备使用线来绘制图像。

    在屏幕或打印机上显示的图形类型本身可以被分为几类,通常称为“图元”。它们是:

u       直线和曲线      线条是所有矢量图形绘制系统的基础。线条用设备描述表中选中的当前画笔绘制。

u       填充区域        当一系列直线或曲线封闭了一个区域时,该区域就可以当前GDI画刷对象进行填充。画刷可以是实现色彩、图案或者位图。

u       位图            位图是位的矩形数组。这些位对应显示设备上的象素,它们是光栅图形的基础。GDI支持两种类型位图:老的“设备有关”位图,是GDI对象;新的“设备无关”位图,可以存储在磁盘文件中。

u       文本           

    无法简单分类的其他:

u       映射模式和变换  默认以象素为单位

u       元文件          以二进制形式存储的GDI命令的集合

u       区域            形状任意的复杂区

u       路径            GDI内部存储的直线和曲线的集合。路径可以用于绘图、填充和剪裁,还可以转换为区域。

u       剪裁            绘图可以限制在客户区的某一部分中,这就是所谓的剪裁。剪裁通常通过区域或路径来定义。

u       调色板          定制调色板通常限于显示256色的显示器。可以改变除20种系统保留外的236种色彩。

    要在一个图形输出设备(显示器或打印机)上绘图,必须先获得一个设备描述表句柄。设备描述表中包含许多确定GDI函数如何在输出设备上工作的当前“属性”。

    最常用的获取并释放设备描述表句柄的办法是,在处理WM_PAINT消息时,调用BeginPaintEndPaint;在处理非WM_PAINT消息时,调用GetDCReleaseDC(绘图区域为窗口客户区)以及GetWindowDCReleaseDC(绘图区域为整个窗口)。

    BeginPaintGetDCGetWindowDC获得的设备描述表句柄都与显示器上的窗口有关。获取设备描述表句柄有一个更通用的函数是CreateDC

    hdc = CreateDC(pszDriver,pszDevice,pszOutput,pData);

   

    Delete(hdc);

    下列调用可获得整个屏幕的设备描述表句柄:

    Hdc = CreateDC(TEXT(“DISPLAY”,NULL,NULL,NULL,NULL));

    调用CreateIC函数可以获得一个信息描述表,无法使用它绘制图形。

    调用CreateCompatibleDC函数创建一个兼容指定设备的内存设备描述表,显示表面默认只有一个单色象素宽度和高度。因此绘制前必须将一个合理宽度和高度的位图选进内存设备描述表,然后使用GDI函数在位图上绘图。

调用CreateMetaFile函数创建元文件:

hdcMeta = CreateMetaFile(pFileName);

Hmf = CloseMetaFile(hdcMeta);

    一个设备描述表通常代表一个物理显示设备。调用GetDeviceCaps函数可获得有关该设备的信息。

    打印机以“每英寸的象素数”表示分辨率;显示器以水平和垂直方向总的象素数如1024×768表示分辨率。调用GetSystemMetricsGetDeviceCaps都可以得到屏幕象素数。字体大小一般以“磅“为单位表示。 一磅 大约等于1/72英寸。为什么都是 10磅 字体,还分大字体和小字体呢?一般情况下假定显示器分辨率为每英寸96个象素,而选择大字体时,假定为每英寸120象素。因此,屏幕分辨率越高,同一号字体越小。

    一个象素颜色值可以以1位、8位、16位或者24位表示。GetDeviceCaps可返回指定设备上每个象素的颜色位数。一般使用COLORREF类型来表示颜色值,它是一个32位无符号长整数,从024位每8位分别代表红、绿、蓝值。

    下表列举了设备描述表的基本属性以及获取和设置每一种属性的方法:

 

设备内容属性

默认值

修改该值的函数

取得该值的函数

Mapping Mode

MM_TEXT

SetMapMode

GetMapMode

Window Origin

(0, 0)

SetWindowOrgEx

OffsetWindowOrgEx

GetWindowOrgEx

Viewport Origin

(0, 0)

SetViewportOrgEx

OffsetViewportOrgEx

GetViewportOrgEx

Window Extents

(1, 1)

SetWindowExtEx

SetMapMode

ScaleWindowExtEx

GetWindowExtEx

Viewport Extents

(1, 1)

SetViewportExtEx

SetMapMode

ScaleViewportExtEx

GetViewportExtEx

Pen

BLACK_PEN

SelectObject

SelectObject

Brush

WHITE_BRUSH

SelectObject

SelectObject

Font

SYSTEM_FONT

SelectObject

SelectObject

Bitmap

None

SelectObject

SelectObject

Current Position

(0, 0)

MoveToEx

LineTo

PolylineTo

PolyBezierTo

GetCurrentPositionEx

Background Mode

OPAQUE

SetBkMode

GetBkMode

Background Color

White

SetBkColor

GetBkColor

Text Color

Black

SetTextColor

GetTextColor

Drawing Mode

R2_COPYPEN

SetROP2

GetROP2

Stretching Mode

BLACKONWHITE

SetStretchBltMode

GetStretchBltMode

Polygon Fill Mode

ALTERNATE

SetPolyFillMode

GetPolyFillMode

Intercharacter Spacing

0

SetTextCharacterExtra

GetTextCharacterExtra

Brush Origin

(0, 0)

SetBrushOrgEx

GetBrushOrgEx

Clipping Region

None

SelectObject

SelectClipRgn

IntersectClipRgn

OffsetClipRgn

ExcludeClipRect

SelectClipPath

GetClipBox

    在注册窗口类前,如果在窗口类风格中指定CS_OWNDC风格,则该类每个窗口都将独自有一个设备描述表;如果在窗口类风格中指定CS_CLASSDC风格,则该类每个窗口都将共享一个设备描述表;如果上述两种风格都没有包含,则返回一个临时设备描述表。SaveDCRestoreDC函数分别用以保存或恢复某个状态时设备描述表的一些属性。

    GetPixelSetPixel函数分别用以读、写某个象素。

    LineTo                      画直线

    PolyLinePolyLineTo       画一组相连直线

    PolyPolyLine                画多组相连直线

    ArcArcTo                 画椭圆线

    PolyBezierPolyBezierTo   画贝赛尔样条

    Rectangle                   画矩形

    Ellipse                     画椭圆

    RoundRect                   画圆角矩形

    Pie                         画饼形

    Chord                       画弓形

    在设备描述表中有个“当前位置(current position)”属性,画直线时表示直线起点。调用GetCurrentPositionEx可获取这一属性。

    RectangleEllipse等绘制封闭区域图形的函数,在绘制线条的同时,还将使用画刷填充封闭区域。

    使用GDI对象应注意的三条规则:

l         使用完毕务必删除自己创建的GDI对象

l         禁止删除在有效设备描述表中使用的GDI对象

l         禁止删除原有GDI对象

    创建一个Pen对象:

    hPen = CreatePen(iPenStyle,iWidth,crColor) 

    LOGPEN logpen;

    hPen = CreatePenIndirect(&logpen);

    删除一个Pen对象:

    DeleteObject(hPen);

    返回Pen对象的属性:

    GetObject(hPen,sizeof(LOGPEN),(LPVOID)&logpen);

    返回设备描述表中的Pen对象:

    hPen = GetCurrentObject(hdc,OBJ_PEN);

    设置Pen模式:

    SetROP2(hdc,iDrawMode);   //Pen颜色和目标象素颜色进行某种按位布尔运算

    设置背景模式:

    SetBKMode(hdc,TRANSPARENT);

    设置背景颜色:

    SetBKColor(hdc,crColor);

    创建一个Brush对象:

    hBrush = CreateSolidBrush(crColor);   //实体画刷

    hBrush = CreateHatchBrush(iHatchStyle,crColor); //背影画刷

    hBrush = CreatePatternBrush(hBmp);   //位图画刷

    hBrush = CreateDIBPatternBrush(hBmp);//设备无关位图画刷

    hBrush = CreateBrushIndirect(&logbrush);

 

    “映射方式”是一种几乎影响所有客户区绘图的设备描述表属性。几乎所有GDI函数都使用“逻辑单位“;而所有非GDI函数都使用”设备单位(即象素单位)“。所有设备坐标

系都以象素为单位,X轴上的值从左到右递增,Y轴上的值从上到下递增。

    设备坐标一般可以分为三种:

l         屏幕坐标    以屏幕左上角为原点,调用CreateDC返回。用于CreateWindow(非子窗口)MoveWnidow(非子窗口)、GetMessagePosGetCursorPosWindowFromPoint等与窗口无关的函数。

l         窗口坐标    以窗口左上角为原点,调用GetWindowDC返回。一般不太使用。

l         客户区坐标  以客户区左上角为原点,调用GetDC返回。ClientToScreenScreenToClient函数使客户区坐标和屏幕坐标之间相互转换。

    视点(ViewPort)坐标基于设备坐标系;而窗口原点(WindowOrg)坐标基于逻辑坐标系。不管窗口原点和视点如何改变,设备坐标原点(0,0)始终是屏幕、窗口、客户区的左上角。因此,不论改变视点(ViewPort)坐标值还是窗口原点(WindowOrg)坐标值,本质上都是在改变逻辑坐标系的原点值。设置视点等于设置设备坐标系中逻辑坐标的原点。设置窗口原点等于设置逻辑坐标系中逻辑坐标的原点。

    SetViewportOrgEx ( hdc, 10,20, NULL)将设备点(10,20)映射为逻辑点(0,0)

    SetWindowOrgEx (hdc, 10, 20, NULL)将逻辑点(10,20)映射为设备点(0,0)

    区域是对显示器上一个范围的描述,这个范围是矩形、多边形和椭圆的组合。区域可以用于绘制和剪裁,通过将区域选进设备描述表,就可以用区域来进行剪裁(就是说将绘图范围限制为客户区的一部分)。

    创建一个区域:

    hRgn = CreateRectRgn(xLeft,yTop,xRight,yBottom);

    hRgn = CreatePolygonRgn(&point,iCount,iPolyFillMode);

    组合区域:

    iRgnType = CombineRgn(hDestRgn,hSrcRgn,hSrcRgn1,iCombine);

    将区域选进设备描述表:

    SelectObject(hdc,hRgn);SelectClipRgn(hdc,hRgn);

                       

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值