PDA

View Full Version : فرم showmodal بسته نمی شود!!!



saeed6162
جمعه 11 شهریور 1390, 18:15 عصر
سلام
خسته نباشید
دو تا فرم دارم ، از تو فرم اول فرم دوم را showmodal می کنم :
form2.showmodal;

تو رویدار onshow فرم دوم ، شرطی بررسی میشه ، در صورتی که شرط صحیح باشه باید فرم دوم نشون داده نشه ، یعنی بسته بشه ، به این صورت نوشتم ، اما عمل نمی کنه :
if b then
form2.close;


حالت زیر رو هم تست کردم اما جواب نمی ده و فرم بسته نمیشه !!!

if b then
form2.modalresult=mrok;

Mahmood_M
جمعه 11 شهریور 1390, 23:18 عصر
در رویداد OnShow هنوز فرم Visible اش True نشده ، فرمی که Visible اش True نباشه نمی تونه Close بشه
شما باید روش چک کردن شرط در فرم دوم رو تغییر بدید ، مثلا از قبل از نمایش فرم دوم شرط رو چک کنید و در صورت درست بودن شرط فرم دوم رو نمایش بدید

موفق باشید ...

saeed6162
شنبه 12 شهریور 1390, 02:49 صبح
ممنون
خب ، OnActivate چی ؟
این رویداد که پس از مرئی شدن فرم اتفاق می افته! چرا پس در این حالت هم جواب نمی ده!
و اگه لازم باشه که حتما شردط در فرم دوم و پس از نمایش فرم صورت بگیره چیکار باید کرد؟
آیا استفاده از یک تایمر که پس از نمایش فرم دوم فعال بشه و شرط رو چک کنه و در مورد بسته شدن فرم تصمیم بگیره روش مناسبی هست؟

JaguarXF
شنبه 12 شهریور 1390, 04:51 صبح
یک جای دیزاین برنامه ات مشکل داره.
اگه قراره فرم نشون داده نشه این شرط رو باید توی همون فرم اول چک کنی.

saeed6162
شنبه 12 شهریور 1390, 09:11 صبح
یک جای دیزاین برنامه ات مشکل داره.

منظورتون اینه که اصلا منطق برنامه نویسیم ، منطق صحیح و اصولیی نیست؟
ممنون

Felony
شنبه 12 شهریور 1390, 10:13 صبح
منظورتون اینه که اصلا منطق برنامه نویسیم ، منطق صحیح و اصولیی نیست؟
بله ؛ وقتی قراره فرم بر اساس شرط خاصی نمایش پیدا کنه پس قبل از نمایش باید شرط بررسی بشه !

tdkhakpur
شنبه 12 شهریور 1390, 22:41 عصر
بله ؛ وقتی قراره فرم بر اساس شرط خاصی نمایش پیدا کنه پس قبل از نمایش باید شرط بررسی بشه !
اینطور نیست!


تو رویدار onshow فرم دوم ، شرطی بررسی میشه ، در صورتی که شرط صحیح باشه باید فرم دوم نشون داده نشه ، یعنی بسته بشه ، به این صورت نوشتم ، اما عمل نمی کنه :

هر رویدادی که داخل ویندوزر ارسال میشه داخل صف قرار میگیره ولی در این میان ابزاری که اقدام به ارسال پیغام میکنه میتونه داخل کد نویسی اهمیت خاصی داشته باشه جاهایی هست که برنامه نویس احتیاج داره پیغام را ارسال کنه و بدون اینکه بررسی کنه thread اصلی مشغول هست یا نه ولی بعضی شرایط مثل همین حالا هست که باید thread برسی بشه تا بعد از اتمام کار برنامه جاری با صف پیغامها, پیغام برای ویندوز ارسال بشه برای همین از postmessage استفاده میشه تا بعد از show شدن برنامه پیغام close بهش ارسال بشه.


if b then
postmessage(Handle, wm_close, 0, 0);

JaguarXF
یک شنبه 13 شهریور 1390, 00:57 صبح
اینطور نیست!

دقیقا همین طور هست. میخواهی گوش بکن یا نکن و کار خودتو بکن.

یک فرم حداقل حداقل یک کلاس پشتش هست. فارغ از اینکه ممکنه پیچیده تر هم باشه ولی فرض کنیم حالا همون یک کلاس. این یک software technical design درست نیست که کلاس رو ایجاد کنی بعد موقع نمایش دادنش بخواهی یک شرطی رو چک کنی و بگی خب بیخیال! نمیخواد نمایشش بدی.

من اصلا این زبان دلفی رو نمیدونم چیچی هست اما فرقی نداره. این اصوله .

fire.angle
یک شنبه 13 شهریور 1390, 01:41 صبح
جوابش خیلی راحته
کافیه توی همون فرم اول ابتدا شرط باز شدن فرم دوم رو بررسی کنید و در صورت مجاز بودن فرم دوم رو نمایش بدید
همین
در فرم اول (جایی که قراره فرم دوم رو Show کنه) مینویسیم
if b then
form2.showmodal

