这个例子有错误! 点的类型很多时候不是单一的;
譬如某个点可能同时是子路径结束点、曲线点、标记点, 此时类型值就是三种类型的复合值.
遗憾的是做这个例子时, 我还不知道... 放在这里吧, 留个纪念, 记下曾经的幼稚!
譬如某个点可能同时是子路径结束点、曲线点、标记点, 此时类型值就是三种类型的复合值.
遗憾的是做这个例子时, 我还不知道... 放在这里吧, 留个纪念, 记下曾经的幼稚!
本例效果图:
代码文件:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); end; var Form1: TForm1; implementation {$R *.dfm} uses GDIPOBJ, GDIPAPI; procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.Align := alRight; StringGrid1.FixedCols := 0; StringGrid1.ColCount := 3; StringGrid1.ColWidths[0] := 25; StringGrid1.ColWidths[1] := 25; StringGrid1.ColWidths[2] := 80; StringGrid1.DefaultRowHeight := 20; StringGrid1.Cells[0,0] := 'X'; StringGrid1.Cells[1,0] := 'Y'; StringGrid1.Cells[2,0] := '点类型'; end; procedure TForm1.FormPaint(Sender: TObject); var g: TGPGraphics; p: TGPPen; path: TGPGraphicsPath; points: array of TGPPoint; types: PByte; typestr: string; i: Integer; begin g := TGPGraphics.Create(Canvas.Handle); p := TGPPen.Create(aclRed); path := TGPGraphicsPath.Create; path.StartFigure; path.AddRectangle(MakeRect(30,20,90,40)); path.AddEllipse(MakeRect(30,80,90,180)); path.CloseFigure; g.DrawPath(p, path); SetLength(points, path.GetPointCount); GetMem(types, path.GetPointCount); path.GetPathPoints(PGPPoint(points), Length(points)); path.GetPathTypes(types, Length(points)); StringGrid1.RowCount := Length(points) + 1; for i := 0 to Length(points) - 1 do begin case types^ of $00 : typestr := '路径起始点'; $01 : typestr := '直线点'; $03 : typestr := '贝塞尔线点'; $07 : typestr := '遮盖点'; $10 : typestr := '虚线点'; $20 : typestr := '路径标记'; $80 : typestr := '子路径结束点'; end; StringGrid1.Cells[0, i+1] := IntToStr(points[i].X); StringGrid1.Cells[1, i+1] := IntToStr(points[i].Y); StringGrid1.Cells[2, i+1] := typestr; Inc(types); end; Dec(types, Length(points)); FreeMem(types); types := nil; path.Free; p.Free; g.Free; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var x,y: Integer; begin x := StrToIntDef(StringGrid1.Cells[0,ARow], 0); y := StrToIntDef(StringGrid1.Cells[1,ARow], 0); Repaint; Canvas.Brush.Color := clBlue; Canvas.FillRect(Bounds(x-3,y-3,6,6)); Text := Format('%d,%d',[x,y]); end; end.这个例子有点麻烦, 如果使用 TPathData 类会简单许多, 下面是用 TPathData 实现的代码, 运行效果相同; 不过这样获取的点数组必须是小数数组. 代码如下:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids; type TForm1 = class(TForm) StringGrid1: TStringGrid; procedure FormCreate(Sender: TObject); procedure FormPaint(Sender: TObject); procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); end; var Form1: TForm1; implementation {$R *.dfm} uses GDIPOBJ, GDIPAPI; procedure TForm1.FormCreate(Sender: TObject); begin StringGrid1.Align := alRight; StringGrid1.FixedCols := 0; StringGrid1.ColCount := 3; StringGrid1.ColWidths[0] := 25; StringGrid1.ColWidths[1] := 25; StringGrid1.ColWidths[2] := 80; StringGrid1.DefaultRowHeight := 20; StringGrid1.Cells[0,0] := 'X'; StringGrid1.Cells[1,0] := 'Y'; StringGrid1.Cells[2,0] := '点类型'; end; procedure TForm1.FormPaint(Sender: TObject); var g: TGPGraphics; p: TGPPen; path: TGPGraphicsPath; PathData: TPathData; Points: PGPPointF; Types: PByte; TypeStr: string; i: Integer; begin g := TGPGraphics.Create(Canvas.Handle); p := TGPPen.Create(aclRed); path := TGPGraphicsPath.Create; path.StartFigure; path.AddRectangle(MakeRect(30,20,90,40)); path.AddEllipse(MakeRect(30,80,90,180)); path.CloseFigure; g.DrawPath(p, path); PathData := TPathData.Create; path.GetPathData(PathData); Points := PathData.Points; Types := PathData.Types; StringGrid1.RowCount := PathData.Count + 1; for i := 0 to PathData.Count - 1 do begin case Types^ of $00 : TypeStr := '路径起始点'; $01 : TypeStr := '直线点'; $03 : TypeStr := '贝塞尔线点'; $07 : TypeStr := '遮盖点'; $10 : TypeStr := '虚线点'; $20 : TypeStr := '路径标记'; $80 : TypeStr := '子路径结束点'; end; StringGrid1.Cells[0, i+1] := IntToStr(Trunc(Points.X)); StringGrid1.Cells[1, i+1] := IntToStr(Trunc(Points.Y)); StringGrid1.Cells[2, i+1] := TypeStr; Inc(Points); Inc(Types); end; PathData.Free; path.Free; p.Free; g.Free; end; procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); var x,y: Integer; begin x := StrToIntDef(StringGrid1.Cells[0,ARow], 0); y := StrToIntDef(StringGrid1.Cells[1,ARow], 0); Repaint; Canvas.Brush.Color := clBlue; Canvas.FillRect(Bounds(x-3,y-3,6,6)); Text := Format('%d,%d',[x,y]); end; end.窗体文件:
object Form1: TForm1 Left = 0 Top = 0 Caption = 'Form1' ClientHeight = 276 ClientWidth = 303 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False Position = poDesktopCenter OnCreate = FormCreate OnPaint = FormPaint PixelsPerInch = 96 TextHeight = 13 object StringGrid1: TStringGrid Left = 88 Top = 40 Width = 154 Height = 120 TabOrder = 0 OnSelectCell = StringGrid1SelectCell end end路径中的点类型枚举:
PathPointType = ( PathPointTypeStart = $00, {路径起始点} PathPointTypeLine = $01, {直线点} PathPointTypeBezier = $03, {默认贝塞尔线点} PathPointTypePathTypeMask = $07, {遮盖点} PathPointTypeDashMode = $10, {虚线点} PathPointTypePathMarker = $20, {路径标记} PathPointTypeCloseSubpath = $80, {子路径结束点} PathPointTypeBezier3 = $03 {立体贝塞尔线点} ); TPathPointType = PathPointType;