其实非常简单,hannuman的方法可以实现你的功能,不过你非要在类中实现的话,可以这样
另外不需要另外给分了,我们只是共同探讨问题。
unit Unit2;
interface
uses
Windows,Classes,Messages;
const
SNoTimers = 'Not enough timers available';
Type
TA=class
public
constructor Create(AOwner: TA); virtual;
end;
TB= class(TA)
private
FInterval: Cardinal;
FWindowHandle: HWND;
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
procedure WndProc(var Msg: TMessage);
protected
procedure Timer; dynamic;
public
constructor Create(AOwner: TA); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end;
implementation
constructor TA.Create(AOwner: TA);
begin
end;
constructor TB.Create(AOwner: TA);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWindowHandle := Classes.AllocateHWnd(WndProc); //我说的问题的关键在这里
end;
destructor TB.Destroy;
begin
FEnabled := False;
UpdateTimer;
Classes.DeallocateHWnd(FWindowHandle);
inherited Destroy;
end;
procedure TB.WndProc(var Msg: TMessage);
begin
with Msg do
if Msg = WM_TIMER then
try
Timer;
except
end
else
Result := DefWindowProc(FWindowHandle, Msg, wParam, lParam);
end;
procedure TB.UpdateTimer;
begin
KillTimer(FWindowHandle, 1);
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
if SetTimer(FWindowHandle, 1, FInterval, nil) = 0 then
raise EOutOfResources.Create(SNoTimers);
end;
procedure TB.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;
procedure TB.SetInterval(Value: Cardinal);
begin
if Value <> FInterval then
begin
FInterval := Value;
UpdateTimer;
end;
end;
procedure TB.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
UpdateTimer;
end;
procedure TB.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;
end.