PDA

View Full Version : سوال: اشکال هنگام free کردن کامپوننت از نوع Shape؟!



mbshareat
شنبه 18 شهریور 1391, 11:17 صبح
سلام بر دوستان بزرگوار
من یه برنامه دارم در اون چندتا Shape با کد نویسی ایجاد می کنم و یه دکمه دارم که همه اونها رو پاک کنه.
هنگام ایجاد اونها مشکلی ندارم اما نمیتونم همه رو free کنم!
این یونیت رو ملاحظه بفرمایین:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Button1Click(Sender: TObject);
private
procedure DrawAnchor(N: Integer);
procedure RemoveAllAnchors;
procedure ShapeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
ShapeNo:Byte;
implementation

{$R *.dfm}
procedure TForm1.ShapeMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Begin
TShape(Sender).Free;
End;
procedure TForm1.DrawAnchor(N:LongInt);
Var
S:TShape;
Begin
S:=TShape.Create(Self);
With S Do
Begin
Parent:=Self;
Tag:=N;
Width:=7;
Height:=7;
Brush.Color:=$00F0D0A0;
Pen.Color:=clBlue;
Shape:=stCircle;
Inc(ShapeNo);
Name:='AnchorShape'+IntToStr(ShapeNo);
Left:=N;
Top:=10;
Tag:=N;
OnMouseDown:=Self.ShapeMouseDown;
End;
End;
procedure TForm1.RemoveAllAnchors();
Var
I:SmallInt;
begin
for I:=0 to Self.ComponentCount-1 Do
If Pos('AnchorShape',Self.Components[I].Name)>0 then
Begin
ShowMessage(Self.Components[I].Name);
Self.Components[I].Free;
End;
end;
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
DrawAnchor(X);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RemoveAllAnchors;
end;

end.

جالبه که در پروسیجر RemoveAllAnchors وقتی که دستور Free رو اجرا نمی کنم پنجره پیغام اسم همه Shape ها رو به ترتیب گزارش می کنه. اما اگه Free رو هم اجرا کنم اسمشون رو به ترتیب گزارش نمی کنه!
من خیلی وقت گذاشتم که علت رو بفهمم ولی به نتیجه نرسیدم. نمی دونم ممکنه نحوه ایجاد Shape (دایره ها) درست نبوده یا مشکل از جای دیگست.
لطفا راهنماییم کنین.

mbshareat
شنبه 18 شهریور 1391, 12:14 عصر
سلام
خودم جواب رو فهمیدم
چون وقتی یک شیء رو حذف می کنیم تعداد کامپوننتها کم میشه ولی چیزی که بعد از To در حلقه میاد تغییر نمی کنه مشکل ایجاد میشه.
در ضمن حذف یه شیء یاعث میشه شیء بعدی در ترتیب کامپوننتها جاشو بگیره.
کد درست این بود:

For I:=1 To ShapeNo Do
Self.FindComponent('AnchorShape'+IntToStr(I)).Free ;

Felony
شنبه 18 شهریور 1391, 12:16 عصر
کد درست این هست که کامپوننت ها رو از آخر به اول آزاد کنید تا ترتیبشون به هم نخوره :


procedure TForm1.RemoveAllAnchors();
Var
I:SmallInt;
begin
for I:= Self.ComponentCount-1 downto 0 do
If Pos('AnchorShape',Self.Components[I].Name)>0 then
Begin
ShowMessage(Self.Components[I].Name);
Self.Components[I].Free;
End;
end;

mbshareat
شنبه 18 شهریور 1391, 15:00 عصر
درسته. من قبلا هم از این روش استفاده می کردم. اما اینجا ناشی بودنم کار دستم داد و بی توجهی کردم!
یه سری اشکالات هست که بارها درگیرشون شدم و به سختی تونستم بفهمم که مشکل همون اشکال تکراری هست.
مثلا تو همین برنامه که دارم روش کار می کنم جای دو دستور رو اشتباه نوشته بودم یا خیلی وقتها وقت کپی گرفتن یادم میره جاهای ضروری رو تغییر بدم.
به نظر شما چطور میشه اینجور اشکالات رو زودتر متوجه شد؟باهوش بودن یا لیست گرفتن از اشکالات این چنینی؟