Hallo,
timeSetEvent gilt ja als veraltet, daher soll man CreateTimerQueueTimer verwenden. Delphi-Beispiele sind schwer zu finden, daher habe ich ein wenig probiert. Meine Grundidee war eine Klasse, die ein MessageOnly-Window anlegt, an welches sie dann Nachrichten schicken lässt, die im Callback des Timers gesendet werden. Dadurch kann der Timer durchlaufen und versendet eben nur Nachrichten, die Klasse räumt evtl. aufgelaufene Nachrichten ab und ruft einen ggf. zugewiesenen Eventhandler auf. Meine Frage: kann man das so machen, oder habe ich das nicht richtig verstanden und muss irgendwann mit blöden Seiteneffekten rechnen? Hier mal ein Beispiel für so eine Klasse:
Delphi-Quellcode:
const
MYMESSAGE = WM_USER + 42;
type
TTimerTestClass = class
private
FWnd: HWnd;
FOnTimer: TNotifyEvent;
FTimer: THandle;
procedure ClearMessageQueue;
procedure DoOnTimer(var Msg: TMessage);
public
constructor Create;
destructor Destroy; override;
procedure StartTimer;
procedure StopTimer;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
end;
implementation
procedure TTimerTestClass.ClearMessageQueue;
var
Msg: TMsg;
begin
while PeekMessage(Msg, FWnd, MYMESSAGE, MYMESSAGE, PM_REMOVE) do;
end;
constructor TTimerTestClass.Create;
begin
FWnd := AllocateHWnd(DoOnTimer);
end;
destructor TTimerTestClass.Destroy;
begin
StopTimer;
DeallocateHWnd(FWnd);
inherited;
end;
procedure TTimerTestClass.DoOnTimer(var Msg: TMessage);
begin
ClearMessageQueue;
if Assigned(FOnTimer) then
FOnTimer(self);
end;
procedure WaitOrTimer(lpParameter: Pointer; TimerOrWaitFired: Boolean); stdcall;
var
Test: TTimerTestClass;
begin
Test := TTimerTestClass(lpParameter);
if Assigned(Test) then
PostMessage(Test.FWnd, MYMESSAGE, 0, 0);
end;
procedure TTimerTestClass.StartTimer;
begin
if not CreateTimerQueueTimer(FTimer, 0, WaitOrTimer, self, 0, 50,
WT_EXECUTELONGFUNCTION) then
FTimer := 0;
end;
procedure TTimerTestClass.StopTimer;
begin
if FTimer <> 0 then
begin
DeleteTimerQueueTimer(0, FTimer, 0);
FTimer := 0;
end;
end;