MMThread.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:12k
- {========================================================================}
- {= (c) 1995-98 SwiftSoft Ronald Dittrich =}
- {========================================================================}
- {= All Rights Reserved =}
- {========================================================================}
- {= D 01099 Dresden = Fax.: +49(0)351-8037944 =}
- {= Loewenstr.7a = info@swiftsoft.de =}
- {========================================================================}
- {= Actual versions on http://www.swiftsoft.de/index.html =}
- {========================================================================}
- {= This code is for reference purposes only and may not be copied or =}
- {= distributed in any format electronic or otherwise except one copy =}
- {= for backup purposes. =}
- {= =}
- {= No Delphi Component Kit or Component individually or in a collection=}
- {= subclassed or otherwise from the code in this unit, or associated =}
- {= .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed =}
- {= without express permission from SwiftSoft. =}
- {= =}
- {= For more licence informations please refer to the associated =}
- {= HelpFile. =}
- {========================================================================}
- {= $Date: 05.10.98 - 18:49:02 $ =}
- {========================================================================}
- unit MMThread;
- {$I COMPILER.INC}
- {$C FIXED PRELOAD PERMANENT}
- {.$DEFINE _MMDEBUG}
- interface
- Uses
- Windows,
- Forms,
- Classes,
- SysUtils,
- MMObj,
- MMString,
- MMUtils
- {$IFDEF _MMDEBUG}
- ,MMDebug
- {$ENDIF}
- ;
- type
- EMMThreadError = class(Exception);
- TMMThread = class;
- {-- TMMRealThread --------------------------------------------------}
- TMMRealThread = class(TMMThreadEx)
- private
- MMThread: TMMThread;
- Terminating: Boolean;
- procedure Execute; override;
- end;
- {-- TMLThread ------------------------------------------------------}
- TMMThread = class(TMMNonVisualComponent)
- private
- FThread : TMMRealThread;
- FGeneralEvent : THandle;
- FThreadCreated : Boolean;
- FPriority : TThreadPriority;
- FEnabled : Boolean;
- FSynchronize : Boolean;
- FAutoExecute : Boolean;
- FMainThreadWaiting: Boolean;
- FWaitForTerminate : Boolean;
- FOnStart : TNotifyEvent;
- FOnTerminate : TNotifyEvent;
- FOnThread : TNotifyEvent;
- procedure SetPriority(aValue: TThreadPriority);
- procedure SetEnabled(aValue: Boolean);
- procedure SetAutoExecute(aValue: Boolean);
- function GetHandle: THandle;
- function GetThreadID: THandle;
- function GetTerminating: Boolean;
- function GetTerminated: Boolean;
- procedure DoThread;
- protected
- procedure ChangeDesigning(aValue: Boolean); override;
- procedure Loaded; override;
- procedure Thread; virtual;
- public
- constructor Create(AOwner : TComponent); override;
- destructor Destroy; override;
- procedure Execute; virtual;
- procedure Terminate; virtual;
- procedure SynchronizeVCL(VCLProc: TThreadMethod);
- property Handle: THandle read GetHandle;
- property ThreadID: THandle read GetThreadID;
- property Terminating: Boolean read GetTerminating;
- property Terminated: Boolean read GetTerminated;
- published
- { Events }
- property OnStart: TNotifyEvent read FOnStart write FOnStart;
- property OnThread: TNotifyEvent read FOnThread write FOnThread;
- property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
- property AutoExecute: Boolean read FAutoExecute write SetAutoExecute default False;
- property Enabled: Boolean read FEnabled write SetEnabled default True;
- property Priority: TThreadPriority read FPriority write SetPriority default tpNormal;
- property Synchronize: Boolean read FSynchronize write FSynchronize default True;
- property WaitForTerminate: Boolean read FWaitForTerminate write FWaitForTerminate default False;
- end;
- implementation
- {== TMMRealThread ======================================================}
- procedure TMMRealThread.Execute;
- var
- H: THandle;
- begin
- if (MMThread <> nil) then
- try
- Priority := MMThread.FPriority;
- { Ready to go, set the general event }
- SetEvent(MMThread.FGeneralEvent);
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'ThreadProc started...');
- {$ENDIF}
- while not Terminated and (MMThread <> nil) do
- begin
- if not Terminating then MMThread.DoThread;
- end;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Leave ThreadProc...');
- {$ENDIF}
- if (MMThread <> nil) then
- begin
- h := MMThread.FGeneralEvent;
- MMThread.FThread := nil;
- MMThread := nil;
- SetEvent(h);
- end;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Ready for done...');
- {$ENDIF}
- except
- Application.HandleException(Self);
- end;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'ThreadProc terminated...');
- {$ENDIF}
- end;
- {== TMMThread ==========================================================}
- constructor TMMThread.Create(aOwner:TComponent);
- begin
- inherited Create(aOwner);
- FPriority := tpNormal;
- FAutoExecute := False;
- FEnabled := True;
- FSynchronize := True;
- FWaitForTerminate := False;
- FMainThreadWaiting := False;
- ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
- if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
- end;
- {-- TMMThread ----------------------------------------------------------}
- destructor TMMThread.Destroy;
- begin
- if FThreadCreated then
- begin
- { Don't run event if form is being destroyed ! }
- OnTerminate := Nil;
- OnThread := Nil;
- Terminate;
- end;
- inherited Destroy;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.ChangeDesigning(aValue: Boolean);
- begin
- inherited;
- if not (csDesigning in ComponentState) then
- begin
- if AutoExecute and not FThreadCreated then Execute;
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.Loaded;
- begin
- inherited Loaded;
- if FAutoExecute then Execute;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.Execute;
- begin
- if not (csDesigning in ComponentState) and
- not (csLoading in ComponentState) then
- begin
- if assigned(FOnThread) and not FThreadCreated then
- begin
- {$IFDEF TRIAL}
- {$DEFINE _HACK1}
- {$I MMHACK.INC}
- {$ENDIF}
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Try to start Thread...');
- {$ENDIF}
- FGeneralEvent := CreateEvent(nil, False, False, nil);
- FThread := TMMRealThread.Create(True);
- if (FThread = nil) then
- raise EMMThreadError.Create('Thread:'#10#13+LoadResStr(IDS_THREADERROR));
- FThread.MMThread := Self;
- FThread.FreeOnTerminate := True;
- FThread.Terminating := False;
- FThreadCreated := True;
- if FEnabled then
- begin
- FThread.Resume;
- { Wait for it to start... }
- if WaitForSingleObject(FGeneralEvent, 1000) <> WAIT_OBJECT_0 then
- raise EMMThreadError.Create('Thread:'#10#13+LoadResStr(IDS_THREADERROR));
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Thread started...');
- {$ENDIF}
- end;
- if Assigned(FOnStart) then FOnStart(self);
- end;
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.Terminate;
- begin
- if FThreadCreated then
- begin
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Shot down Thread...');
- {$ENDIF}
- FThread.Terminating := True;
- { in case it is suspended remove all before terminate }
- while FThread.Suspended do FThread.Resume;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Terminate Thread...');
- {$ENDIF}
- FThread.Terminate;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Start Waiting...');
- {$ENDIF}
- { ...and wait for it to die }
- if FWaitForTerminate and not FMainThreadWaiting then
- WaitForSingleObject(FGeneralEvent, 5000);
- if (FThread <> nil) then
- FThread.MMThread := nil;
- { free the event }
- CloseHandle(FGeneralEvent);
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Call OnTerminate...');
- {$ENDIF}
- if Assigned(FOnTerminate) then FOnTerminate(Self);
- FThreadCreated := False;
- {$IFDEF _MMDEBUG}
- DB_WriteStrLn(0,'Thread now stopped...');
- {$ENDIF}
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- function TMMThread.GetTerminating: Boolean;
- begin
- Result := (FThread = nil) or FThread.Terminating;
- end;
- {-- TMMThread ----------------------------------------------------------}
- function TMMThread.GetTerminated: Boolean;
- begin
- Result := not FThreadCreated;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.SetAutoExecute(aValue: Boolean);
- begin
- if (aValue <> FAutoExecute) then
- begin
- FAutoExecute := aValue;
- if FAutoExecute then Execute;
- end;
- {$IFDEF TRIAL}
- {$DEFINE _HACK2}
- {$I MMHACK.INC}
- {$ENDIF}
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.SetEnabled(aValue:Boolean);
- begin
- if (aValue <> FEnabled) then
- begin
- FEnabled := aValue;
- if FThreadCreated then FThread.Suspended := not FEnabled;
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.SetPriority(aValue: TThreadPriority);
- begin
- if (aValue <> FPriority) then
- begin
- FPriority := aValue;
- if FThreadCreated then FThread.Priority := FPriority;
- end;
- {$IFDEF TRIAL}
- {$DEFINE _HACK3}
- {$I MMHACK.INC}
- {$ENDIF}
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.SynchronizeVCL(VCLProc: TThreadMethod);
- begin
- if FThreadCreated then
- begin
- FMainThreadWaiting := True;
- FThread.Synchronize(VCLProc);
- FMainThreadWaiting := False;
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.DoThread;
- begin
- if FEnabled then
- begin
- if FSynchronize then
- SynchronizeVCL(Thread)
- else
- Thread;
- end;
- end;
- {-- TMMThread ----------------------------------------------------------}
- procedure TMMThread.Thread;
- begin
- if assigned(FOnThread) then FOnThread(Self);
- end;
- {-- TMMThread ----------------------------------------------------------}
- function TMMThread.GetHandle : THandle;
- begin
- Result := 0;
- if FThreadCreated then Result := FThread.Handle;
- end;
- {-- TMMThread ----------------------------------------------------------}
- function TMMThread.GetThreadID: THandle;
- begin
- Result := 0;
- if FThreadCreated then Result := FThread.ThreadId;
- end;
- end.