PDA

View Full Version : ایجاد کامپوننت در حلقه for



sima_gh7
یک شنبه 20 شهریور 1384, 09:22 صبح
من میخوام در یک حلقه for یک کامپوننت رو به تعداد creat ، n کنم . چه کدی بنویسم ؟

m-khorsandi
یک شنبه 20 شهریور 1384, 09:56 صبح
درود

با کد زیر میتونید 10 تا Instance از کلاس TButton بسازید:



procedure TForm1.Button1Click(Sender: TObject);
var
iCounter: Integer;
iTop: Integer;
begin
iTop := 50;
for iCounter := 1 to 10 do
begin
with TButton.Create(Self) do
begin
Name := 'Btn_' + IntToStr(iCounter);
Caption := ' Button #' + IntToStr(iCounter);
Parent := Form1;
Left := 100;
Top := iTop;
Inc(iTop, 30);
end;
end;
end;


فقط Destroy کردن Object هایی که ساخته شده رو (در صورت عدم نیاز) فراموش نکنید.

sima_gh7
دوشنبه 21 شهریور 1384, 21:25 عصر
ممکنه بگید چطور و چه وقت destroy کنم ؟

sima_gh7
سه شنبه 22 شهریور 1384, 07:25 صبح
کسی نیست جواب بده ؟

m-khorsandi
سه شنبه 22 شهریور 1384, 07:44 صبح
زمانی که دیگه نیازی به Object ها نداشتید میبایست اونها رو Destroy کنید تا حافظه تخصیص یافته ازاد بشه،
برای این کار هم میتونی از ObjectName.Free استفاده کنی.

sima_gh7
چهارشنبه 23 شهریور 1384, 22:43 عصر
من object ها رو در یک حلقه for ایجاد کردم و حالا برای free کردنشون باید از یک حلقه for دیگه استفاده کنم ولی نمیدونم چطور به object های ایجاد شده دسترسی داشته باشم .
ممکنه بگید دقیقاً چه کدی بنویسم ؟

vcldeveloper
پنج شنبه 24 شهریور 1384, 02:05 صبح
از خصوصیت Name اون کامپوننت ها استفاده کن


Form1.FindComponent('Btn' + IntToStr(iCounter)).Free;

hkiani
پنج شنبه 24 شهریور 1384, 11:29 صبح
سلام

من هم یک نظری می‌دهم، اگر اشکال داشت لطفا بگویید:

هنگامی که ما از طریق کدنویسی یک کامپوننت به فرم خود می‌افزاییم و Owner آن را فرم خود قرار می‌دهیم (مانند فوق) حتی اگر آنها را خودمان Destroy نکنیم، هنگامی که فرم Destroy می‌شود خودش آنها را Destroy می‌کند. هر چند که تاکید بر این است که خودمان این کار را انجام بدهیم.

نکته بعد اینکه قبل از Destroy کردن یک کامپوننت باید با فراخوانی متد RemoveComponent و ارسال نام کامپوننت خود به آن، آن را از لیست کامپوننت‌های فرم خارج کنیم:

RemoveComponent(ComponentName);
ComponentName.Free;

Naficy
پنج شنبه 24 شهریور 1384, 16:39 عصر
صحبت شما درسته. اما در مورد RemoveComponent نه. برای من جالبه که شما اینو از کجا باش آشنا شدین، اما نه نیازی به صدا زدن هیچی نیست. ضمنا هیچ تاکیدی هم بر Destroy کردن دستی کمپوننت نیست. (وقتی Owner داره!)

vcldeveloper
جمعه 25 شهریور 1384, 03:14 صبح
هنگامی که ما از طریق کدنویسی یک کامپوننت به فرم خود می‌افزاییم و Owner آن را فرم خود قرار می‌دهیم (مانند فوق) حتی اگر آنها را خودمان Destroy نکنیم، هنگامی که فرم Destroy می‌شود خودش آنها را Destroy می‌کند. هر چند که تاکید بر این است که خودمان این کار را انجام بدهیم.
این مطلب بستگی داره به اینکه فرم شما چقدر عمر میکنه. اگه قرار باشه فرم شما به مدت طولانی عمر کنه و شما در طول این مدت نیازی به اون کامپوننت هایی که اضافه کردید، نداشته باشید، Free نکردن اون کامپوننت ها فقط منابع سیستم رو هدر میده!

