文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 866
阅读 6
收藏 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
实战开发:新手小白如何用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
MFC用GDI+动感歌词的制作

源代码:http://download.csdn.net/detail/nuptboyzhb/4219669 源代码: 1. 插入一个对话框的资源,删除默认控件,并为对话框创建一个类,命名为ClyricDlg; 2. 在对话框的头文件中添加GDI+相...

长平狐
2012/10/08
236
0

没有更多内容

加载失败,请刷新页面

加载更多

身处小公司,如何在2年内快速突破,拿到大厂offer?|掘金技术征文

本文是我一个朋友的经历,谨以此文告诉那些向往更好的未来发展而一直努力奋斗的朋友们。不管你现在身处什么小公司,都不要气馁,机会还是有的,只要你敢于拼搏奋斗,我相信你一定可以成功的。...

SuShine
10分钟前
0
0
web应用防火墙的作用

web应用防火墙也被称为网站应用级入侵防御系统,按照一些常规的定义,WAF是指通过一些列针对HTTP/HTTPS的安全策略专门为web应用提供保护的产品。它主要用于防御针对网络应用层的攻击,像SQL...

上树的熊
11分钟前
1
0
5分钟掌握var,let和const异同

转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 原文出处:https://dzone.com/articles/javascript-difference-between-var-let-and-const-...

葡萄城技术团队
14分钟前
1
0
gif工具ffmpeg 的安装

ffmpeg 是一个可以将视频生成gif 格式的图片的工具, 下面说说如何安装这个工具吧: 1、 2 3 4 5 配置环境变量:

wangyanbao
15分钟前
0
0
RocketMq在windows下安装

mqnamesrv.cmd -n localhost:9876#启动namesrvmqbroker.cmd #启动brokermqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true//启动控制台java -jar rocketmq-console-ng......

王桥修道院副院长
15分钟前
0
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部