Taki mój kawałek kodu który umożliwia uruchomienie procedury z opóźnieniem,
ja to wykorzystuję przy wszelkiego rodzaju suwakach i innych komponentach wizualnych które są w stanie wygenerować w krótkim czasie wiele zdarzeń podczas podczas przesuwania myszką . A jak procedura obsługi zdarzenia trwa długo to aplikacją się przytyka.
Co prawda niektóre komponenty mają do tego odpowiedni parametr (np. TTreeView.ChangeDelay ) ale niestety nie wszystkie.
Taka bardzo prosta implementacja.
Dlatego też w kodzie obsługi zdarzenia np. suwaka daje taki kod:
var
a_uruchomMulti: TUruchomZaChwileMulti;
procedure TForm2.scrlbr1Change(Sender: TObject);
begin
a_uruchomMulti.uruchom_za_chwile(3000,procedura_suwak1);
end;
Procedura procedura_suwak1 wykona sie dopiero w 3000ms od ostatnie zdarzenia suwaka.
unit UUruchomZaChwile;
(*
Autor: Ja
URL: http://4programmers.net/Forum/Delphi_Pascal/180505-uruchom_za_chwile
Examples: http://4programmers.net/Forum/Delphi_Pascal/180505-uruchom_za_chwile
Version: 1.0
*)
interface
uses
Windows, ExtCtrls, SysUtils;
type
TUruchomZaChwileProcedure = procedure of object;
TUruchomZaChwile = class
private
a_timer: TTimer;
a_procedura: TUruchomZaChwileProcedure;
procedure a_timerTimer(Sender: TObject);
public
constructor create;
destructor Destroy; override;
procedure uruchom_za_chwile(milisekundy: integer; p_procedura: TUruchomZaChwileProcedure);
end;
const
TUruchomZaChwileList_MAX_COUNT = 128;
type
TUruchomZaChwileMulti = class
private
a_count: integer;
a_lista_timer: array[0..TUruchomZaChwileList_MAX_COUNT-1] of TTimer;
a_lista_proc: array[0..TUruchomZaChwileList_MAX_COUNT-1] of TMethod;
procedure a_timerOnTimer(Sender: TObject);
public
constructor create;
destructor Destroy; override;
procedure uruchom_za_chwile(milisekundy: integer; p_procedura: TUruchomZaChwileProcedure);
end;
implementation
{ TUruchamiacz }
procedure TUruchomZaChwile.a_timerTimer(Sender: TObject);
begin
a_timer.Enabled := false; //wyłaczam timer, żeby nie dostać jego eventu jeszcze raz
if Assigned(a_procedura) then a_procedura();
end;
constructor TUruchomZaChwile.create;
begin
a_timer := TTimer.create(nil);
a_timer.Enabled := false;
a_timer.OnTimer := a_timerTimer;
end;
destructor TUruchomZaChwile.Destroy;
begin
a_timer.Free();
inherited;
end;
procedure TUruchomZaChwile.uruchom_za_chwile(milisekundy: integer;
p_procedura: TUruchomZaChwileProcedure);
begin
//wyłączneie timera powoduje reset pozostałego interwału.
a_timer.Enabled := false;
//setup timera
a_timer.Interval := milisekundy;
a_procedura := p_procedura;
//włączamy go poniownie, z pełnym interwałem.
a_timer.Enabled := True;
end;
{ TUruchomZaChwileList }
procedure TUruchomZaChwileMulti.a_timerOnTimer(Sender: TObject);
var
v_id: integer;
begin
v_id := (sender as Ttimer).Tag;// odczytuje ID mojego timer-a
a_lista_timer[v_id].Enabled := false;
TUruchomZaChwileProcedure(a_lista_proc[v_id]);
end;
constructor TUruchomZaChwileMulti.create;
begin
a_count := 0;
end;
destructor TUruchomZaChwileMulti.Destroy;
var
i: integer;
begin
for I := 0 to a_count - 1 do
begin
if Assigned(a_lista_timer[i]) then
a_lista_timer[i].Free;
end;
inherited;
end;
procedure TUruchomZaChwileMulti.uruchom_za_chwile(milisekundy: integer;
p_procedura: TUruchomZaChwileProcedure);
var
i: integer;
v_index: integer;
v_timer: TTimer;
begin
v_index := -1;
for I := 0 to a_count - 1 do // szukamy indeksu procedury
begin
if (TMethod(p_procedura).Code = a_lista_proc[i].Code) and
(TMethod(p_procedura).Data = a_lista_proc[i].Data) then
begin
v_index := i;
Break;
end;
end;
// jezeli v_index = -1 to dodajemy procedure do listy bo jej nie ma
if v_index = -1 then
begin
a_lista_proc[a_count].Code := TMethod(p_procedura).Code;
a_lista_proc[a_count].Data := TMethod(p_procedura).Data;
//
a_lista_timer[a_count] := TTimer.Create(nil);
a_lista_timer[a_count].Enabled := false;
a_lista_timer[a_count].Tag := a_count;// zaznaczamy timer;
a_lista_timer[a_count].OnTimer := a_timerOnTimer;
v_index := a_count;
Inc(a_count);
if a_count > TUruchomZaChwileList_MAX_COUNT then
raise Exception.Create('Za duza ilosc procedur TUruchomZaChwileList, zwieksz TUruchomZaChwileList_MAX_COUNT');
end;
v_timer := a_lista_timer[v_index];
v_timer.Enabled := false; //wyłączneie timera powoduje reset pozostałego interwału.
v_timer.Interval := milisekundy; //setup timera
v_timer.Enabled := True; //włączamy go poniownie, z pełnym interwałem.
end;
end.
Przykładowy kod w załączniku (za chwilę)