unit AutoSVNNotify;
interface
uses
Classes, Windows, StrUtils;
type
TAutoSVNNotify =
class(TThread)
private
sDirName:
string;
cResFilename1:
string;
cResFilename2:
string;
cResAction: Integer;
procedure UpdateEvent();
protected
procedure Execute;
override;
public
constructor Create(sDirName:
string; CreateSuspended: Boolean);
end;
FILE_NOTIFY_INFORMATION =
record
dwNextEntryOffset: DWORD;
dwAction: DWORD;
dwFileNameLength: DWORD;
end;
implementation
uses Unit1;
{ TAutoSVNNotify }
procedure TAutoSVNNotify.UpdateEvent;
begin
if cResAction <> FILE_ACTION_RENAMED_NEW_NAME
then
cResFilename2 := '
';
Form1.UpdateEvent(cResFilename1, cResFilename2, cResAction);
end;
procedure TAutoSVNNotify.Execute;
var
dirHandle: THandle;
iBuf: Pointer;
iBufWorker: Pointer;
iBufLen: Cardinal;
iRead: DWORD;
FN: FILE_NOTIFY_INFORMATION;
s:
string;
begin
dirHandle := CreateFile(PChar(sDirName), GENERIC_READ
or 1, FILE_SHARE_READ
or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,
nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if (dirHandle = 0)
or (dirHandle = INVALID_HANDLE_VALUE)
then Exit;
iBufLen := 65536;
GetMem(iBuf, iBufLen);
while not Self.Terminated
do
begin
if not ReadDirectoryChanges(dirHandle, iBuf, iBufLen, True, FILE_NOTIFY_CHANGE_FILE_NAME
or FILE_NOTIFY_CHANGE_DIR_NAME
or FILE_NOTIFY_CHANGE_LAST_WRITE, @iRead,
nil,
nil)
then
Exit;
iBufWorker := iBuf;
repeat
Move(iBufWorker^, FN, 12);
s := WideCharLenToString(Pointer(Cardinal(iBufWorker) + 12), FN.dwFileNameLength);
s := LeftStr(s, FN.dwFileNameLength
div 2);
cResAction := FN.dwAction;
if FN.dwAction <> FILE_ACTION_RENAMED_NEW_NAME
then
cResFilename1 := s
else
cResFilename2 := s;
if FN.dwAction <> FILE_ACTION_RENAMED_OLD_NAME
then
Synchronize(UpdateEvent);
Inc(Cardinal(iBufWorker), FN.dwNextEntryOffset);
until FN.dwNextEntryOffset = 0;
end;
end;
constructor TAutoSVNNotify.Create(sDirName:
string; CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
Self.sDirName := sDirName;
end;
end.