Delphiのキャンバスはシンプルで便利であるといつも聞いてきました。これで、キャンバスを使用して、単純なツリーメカニズムのグラフィカルな表現を実装します。このシステムは、ノードの選択、動き、木の保存、木の開放などをサポートします。再帰とポインターは利便性に使用されますが、効率に問題がありますが、問題を迅速に解決することは依然として良いことです。
このプログラムは混乱して書かれています、ようこそ、[email protected]
ソースコードは次のとおりです。
ユニットU_Tree;
インタフェース
用途
Windows、メッセージ、sysutils、クラス、グラフィック、コントロール、フォーム、ダイアログ、
extctrls、stdctrls、jpeg、menus、inifiles32;
タイプ
tobj =レコード
Objid:文字列;
CenterX:整数;
Centery:整数;
Typeno:整数;
選択:boolean;
fnode:string;
示された:boolean;
終わり;
tfrm_tree = class(tform)
パネル:Tpanel;
paintbox1:tpaintbox;
パネル2:Tpanel;
ラベル1:tlabel;
Button2:tbutton;
Button1:Tbutton;
Button3:Tbutton;
Button4:Tbutton;
Button5:Tbutton;
Button6:Tbutton;
mainmenu1:tmainmenu;
fadestream1:tmenuitem;
randomRandomSelection1:tmenuitem;
savedialog1:tsavedialog;
OpenDialog1:Topendialog;
Button7:tbutton;
手順paintbox1Mousedown(送信者:tobject; button:tmousebutton;
シフト:tshiftState; x、integer);
手順formcreate(sender:tobject);
手順button1click(sender:tobject);
手順button2click(sender:tobject);
手順paintbox1paint(sender:tobject);
手順button3click(sender:tobject);
手順button4click(sender:tobject);
手順button5click(sender:tobject);
手順button6click(sender:tobject);
手順paintbox1mouseup(sender:tobject; button:tmousebutton;
シフト:tshiftState; x、integer);
手順paintbox1Mousemove(送信者:tobject; shift:tshiftstate; x、
Y:整数);
手順fadestream1click(sender:tobject);
手順randomRandomSelection1click(sender:tobject);
手順button7click(sender:tobject);
プライベート
{プライベート宣言}
Toolno:整数;
beginx、beginy、endx、endy:integer;
クリック:boolean;
OLST:tlist;
セリッド:文字列;
root:boolean;
Searilid:整数;
手順DrawNode(ID:String);
手順addobj(id:string; x、y:integer; typeno:integer; selected:boolean; fnode:string; show:boolean);
function getobj(id:string):tobj;
function getPobj(ID:文字列):ポインター;
関数getSelect:tobj;
function haveselect:boolean;
関数clickobj(x、y:integer):string;
手順Drawfull;
手順Setedected(x、y:integer);
関数SetShowsel(x、y:integer):tobj;
手順setfnode(id:string);
手順setcnode(id:string);
手順が透明になっています。
手順ClearCanvas;
手順moveobj(dx、dy:integer);
手順movenode(dx、dy:integer; id:string);
手順Movelocal(dx、dy:integer);
//手順
公共
{公開宣言}
終わり;
var
FRM_TREE:TFRM_TREE;
実装
{$ r *.dfm}
{tform1}
手順tfrm_tree.drawnode(id:string);
var
OldBrushColor:TColor;
OldPencolor:TColor;
OBJ:TOBJ;
始める
obj:= getobj(id);
frm_tree.paintbox1.canvas do
始める
obj.showedがいれば
始める
OldBrushColor:= Brush.Color;
OldPencolor:= Pen.Color;
OBJ.Selectedの場合
始める
Pen.Color:= RGB(255,0,0);
終わり;
Brush.Color:= $ 00FF31FF;
Ellipse(obj.centerx-10、obj.centery-10、obj.centerx+10、obj.centery+10);
Pen.Color:= $ 00FF31FF;
obj.typeno> 0の場合
始める
Moveto(obj.centerx、obj.centery);
Lineto(getobj(obj.fnode).centerx、getobj(obj.fnode).centery);
終わり;
Pen.Color:= OldPencolor;
Brush.Color:= OldBrushColor;
終わり;
終わり;
終わり;
手順tfrm_tree.paintbox1mousedown(sender:tobject;
ボタン:TMouseButton;
var
curobj:tobj;
始める
ボタン= mbleftの場合
始める
のケースツールノ
1:
始める
searilid:= searilid+1;
rootの場合
始める
addobj(inttostr(searilid)、x、y、0、false、 ''、true);
drawnode(inttostr(searilid));
root:= false;
終わり
それ以外
始める
HavesElectの場合
始める
addobj(inttostr(searilid)、x、y、1、false、getSelect.objid、true);
drawnode(inttostr(searilid));
label1.caption:= 'ノードを追加、id:'+inttostr(searilid);
終わり
それ以外
始める
label1.caption:= 'ノードを選択してください!';
終わり;
終わり;
終わり;
2:
始める
SetSelected(x、y);
終わり;
3://表示
始める
// ClearCanvas;
curobj:= setshowsel(x、y);
curobj.objid <> ''の場合
始める
clearshowed;
curobj:= setshowsel(x、y);
curobj.showed:= true;
setfnode(curobj.fnode);
setcnode(curobj.objid);
drawfull;
終わり;
終わり;
4://モバイル
始める
clickobj(x、y)<> ''の場合、クリック:= true;
beginx:= x;
beginy:= y;
終わり;
5:
始める
clickobj(x、y)<> ''の場合、クリック:= true;
beginx:= x;
beginy:= y;
終わり;
終わり;
終わり
それ以外
始める
SetSelected(x、y);
終わり;
終わり;
手順tfrm_tree.formcreate(sender:tobject);
始める
olst:= tlist.create;
toolno:= 0;
root:= true;
セリッド:= '';
Searilid:= 0;
クリック:= false;
PaintBox1.Canvasを使用します
始める
brush.color:= clwhite;
fillrect(rect(0,0、paintbox1.width、paintbox1.height));
終わり;
終わり;
手順tfrm_tree.button1click(sender:tobject);
始める
toolno:= 1;
終わり;
手順tfrm_tree.button2click(sender:tobject);
始める
toolno:= 2;
終わり;
手順tfrm_tree.addobj(id:string; x、y、typeno:integer;
選択:boolean;
var
obj: ^tobj;
始める
new(obj);
obj.objid:= id;
obj.centerx:= x;
obj.centery:= y;
obj.typeno:= Typeno;
obj.selected:= selected;
obj.fnode:= fnode;
obj.showed:= show;
olst.add(obj);
終わり;
関数tfrm_tree.getobj(id:string):tobj;
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。objid = id thenの場合
始める
結果:= tobj(olst.items [i]^);
壊す;
終わり;
終わり;
終わり;
関数TFRM_TREE.GETSELECT:TOBJ;
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。選択した場合
始める
結果:= tobj(olst.items [i]^);
壊す;
終わり;
終わり;
終わり;
関数tfrm_tree.haveselect:boolean;
var
I、J:整数;
始める
結果:= false;
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。選択した場合
始める
結果:= true;
壊す;
終わり;
終わり;
終わり;
手順tfrm_tree.drawfull;
var
I、J:整数;
始める
//paintbox1.canvas.fillrect(rect(0,0,0,0,0,0,0,0,0、width, paintbox1.height));
ClearCanvas;
J:= olst.count;
i:= 0からj-1の場合
始める
drawnode(tobj(olst.items [i]^)。objid);
終わり;
終わり;
手順tfrm_tree.paintbox1paint(sender:tobject);
始める
drawfull;
終わり;
手順TFRM_TREE.SETSELECTED(x、y:integer);
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。selected:= false;
if(tobj(olst.items [i]^)。Centerx-10 <x)および(tobj(olst.items [i]^)。センターx+10> x)
および(tobj(olst.items [i]^)。センターリー10 <y)および(tobj(olst.items [i]^)。センター+10> y)
始める
tobj(olst.items [i]^)。selected:= true;
label1.caption:= 'ノードIDを選択:'+ tobj(olst.items [i]^)。objid;
終わり;
終わり;
drawfull;
終わり;
手順tfrm_tree.button3click(sender:tobject);
始める
toolno:= 3;
終わり;
関数tfrm_tree.setshowsel(x、y:integer):tobj;
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。selected:= false;
if(tobj(olst.items [i]^)。Centerx-10 <x)および(tobj(olst.items [i]^)。センターx+10> x)
および(tobj(olst.items [i]^)。センターリー10 <y)および(tobj(olst.items [i]^)。センター+10> y)
始める
tobj(olst.items [i]^)。show:= true;
label1.caption:= 'ノードIDを見てください:'+ tobj(olst.items [i]^)。objid;
結果:= tobj(olst.items [i]^);
壊す;
終わり;
終わり;
終わり;
手順TFRM_TREE.CLEARSHOWED;
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。show:= false;
終わり;
終わり;
手順tfrm_tree.setfnode(id:string);
var
curobj:^tobj;
始める
id <> ''の場合
始める
// new(curobj);
curobj:= getpobj(id);
curobj^.typeno = 1 do
始める
curobj^.showed:= true;
curobj:= getpobj(curobj^.fnode);
終わり;
curobj^.showed:= true;
//処分(curobj);
終わり;
終わり;
手順tfrm_tree.setcnode(id:string);
var
curobj:^tobj;
I、J:整数;
始める
// curobj:= getobj(id);
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。fnode = id thenの場合
始める
curobj:= getpobj(tobj(olst.items [i]^)。objid);
curobj^.showed:= true;
setcnode(curobj^.objid);
終わり;
終わり;
終わり;
手順TFRM_TREE.CLEARCANVAS;
始める
//paintbox1.canvas
paintbox1.canvas.fillrect(rect(0,0、paintbox1.width、paintbox1.height));
終わり;
手順tfrm_tree.button4click(sender:tobject);
始める
クリック:= false;
paintbox1.canvas.fillrect(rect(0,0、paintbox1.width、paintbox1.height));
olst.clear;
root:= true;
セリッド:= '';
Searilid:= 0;
{paintbox1.canvas do
始める
Pen.Width:= 2;
pen.color:= clblack;
pen.style:= psclear;
brush.style:= bssolid;
brush.color:= clwhite;
長方形(0,0、paintbox1.width、paintbox1.height);
終わり;}
終わり;
手順tfrm_tree.button5click(sender:tobject);
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。show:= true;
終わり;
drawfull;
終わり;
関数tfrm_tree.getpobj(id:string):pointer;
var
I、J:整数;
始める
結果:= nil;
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。objid = id thenの場合
始める
結果:= olst.items [i];
壊す;
終わり;
終わり;
終わり;
関数tfrm_tree.clickobj(x、y:integer):string;
var
I、J:整数;
始める
結果:= '';
J:= olst.count;
SetSelected(x、y);
i:= 0からj-1の場合
始める
if(tobj(olst.items [i]^)。Centerx-10 <x)および(tobj(olst.items [i]^)。センターx+10> x)
および(tobj(olst.items [i]^)。センターリー10 <y)および(tobj(olst.items [i]^)。センター+10> y)
始める
label1.caption:= 'ノードIDをクリック:'+ tobj(olst.items [i]^)。objid;
結果:= tobj(olst.items [i]^)。objid;
壊す;
終わり;
終わり;
終わり;
手順tfrm_tree.button6click(sender:tobject);
始める
toolno:= 4;
終わり;
手順tfrm_tree.moveobj(dx、dy:integer);
var
I、J:整数;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。centerx:= tobj(olst.items [i]^)。centerx+dx;
tobj(olst.items [i]^)。Centery:= tobj(olst.items [i]^)。Centery+dy;
終わり;
// drawfull;
終わり;
手順tfrm_tree.paintbox1mouseup(sender:tobject; button:tmousebutton;
シフト:tshiftState; x、integer);
始める
のケースツールノ
4:
始める
クリックした場合
始める
endx:= x;
endy:= y;
moveobj((endx-beginx)、(endy-beginy));
終わり;
クリック:= false;
終わり;
5:
始める
クリック:= false;
終わり;
終わり;
終わり;
手順tfrm_tree.paintbox1mousemove(sender:tobject; shift:tshiftstate;
x、y:整数);
始める
if(クリック)then
始める
のケースツールノ
4:
始める
moveobj((x-beginx)、(y-beginy));
beginx:= x; beginy:= y;
drawfull;
終わり;
5:
始める
movenode((x-beginx)、(y-beginy)、getSelect.objid);
Movelocal((x-beginx)、(y-beginy));
beginx:= x; beginy:= y;
drawfull;
終わり;
終わり;
終わり;
終わり;
手順TFRM_TREE.FADESTREAM1CLICK(SENDER:TOBJECT);
var
セルタイル:文字列;
キュリッド:文字列;
curobj:tobj;
lstdate:tinifile32;
I、J:整数;
始める
J:= olst.count;
savedialog1.executeの場合
始める
セルタイル:= savedialog1.filename;
lstdate:= tinifile32.create(servile+'。dat');
lstdate.writeinteger( 'title'、 'num'、j);
i:= 0からj-1の場合
始める
curobj:= tobj(olst.items [i]^);
キュリッド:= curobj.objid;
lstdate.writestring(curid、 'objid'、curobj.objid);
lstdate.writeinteger(curid、 'centerx'、curobj.centerx);
lstdate.writeinteger(curid、 'Centery'、curobj.centery);
lstdate.writeinteger(curid、 'typeno'、curobj.typeno);
lstdate.writebool(curid、 'selected'、curobj.selected);
lstdate.writestring(curid、 'fnode'、curobj.fnode);
lstdate.writebool(curid、 'show'、curobj.showed);
終わり;
終わり;
終わり;
手順tfrm_tree.randomrandomselection1click(sender:tobject);
var
セルタイル:文字列;
// curid:string;
lstdate:tinifile32;
I、J:整数;
始める
opendialog1.executeの場合
始める
セルタイル:= opendialog1.filename;
クリック:= false;
paintbox1.canvas.fillrect(rect(0,0、paintbox1.width、paintbox1.height));
olst.clear;
root:= true;
セリッド:= '';
Searilid:= 0;
lstdate:= tinifile32.create(selfile);
j:= lstdate.readinteger( 'title'、 'num'、0);
i:= 1からjの場合
始める
addobj(lstdate.readstring(inttostr(i)、 'objid'、 '')、lstdate.readinteger(inttoStr(i)、 'centerx'、0)、lstdate.readeger(inttoStr(i)、 'centery'、0) 、lstdate.readinteger(inttostr(i)、 'typeno'、0)、lstdate.readbool(inttostr(i)、 'selected'、true)、lstdate.readstring(inttostr(i)、 'fnode'、 '')、 lstdate.readbool(inttostr(i)、 'show'、true));
終わり;
searilid:= j;
root:= false;
drawfull;
終わり;
終わり;
手順tfrm_tree.button7click(sender:tobject);
始める
toolno:= 5;
終わり;
手順tfrm_tree.movenode(dx、dy:integer; id:string);
var
I、J:整数;
curobj:^tobj;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。fnode = id thenの場合
始める
curobj:= getpobj(tobj(olst.items [i]^)。objid);
curobj^.centerx:= curobj^.centerx+dx;
curobj^.centery:= curobj^.centery+dy;
movenode(dx、dy、curobj^.objid);
終わり;
終わり;
終わり;
手順TFRM_TREE.MOVELOCAL(DX、DY:Integer);
var
I、J:整数;
// curobj:tobj;
始める
J:= olst.count;
i:= 0からj-1の場合
始める
tobj(olst.items [i]^)。選択した場合
始める
tobj(olst.items [i]^)。centerx:= tobj(olst.items [i]^)。centerx+dx;
tobj(olst.items [i]^)。Centery:= tobj(olst.items [i]^)。Centery+dy;
壊す;
終わり;
終わり;
終わり;
終わり。