PDA

View Full Version : Exit From Frame



حمید محمودی
دوشنبه 08 شهریور 1389, 17:38 عصر
سلام،

فرض کنید توی پروژه یه Frame1 داریم، که اونو توی فرم1 میسازیم.(پارنت و اونرش خود فرم هست). توی همین فرم 1 ، یه باتن هست. چطوری میشه وقتی روی این دکمه کلیک کردیم، اون فریم دیستوری بشه؟

البته ممکنه instanceهای مختلفی از این فریم داشته باشیم که ساخته شده باشه و یا فریم های دیگه ای هم به غیر از Frame1 داشته باشیم که کریت شده باشه. دنبال روشی هستم که وقتی در فریم مورد نظر هستیم با کلیک روی دکمه ای که در فرم گذاشته شده، اون فریم بسته بشه.

جواد ملاولی
دوشنبه 08 شهریور 1389, 18:13 عصر
سلام.
خوب این کار روش نمی خواد که. این یه خط کده دیگه:

FreeAndNil(Frame1)
مگه اینکه سؤالتو درست متوجه نشده باشم!

حمید محمودی
دوشنبه 08 شهریور 1389, 20:55 عصر
فرضا" توی Button1 که در فرم 1 هست اومدیم گفتیم :



with TFrame1.Create(Self) do
begin
Name := '';Parent := Self;
end;
حالا توی باتن button2 ( باتن خروج از فریم1 ) که در فرم1 هست چطور باید همین FreeAndNil رو بکار گرفت؟
فقط بگیم FreeAndNil(Frame1) ; l که خطا میگیره فریم1 رو نمیشناسم. اگه همون تو با var تعریفش کنم وقتی روی باتن کلیک کنم، ارور اکسس ولیدشن میده!

SAASTN
دوشنبه 08 شهریور 1389, 22:12 عصر
خوب شما که هیچ وقت کنترلی که ایجاد کردید رو به Frame1 اختصاص ندادید، بنده خدا بایدم خطا بده. شما باید Frame1 رو در محلی که هم در دسترس Button1 و هم Button2 باشه تعریف کنید و کد رو بصورت زیر تغییر بدید:
Frame1 := TFrame1.Create(Self);
with Frame1 do
begin
Name := '';
Parent := Self;
end;

حمید محمودی
دوشنبه 08 شهریور 1389, 23:24 عصر
FreeAndNil قادر نیست بقیه instanceهای فریم کنونی که ساخته شده رو از بین ببره؟

مثلا چهار بار روی همین button1 ( ساخت فریم ) کلیک کردیم حالا با کلیک روی باتن Exit Feame چطور وقتی توی فریم مورد نظر هستیم، اون فریم از بین بره؟ (چون الان فقط یک بار میتونه فریم1 رو حذف کنه.) (گویا چون گفتیم name:='' l بخاطر همین نمیشناسدش)

مشکل اصلیم اینه که قبلم گفتم »


البته ممکنه instanceهای مختلفی از این فریم داشته باشیم که ساخته شده باشه و یا فریم های دیگه ای هم به غیر از Frame1 داشته باشیم که کریت شده باشه. دنبال روشی هستم که وقتی در فریم مورد نظر هستیم با کلیک روی دکمه ای که در فرم گذاشته شده، اون فریم بسته بشه.