نکته بعد اینکه قبل از Destroy کردن یک کامپوننت باید با فراخوانی متد RemoveComponent و ارسال نام کامپوننت خود به آن، آن را از لیست کامپوننت‌های فرم خارج کنیم
هیچ لزومی به فراخوانی RemoveComponent قبل از آزاد کردن کامپوننت نیست.

sima_gh7
شنبه 26 شهریور 1384, 12:40 عصر
خب حالا بعد از این که component ها creat یا free شد آیا فقط با استفاده از خصوصیات top و left میشه موقعیت این component ها و بقیه component هایی که زیر اونها قرار گرفتند رو کنترل کرد ؟ یا اینکه روش دیگه ای هم وجود داره ؟
منظورم اینه که هر بار که این component ها creat یا free می شن ، باید خصوصیات top و left بقیه component های زیر اونها هم تغییر داده بشه؟

vcldeveloper
یک شنبه 27 شهریور 1384, 02:15 صبح
منظورم اینه که هر بار که این component ها creat یا free می شن ، باید خصوصیات top و left بقیه component های زیر اونها هم تغییر داده بشه؟
خیر. موقعیت کنترل ها نسبت به گوشه بالا سمت چپ کنترل والدشون (Parent) سنجیده میشه، نه نسبت به هم. تغییر مکان یک کنترل روی کنترل های دیگه تاثیری نداره.
در ضمنFree کردن یک کنترل موجب از بین رفتن اون میشه و بعد از اون دیگه کنترلی وجود نداره که بخواید به خصوصیات اون دسترسی داشته باشید.

sima_gh7
یک شنبه 27 شهریور 1384, 07:36 صبح
تغییر مکان یک کنترل روی کنترل های دیگه تاثیری نداره.
خب من هم همین رو می گم . اگه یه component در جایی creat بشه که قبلاً یک component دیگه وجود داشته ، اونوقت component جدید روی component قبلی قرار می گیره .
من می خوام در حالت Runtime برای کامپوننت های جدید جای خالی باز کنم که روی کامپوننت های قبلی قرار نگیرند و چون تعداد کامپوننت های ایجاد شده در هر اجرا متفاوته بنابراین کنترل موقعیت کامپوننت ها باید به صورت پویا انجام بشه .
حالا می خوام بدونم فقط با خصوصیات top و left می تونم این کار رو انجام بدم یا روش دیگه ای هم هست ؟
نمیدونم تونستم منظورم رو خوب برسونم یا نه؟...

m-khorsandi
یک شنبه 27 شهریور 1384, 08:00 صبح
تفاوتی یا زمان Design نداره، شما اونجا میتونید یک Component رو روی Component دیگه بندازید ، به صورت RunTime
هم فرقی نمیکنه.

شما میبایست Top و Left رو تنظیم کنید.
ولی خیلی دوست دارم بدونم که چه برنامه ایی هست که Component ها رو در زمان اجرا میبایست که بسازید؟

sima_gh7
جمعه 01 مهر 1384, 07:08 صبح
من همچنان در free کردن کامپونت ها مشکل دارم .
در یک حلقه for یه سری کامپوننت creat کردم و وقتی فرم hide میشه اونها رو free می کنم ، با F7 هم trace کردم ، دقیقاً به تعداد کامپوننت های ایجاد شده عمل free انجام می شه ، ولی وقتی برای بار دوم فرم میخواد show بشه این Error رو می ده :
component ' DC1' alerady exist

DC1 اسم کامپوننتی که قبلاً creat شده .

m-khorsandi
شنبه 02 مهر 1384, 07:51 صبح
میشه روش Free کردن رو بنویسید؟

sima_gh7
شنبه 02 مهر 1384, 12:43 عصر
با استفاده از این کد کامپوننت ها رو free می کنم :


for i:=1 to AdoQuery2.recordCount do
form9.FindComponent('DC'+inttostr(i)).Free;


که AdoQuery2.recordCount تعداد فیلدهایی رو مشخص می کنه که باید به تعداد اونها کامپوننت ایجاد بشه .

و برای creat کردن هم این کد رو نوشتم :