Mahmood_M
یک شنبه 13 شهریور 1390, 03:58 صبح
دقیقا همین طور هست. میخواهی گوش بکن یا نکن و کار خودتو بکن.

یک فرم حداقل حداقل یک کلاس پشتش هست. فارغ از اینکه ممکنه پیچیده تر هم باشه ولی فرض کنیم حالا همون یک کلاس. این یک software technical design درست نیست که کلاس رو ایجاد کنی بعد موقع نمایش دادنش بخواهی یک شرطی رو چک کنی و بگی خب بیخیال! نمیخواد نمایشش بدی.

من اصلا این زبان دلفی رو نمیدونم چیچی هست اما فرقی نداره. این اصوله .
برای نمایش یک فرم کلاسش دوباره ایجاد نمیشه ( مگر اینکه فرم در تنظیمات پروژه از نوع Auto-Create نباشه ) ، بلکه کلاسی که در هنگام شروع برنامه ایجاد شده ، فقط Show میشه

در کل به نظر من هم راه منطقی اینه که شرط قبل از نمایش فرم بررسی بشه ، گرچه راه حلی که در پست 7 ارایه شد هم جواب میده ، البته بعد از اجرای کامل رویداد OnShow فرم ، اگر مثلا بعد از دستور Close دستور دیگه ای در OnShow نوشته باشید هم اجرا میشه و بعد از نمایش کامل فرم ، فرم بسته خواهد شد

میشه بگید که شرط چی هست ؟

Felony
یک شنبه 13 شهریور 1390, 06:30 صبح
اینطور نیست!
:لبخندساده:


ولی بعضی شرایط مثل همین حالا هست که باید thread برسی بشه تا بعد از اتمام کار برنامه جاری با صف پیغامها, پیغام برای ویندوز ارسال بشه برای همین از postmessage استفاده میشه
چی میگی ؟!
PostMessage زمانی استفاده میشه که ارسال کننده پیام فقط قصد اطلاع رسانی به دریافت کننده پیام رو داره و پردازش کردن یا نکردن پیام یا زمان پردازش پیام برای ارسال کننده اهمیتی نداره !

saeed6162
یک شنبه 13 شهریور 1390, 10:42 صبح
دوستان می دونید مسأله چیه که انقد پیچیده شده!
تو فرم دوم یک تایمر دارم که بعد از نمایش فرم دوم فعال میشه ، یعنی نیازی نیست که قبلش فعال بشه ، بعد از فعال شدن بانک مربوط به تاریخ و ساعت رو چک می کنه که آیا زمان آلارم رسیده یا نه!
و وقتی که تو فرم اول هستیم نیازی به این چک کردن نیست!

حالا بگید چیکار باید کرد؟
آیا استفاده کردن از تایمر اشتباهه؟ اونم به این صورت که پس از نمایش فرم دوم فعال بشه!!

Felony
یک شنبه 13 شهریور 1390, 10:59 صبح
شما باز هم نگفتی شرطی که در OnShow قرار دادی چی رو بررسی میکنه ؟!

saeed6162
یک شنبه 13 شهریور 1390, 11:15 صبح
شرط اینه :

procedure TFLWF_Main_.FormShow(Sender: TObject);
begin
If Not ShowAlarm then
Self.Close;
end;



تابع ShowAlarm هم به اینصورته :

Function TFLWF_Main_.ShowAlarm:Boolean;
var i:integer;
begin
for i:= 1 to 5 do
begin
Result:=ShowAlarm1_5(i);
if Result=false then break;
end;

//فعال کردن تایمر چک نیم ساعته
DataModule1.ADOQueryLWFCheck.Close;
DataModule1.ADOQueryLWFCheck.SQL.Clear;
DataModule1.ADOQueryLWFCheck.SQL.Text:='Select * From LWF Where DateRev1 <= '+QuotedStr(SHDate)+' and CheckRev1=False';
DataModule1.ADOQueryLWFCheck.Open;
if DataModule1.ADOQueryLWFCheck.RecordCount>0 then
begin
TimerCheckRev1.Enabled:=True;
TimerCheckRev1Timer(nil);
end else TimerCheckRev1.Enabled:=False;
end;


و تابع جزئی تر هم به این صورته :

