Einzelnen Beitrag anzeigen

Benutzerbild von sieppl
sieppl

Registriert seit: 15. Aug 2004
Ort: Münster
198 Beiträge
 
Delphi 7 Professional
 
#1

WaitForMultipleObjects - finde den Fehler nicht [solved]

  Alt 29. Sep 2004, 21:53
Habe mir eine Klasse geschrieben, die mehrere Verzeichnisse gleichzeitig per FindFirstChangeNotification überwachen kann. Leider bekomme ich immer Wait_Failed zurück.
Delphi-Quellcode:
{ TDirWatcherThread }

function TDirWatcherThread.CheckNewPath: Boolean;
begin

end;

constructor TDirWatcherThread.Create(ExeFunc: TExecuteOnChange; Path: string;
                        WatchSubTrees: Boolean; NotifyFilter: LongWord);
begin
  inherited Create(false);
  Priority := tpNormal;
  FreeOnTerminate := True;
  SetNewPath(ExeFunc, Path, WatchSubTrees, NotifyFilter);
end;

procedure TDirWatcherThread.DeletePath(Index: Integer);
begin

end;

destructor TDirWatcherThread.Destroy;
var
  I: Integer;
begin
  for I := 0 to High(FHandleArray) do
  begin
    FindCloseChangeNotification(FHandleArray[I]);
  end;
  Finalize(FHandleArray);
  Finalize(FExecuteFuncList);
  inherited;
end;

procedure TDirWatcherThread.Execute;
var
  I: Integer;
begin
  while not Terminated and (Length(FHandleArray) > 0) do
  begin
    FWaitStatus := WaitForMultipleObjects(Length(FHandleArray), @FHandleArray,
                                            False, 500);
    if FWaitStatus = WAIT_FAILED then Exit;
    if (FWaitStatus >= WAIT_OBJECT_0) and (FWaitStatus <= High(FHandleArray)) then
    begin
      //der nachfolgende Block fängt viele hintereinander auftretende Notfications des
      //gleichen Handles erstmal an, damit die auszuführende Funktion nicht unnötig oft
      //gefeuert wird
      FindNextChangeNotification(FHandleArray[FWaitStatus]);
      while WaitForSingleObject(FHandleArray[FWaitStatus], 500) = WAIT_OBJECT_0 do
        FindNextChangeNotification(FHandleArray[FWaitStatus]);
      //hier wird die verknüpfte Funktion des z.B. ListViews angesprochen
      Synchronize(ExecuteOnChange);
    end;
    //alle Handles im Array 'auffrischen'
    for I := 0 to High(FHandleArray) do
      FindNextChangeNotification(FHandleArray[I]);
  end;
end;

procedure TDirWatcherThread.ExecuteOnChange;
begin
  //Hier wird sozusagen die übergebene 'OnNotification'-Funktion aufgerufen
  //für den Fehler irrelevant
  FExecuteFuncList[FWaitStatus];
end;

//public, ersetzt eine Pfad der bereits im Array der zu überwachenden Handles steht
procedure TDirWatcherThread.ReplacePath(Index: Integer;
  ExeFunc: TExecuteOnChange; Path: string; WatchSubTrees: Boolean;
  NotifyFilter: LongWord);
var
  TempHandle: THandle;
begin
  TempHandle := FindFirstChangeNotification(PChar(Path), WatchSubTrees, NotifyFilter);
  if TempHandle <> INVALID_HANDLE_VALUE then
  begin
    if Index > High(FHandleArray) then Exit;
    FHandleArray[Index] := TempHandle;
    FExecuteFuncList[Index] := ExeFunc;
  end;

end;

//public, ein neuer zu überwachender Pfad wird in den Array eingefügt
function TDirWatcherThread.SetNewPath(ExeFunc: TExecuteOnChange; Path: string;
                            WatchSubTrees: Boolean; NotifyFilter: LongWord): Integer;
var
  TempHandle: THandle;
begin
  Result := -1;
  TempHandle := FindFirstChangeNotification(PChar(Path), WatchSubTrees, NotifyFilter);
  if TempHandle <> INVALID_HANDLE_VALUE then
  begin
    //den neuen Handle in die Liste einfügen
    SetLength(FHandleArray, Length(FHandleArray) + 1);
    FHandleArray[High(FHandleArray)] := TempHandle;
    Result := High(FHandleArray);
    //die auszuführende Funtion in den Array einfügen
    SetLength(FExecuteFuncList, Length(FExecuteFuncList) + 1);
    FExecuteFuncList[High(FExecuteFuncList)] := ExeFunc;
  end;
end;
Hier der Aufruf:
Delphi-Quellcode:
//dieser wird vom ListView ausgeführt, UpdateAllItems ist eine Funktion des ListViews,
//welche bei einer Notification ausgeführt werden soll
if not Assigned(FDirWatcherThread) then
        FDirWatcherThread := TDirWatcherThread.Create(UpdateAllItems,
                                'c:\', False, FILE_NOTIFY_CHANGE_FILE_NAME);
Danke für Eure Hilfe!

vielleicht noch wichtig:
Delphi-Quellcode:
TExecuteOnChange = procedure of object;
//private-Deklarationen des TDirWatchers:
FHandleArray: array of THandle;
FExecuteFuncList: array of TExecuteOnChange;
Sebastian
  Mit Zitat antworten Zitat