count:=form9.ADOQuery2.recordCount;
for i:=1 to count do
begin
groupbox1.Height:=groupbox1.Height+25;
with TDbCheckbox.create(self) do
begin
name:='DC'+inttostr(i);
caption:=ADOQuery2.FieldValues['name'];
parent:=groupbox1;
BiDiMode:=bdRightToLeft;
dataSource:=datasource2;
dataField:='name';
top:=t;
t:=t+16;
left:=90;
font.charset:=ARABIC_CHARSET;
font.Name:='Arial Black';
font.Size:=10;
checked:=false;

end;

ADOQuery2.Next;
end;

Naficy
شنبه 02 مهر 1384, 20:21 عصر
روش فعلیتان کلا خیلی جالب نیست.
پیشنهاد می کنم یک لیست از نوع TComponentList بسازید و همه کامپوننت ها را پس از اینکه create کردید به آن اضافه کنید. سپس صدا زدن متد Clear همین شی لیست؛ به سادگی کلیه کامپوننتهایی که درون آن هستند را free می کند.
ضمنا لیست مزبور در یونیت Contnrs تعریف شده است.

sima_gh7
یک شنبه 03 مهر 1384, 07:49 صبح
میشه بیشتر توضیح بدید لطفاً .
چطور از TComponentList استفاده کنم ...

hr110
یک شنبه 03 مهر 1384, 08:04 صبح
جناب نفیسی ، clear برای تخریب لیست کامپوننتها نیست.

شما وقتی کنترلهایی را به فرمتان اضافه میکنید (با استفاده از InsertControl) هندل آنها در Controls وجود خواهد داشت که با یک دستور ساده میتوانید تمامی آنها را تخریب نمایید:
while controlCount>0 do
Controls[0].Free;

sima_gh7
یک شنبه 03 مهر 1384, 09:55 صبح
من بالاخره چطور از TComponentList استفاده کنم

sima_gh7
دوشنبه 04 مهر 1384, 11:17 صبح
مشکلم حل شد

Naficy
دوشنبه 04 مهر 1384, 20:13 عصر
خب الحمد لله. (نمی دونم بالاخره از TComponentList استفاده کردین یا نه؟)

در پاسخ به جناب hr110 هم باید بپرسم که از کجای جمله چنین برداشت می شه که clear شی TComponentList رو تخریب می کنه؟ شایدم منظورتون اینه که کمپوننتهای درون لیست رو تخریب نمی کنه؟

لازم به توضیحه که:
متد clear کلیه اشیا داخل لیست را از آن حذف کرده و در نتیجه همگی تخریب نیز می شوند. (البته اگر OwnsObjects مقدار "درست" داشته باشد)
اما خود TComponentList مسلما و همانند تمامی اشیای دیگر، باید با صدا زدن متد Free تخریب شود.

hr110
شنبه 09 مهر 1384, 07:00 صبح
متد clear کلیه اشیا داخل لیست را از آن حذف کرده و در نتیجه همگی تخریب نیز می شوند.
لطفاً راهنمای دلفی را مجدداً مطالعه نمایید.

Naficy
شنبه 09 مهر 1384, 18:57 عصر
من با وجود اطمینان صد در صد و یقین مطلقی که به صحبت خودم داشتم، دلفی را بازکردم و صحبت خودم را امتحان کردم. (و همونطور که قبلا هم گفته ام از اینکه وسط کار با اینترنت دلفی رو باز کنم، اونهم وقتی کوچکترین سودی برایم نداره، واقعا متنفرم)

به شما دوست عزیز هم جدا توصیه می کنم که قبل از اینکه به کسی پیشنهاد کنین مثلا راهنمای دلفی رو بخونه، (اگر تجربه کافی در دلفی ندارین) حداقل به خودتون زحمت یکبار تجربه کردن رو بدین. واقعا آدم از تجربه کردن ضرر نمی کنه.


-------------------

در نهایت برای مفید بودن این صحبت برای سایر دوستان، باید بگم که آنچه در مورد متد clear نوشتم کاملا صحیح است. (امتحان کنید یا سورس کامپوننت را با دقت بخوانید)

hr110
یک شنبه 10 مهر 1384, 07:06 صبح
سلام؛
جناب نقیسی حق با شما بود، متد clear علاوه بر حذف آیتمها ، حافظه گرفته شده را نیز به سیستم برمیگرداند.

عذر خواهی مرا بپذیرید.:خجالت: :قلب:

mahdi939
دوشنبه 11 مهر 1384, 09:58 صبح
با سلام
روشی تعریف event برای کامپوننتهای ایجاد شده در برنامه چگونه می باشد .

با تشکر