Function TFLWF_Main_.ShowAlarm1_5(No:Integer):Boolean;
Const
RevNo:array[1..5]of string=
('مرور پس از نیم ساعت خلاصه برداری مورخ %s فرا رسیده است، آیا مطالعه می کنید؟',
'مرور پس از یک روز خلاصه برداری مورخ %s فرا رسیده است، آیا مطالعه می کنید؟',
'مرور پس از 7 روز خلاصه برداری مورخ %s فرا رسیده است، آیا مطالعه می کنید؟',
'مرور پس از 30 روز خلاصه برداری مورخ %s فرا رسیده است، آیا مطالعه می کنید؟',
'مرور پس از 90 روز خلاصه برداری مورخ %s فرا رسیده است، آیا مطالعه می کنید؟');
begin
result:=True;
DataModule1.ADOQueryLWFCheck.Close;
DataModule1.ADOQueryLWFCheck.SQL.Clear;
if No=1 then
DataModule1.ADOQueryLWFCheck.SQL.Text:='Select * From LWF Where DateRev1 <= '+QuotedStr(SHDate)+' and TimeRev1<='+QuotedStr(FormatDateTime('hh:nn',Now))+' and CheckRev1=False ORDER BY LWF.[DateRev1], LWF.[TimeRev1];' else
DataModule1.ADOQueryLWFCheck.SQL.Text:='Select * From LWF Where DateRev'+IntToStr(No)+' <= '+QuotedStr(SHDate)+' and CheckRev'+IntToStr(No)+'=False';
DataModule1.ADOQueryLWFCheck.Open;
if DataModule1.ADOQueryLWFCheck.RecordCount>0 then
begin
DataModule1.ADOQueryLWFCheck.First;
while Not(DataModule1.ADOQueryLWFCheck.Eof) do
begin
if DLG(Format(RevNo[No],[DataModule1.ADOQueryLWFCheck.FieldByName('DateSave ').AsString]),[mbyes,mbno],mtConfirmation)=mrYes then
begin
Result:=True;
ShowReading(DataModule1.ADOQueryLWFCheck,No);
end else
begin
Result:=False;
exit;
end;
DataModule1.ADOQueryLWFCheck.Next;
end;
end;
end;



و داخل تایمر عملیات مربوط به چک کردن آلارم هر ثانیه اتفاق می افته ، کدش تکرار تابع بالاس دیگه نذاشتمش.

tdkhakpur
یک شنبه 13 شهریور 1390, 15:43 عصر
:لبخندساده:
چی میگی ؟!
PostMessage زمانی استفاده میشه که ارسال کننده پیام فقط قصد اطلاع رسانی به دریافت کننده پیام رو داره و پردازش کردن یا نکردن پیام یا زمان پردازش پیام برای ارسال کننده اهمیتی نداره !
سوادت قد نمیده!


حالا بگید چیکار باید کرد؟
آیا استفاده کردن از تایمر اشتباهه؟ اونم به این صورت که پس از نمایش فرم دوم فعال بشه!!


قرار دادن کد مربوط به تراکنش یا دیتابیس داخل timer کار درستی نیست مگر اینکه مطمئن بشید چه زمانی تراکنش ویا هر پردازش دیگه کی تموم میشه.
ولی اگر هدفتان بستن فرم هست یاید wm_close رو با postmessage به فرم ارسال کنید تا بتونید فرم را ببندید.

saeed6162
یک شنبه 13 شهریور 1390, 18:08 عصر
قرار دادن کد مربوط به تراکنش یا دیتابیس داخل timer کار درستی نیست مگر اینکه مطمئن بشید چه زمانی تراکنش ویا هر پردازش دیگه کی تموم میشه.
خوب می فرمائید که چیکار کنم ؟

اصلا شما اساتید ، برای نوشتن یک برنامه آلارم که راس زمان های خاصی که تو بانک ذخیره شدند باید یک پیغام رو نشون بده رو چجوری و با استفاده از روشی می نویسید ، میشه من رو تفهیم کنید که راه اصولی پیاده سازیش چیه که این قضیه showmodal هم تو اون حل بشه؟

JaguarXF
یک شنبه 13 شهریور 1390, 20:12 عصر
برای نوشتن یک برنامه آلارم که راس زمان های خاصی که تو بانک ذخیره شدند باید یک پیغام رو نشون بده رو چجوری و با استفاده از روشی می نویسید

والا ما یک شرکتی که یک برنامه Expert System برای این کار نوشته بود رو یکجا خریدیم!

Felony
یک شنبه 13 شهریور 1390, 20:13 عصر
شما اساتید ، برای نوشتن یک برنامه آلارم که راس زمان های خاصی که تو بانک ذخیره شدند باید یک پیغام رو نشون بده رو چجوری و با استفاده از روشی می نویسید ، میشه من رو تفهیم کنید که راه اصولی پیاده سازیش چیه که این قضیه showmodal هم تو اون حل بشه؟
زمان ها رو موقع شروع روند چک کردن یک بار از داخل بانک به داخل یک آرایه دینامیک یا StringList یا ... میریختم و بعد تو تایمر مثلا توسط متد IndexOf کلاس TStringList بررسی میکردم ببینم زمان فعلی سیستم داخل لیست من هست یا نه ( اینطوری سربار ناشی از کار با بانک از برنامه حذف میشه ) اگر بود اطلاعات تکمیلی رو از بانک میخوندم و کارهای مورد نظر رو انجام میدادم .

tdkhakpur
یک شنبه 13 شهریور 1390, 20:17 عصر
برای نوشتن یک برنامه آلارم که راس زمان های خاصی که تو بانک ذخیره شدند باید یک پیغام رو نشون بده رو چجوری و با استفاده از روشی می نویسید ، میشه من رو تفهیم کنید که راه اصولی پیاده سازیش چیه که این قضیه showmodal هم تو اون حل بشه؟

شما اون بالا ذکر کردید که


و داخل تایمر عملیات مربوط به چک کردن آلارم هر ثانیه اتفاق می افته ، کدش تکرار تابع بالاس دیگه نذاشتمش.

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