在Panel上绘图的实现

近期制作了FDS的一个建模工具,由于知识有限,做出的效果是2D的。昨天上课的时候看老师画一个长方体,突然想到,为什么不给普通的2D图形加画上几条直线,就能实现2D图形的3D视觉效果呢?于是回来马上做了尝试,果然,效果很好,非常满意。但是把测试程序代码移植到FDS建模工具上的时候出现问题了:Panel没有Canvas属性,也不能说没有,实际上在TPanel的实现源码里有Canvas属性,不过是Protected不允许外部访问。怎么办?简单思考了一下,有这么几个方向:
一、把Panel设置成透明的,在Form的Canvas上绘画图形
二、在Panel里面加一个有Canvas属性的组件,然后在那上面绘图
三、想办法在Panel本身上实现画图的方法
通过查资料,改源程序代码,发现方案一,画出的图形总是被Panel本身遮挡(这是由于我程序本身的需要,Panel里面也要套一层Panel),没有找到好的解决办法。
方案二:在Panel里面加了一个Image组件,但引发了更多问题:由于组件是动态生成了,产生了比如如何确定在哪个组件添加的Image,另外Image挡住了Panel的事件响应。总之也是没有很好的解决。
走了很多很多弯路后才最后走到第三步。最后在台湾的一个Delphi论坛上找到了类似的问题:如何在Panel组件上定点写字http://delphi.ktop.com.tw/board.php?cid=168&fid=921&tid=70988源码是C++的,我以前学过一点C++就根据自己的理解转换成了Delphi的,可能有不对的地方,但没想到一运行居然成功了!

uses Math;

procedure TForm1.pnl1Click(Sender: TObject);
var
Panel:TPanel;
PanelCanvas:TControlCanvas;
begin
PanelCanvas:=TControlCanvas.Create;
PanelCanvas.Control:=pnl5;
Panel:=sender as TPanel;
with PanelCanvas do
begin
pen.Color:=clGreen;
MoveTo(Panel.Left,Panel.Top);
LineTo(Panel.left+round(Panel.Height/sqr(2)),Panel.top-round(Panel.Height/sqr(2)));
LineTo(Panel.left+Panel.Width+round(Panel.Height/sqr(2)),Panel.top-round(Panel.Height/sqr(2)));
LineTo(Panel.left+Panel.Width,Panel.top); MoveTo(Panel.Left+Panel.Width,Panel.Top+Panel.Height);
LineTo(Panel.left+Panel.Width+round(Panel.Height/sqr(2)),Panel.top+Panel.Height-round(Panel.Height/sqr(2)));
LineTo(Panel.left+Panel.Width+round(Panel.Height/sqr(2)),Panel.top-round(Panel.Height/sqr(2)));
end; PanelCanvas.Free;
end;

  成功的关键在TControlCanvas的使用,TControlCanvas的Control属性使得Panel的Canvas属性可以被访问使用。

看看TControlCanvas的Control属性说明:Specifies the control associated with the control canvas object.

