zoukankan      html  css  js  c++  java
  • 再学 GDI+[50]: 路径 GetPathPoints、GetPathTypes、TPathData、GetPathData


    这个例子有错误! 点的类型很多时候不是单一的;

    譬如某个点可能同时是子路径结束点、曲线点、标记点, 此时类型值就是三种类型的复合值.

    遗憾的是做这个例子时, 我还不知道... 放在这里吧, 留个纪念, 记下曾经的幼稚!


    本例效果图:



    代码文件:
    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;
    
  • 相关阅读:
    CentOS-6.9搭建NFS服务器
    CentOS6.9-搭建vsftpd三种模式及参数详解
    CentOS-7.3 MySQL数据库入门简介及源码编译安装MySQL服务
    CentOS7.3系统vsftpd服务简介及vsftpd的三种模式的搭建
    安装CentOS7.4 Linux操作系统
    windows server2008R2 64位 配置 mysql-8.0.15-winx64
    怎么删除服务中的mysql服务
    mysql-8.0.15-winx64 解压版安装 图文详解
    命令行下创建MySQL数据库与创建用户以及授权
    windows 2008r2+php5.6.28环境搭建详细过程
  • 原文地址:https://www.cnblogs.com/del/p/1224867.html
Copyright © 2011-2022 走看看