setTimeout
對JavaScript語言很有幫助。你將如何在delphi中創建這個功能?如何在Delphi中創建一個定時器函數(如JavaScript中的setTimeout)?
SetTimeOut(procedure (Sender: TObject);
begin
Self.Counter := Self.Counter + 1;
end, 200);
setTimeout
對JavaScript語言很有幫助。你將如何在delphi中創建這個功能?如何在Delphi中創建一個定時器函數(如JavaScript中的setTimeout)?
SetTimeOut(procedure (Sender: TObject);
begin
Self.Counter := Self.Counter + 1;
end, 200);
我想你可能會離開TTimer
,並嘗試使用SetTimer
函數並使用它的回調函數。您需要將計時器ID及其(匿名)方法存儲在某個集合中。既然你沒有提到你的Delphi版本,我已經使用了一個簡單的類和TObjectList
作爲一個集合。
原理很簡單,您只需使用指定的回調函數調用SetTimer
函數,並將新實例化的系統計時器ID與匿名方法一起存儲到集合中。執行該回調函數時,通過其ID找到導致集合中回調的計時器,殺死它,執行匿名方法並將其從集合中刪除。下面是示例代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Contnrs;
type
TOnTimerProc = reference to procedure;
TOneShotTimer = class
ID: UINT_PTR;
Proc: TOnTimerProc;
end;
procedure SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal);
type
TForm1 = class(TForm)
Timer1: TTimer;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
TimerList: TObjectList;
implementation
{$R *.dfm}
procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR;
dwTime: DWORD); stdcall;
var
I: Integer;
Timer: TOneShotTimer;
begin
for I := 0 to TimerList.Count - 1 do
begin
Timer := TOneShotTimer(TimerList[I]);
if Timer.ID = idEvent then
begin
KillTimer(0, idEvent);
Timer.Proc();
TimerList.Delete(I);
Break;
end;
end;
end;
procedure SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal);
var
Timer: TOneShotTimer;
begin
Timer := TOneShotTimer.Create;
Timer.ID := SetTimer(0, 0, ATimeout, @TimerProc);
Timer.Proc := AProc;
TimerList.Add(Timer);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetTimeout(procedure
begin
ShowMessage('OnTimer');
end,
1000
);
end;
initialization
TimerList := TObjectList.Create;
TimerList.OwnsObjects := True;
finalization
TimerList.Free;
end.
簡體版(德爾福2009年增長):
像通過@大衛的評論,下面是相同的代碼上面,只是在一個單獨的建議單位與使用泛型字典。從本機SetTimeout
的使用是一樣的,在上面的代碼:
unit OneShotTimer;
interface
uses
Windows, Generics.Collections;
type
TOnTimerProc = reference to procedure;
procedure SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal);
var
TimerList: TDictionary<UINT_PTR, TOnTimerProc>;
implementation
procedure TimerProc(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR;
dwTime: DWORD); stdcall;
var
Proc: TOnTimerProc;
begin
if TimerList.TryGetValue(idEvent, Proc) then
try
KillTimer(0, idEvent);
Proc();
finally
TimerList.Remove(idEvent);
end;
end;
procedure SetTimeout(AProc: TOnTimerProc; ATimeout: Cardinal);
begin
TimerList.Add(SetTimer(0, 0, ATimeout, @TimerProc), AProc);
end;
initialization
TimerList := TDictionary<UINT_PTR, TOnTimerProc>.Create;
finalization
TimerList.Free;
end.
喜歡的東西
type
TMyProc = Procedure of Object(Sender: TObject);
TMyClass = Object
HandlerList = TStringList;
TimerList = TStringlist;
Procedure CallThisFunction(Sender :TObject);
function setTimeout(Timeout: Integer; ProcToCall : TMyProc)
end;
function setTimeout(Timeout: Integer; ProcToCall : TMyProc)
var
Timer : TTimer;
begin
Timer := TTimer.Create(nil);
Timer.OnTimer := CallOnTimer;
Timer.Interval := Timeout;
Timer.Enabled := true;
HandlerList.AddObject(ProcToCall);
TimerList.AddObject(ProcToCall);
end;
function CallOnTimer(Sender : TObject)
var TimerIndex : Integer;
HandlerToCall : TMyProc;
Timer : TTimer;
begin
TimerIndex := TimerList.IndexOfObject(Sender);
HandlerToCall := (HandlerList.Objects[TimerIndex] as TMyProc) ;
HandlerToCall(Self);
HandlerList.Delete(TimerIndex);
Timer := (TimerList.Objects(TimerIndex) as TTimer);
Timer.Free;
TimerList.Delete(TimerIndex);
end;
這剛剛被黑客攻擊在一起,而不是測試以任何方式,表示的是概念。基本上建立你想要調用的定時器和過程的列表。由於自身對象在被調用時被傳遞給過程,但是您可以構建第三個包含要在setTimeout調用中用作參數的對象的列表。
然後在調用該方法後釋放對象。
與javascripts setTimeout不同,但是與delphi近似。
ps。我還沒有真正從Delphi7上移開,所以如果在Delphi XE中有這樣一個新的混亂的方式,我不知道它。
不,我想用[匿名函數](http://delphi.about.com/od/objectpascalide/a/understanding-anonymous-methods-in-delphi.htm)。你的代碼使用方法指針。 – MajidTaheri
假設,該功能將被調用一次,而不是5次每秒,也許那樣:
Parallel.Async(
procedure; begin
Sleep(200);
Self.Counter:=Self.Counter+1; end;);
有是比較複雜的解決方案,比如您接受的解決方案,爲定時器操作和使用SetTimer方法提供命名對象。像http://code.google.com/p/omnithreadlibrary/source/browse/trunk/tests/17_MsgWait/test_17_MsgWait.pas 以前的版本讓SetTimer具有匿名功能,但它們現在不在了。
但是,對於您要求的簡單匿名關閉方法,也許Wait(xxX)會適合。
我平時做這樣
TThread.CreateAnonymousThread(procedure begin
Sleep(1000); // timeout
// put here what you want to do
end).Start;
我無法理解這一點。你能否試着詳細說明一下。 –
你想要一個快速和骯髒的一次性定時器。然後,您可以將其封裝在setTimeout函數中以方便使用。 –