GDI图形设备接口,WINDOWS大部分的视觉信息都是通过它,一方面WINDOWS自己使用它来显示图形,一方面提供给用户API使用.在WINDOWS可视化世界里,它的重要性不言而喻.
在以前是GDI.EXE提供此接口,在WIN98后改用GDI.DLL,当然GDIK.EXE还是存在的,但是只适用16位应用程序.
GDI一些概念:
一,GDI图元:直线与曲线、填充区域、位图、文本
二,GDI其他一些概念:映射模式和变换、元文件、区域、路径、剪裁、调色板以及打印
图元,就是在屏幕或打印机上显示的图形类型了,比如填充区域,位图.
下面我们看下相关的API函数:
像素:
SetPixel
GetPixel
直线:
MoveToEx 更新当前点,并设置OLDPOINT
LineTo 画一条线,用到PEN对象(看源代码似乎也用到了BRUSH,??)
注意WINDOWS不知道为什么没有提供MOVETO,DELPHI的MOVETO是封装了MOVETOEX。
曲线:
PolyLine 画一系列相连的线,不带TO说明不用更新当前位置了
PolyLineTo 画一系列相连的线,带TO就是第一次要先从当前点画,比PolyLine多一个点
PolyPolyLine 画多组系列相连的线,而此函数则是画数组的数组
AngleArc 画椭圆线
Arc 画椭圆线
ArcTo 画椭圆线
PolyBezier 画贝塞尔样条
PolyBezierTo 画贝塞尔样条
PolyDraw 画一系列相连的线以及贝塞尔样条
FrameRect 画矩形框,不填充
举例:
procedure TForm1.Button1Click(Sender: TObject);
const
AryPoint: array[0..2] of TPoint = ((x:100;y:100),(x:260;y:350),(x:158;y:125));
AryPoint1: array[0..2] of TPoint = ((x:110;y:120),(x:240;y:310),(x:128;y:128));
AryAryPoint: Array[0..2] of PPoint = (@AryPoint[0],@AryPoint1[0],@AryPoint[0]);
begin
Windows.Polyline(Canvas.Handle,AryPoint,Length(AryPoint));
Windows.PolylineTo(Canvas.Handle,AryPoint,Length(AryPoint));
Windows.PolyPolyline(Canvas.Handle,AryAryPoint,[3,3,3],3); //????,不知道为什么不行
end;
procedure TForm1.Button1Click(Sender: TObject);
const
AryPoint: array[0..2] of TPoint = ((x:100;y:100),(x:260;y:350),(x:158;y:125));
begin
Windows.PolyBezier(Canvas.Handle,AryPoint,Length(AryPoint));
Windows.PolyBezierTo(Canvas.Handle,AryPoint,Length(AryPoint));
end;
贝塞尔曲线,共有四个定点,两端点两控制点,两端点不动,两控制点动态改变任意弧形。他的作用,仅亚于直线和椭圆.
填充区域:
FillRect
FillPath
FillRgn
InvertRect 反转
以上三个是专门填充函数
Rectangle 画矩形
RoundRect 画圆角的矩形
Pie 画扇形
Ellipse 画椭圆
Chord 画弓形
Polygon 多边形
举例:
Canvas.Brush.Color := clGreen;
lRect := Bounds(100,100,300,250);
Windows.FillRect(Canvas.Handle,lRect,GetSysColorBrush(COLOR_BTNSHADOW));
以上涉及到矩形,不得不提及几个函数,这些都是惯用的函数:
SetRect
OffsetRect
InflateRect
SetRectEmpty
CopyRect
IntersectRect
UnionRect
IsRectEmpty
PtInRect
var
ARect,BRect: TRect;
begin
Windows.SetRect(ARect,10,10,100,100);
Windows.CopyRect(BRect,ARect);
Windows.OffsetRect(ARect,5,6);
Windows.InflateRect(ARect,-1,-5);
Windows.SetRectEmpty(BRect);
Windows.IntersectRect(BRect,ARect,BRect);
if Windows.IsRectEmpty(BRect) then
Windows.UnionRect(BRect,ARect,BRect);
if Windows.PtInRect(ARect,Mouse.CursorPos) then
MessageBox(0,'Study very Hard!',0,0);
end;
其实后面看到位图与字体那部分时候,我们应该就知道了,其实这些填充函数他们最终都调用了Patblt函数。
设备描述表一些属性
映射模式
视点与窗点
当前位置
MoveToEx
GetCurrentPositionEx
背景模式,背景色
SetBKMode(OPAQUE),SetBKColor(white)
文本颜色
SetTextColor(Black),注意其实DELPHI里的Font.Color也是从这而来的SetTextColor(FHandle, ColorToRGB(Font.Color));
画图模式
SetROP2(R2_COPYPEN),GetROP2
伸展模式
SetStretchBltMode(BLACKONWHITE)
多边形填充模式
SetPolyFillMode(ALTERNATE)
画刷原点
SetBrushOrgEx(0,0)
剪裁区域
SelectClipRgn
ExcludeClipRect
GetClipBox
由于设备描述表属性众多,经常修改后又要恢复,为此GDI也提供俩函数:
SaveDC
RestoreDC
其实映射模式、视点与窗点以及当前位置可以放到一个地方说:
什么是映射模式?说到映射模式不得不说三种坐标:设备坐标和逻辑坐标还有屏幕坐标。当然屏幕也是一个设备,也可以说是设备坐标,但它比较特别,所以单独出来。
WINDOWS为了提供统一的接口,所以产生了逻辑坐标,其实不管是什么坐标都是标识一个位置的。这样说来,我们基本所用到的坐标都是逻辑坐标。比如:Windows.TextOut(hdc,x,y,str,length(str))中X和Y都是逻辑坐标。但是逻辑坐标最终计算时候还是要转换为设备坐标的。
何谓映射,从逻辑坐标到设备坐标的转换就是映射。我们这里的坐标都有个单位,设备坐标单位是像素,而逻辑坐标单位可多着了。这样的映射关系就多了,也就有了映射模式这一说法。
映射模式可多着了:(因为设备坐标都是像素,只有逻辑坐标不同,所以)
{ Mapping Modes } 逻辑坐标 原点
MM_TEXT = 1; 像素 左上角
MM_LOMETRIC = 2; 0.1mm 左下角
MM_HIMETRIC = 3; 0.01mm 左下角
MM_LOENGLISH = 4; 0.1in 左下角
MM_HIENGLISH = 5; 0.01in 左下角
MM_TWIPS = 6; 1/1440in 左下角
MM_ISOTROPIC = 7; 任意 任意 这两种模式可以改变视口和窗口的范围
MM_ANISOTROPIC = 8; 任意 任意
另外这里还有一个视点和窗点之说,其实他们俩其实说的就是一个设备一个窗口。视点就是在设备坐标的位置,窗点就是在窗口的位置。
GDI提供两函数将视点与窗点之间转换
DPtoLP :设备点转换到逻辑点
LPtoDP: 逻辑点转换到设备点
举例:
procedure TForm1.Button1Click(Sender: TObject);
var
AryPoint: Array[0..2] of TPoint;
begin
AryPoint[0] := Point(0,0);
AryPoint[1] := Point(100,100);
Windows.LPtoDP(Canvas.Handle,AryPoint,2) //将FORM1的坐标转换成屏幕坐标
end;
另外,GDI还提供两函数,进行原点设置:
Windows.SetViewportOrgEx(Canvas.Handle,1,6,0);
Windows.SetWindowOrgEx(Canvas.Handle,1,6,0);
当然还有两取得原点API:
GetViewportOrgEx
GetWindowOrgEx
图形其实是非常复杂的,历史是非常悠久源远的,以前图形没学好,现在简单总结下。继续努力!