Also ich habe da mal auf die Schnelle zusammengehauen mit dem ComponentState und das funktioniert einwandfrei
Delphi-Quellcode:
procedure TMyThreadComponent.DoEvent( const Info : string );
begin
if Assigned( Edit ) and ( Self.ComponentState = [] )
then
Edit.Text := Info;
end;
Die Komponente hat als Owner das Formular und sobald das Formular in die ewigen Jagdgründe geschickt wird, dann ändert sich erstmal der ComponentState von allen Components, die das Formular als Owner haben. Somit würden also diese Events zwar vom Thread noch aufgerufen aber nicht mehr wirklich bedient.
Und
( Self.ComponentState = [] )
prüft ja auch nicht irgendwas abstruses von ausserhalb ab, sondern den Status deiner eigenen Komponente
EDIT
Hier mal die gesamte Komponente (ist nicht schön und auch nicht wirklich ThreadSafe abgesichert)
Delphi-Quellcode:
unit uMyThreadComponent;
interface
uses
Classes,
Vcl.StdCtrls;
type
TMyDoEvent =
procedure(
const Info :
string )
of object;
TMyThread =
class( TThread )
private
FOnDoEvent : TMyDoEvent;
procedure SetOnDoEvent(
const Value : TMyDoEvent );
protected
procedure Execute;
override;
procedure DoEvent;
public
property OnDoEvent : TMyDoEvent
read FOnDoEvent
write SetOnDoEvent;
end;
TMyThreadComponent =
class( TComponent )
private
FMyThread : TMyThread;
FEdit : TEdit;
procedure SetEdit(
const Value : TEdit );
protected
procedure DoEvent(
const Info :
string );
public
constructor Create( AOwner : TComponent );
override;
destructor Destroy;
override;
published
property Edit : TEdit
read FEdit
write SetEdit;
end;
implementation
uses
System.SysUtils;
{ TMyThreadComponent }
constructor TMyThreadComponent.Create( AOwner : TComponent );
begin
inherited;
FMyThread := TMyThread.Create( True );
FMyThread.OnDoEvent := DoEvent;
FMyThread.Start;
end;
destructor TMyThreadComponent.Destroy;
begin
FMyThread.Terminate;
FMyThread.WaitFor;
FMyThread.Free;
inherited;
end;
procedure TMyThreadComponent.DoEvent(
const Info :
string );
begin
if Assigned( Edit )
and ( Self.ComponentState = [] )
then
Edit.Text := Info;
end;
procedure TMyThreadComponent.SetEdit(
const Value : TEdit );
begin
FEdit := Value;
end;
{ TMyThread }
procedure TMyThread.DoEvent;
begin
if Assigned( OnDoEvent )
then
FOnDoEvent( FormatDateTime( '
hh:nn:ss.zzz', now ) );
end;
procedure TMyThread.Execute;
begin
while not Terminated
do
begin
Synchronize( DoEvent );
Sleep( 20 );
end;
end;
procedure TMyThread.SetOnDoEvent(
const Value : TMyDoEvent );
begin
FOnDoEvent := Value;
end;
end.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ea 0a 4c 14 0d b6 3a a4 c1 c5 b9
dc 90 9d f0 e9 de 13 da 60)