Stack Exchange
How can I periodically process the next item of a list box?
I have a list of proxy addresses in a TListBox (1.2.42.x.2.4:42, 2.4.1.x.1.2.x.2:60, etc.) that I use with TIdHTTP. When a button is clicked, I fetch a given URL using the selected proxy:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  S: String;
begin
  I := Listbox1.ItemIndex;
  if I <> -1 then
  begin
    S := Listbox1.Items[I];
    IdHTTP1.ProxyParams.ProxyServer := Fetch(S, ':');
    IdHTTP1.ProxyParams.ProxyPort := StrToInt(S);
    try
      IdHTTP1.ReadTimeout:=strtoint(form1.Edit1.Text); // ZMAAN AŞIMI
      IdHTTP1.Get(Edit4.Text);                         // POST GET
      MessageDlg('Ok.', mtinformation,[mbOK],0); // TAMAMLANDI.
    except
      MessageDlg('Error.', mtinformation,[mbOK],0);   // HATA VERDİ.
      IdHTTP1.Disconnect;   // ÖLDÜR.
    end;
  end;
end;

After clicking the button, I want my program to automatically do the same as above, but with ListBox1.Items[1], then ListBox1.Items[2], and so on.
I think I could use a TTimer for this, but how?

Of course. Here's one way:
procedure TForm1.ListBox1Click(Sender: TObject);
var
  I: Integer;
  S: String;
begin
  I := Listbox1.ItemIndex;
  if I <> -1 then
  begin
    S := Listbox1.Items[I];
    IdHTTP1.ProxyParams.ProxyServer := Fetch(S, ':');
    IdHTTP1.ProxyParams.ProxyPort := StrToInt(S);
     try
      IdHTTP1.ReadTimeout:=strtoint(form1.Edit1.Text); // ZMAAN AŞIMI
      IdHTTP1.Get(Edit4.Text);                         // POST GET
      MessageDlg('Ok.', mtinformation,[mbOK],0); // TAMAMLANDI.
    except
      MessageDlg('Error.', mtinformation,[mbOK],0);   // HATA VERDİ.
      IdHTTP1.Disconnect;   // ÖLDÜR.
    end;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  try
    ListBox1Click(nil);
    if ListBox1.ItemIndex < ListBox1.Items.Count - 1 then
      ListBox1.ItemIndex := ListBox1.ItemIndex + 1
    else
      ListBox1.ItemIndex := -1;
  finally
    // To stop after only one loop through all items, as you asked in your comment:
    Timer1.Enabled := (ListBox1.ItemIndex > -1);
  end;
end;

I'd personally move almost all of the code from the ListBox1Click event into it's own standalone method that you could call from either the ListBox.OnClick event or the Timer.OnTimer event easily. You could pass in the ListBox1.Items[ListBox1.ItemIndex] as a parameter to that method. It would make your code much cleaner, IMO.

very thanks. Label1.caption:= Successful? Label2.caption:= Unsuccessful?  how do I? so, 4 successful, 5 unsuccesfull, 2 Timeout? And only one loop..?

Use a TMemo instead. For each one that you try, add a line to the memo. Memo1.Lines.Add(Format('Try %d: %s', [i, StatusMessage]));, where StatusMessage is whatever you want to display (Successful, Unsuccessful, TimeOut). Do that where you're using the two MessageDlg calls now in the ListBox1Click event.

[Error] Unit1.pas(142): Undeclared identifier: 'StatusMessage'  Error :$

where StatusMessage is whatever you want to display +++
you want +++
you want and you make it whatever you want it to be

Please read what I wrote. Declare StatusMessage as a string variable; assign it Successful, Unsuccessful, or whatever, and then display it. StatusMessage is the name of a variable that will, well, contain a status message that you can  then show the user in place of the MessageDlg calls you're showing now (as I wrote in my last comment).

I understand you. But.. Only one loops?

As it is now, it only loops once. When it reaches the last item, it sets the ListBox1.ItemIndex back to -1, and your ListBox1Click event already checks for I <> -1. When it hits -1 again, disable the timer and leave it disabled (by setting Timer1.Enabled := False;). I edited the Timer1Timer event in my code to do just that - leave the timer disabled if the ItemIndex is -1.