Panel的更多相关文章

  1. Chrome Developer Tools:Timeline Panel说明

    一.Timeline panel 概况 Timeline工具栏可以详细检测出Web应用在加载过程中,时间花费情况的概览.这些应用包括下载资源,处理DOM事件, 页面布局渲染或者向屏幕绘制元素. 如下图 ...

  2. Ubuntu[1]安装Vesta Control Panel

    参考:http://www.5013.org/archives/819 1)登录 ssh ubuntu@139.199.9.173 ubuntu@139.199.9.173's password: 重 ...

  3. 本地数据Store。Cookie,Session,Cache的理解。Timer类主要用于定时性、周期性任务 的触发。刷新Store,Panel

    本地数据Store var monthStore = Ext.create('Ext.data.Store', { storeId : 'monthStore', autoLoad : false, ...

  4. Delphi控件之---通过编码学习TStringGrid(也会涉及到Panel控件,还有对Object Inspector的控件Events的介绍

    我是参考了万一的博客里面的关于TStringGrid学习的教程,但是我也结合自己的实际操作和理解,加入了一些个人的补充,至少对我有用! 学用TStringGrid之——ColCount.RowCoun ...

  5. 我的面板我做主 -- 淘宝UWP中自定义Panel的实现

    在Windows10 UWP开发平台上内置的XMAL布局面板包括RelativePanel.StackPanel.Grid.VariableSizedWrapGrid 和 Canvas.在开发淘宝UW ...

  6. Extjs Panel

    刚学习Extjs @{ Layout = "~/_SiteLayout.cshtml"; Page.Title = "欢迎访问我的网站!"; } @{ stri ...

  7. Chrome Developer Tools:Network Panel说明

    官方资料:Chrome Developer Tools: Network Panel 一.chrome Developer Tools:Network Panel 从网络面板中可以获取很多有用信息,如 ...

  8. panel的展开,关闭的一种应用。

    js: <script type="text/javascript"> $('#p2').panel({ title: 'panel1', closable: fals ...

  9. ASP.Net 在Update Panel局部刷新后 重新绑定JS方法

    我们知道Asp.Net中的Update Panel可以完成页面的局部刷新(实质上是Ajax),但是局部刷新完后,此区域的控件上所绑定的JS方法就会失效,因为我们用如下方法来重新绑定. var prm ...

  10. Ext.Net 学习随笔 003 Panel基本使用

    Panel() 1.使用Content和Html属性设置Panel内容 前台View代码 @(X.Panel() .ID("panel1") .Width() .Height() ...

随机推荐

  1. HDU 6090 Rikka with Graph —— 2017 Multi-University Training 5

    Rikka with Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. paper 161:python的Json数据解析

    概念 序列化(Serialization):将对象的状态信息转换为可以存储或可以通过网络传输的过程,传输的格式可以是JSON.XML等.反序列化就是从存储区域(JSON,XML)读取反序列化对象的状态 ...

  3. ajax 封装(集中 认证、错误、请求loading处理)

    一.为什么要对 ajax 进行封装:    (在使用antd pro 开发项目时,里面默认是把请求进行了封装的,放在 utils/request.js 中.使用起来非常方便   https://pro ...

  4. SQL学习记录:定义(一)

    --1.在这里@temp是一个表变量,只有一个批处理中有效,declare @temp table; --2. 如果前面加#就是临时表,可以在tempDB中查看到,它会在最后一个使用它的用户退出后才失 ...

  5. Oracle 表空间、用户

    一.表空间 临时表空间 创建临时表空间范例 CREATE TEMPORARY TABLESPACE duke_temp /* 临时表空间名称:duke_temp */ tempfile 'C:\ora ...

  6. yarn 国内加速,修改镜像源

    为什么慢 由于默认情况下执行 yarn 各种命令是去国外的 yarn 官方镜像源获取需要安装的具体软件信息,所以在不使用代理.不翻墙的情况下,从国内访问国外服务器的速度相对比较慢 可以通过以下命令快速 ...

  7. 查找android so文件中绕过c/c++ api直接调用SYSCALL的方法位置

    很多应用会通过arm汇编,自行调用syscall,直接操作系统内核,来绕过c层的hook,保证程序安全 所以想hook的话只能找到这些方法的c入口分别hook 可以通过查找bxls指令找到这些位置

  8. Python笔记(八)_内部函数与闭包

    内部函数 在函数内部定义另一个函数,也就是函数的嵌套 在外部函数的作用域内,外部函数可以随意调用内部函数 由于内部函数的整个定义过程都在外部函数中,所以出了外部函数就无法再被调用了 def outsi ...

  9. webservice 学习笔记 1

    Webservice----------->跨语言服务调用 (视频学习总结) 1-1.有OA系统 需要添加一个功能,登录之后显示天气情况 此时可以使用Webservice eg1: 气象局自己有 ...

  10. 记C函数指针的“小坑”

    今天遇到一个C函数指针的小坑,索性记下来. 我在a.c 文件里面,引用b.c 文件的函数声明作为指针引用 比如在a.c生命一个函数指针 typedef void (*free)(void *val) ...