Delphi Can

Orjinalini görmek için tıklayınız: 4 Puanlık Soru
Şu anda (Arşiv) modunu görüntülemektesiniz. Orjinal Sürümü Görüntüle internal link
Merhabalar,

Bir döngü içerisindeyiz... Döngü devam ederken esc tuşuna basınca kullanıcıya soru sormak istiyorum duruma göre devam edeceğim ya da çıkacağım.

Bunu nasıl yapardınız ?

for I := 0 to 10000 do
  begin
   Memo1.Lines.Add('Items' + inttostr(i));
   if BASILANTUŞ=VK_ESCAPE then // Esc tuşuna basıldıysaa
   begin
     if MessageDlg('Escye bastın çıkayım mııı yoksa yanlışlıkla mı oldu ?',
       mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
     begin
       Break
     end;
   end;
 end;
if GetKeyState(VK_ESCAPE)<0 then

kullanabilirsin.

Daha karışık şeyler olursa WaitForSingleObject de olur.
Merhaba.

Bir ekleme yapmak isterim, döngü içinde sisteme nefes aldıracak unsur yoksa belki de bir Application.ProcessMessages; satırı ilavesi ile mesajların yürümesini sağlamanız gerekebilir. Yoksa tuşu yakalama ve döngü içinde dikkate imkanı olmayabilir.
(05-09-2018, Saat: 14:58)ssahinoglu Adlı Kullanıcıdan Alıntı: [ -> ]
if GetKeyState(VK_ESCAPE)<0 then

kullanabilirsin.

Daha karışık şeyler olursa WaitForSingleObject de olur.


neden GetKeyState(VK_ESCAPE)<0 tuş basılı iken ne değer dönüyor ki ?
Merhaba,
Allah bereket versin, azı çoğu önemli değil. Smile

  private
   FEsc: Boolean;

Uses System.UITypes;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FEsc := False;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key = VK_ESCAPE then
 begin
   FEsc := True;
   Key := 0;
 end;
end;

Aşağıdaki kodu herhangi bir yerde tetiklemeniz yeterli olacaktır.
  TThread.CreateAnonymousThread(
   procedure
   var
     I: Integer;
   begin
     for I := 0 to integer.MaxValue do
     begin
       TThread.Synchronize(TThread.CurrentThread,
         procedure
         begin
           Memo1.Lines.Add('Items' + inttostr(i));
         end);

       if FEsc then
       begin // Esc tuşuna basıldıysaa
         if MessageDlg('Escye bastın çıkayım mııı yoksa yanlışlıkla mı oldu ?',
           mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
         begin
           FEsc := False;
         end
         else
           Break
       end;
     end;
   end).Start;
Application.ProcessMessages arayüze nefes aldırır ama sık kullanılması sistemi yoruyor.

Hızlı döngülerde "if döngü mod 1000=0" gibi bir koşulla kullanmak daha iyi olur.

https://docs.microsoft.com/en-us/windows...etkeystate
haklısınız daha önce bu konuyu konuştuk.
Bu da bir çözüm olarak ( sıklığını azaltmak ) sunulmuştu. Hatırlatma için teşekkürler.
(05-09-2018, Saat: 15:25)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba,
Allah bereket versin, azı çoğu önemli değil. Smile

  private
   FEsc: Boolean;

Uses System.UITypes;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FEsc := False;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key = VK_ESCAPE then
 begin
   FEsc := True;
   Key := 0;
 end;
end;

Aşağıdaki kodu herhangi bir yerde tetiklemeniz yeterli olacaktır.
  TThread.CreateAnonymousThread(
   procedure
   var
     I: Integer;
   begin
     for I := 0 to integer.MaxValue do
     begin
       TThread.Synchronize(TThread.CurrentThread,
         procedure
         begin
           Memo1.Lines.Add('Items' + inttostr(i));
         end);

       if FEsc then
       begin // Esc tuşuna basıldıysaa
         if MessageDlg('Escye bastın çıkayım mııı yoksa yanlışlıkla mı oldu ?',
           mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
         begin
           FEsc := False;
         end
         else
           Break
       end;
     end;
   end).Start;

Böyle bir cevap beklemiyordum Big Grin

Bu da benden,

   
type
  TKey = record
    lo, hi: byte;
  end;

function KeyCtrl(const Key: Integer): Boolean;
VAR
  sm: Smallint;
  bp: PByte;
begin
  sm := GetKeyState(Key);
  bp := @sm;
  Inc(bp);
  Result := TKey(sm).hi = 255;
end;


if KeyCtrl(VK_ESCAPE) then
    begin
   
   end;

(05-09-2018, Saat: 15:36)yhackup Adlı Kullanıcıdan Alıntı: [ -> ]
(05-09-2018, Saat: 15:25)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba,
Allah bereket versin, azı çoğu önemli değil. Smile

  private
   FEsc: Boolean;

Uses System.UITypes;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FEsc := False;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key = VK_ESCAPE then
 begin
   FEsc := True;
   Key := 0;
 end;
end;

Aşağıdaki kodu herhangi bir yerde tetiklemeniz yeterli olacaktır.
  TThread.CreateAnonymousThread(
   procedure
   var
     I: Integer;
   begin
     for I := 0 to integer.MaxValue do
     begin
       TThread.Synchronize(TThread.CurrentThread,
         procedure
         begin
           Memo1.Lines.Add('Items' + inttostr(i));
         end);

       if FEsc then
       begin // Esc tuşuna basıldıysaa
         if MessageDlg('Escye bastın çıkayım mııı yoksa yanlışlıkla mı oldu ?',
           mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
         begin
           FEsc := False;
         end
         else
           Break
       end;
     end;
   end).Start;

Böyle bir cevap beklemiyordum Big Grin

Bu da benden,

   
type
  TKey = record
    lo, hi: byte;
  end;

function KeyCtrl(const Key: Integer): Boolean;
VAR
  sm: Smallint;
  bp: PByte;
begin
  sm := GetKeyState(Key);
  bp := @sm;
  Inc(bp);
  Result := TKey(sm).hi = 255;
end;


if KeyCtrl(VK_ESCAPE) then
    begin
   
   end;


Bildiğin gibi, uzun zamandır beynim multi-platform eksenli çalışmaya başladı. Smile
Kodları tüm platformlarda gönül rahatlığıyla kullanabilirsin.
(05-09-2018, Saat: 15:25)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: [ -> ]Merhaba,
Allah bereket versin, azı çoğu önemli değil. Smile

  private
   FEsc: Boolean;

Uses System.UITypes;

procedure TForm1.FormCreate(Sender: TObject);
begin
 FEsc := False;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
 if Key = VK_ESCAPE then
 begin
   FEsc := True;
   Key := 0;
 end;
end;

Aşağıdaki kodu herhangi bir yerde tetiklemeniz yeterli olacaktır.
  TThread.CreateAnonymousThread(
   procedure
   var
     I: Integer;
   begin
     for I := 0 to integer.MaxValue do
     begin
       TThread.Synchronize(TThread.CurrentThread,
         procedure
         begin
           Memo1.Lines.Add('Items' + inttostr(i));
         end);

       if FEsc then
       begin // Esc tuşuna basıldıysaa
         if MessageDlg('Escye bastın çıkayım mııı yoksa yanlışlıkla mı oldu ?',
           mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
         begin
           FEsc := False;
         end
         else
           Break
       end;
     end;
   end).Start;

Merhaba,

Yukarıdaki kodda MessageDlg yerine Windows.MessageBox kullanmak gerekiyor. MessageDlg kullandığınız zaman VCL bileşeni kullanmış oluyorsunuz (Application.Message veya ShowMessage fonksiyonlarında da). VCL bileşenleri thread-safe olmadığı için programınız belirsiz davranır ve büyük ihtimalle çöker. Ama Windows.MessageBox fonksiyonunu, ilk parametresi 0 olacak şekilde kullanacak olursanız o zaman sorun olmaz. İlk parametre 0 değilse gene sorun olabilir. Tabii Windows unitini uses kısmına eklediğiniz zaman da her platformda çalışmaz.

Bana soracak olursanız thread içinden kullanıcıya mesaj göstermek doğru değil. Onun yerine thread için bir bekleme mekanizması koymak, kullanıcı ESC düğmesine basınca thread'i beklemeye almak ve soruyu ana programda sormak, sorunun cevabına göre de işlem yapmak daha doğru. Hem bütün platformlarda da çalışır Smile

İyi çalışmalar