-
Поток смотрит за изменением и отсылает сообщение Создание-удаление-переименование отслеживается. Почему изменение файла не ловится?
FFN: TFindFileNotify;
FFN := TFindFileNotify.Create(True);
FFN.FreeOnTerminate := True;
FFN.HWND := Self.Handle;
FFN.Msg := WM_USER;
FFN.Ident := 1;
FFN.MyDir := 'c:\1111\';
FFN.AndSubFolder := True;
FFN.Resume;
procedure TForm1.WM_FFN(var Message: TMessage);
begin
Memo1.Lines.Add(StrPas(PAnsiChar(TMessage(Message).LParam)));
=====
unit uFileNotify;
interface
uses
Classes, Windows;
type
PFileNotifyInformation = ^TFileNotifyInformation;
TFileNotifyInformation = record
NextEntryOffset : DWORD;
Action : DWORD;
FileNameLength : DWORD;
FileName : array[0..0] of WideChar;
end;
type
TFindFileNotify = class(TThread)
private
FHWND: THandle;
FMsg: THandle;
FIdent: THandle;
FMyDir: string;
FAndSubFolder: Boolean;
procedure SetHWND(const Value: THandle);
procedure SetMsg(const Value: THandle);
procedure SetIdent(const Value: THandle);
procedure SetMyDir(const Value: string);
procedure SetAndSubFolder(const Value: Boolean);
protected
procedure Execute; override;
public
property HWND:THandle read FHWND write SetHWND;
property Msg:THandle read FMsg write SetMsg;
property Ident:THandle read FIdent write SetIdent;
property MyDir:string read FMyDir write SetMyDir;
property AndSubFolder:Boolean read FAndSubFolder write SetAndSubFolder;
end;
implementation
procedure TFindFileNotify.Execute;
const
BUF_SIZE = 2048;
var
hDir : THandle;
lpBuf : Pointer;
Ptr : Pointer;
cbReturn : Cardinal;
FileName : PWideChar;
S: string;
begin
hDir := CreateFile (PAnsiChar(FMyDir),
GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
0);
if hDir = INVALID_HANDLE_VALUE then
begin
S := 'hDir = INVALID_HANDLE_VALUE';
if HWND <> 0 then
SendMessage(HWND, Msg, Ident, LPARAM(PChar(s)));
exit;
end;
GetMem(lpBuf, BUF_SIZE);
repeat
ZeroMemory(lpBuf, BUF_SIZE);
if not ReadDirectoryChangesW(hDir,
lpBuf,
BUF_SIZE,
FAndSubFolder, FILE_NOTIFY_CHANGE_FILE_NAME,
@cbReturn,
nil,
nil) then
Break;
Ptr := lpBuf;
repeat
S := '';
GetMem(FileName, PFileNotifyInformation(Ptr).FileNameLength + 2);
ZeroMemory(FileName, PFileNotifyInformation(Ptr).FileNameLength+2);
lstrcpynW(FileName,
PFileNotifyInformation(Ptr).FileName,
PFileNotifyInformation(Ptr).FileNameLength div 2 + 1);
S := MyDir + FileName;
FreeMem(FileName);
case PFileNotifyInformation(Ptr).Action of
FILE_ACTION_ADDED : S := '[Создан]' + S;
FILE_ACTION_REMOVED : S := '[Удален]' + S;
FILE_ACTION_MODIFIED : S := '[Изменен]' + S;
FILE_ACTION_RENAMED_OLD_NAME : S := '[ДоПереименован]' + S;
FILE_ACTION_RENAMED_NEW_NAME : S := '[ПослеПереименован]' + S;
else S := '[Непонятно]' + S;
end;
if S <> '' then
begin
if (HWND <> 0) and not(Terminated) then
SendMessage(HWND, Msg, Ident, LPARAM(PChar(S)));
S := '';
end;
if PFileNotifyInformation(Ptr).NextEntryOffset = 0 then
Break else
Inc(Cardinal(Ptr),PFileNotifyInformation(Ptr).NextEntryOffset);
until Terminated;
until Terminated;
FreeMem(lpBuf);
end;
procedure TFindFileNotify.SetAndSubFolder(const Value: Boolean);
begin
FAndSubFolder := Value;
end;
procedure TFindFileNotify.SetHWND(const Value: THandle);
begin
FHWND := Value;
end;
procedure TFindFileNotify.SetIdent(const Value: THandle);
begin
FIdent := Value;
end;
procedure TFindFileNotify.SetMsg(const Value: THandle);
begin
FMsg := Value;
end;
procedure TFindFileNotify.SetMyDir(const Value: string);
begin
FMyDir := Value;
end;
end.
-
> if not ReadDirectoryChangesW(hDir, > lpBuf, > BUF_SIZE, > FAndSubFolder, // true c подкаталогами > FILE_NOTIFY_CHANGE_FILE_NAME, > @cbReturn, > nil, > nil) then
FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
Any file name change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file.
(c) MSDN
-
черт.. спасибо
-
только сейчас руки дошли надо так, значит: (исправлю по ответу, заодно пусть будет. Может потом найду, если потеряю. Вроде, модуль целиком запостил в прошлый раз) procedure TForm1.btn1Click(Sender: TObject);
begin
if B then
FFN.Terminate else
begin
FFN := TFindFileNotify.Create(True);
FFN.FreeOnTerminate := True;
FFN.HWND := Self.Handle;
FFN.Msg := WM_USER;
FFN.Ident := 1;
FFN.MyDir := edt1.Text;
if cbAndSubFolder.Checked then
FFN.AndSubFolder := True else
FFN.AndSubFolder := False;
FFN.WatchFind := 0; if cbCreateDelRename.Checked then
FFN.WatchFind := FFN.WatchFind or FILE_NOTIFY_CHANGE_FILE_NAME;
if cbChangeContent.Checked then
FFN.WatchFind := FFN.WatchFind or FILE_NOTIFY_CHANGE_SIZE;
if cbOtherChange.Checked then
FFN.WatchFind := FFN.WatchFind or FILE_NOTIFY_CHANGE_ATTRIBUTES or
FILE_NOTIFY_CHANGE_LAST_WRITE or FILE_NOTIFY_CHANGE_LAST_ACCESS or
FILE_NOTIFY_CHANGE_SECURITY or FILE_NOTIFY_CHANGE_CREATION;
FFN.Resume;
end;
B := not(b);
if B then
btn1.Caption := 'Стоп' else
btn1.Caption := 'Старт';
end; и, соответственно, if not ReadDirectoryChangesW(hDir, lpBuf,
BUF_SIZE,
FAndSubFolder,
FWatchFind,
@cbReturn,
nil,
nil) then
Break;
|