vcldeveloper
سه شنبه 09 شهریور 1389, 02:13 صبح
مثلا چهار بار روی همین button1 ( ساخت فریم ) کلیک کردیم حالا با کلیک روی باتن Exit Feame چطور وقتی توی فریم مورد نظر هستیم، اون فریم از بین بره؟
ساخت و آزاد کردن Frame در دلفی مثل ساخت و آزاد کردن سایر اشیاء هست. با سایر اشیاء چیکار می کنید؟ با Frame هم باید همون کار رو بکنید.
وقتی شی ایی رو میسازید، و هیچ ارجاعی بهش نگاه داری نمی کنید، چطور میخواید دوباره پیداش کنید و آزادش کنید؟! وقتی فرضا در کد پست شماره 4 شما به Frame1 یک بار مقدار دادید، اگر دوباره همان کد را اجرا کنید، چه اتفاقی میافته؟ به Frame1 یک مقدار جدید اختصاص پیدا میکنه. مقدار قبلی اش چی میشه؟ هیچی، دیگه ارجاعی به مقدار قبلی اش وجود نداره، پس دیگه به اون شی قبلی دسترسی ندارید، و اون شی تبدیل میشه به Memory Leak (نشت حافظه)! پس اگر شما 10 بار روی اون دکمه فرضی کلیک کنید، در واقع چیکار کردید؟ 10 فریم مختلف ایجاد کردید، که 9 تای آنها را تبدیل به آشغال غبرقابل بازیافت کردید، و فقط آخری برایتان از طریق Frame1 قابل دسترس هست.

شما اگر میخواید چند فریم ایجاد کنید، و به همه آنها دسترسی داشته باشید، باید یک مکانیزم برای ارجاع به آنها داشته باشید؛ یعنی یا یک لیست یا آرایه در نظر بگیرید که هر عنصرش حاوی ارجاعی به یکی از این فریم ها ست، یا به هر فریم یک نام منحصر بفرد از طریق خصوصیت Nameاش بدید، و البته در زمان ایجادش هم Owner آن را فرم مورد نظرتان در نظر بگیرید، اون وقت از طریق FindComponent یا لیست Components مربوط به فرم، آن را پیدا کنید، و عملیات مورد نظرتان را روی آن اعمال کنید.

سعی کنید فرآیند Create شدن و Destroy شدن اشیاء؛ مفهوم Owner و Parent، مفهوم Class در قیاس با شی، و مفهوم ارجاع به اشیاء را دقیق متوجه بشید؛ وگرنه اگر روی این مفاهیم اولیه مرتبط با مدیریت حافظه در برنامه های شی گرای دلفی ضعف داشته باشید، در پروژه های مختلف تان با انواع و اقسام Memory Leak و خطاهای حافظه، یا حداقل کارایی پایین نرم افزار مواجه میشید.

SAASTN
سه شنبه 09 شهریور 1389, 02:26 صبح
FreeAndNil قادر نیست بقیه instanceهای فریم کنونی که ساخته شده رو از بین ببره؟
خوب وقتی شما چهارتا کنترل رو می سازی و همشون رو میریزی توی یه متغیر، اون متغیر فقط می تونه آخرین کنترل رو داخل خودش نگه داره. مثل:
var
A: Integer;
begin
A := 12;
A := 7;
A := 36;
A := 4;

آخر سر چی توی A باقی می مونه؟ فقط آخرین مقدار.
حالا شما اگه می خوای چند تا نمونه از یه کلاس ایجاد کنی و باهاشون کار بکنی باید دسترسی به همشون رو حفظ کنی. برای این منظور هم باید از آرایه های داینامیک یا لیست ها استفاده کنی:
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
Frame1sList: TList;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
type
TFrame1 = class(TFrame)

end;

procedure TForm1.Button1Click(Sender: TObject);
var
aFrame1: TFrame1;
begin
aFrame1 := TFrame1.Create(Self);
with aFrame1 do
begin
Name := '';
Parent := Self;
end;
Frame1sList.Add(aFrame1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
aFrame1: TFrame1;
begin
if Frame1sList.Count > 0 then
begin
aFrame1 := TFrame1(Frame1sList.Last);
Frame1sList.Remove(aFrame1);
FreeAndNil(aFrame1);
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Frame1sList := TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := 0 to Frame1sList.Count - 1 do
TFrame1(Frame1sList.Items[I]).Free;
Frame1sList.Free;
end;

---------------------------------
بازم جوابا همزمان شد...