PDA

View Full Version : سوال: لغو و خروج یک حلقه با فشردن کلید ESC



hadisalahi2
پنج شنبه 29 مهر 1389, 09:36 صبح
سلام به همگی دوستان.
من یک فرم دارم که داخل اون عکسها رو با عناوینشون ذخیره میکنم. به عبارتی یک برنامه مدیریت تصاویر دارم.
پس از ذخیره تصویر در صورتی که کاربر سطر مورد نظر رو از گرید انتخاب کنه و کلید Enter رو بزنه عکسهای مربوط به اون عنوان که قبلا ذخیره شدند در یک Picture List نمایش داده میشوند.

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

من از کد زیر برای نمایش تصاویر استفاده میکنم.



procedure TPictureForm.DBGridEh2KeyPress(Sender: TObject; var Key: Char);
var TempSQl:string[100];
begin
Try
if Key<>#13 then Exit;
PictureList.Items.Clear;
IMGCount:=0;
if DataBaseForm.InserADO.RecordCount<>0 then VisitID.Caption:=IntToStr(DataBaseForm.InserADO['ID']);
TempSQl:='select PicturePath From EqeepPicDetailTable where ID='+VisitID.Caption+' Order By Row';
DataBaseForm.EXECuteSQL(ADOQuery1,TempSQl,True);
ADOQuery1.First;
ProgressBar1.Max:=ADOQuery1.RecordCount;
while not ADOQuery1.Eof do begin
if Key=#27 then Break;
Sleep(1);
if Key=#27 then Break;
ProgressBar1.Position:=ProgressBar1.Position+1;
PictureList.Items.Add();
PictureList.Items.Items[IMGCount].Image.LoadFromFile(Trim(ADOQuery1['PicturePath']));
PictureList.Items.Items[IMGCount].Hint:=Trim(ADOQuery1['PicturePath']);
if Key=#27 then Break;
INC(IMGCount);
ADOQuery1.Next;
end;
ProgressBar1.Position:=0;
Except end;
end;


حالا کاری که من میخوام انجام بدم اینه که کاربر بتونه با زدن کلید ESC لود کردن تصاویر رو لغو کنه و منتظر لود شدن تمام تصاویر نشه.
البته تکه کد زیر رو گذاشتم ولی اصلا کار نمی کنه


if Key=#27 then Break;

در ضمن در KEyPress فرم هم این کد رو قرار دادم ولی بازهم تاثیری نداره.
ممنون میشم اگه دوستان در این مورد راهنمایی کنند.
یا حق

Felony
پنج شنبه 29 مهر 1389, 10:07 صبح
معلومه که نباید جواب بده ، شما با اون حلقه Thread اصلی برنامه رو تا زمان پایان یافتن عملیات فریز میکنید ، دو راه دارید :

1. تو حلقتون Application.ProcessMessages رو فراخوانی کنید تا Thread اصلی برنامه در حلقه پیغام های دریافتی رو هم پردازش کنه و فریز نشه و بعد داخل حلقه یا یک شرط ادامه کار حلقه رو چک کنید ، مثلا :

یک متغییر سراسری با نام NextLoop و از نوع Boolean تعریف کنید :
NextLoop: Boolean= True;

و بعد در رویداد OnKeyDown فرم یا ... کد زیر رو بنویسید :
if key= VK_ESCAPE then
NextLoop:= False;

در داخل حلقه هم به صورت زیر ادامه روند اجرای حلقه رو بررسی کنید :
var
I: Integer;
begin
for I := 0 to 100000 - 1 do
begin
ListBox1.Items.Add(IntToStr(i));
if NextLoop= False then
Break;
Application.ProcessMessages;
end;
end;

2. راه دوم هم که فنی تره ولی پیچیده تره ساخت یک ترد مجزا برای انجام عملیات بارگزاری تصاویر هست ، زمانی هم که نیاز به لغو عملیات شد ترد رو Stop میکنید .