文档章节

再学 GDI+[50]: 路径 - GetPathPoints、GetPathTypes、TPathData、GetPathData

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 866
阅读 7
收藏 0

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

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

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


本例效果图:



代码文件:
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;

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2008/06/18/1224867.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
私信 提问
Windows的GDI映射方式,逻辑坐标,设备坐标的理解

最近在学Win32的编程,看的是《Windows程序设计第5版》一书,这本书是台湾人翻译的,有些译法和大陆不一样,书中还有一些错误的地方,很多时候需要中英文对照阅读,下载请点击 https://down...

蓝域小兵
08/18
0
0
简述WPF中的画刷(Brush)

-------------------------------------------------------------------------------- 引用或转载时请保留以下信息: 大可山 [MSN:a3news(AT)hotmail.com] http://www.zpxp.com http://www.b......

Andrewniu
09/30
0
0
实战开发:新手小白如何用C++制作经典网游DNF

十年前,那时候的网吧还不叫网咖,那时候没有王者荣耀也没有英雄联盟,那时候梦幻西游刚推出珍宝阁系统,那时候巫妖王的灵魂还封闭在冰封王座。 寻仙、穿越火线、征途、天龙八部……同时在线...

stone15165
05/05
0
0
OSG3.2+Qt5.2.1+VS2012+OSGEarth 2.5编译问题记录

问题1:CMake Error at D:/Qt/Qt5.2.1/5.2.1/msvc201264opengl/lib/cmake/Qt5Gui/Qt5GuiConfigExtras.cmake:16 (message): Failed to find "glu32" in "" with CMAKECXXLIBRARY_ARCHITECTURE ......

天蚕宝衣
2016/11/21
17
0
在C++Builder中使用GDI+的流程

在C++Builder中使用GDI+的流程: 1、 GDI+主要是通过gdiplus.dll进行调用,而BCB没有直接提供与gdiplus.dll对应的静态链接库,所以需要我们自己建立。如果在自己的计算机没有找到文件gdiplus...

hack_tian
04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

颜色模型与颜色应用---RGB颜色模型

中国龙-扬科
7分钟前
0
0
网络优化-tcp和udp的协作

TODO

梦想游戏人
10分钟前
1
0
list和数组转化

Java中List转换为数组,数组转List List转换为Array可以这样处理: ArrayList<String> list=new ArrayList<String>(); String[] strings = new String[list.size()]; list.toArray(strings);......

west_coast
10分钟前
1
0
LSP 商户端API

Your domain:                  lsp-api-merchant.hhs2717.cnVirtualhost conf:             /usr/local/nginx/conf/vhost/lsp-api-merchant.hhs2717.cn.confDirectory of:......

BeanHo
19分钟前
0
0
设计模式 之 访问者模式

设计模式 之 访问者模式 概念 核心理念:将数据结构与算法分离。 使用场景:数据结构不变动,算法经常变动。 1、一个Visitor类存放被访问的对象,访问者主要处理具体算法与行为。 // 访问者...

GMarshal
23分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部