PDA

View Full Version : اشکال در شمارش فرم های فرزند MDICHILD



MEhdi Sobhani
شنبه 20 آذر 1389, 22:40 عصر
با عرض سلام و خسته نباشید .
این کد رو ببینید :



procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
I:integer;
MdiCount:integer;
begin
MdiCount:=self.MDIChildCount;
for I := MdiCount-1 downto 0 do
begin
self.MDIChildren[i].Close;
end;
showmessage(inttostr(self.MDIChildCount));
FreeObjectDLLS;
end;


در واقع میام و تمام فرم ها ی فرزند رو میبندم اما وقتی تعداد رو می خوام انگار هیچ فرمی بسته نشده ؟
دیده میشه که فرمی وجود نداره اما عدد اشتباه هست .
لطفا راهنمای بفرمایید.
با تشکر .

vcldeveloper
شنبه 20 آذر 1389, 23:19 عصر
خب، فرم های فرزند رو بستید، چرا باید تعداد فرم های فرزند تغییر کنه؟! فرمها که Free نشدند، فقط از روی صفحه نمایش ناپدید شدند. خصوصیت MDIChidren لیست فرم های فرزند در حال نمایش را برنمیگردونه، بلکه لیست فرم های فرزند موجود رو برمیگردونه. حالا هر فرم موجود ممکنه در حال نمایش باشه، یا مخفی شده باشه.

MEhdi Sobhani
شنبه 20 آذر 1389, 23:57 عصر
خب، فرم های فرزند رو بستید، چرا باید تعداد فرم های فرزند تغییر کنه؟! فرمها که Free نشدند، فقط از روی صفحه نمایش ناپدید شدند. خصوصیت MDIChidren لیست فرم های فرزند در حال نمایش را برنمیگردونه، بلکه لیست فرم های فرزند موجود رو برمیگردونه. حالا هر فرم موجود ممکنه در حال نمایش باشه، یا مخفی شده باشه.
متشکر
به جای کلوز از فری استفاده کردم و درست شد .
یه سوال دیگه هم داشتم و اون اینکه در ایونت کلوز فرم های فرزندم این دستور وجود داشت :

Action := caFree;
این دستور خودش باعث نمیشه وقتی فرم کلوز میشه ، فری هم فراخوانی بشه ؟
با تشکر .

vcldeveloper
دوشنبه 22 آذر 1389, 02:39 صبح
این دستور خودش باعث نمیشه وقتی فرم کلوز میشه ، فری هم فراخوانی بشه ؟
اگر اون کد در رویداد OnClose فرم های فرزندتان وجود داشته باشه، باید به طور خودکار Free بشند.

من بررسی کردم، و کد فوق برای فرم های MDIChild به درستی عمل میکنه، و مقدار MDIChildCount هم به درستی تغییر میکنه. اما مسئله کد اولیه شما (در پست اول) این هست که MDIChildCount را بلافاصله بعد از Close کردن فرم ها دریافت می کنید. وقتی Action := caFree را تنظیم می کنید، فرم شما به خودش یک پیام CM_RELEASE ارسال میکنه، که معنی آن Free شدن فرم هست، اما پیام CM_RELEASE به صف پیام های فرم ارسال میشه، و بلافاصله اجرا نمیشه، بلکه در نوبت پردازش قرار میگیره. زمانی که پردازش بشه، فرم Free میشه. در کد شما، مقدار MDIChildCount قبل از اینکه CM_RELEASE فرصت پردازش شدن پیدا کنه، دریافت میشه، به همین علت هم تعداد فرم ها درست نمایش داده نمیشه. اگر چند لحظه بعد، مجددا مقدار MDIChildCount را چک کنید، می بینید که مقدارش صفر شده. برای بررسی این موضوع، کافیه بعد از بستن همه فرم ها و قبل از دریافت مقدار MDIChildCount، یک بار Application.ProcessMessages را فراخوانی کنید. این کار باعث میشه که همه پیام های موجود در صف پیام های برنامه شما پردازش بشند، یعنی همه پیام های CM_RELEASE پردازش میشند و فرم های مربوطه آزاد میشند. در نتیجه وقتی اجرا به MDIChildCount میرسه، مقدارش صفر خواهد بود.