uses
Classes
// hier ist die TThread-Klasse drin
SysUtils;
const
WM_SERVER_STATUS = WM_USER + 2;
type
TServerStatus = (ssUnknown, ssOkay, ssUnreachable);
PServerStatusResponse = ^ServerStatusResponse;
RServerStatusResponse =
record
Address :
String;
Status : TServerStatus;
end;
type
TServerCheckThread =
class(TThread)
private
FWatcherHandle : HWND;
FServerAddress :
String;
protected
procedure Execute();
override;
public
property WatcherHandle : HWND
read FWatcherHandle
write FWatcherHandle;
property ServerAddress :
String read FServerAddress
write FServerAddress;
end;
procedure TServerCheckThread.Execute();
var
sr : PServerStatusResponse;
begin
while (
not Terminated)
do
begin
//
// Ping ServerAddress...
//
New(sr);
sr^.Address := Self.ServerAddress
sr^.Status := ... ;
// set server status after ping
SendMessage(FWatcherHandle, WM_SERVER_STATUS, Integer(sr), 0);
// sleep 10 sec. between two checks...
SleepEx(10000, True);
end;
end;
{ ... }
type
TServerWatcher =
class(TObject)
private
FHandle : HWND;
FWatcherThreads : TList;
FServerStatus : TStringList;
procedure WndProc(
var Msg:TMessage);
procedure OnServerStatus(
var Msg: TMessage);
message WM_SERVER_STATUS;
public
property Handle : HWND
read FHandle;
constructor Create();
reintroduce;
destructor Destroy();
override;
procedure StartWatcherThread(
const AServerAddress:
String);
end;
procedure TServerWatcher.WndProc(
var Msg: TMessage);
begin
Dispatch(Msg);
end;
procedure TServerWatcher.OnServerStatus(
var Msg: TMessage);
var
sr : PServerStatusResponse
begin
sr := PServerStatusResponse(msg.WParam);
try
FServerStatus.Values[sr^.Address] := ... ;
// cast sr^.Status to a good format
finally
// free memory (important!)
Dispose(sr);
end;
end;
constructor TServerWatcher.Create();
begin
inherited Create();
// allocate handle
FHandle := AllocateHWnd(WndProc);
// create thread list
FWachterThreads := TList.Create();
// create server status list
FServerStatus := TStringList.Create();
end;
destructor TServerWatcher.Destroy();
var
i : Integer;
wt : TWatcherThread;
begin
// free threads and thread-container
for i := FWachterThreads.Count - 1
downto 0
do
begin
wt := FWachterThreads[i];
wt.Terminate();
WaitForSingleObject(FStartupThread.Handle, 1000);
FreeAndNil(wt);
end;
FreeAndNil(FWachterThreads);
// free server-status list
FreeAndNil(FServerStatus);
// free handle
DeallocateHWnd(FHandle);
inherited Destroy();
end;
procedure TServerWatcher.StartWatcherThread(
const AServerAddress:
String);
var
wt : TWatcherThread;
begin
// create status for server in list
FServerStatus.Add(AServerAddress + '
=' + ... );
// cast ssUnknown to a good format
// create sleeping watcher-thread
wt := TWatcherThread.Create(True);
wt.WatcherHandle := FHandle;
wt.ServerAddress := AServerAddress;
FThreadList.Add(wt);
wt.Start();
end;