나는 항상 델파이의 캔버스가 간단하고 사용하기 편리하다고 들었습니다. 이제 캔버스를 사용하여 간단한 트리 메커니즘의 그래픽 표현을 구현합니다. 이 시스템은 노드 선택, 움직임, 나무 저장, 나무 열리는 나무 등을 지원합니다. 재귀와 포인터는 효율성에 약간의 문제가 있지만 문제를 빠르게 해결하는 것이 좋습니다.
이 프로그램은 엉망으로 작성되었습니다. 커뮤니케이션에 오신 것을 환영합니다 : [email protected]
소스 코드는 다음과 같습니다.
UNIT U_TREE;
인터페이스
용도
창, 메시지, 시스템, 클래스, 그래픽, 컨트롤, 양식, 대화, 대화,
extctrls, stdctrls, jpeg, 메뉴, inifiles32;
유형
TOBJ = 레코드
objid : 문자열;
CenterX : 정수;
센터 : 정수;
타자 : 정수;
선택 : 부울;
fnode : 문자열;
보여 주었다 : 부울;
끝;
tfrm_tree = 클래스 (tform)
패널 1 : tpanel;
Paintbox1 : tpaintbox;
패널 2 : tpanel;
라벨 1 : tlabel;
버튼 2 : tbutton;
버튼 1 : tbutton;
버튼 3 : tbutton;
버튼 4 : tbutton;
버튼 5 : tbutton;
버튼 6 : tbutton;
MainMenu1 : tmainmenu;
Fadestream1 : tmenuitem;
RandomRandomSelection1 : tmenuitem;
Savedialog1 : Tsavedialog;
Opendialog1 : 토포 리그;
버튼 7 : tbutton;
절차 Paintbox1mousedown (발신자 : Tobject; Button : TmouseButton;
Shift : TshiftState; X, Y : Integer);
프로 시저 Formcreate (sender : tobject);
절차 버튼 1Click (sender : tobject);
절차 button2click (sender : tobject);
절차 Paintbox1paint (Sender : Tobject);
절차 버튼 3Click (sender : tobject);
절차 버튼 4Click (sender : tobject);
절차 버튼 5Click (sender : tobject);
프로 시저 Button6Click (sender : tobject);
절차 Paintbox1mouseup (sender : tobject; button : tmousebutton;
Shift : TshiftState; X, Y : Integer);
절차 Paintbox1mouseMove (Sender : Tobject; Shift : TshiftState; X,
Y : 정수);
절차 fadestream1click (sender : tobject);
절차 randomRandomSelection1Click (sender : tobject);
절차 버튼 7Click (sender : tobject);
사적인
{개인 선언}
Toolno : Integer; // 1 Draw Dots, 2 Select view 4 이동 5 하위 Move
beginx, beginy, endx, endy : 정수;
클릭 : 부울;
olst : tlist;
Selid : 문자열;
뿌리 : 부울;
Searilid : 정수;
절차 끌기 (id : String);
절차 addObj (id : String; x, y : Integer; typeno : 정수; 선택 : 부울; fnode : String; show : boolean);
함수 getObj (id : String) : tobj;
함수 getPobj (id : String) : 포인터;
함수 getSelect : TOBJ;
기능 허비 : 부울;
함수 clickObj (x, y : 정수) : 문자열;
절차 drawfull;
절차 setSelected (x, y : integer);
함수 setShowsel (x, y : integer) : tobj;
절차 setfnode (id : string);
절차 setcnode (id : string);
절차가 맑아졌습니다.
절차 ClearCanvas;
절차 moveObj (dx, dy : 정수);
절차 movenode (dx, dy : 정수; id : String);
절차 movelocal (dx, dy : 정수);
//절차
공공의
{공개 선언}
끝;
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와 함께
시작하다
obj.show가 있다면
시작하다
OldBrushColor : = Brush.Color;
OldPencolor : = pen.color;
obj.selected
시작하다
펜 콜러 : = RGB (255,0,0);
끝;
Brush.Color : = $ 00ff31ff;
Ellipse (OBJ.CENTERX-10, OBJ.CENTERY-10, OBJ.CENTERX+10, OBJ.CENTERY+10);
펜 콜러 : = $ 00ff31ff;
if obj.typeno> 0이면
시작하다
moveto (obj.centerx, obj.centery);
lineto (getobj (obj.fnode) .centerx, getobj (obj.fnode) .centery);
끝;
펜 콜로르 : = OldPencolor;
Brush.Color : = OldBrushColor;
끝;
끝;
끝;
절차 tfrm_tree.paintbox1mousedown (발신자 : Tobject;
버튼 : tmousebutton;
var
curobj : Tobj;
시작하다
if button = mbleft라면
시작하다
사례 도구
1 :
시작하다
searilid : = searilid+1;
그렇다면 루트
시작하다
addobj (inttostr (searilid), x, y, 0, false, ', true);
Drawnode (inttostr (searilid));
루트 : = 거짓;
끝
또 다른
시작하다
그럼에도 불구하고
시작하다
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 <> ''이면
시작하다
클리어 쇼;
curobj : = setShowsel (x, y);
curobj.showed : = true;
setfnode (curobj.fnode);
setcnode (curobj.objid);
그림자;
끝;
끝;
4 : // 모바일
시작하다
clickObj (x, y) <> ''인 경우 다음을 클릭했습니다 : = true;
beginx : = x;
시작 : = y;
끝;
5 :
시작하다
clickObj (x, y) <> ''인 경우 다음을 클릭했습니다 : = true;
beginx : = x;
시작 : = y;
끝;
끝;
끝
또 다른
시작하다
setSelected (x, y);
끝;
끝;
절차 tfrm_tree.formcreate (sender : tobject);
시작하다
olst : = tlist.create;
도구 : = 0;
루트 : = 참;
Selid : = '';
Searilid : = 0;
클릭 : = 거짓;
Paintbox1.canvas와 함께
시작하다
브러시 콜러 : = Clwhite;
fillRect (rect (0,0, Paintbox1.Width, Paintbox1.height));
끝;
끝;
절차 tfrm_tree.button1click (sender : tobject);
시작하다
도구 : = 1;
끝;
절차 tfrm_tree.button2click (sender : tobject);
시작하다
도구 : = 2;
끝;
절차 tfrm_tree.addobj (id : string; x, y, typeno : 정수;
선택 : 부울;
var
obj : ^Tobj;
시작하다
새로운 (obj);
obj.objid : = id;
obj.centerx : = x;
obj.centery : = y;
obj.typeno : = typeno;
obj.selected : = 선택;
obj.fnode : = fnode;
obj.show : = show;
olst.add (obj);
끝;
함수 tfrm_tree.getobj (id : String) : tobj;
var
I, J : 정수;
시작하다
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
if 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 : 부울;
var
I, J : 정수;
시작하다
결과 : = 거짓;
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
tobj (olst.items [i]^)
시작하다
결과 : = 참;
부서지다;
끝;
끝;
끝;
절차 tfrm_tree.drawfull;
var
I, J : 정수;
시작하다
//paintbox1.canvas.fillRect(Rect(0,0,PaintBox1.Width,PaintBox1.Height));
ClearCanvas;
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
Drawnode (tobj (olst.items [i]^). objid);
끝;
끝;
절차 tfrm_tree.paintbox1paint (sender : tobject);
시작하다
그림자;
끝;
절차 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]^). centerx+10> x)
그리고 (tobj (olst.items [i]^). centery-10 <y) 및 (tobj (olst.items [i]^). Centery+10> y)
시작하다
tobj (olst.items [i]^). selected : = true;
label1.caption : = '노드 id를 선택했습니다.'+ tobj (olst.items [i]^). objid;
끝;
끝;
그림자;
끝;
절차 tfrm_tree.button3click (sender : tobject);
시작하다
도구 : = 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]^). centerx+10> x)
그리고 (tobj (olst.items [i]^). centery-10 <y) 및 (tobj (olst.items [i]^). Centery+10> y)
시작하다
tobj (olst.items [i]^).
label1.caption : = '노드 ID를보십시오.'+ tobj (olst.items [i]^). objid;
결과 : = tobj (olst.items [i]^);
부서지다;
끝;
끝;
끝;
절차 TFRM_TREE. CLEARSHOW;
var
I, J : 정수;
시작하다
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
tobj (olst.items [i]^).
끝;
끝;
절차 tfrm_tree.setfnode (id : string);
var
curobj :^tobj;
시작하다
ID <> ''라면
시작하다
// new (curobj);
curobj : = getpobj (id);
curobj^.typeno = 1을 수행합니다
시작하다
curobj^.showed : = 참;
curobj : = getpobj (curobj^.fnode);
끝;
curobj^.showed : = 참;
// dispose (curobj);
끝;
끝;
절차 tfrm_tree.setcnode (id : string);
var
curobj :^tobj;
I, J : 정수;
시작하다
// curobj : = getObj (id);
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
if tobj (olst.items [i]^). fnode = id then
시작하다
curobj : = getpobj (tobj (olst.items [i]^). objid);
curobj^.showed : = 참;
setcnode (curobj^.objid);
끝;
끝;
끝;
절차 tfrm_tree.clearcanvas;
시작하다
//paintbox1.canvas
Paintbox1.canvas.fillRect (rect (0,0, Paintbox1.Width, Paintbox1.Height));
끝;
절차 tfrm_tree.button4click (sender : tobject);
시작하다
클릭 : = 거짓;
Paintbox1.canvas.fillRect (rect (0,0, Paintbox1.Width, Paintbox1.Height));
olst.clear;
루트 : = 참;
Selid : = '';
Searilid : = 0;
{paintbox1.canvas와 함께
시작하다
Pen.width : = 2;
펜. 콜러 : = Clblack;
펜 스타일 : = psclear;
Brush.style :=BSSOLID;
브러시 콜러 : = 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]^).
끝;
그림자;
끝;
함수 tfrm_tree.getPobj (id : String) : 포인터;
var
I, J : 정수;
시작하다
결과 : = nil;
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
if tobj (olst.items [i]^). objid = id then
시작하다
결과 : = olst.items [i];
부서지다;
끝;
끝;
끝;
함수 tfrm_tree.clickobj (x, y : integer) : 문자열;
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]^). centerx+10> x)
그리고 (tobj (olst.items [i]^). centery-10 <y) 및 (tobj (olst.items [i]^). Centery+10> y)
시작하다
label1.caption : = '노드 ID를 클릭하십시오.'+ tobj (olst.items [i]^). objid;
결과 : = tobj (olst.items [i]^). objid;
부서지다;
끝;
끝;
끝;
절차 tfrm_tree.button6click (sender : tobject);
시작하다
도구 : = 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;
Shift : TshiftState; X, Y : Integer);
시작하다
사례 도구
4 :
시작하다
클릭하면
시작하다
endx : = x;
Endy : = y;
MoveObj ((endx-beginx), (endy-beginy));
끝;
클릭 : = 거짓;
끝;
5 :
시작하다
클릭 : = 거짓;
끝;
끝;
끝;
절차 tfrm_tree.paintbox1mouseMove (sender : tobject; shift : tshiftState;
x, y : 정수);
시작하다
그렇다면 (클릭)
시작하다
사례 도구
4 :
시작하다
MoveObj ((x-beginx), (y-beginy));
beginx : = x; beginy : = y;
그림자;
끝;
5 :
시작하다
movenode ((x-beginx), (y-beginy), getselect.objid);
movelocal ((x-beginx), (y-beginy));
beginx : = x; beginy : = y;
그림자;
끝;
끝;
끝;
끝;
절차 tfrm_tree.fadestream1click (sender : tobject);
var
selfile : 문자열;
커리드 : 문자열;
curobj : Tobj;
lstdate : tinifile32;
I, J : 정수;
시작하다
J : = olst.count;
Savedialog1.Execute 인 경우
시작하다
selfile : = savedialog1.filename;
lstdate : = tinifile32.create (selfile+'. dat');
lstdate.writeInteger ( 'title', 'num', j);
i : = 0에서 J-1을 위해
시작하다
curobj : = tobj (olst.items [i]^);
curid : = curobj.objid;
lstdate.writestring (curid, 'objid', curobj.objid);
lstdate.writeInteger (curid, 'centrex', 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
selfile : 문자열;
// curid : 문자열;
lstdate : tinifile32;
I, J : 정수;
시작하다
opendialog1.Execute 인 경우
시작하다
selfile : = opendialog1.filename;
클릭 : = 거짓;
Paintbox1.canvas.fillRect (rect (0,0, Paintbox1.Width, Paintbox1.Height));
olst.clear;
루트 : = 참;
Selid : = '';
Searilid : = 0;
lstdate : = tinifile32.create (selfile);
j : = lstdate.readinteger ( 'title', 'num', 0);
i : = 1 ~ j do의 경우
시작하다
addObj (lstDate.ReadString (inttoStr (i), 'objid', ''), lstdate.readinteger (inttostr (i), 'centrex', 0), lstdate.readinteger (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;
루트 : = 거짓;
그림자;
끝;
끝;
절차 tfrm_tree.button7click (sender : tobject);
시작하다
도구 : = 5;
끝;
절차 tfrm_tree.movenode (dx, dy : 정수; id : String);
var
I, J : 정수;
curobj :^tobj;
시작하다
J : = olst.count;
i : = 0에서 J-1을 위해
시작하다
if 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;
부서지다;
끝;
끝;
끝;
끝.