文档章节

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

涂孟超
 涂孟超
发布于 2014/09/26 15:35
字数 866
阅读 5
收藏 0
点赞 0
评论 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
博文 2004
码字总数 14107
作品 0
深圳
程序员
实战开发:新手小白如何用C++制作经典网游DNF

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

stone15165 ⋅ 05/05 ⋅ 0

为Dll重新构造Lib

分类: Windows Repository 2010-06-12 12:56 1151人阅读 评论(0) 收藏 举报dllmicrosoft正则表达式variables工具文本编辑有些时候, 我们手头只有.dll和.h文件, 没有.lib. 而VC链接必须要提供...

真是杨晓光 ⋅ 2013/03/16 ⋅ 2

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 ⋅ 0

在C++Builder中使用GDI+的流程

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

hack_tian ⋅ 04/11 ⋅ 0

MFC程序开机启动,图片无法加载,显示一片空白

开机时程序无法加载相应的图片,在应该有图片的地方显示为背景色。 程序使用GDI+加载图片,使用相对路径。当双击打开时程序显示正常,而当程序使用注册表添加到开机启动项时,程序开机时的主体部...

饕餮之怒 ⋅ 2013/05/18 ⋅ 1

基于MFC的OpenGL绘图

本文更新版本请点击 [置顶]《基于MFC的OpenGL编程》系列文章 一、简介   GDI是通过设备句柄(Device Context以下简称"DC")来绘图,而OpenGL则需要绘制环境(Rendering Context,以下简称"...

嗯哼9925 ⋅ 2017/12/26 ⋅ 0

MFC用GDI+动感歌词的制作

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

长平狐 ⋅ 2012/10/08 ⋅ 0

C# WinForm开发系列 - GDI+

UI(User Interface)编程在整个项目开发过程中是个颇为重要的环节,任何好的解决方案若没有良好的用户界面呈现给最终用户,那么就算包含了最先进的技术也不能算是好程序。UI编程体现在两个方...

长征2号 ⋅ 2017/11/14 ⋅ 0

VC 6.0 配置和使用gdi+

GDI+ GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,W...

junwong ⋅ 2012/03/23 ⋅ 0

vs 2005 添加GDI配置

在VS2005当中由于自带了GDI+的开发包,所以不需要在安装GDI开发包,这些头文件的位置由VS中的$(WindowsSdkDir)/include自动包含进来了 下午自己添加了好几次,总是出现有报错,,在 stdafx.h...

种地瓜 ⋅ 2015/12/08 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

中标麒麟(龙芯版)7.0优盘安装

########################################## 制作U盘安装盘: 1.准备U盘: PMON环境下U盘必须格式化成ext3; 昆仑固件环境下可以格式化成ext3,ext4 2.把整个镜像 xxx.iso 复制到U盘下面 3....

gugudu ⋅ 8分钟前 ⋅ 0

老司机写的大数据建模五步走

本文将尝试来梳理一下数据建模的步骤,以及每一步需要做的工作。 01 第一步:选择模型或自定义模式 这是建模的第一步,我们需要基于业务问题,来决定可以选择哪些可用的模型。 比如,如果要预...

gulf ⋅ 17分钟前 ⋅ 0

PacificA 一致性协议解读

PacificA 的 paper 在 08 年左右发出来的,比 Raft 早了 6,7 年。 在 PacificA 论文中,他们强调该算法使用范围是 LAN (Local Area Network),讲白了就是对跨机房不友好。 不管是 ZAB,Raf...

黑客画家 ⋅ 19分钟前 ⋅ 0

盘符图标个性化

设置自己的专属盘符图标 准备ico格式的图片文件一个,在根目录下创建autorun.inf文件 文件内容 [Autorun]icon=logo.ico 重新启动或者插拔U盘即可看到结果...

阿豪boy ⋅ 20分钟前 ⋅ 0

Windows下QQ聊天记录中图片的默认存放位置

Windows下QQ聊天记录中图片的默认存放位置在设置中是没有说明的。 实测位置在:D:\Documents\Tencent Files\974101467\Image 其中: “974101467”为对应的QQ号; “C2C”为个人之间的聊天图...

临江仙卜算子 ⋅ 26分钟前 ⋅ 0

GC 的三种基本实现方式

参考资料《代码的未来》(作者: [日] 松本行弘)。 由于并非本人原著(我只是个“搬运工“),SO 未经本人允许请尽情转载。 另外个人像说明一下这里所说的GC指泛指垃圾回收机制,而单指Jav...

xixingzhe ⋅ 27分钟前 ⋅ 0

Android双击退出

/** * 菜单、返回键响应 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(keyCode......

王先森oO ⋅ 31分钟前 ⋅ 0

idea 整合 vue 启动

刚学习Vue 搭建了一个项目 只能命令启动 Idea里面不会启动 尝试了一下修改启动的配置 如下: 1.首先你要保证你的package.json没有修改过 具体原因没有看 因为我改了这个name的值 就没办法启动...

事儿爹 ⋅ 37分钟前 ⋅ 0

redis在windows环境的后台运行方法

在后台运行,首先需要安装redis服务,命令为 redis-server.exe --service-install redis.windows.conf --loglevel verbose 启动,命令为 redis-server --service-start 停止,命令为 redis-...

程序羊 ⋅ 40分钟前 ⋅ 0

比特币现金开发者提出新的交易订单规则

本周,四位比特币现金的四位开发者和研究员:Joannes Vermorel(Lokad),AmaurySéchet(比特币ABC),Shammah Chancellor(比特币ABC)和Tomas van der Wansem(Bitcrust)共同发表了一篇关...

lpy411 ⋅ 44分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部