2 This part of the unit modified by Tim Slusher and Vladimir Kladov.
\r
5 {* Set of utility methods to work with files
\r
7 When programming KOL, which is Windows API-oriented, You should
\r
8 avoid alien (for Windows) embedded Pascal files handling, and
\r
9 use API-calls which implemented very well. This set of functions
\r
10 is intended to make this easier.
\r
11 Also TDirList object implementation present here and some registry
\r
12 access functions, which allow to make code more elegant.
\r
16 {$IFDEF ASM_VERSION}
\r
18 {$ENDIF ASM_VERSION}
\r
20 {$IFDEF ASM_VERSION}
\r
21 function FileCreate(const FileName: string; OpenFlags: DWord): THandle;
\r
29 MOV CL, FILE_ATTRIBUTE_NORMAL
\r
32 PUSH ECX // CreationMode
\r
35 PUSH ECX // ShareMode
\r
37 PUSH EDX // AccessMode
\r
38 //CALL System.@LStrToPChar // FileName must not be ''
\r
42 {$ELSE ASM_VERSION} //Pascal
\r
43 function FileCreate(const FileName: string; OpenFlags: DWord): THandle;
\r
46 Attr := (OpenFlags shr 16) and $1FFF;
\r
47 if Attr = 0 then Attr := FILE_ATTRIBUTE_NORMAL;
\r
48 Result := CreateFile( PChar(FileName), OpenFlags and $F0000000,
\r
49 OpenFlags and $F, nil, (OpenFlags shr 8) and $F,
\r
52 {$ENDIF ASM_VERSION}
\r
54 {$IFDEF ASM_VERSION}
\r
55 function FileClose(Handle: THandle): Boolean;
\r
62 {$ELSE ASM_VERSION} //Pascal
\r
63 function FileClose(Handle: THandle): boolean;
\r
65 Result := CloseHandle(Handle);
\r
67 {$ENDIF ASM_VERSION}
\r
69 {$IFDEF ASM_VERSION}
\r
70 function FileExists( const FileName : String ) : Boolean;
\r
71 const size_TWin32FindData = sizeof( TWin32FindData );
\r
75 CALL GetFileAttributes
\r
80 DB $24, FILE_ATTRIBUTE_DIRECTORY
\r
82 AND AL, FILE_ATTRIBUTE_DIRECTORY
\r
87 {$ELSE ASM_VERSION} //Pascal
\r
88 function FileExists( const FileName : String ) : Boolean;
\r
92 Code := GetFileAttributes(PChar(FileName));
\r
93 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0);
\r
95 {$ENDIF ASM_VERSION}
\r
97 {$IFDEF ASM_VERSION}
\r
98 function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
\r
105 CALL SetFilePointer
\r
107 {$ELSE ASM_VERSION} //Pascal
\r
108 function FileSeek(Handle: THandle; MoveTo: integer; MoveMethod: TMoveMethod): DWord;
\r
110 Result := SetFilePointer(Handle, MoveTo, nil, Ord( MoveMethod ) );
\r
112 {$ENDIF ASM_VERSION}
\r
114 {$IFDEF ASM_VERSION}
\r
115 function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
\r
133 {$ELSE ASM_VERSION} //Pascal
\r
134 function FileRead(Handle: THandle; var Buffer; Count: DWord): DWord;
\r
136 if not ReadFile(Handle, Buffer, Count, Result, nil) then
\r
139 {$ENDIF ASM_VERSION}
\r
141 {$IFDEF ASM_VERSION}
\r
142 function File2Str(Handle: THandle): String;
\r
146 JZ @@exit // return ''
\r
149 MOV EBX, EAX // EBX = Handle
\r
159 SUB EAX, EDX // EAX = Size - Pos
\r
163 CALL System.@GetMem
\r
175 CALL _LStrFromPCharLen
\r
177 CALL System.@LStrFromPCharLen
\r
187 CALL System.@LStrFromPChar
\r
192 CALL System.@FreeMem
\r
195 {$ELSE ASM_VERSION} //Pascal
\r
196 function File2Str(Handle: THandle): String;
\r
197 var Pos, Size: DWORD;
\r
200 if Handle = 0 then Exit;
\r
201 Pos := FileSeek( Handle, 0, spCurrent );
\r
202 Size := GetFileSize( Handle, nil );
\r
203 SetString( Result, nil, Size - Pos + 1 );
\r
204 FileRead( Handle, Result[ 1 ], Size - Pos );
\r
205 Result[ Size - Pos + 1 ] := #0;
\r
207 {$ENDIF ASM_VERSION}
\r
209 {$IFDEF ASM_VERSION}
\r
210 function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
\r
228 {$ELSE ASM_VERSION} //Pascal
\r
229 function FileWrite(Handle: THandle; const Buffer; Count: DWord): DWord;
\r
231 if not WriteFile(Handle, Buffer, Count, Result, nil) then
\r
234 {$ENDIF ASM_VERSION}
\r
236 {$IFDEF ASM_VERSION}
\r
237 function FileEOF( Handle: THandle ) : Boolean;
\r
255 {$ELSE ASM_VERSION} //Pascal
\r
256 function FileEOF( Handle: THandle ) : Boolean;
\r
257 var Siz, Pos : DWord;
\r
259 Siz := GetFileSize( Handle, nil );
\r
260 Pos := FileSeek( Handle, 0, spCurrent );
\r
261 Result := Pos >= Siz;
\r
263 {$ENDIF ASM_VERSION}
\r
265 {$IFDEF ASM_noVERSION}
\r
266 function FileFullPath( const FileName: String ) : String;
\r
268 BkSlash: String = '\';
\r
269 szTShFileInfo = sizeof( TShFileInfo );
\r
277 CALL System.@LStrClr
\r
282 CALL System.@LStrAsg
\r
285 @@loo: CMP dword ptr [ESI], 0
\r
294 CMP dword ptr [EBX], 0
\r
298 CALL System.@LStrCat
\r
303 CALL System.@LStrLen
\r
308 CMP byte ptr [EAX+1], ':'
\r
314 CALL System.@LStrAsg
\r
320 CALL System.@LStrAsg
\r
323 CALL System.@LStrCat
\r
326 SUB ESP, szTShFileInfo
\r
328 PUSH SHGFI_DISPLAYNAME
\r
334 LEA EDX, [ESP].TShFileInfo.szDisplayName
\r
335 CMP byte ptr [EDX], 0
\r
337 LEA EAX, [ESP+szTShFileInfo+4]
\r
338 CALL System.@LStrFromPChar
\r
340 ADD ESP, szTShFileInfo
\r
345 CALL System.@LStrCat
\r
347 @@3: CALL RemoveStr
\r
350 @@fin: CALL RemoveStr
\r
354 {$ELSE ASM_VERSION} //Pascal
\r
355 function FileFullPath( const FileName: String ) : String;
\r
356 var SFI: TShFileInfo;
\r
363 S := Parse( Src, '\' );
\r
364 if Result <> '' then
\r
365 Result := Result + '\';
\r
366 if (Result = '') and (Length( S ) = 2) and (S[ 2 ] = ':') then
\r
370 ShGetFileInfo( PChar( Result + S ), 0, SFI, Sizeof( SFI ),
\r
371 SHGFI_DISPLAYNAME );
\r
372 if SFI.szDisplayName[ 0 ] <> #0 then
\r
373 S := SFI.szDisplayName;
\r
374 Result := Result + S;
\r
377 if ExtractFileExt( Result ) = '' then
\r
378 // case when flag 'Hide extensions for registered file types' is set on
\r
379 // in the Explorer:
\r
380 Result := Result + ExtractFileExt( FileName );
\r
382 {$ENDIF ASM_VERSION}
\r
384 function FileShortPath( const FileName: String ): String;
\r
385 var Buf: array[ 0..MAX_PATH ] of Char;
\r
387 GetShortPathName( PChar( FileName ), Buf, Sizeof( Buf ) );
\r
391 function FileIconSystemIdx( const Path: String ): Integer;
\r
392 var SFI: TShFileInfo;
\r
394 SFI.iIcon := 0; // Bartov
\r
395 ShGetFileInfo( PChar( Path ), 0, SFI, sizeof( SFI ),
\r
396 //-- Babenko Alexey: -----------------//
\r
397 // SHGFI_ICON or //
\r
398 //----------------------------------//
\r
399 SHGFI_SMALLICON or SHGFI_SYSICONINDEX );
\r
400 Result := SFI.iIcon;
\r
403 function FileIconSysIdxOffline( const Path: String ): Integer;
\r
404 var SFI: TShFileInfo;
\r
406 SFI.iIcon := 0; // Bartov
\r
407 ShGetFileInfo( PChar( Path ), FILE_ATTRIBUTE_NORMAL, SFI, sizeof( SFI ),
\r
408 //-- Babenko Alexey: -----------------//
\r
409 // SHGFI_ATTRIBUTES or SHGFI_ICON or //
\r
410 //----------------------------------//
\r
411 SHGFI_SMALLICON or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES );
\r
412 Result := SFI.iIcon;
\r
415 procedure LogFileOutput( const filepath, str: String );
\r
418 F := FileCreate( filepath, ofOpenWrite or ofOpenAlways );
\r
419 if F = INVALID_HANDLE_VALUE then Exit;
\r
420 FileSeek( F, 0, spEnd );
\r
421 FileWrite( F, {$IFNDEF _D2} String {$ENDIF}
\r
422 ( str + #13#10 )[ 1 ], Length( str ) + 2 );
\r
426 function StrSaveToFile( const Filename, Str: String ): Boolean;
\r
430 F := FileCreate( Filename, ofOpenWrite or ofOpenAlways );
\r
431 if F = INVALID_HANDLE_VALUE then Exit;
\r
432 FileWrite( F, Str[ 1 ], Length( Str ) );
\r
437 function StrLoadFromFile( const Filename: String ): String;
\r
441 F := FileCreate( Filename, ofOpenRead or ofOpenExisting or ofShareDenyWrite );
\r
442 if F = INVALID_HANDLE_VALUE then Exit;
\r
443 Result := File2Str( F );
\r
444 FileClose( F ); {??ee(zhog); Dark Knight}
\r
447 {$IFDEF ASM_VERSION}
\r
448 function DirectoryExists(const Name: string): Boolean;
\r
450 //CALL System.@LStrToPChar // Name must not be ''
\r
452 CALL GetFileAttributes
\r
457 DB $24, FILE_ATTRIBUTE_DIRECTORY
\r
459 AND AL, FILE_ATTRIBUTE_DIRECTORY
\r
464 {$ELSE ASM_VERSION} //Pascal
\r
465 function DirectoryExists(const Name: string): Boolean;
\r
469 Code := GetFileAttributes(PChar(Name));
\r
470 Result := (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code <> 0);
\r
472 {$ENDIF ASM_VERSION}
\r
474 function CheckDirectoryContent( const Name: String; SubDirsOnly: Boolean; const Mask: String ): Boolean;
\r
475 var FD: TWin32FindData;
\r
478 if not DirectoryExists( Name ) then
\r
482 FH := Windows.FindFirstFile( PChar( IncludeTrailingPathDelimiter( Name )
\r
484 if FH = INVALID_HANDLE_VALUE then
\r
490 if not StrIn( FD.cFileName, ['.','..'] ) then
\r
492 if SubDirsOnly and LongBool(FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)
\r
493 or not SubDirsOnly then
\r
499 until not Windows.FindNextFile( FH, FD );
\r
500 Windows.FindClose( FH );
\r
505 function DirectoryEmpty(const Name: String): Boolean;
\r
507 Result := CheckDirectoryContent( Name, FALSE, '*.*' );
\r
511 function DirectorySize( const Path: String ): I64;
\r
512 var DirList: PDirList;
\r
515 Result := MakeInt64( 0, 0 );
\r
516 DirList := NewDirList( Path, '*.*', 0 );
\r
517 for I := 0 to DirList.Count-1 do
\r
519 if LongBool( DirList.Items[ I ].dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY ) then
\r
520 Result := Add64( Result, DirectorySize( DirList.Path + DirList.Names[ I ] ) )
\r
522 Result := Add64( Result, MakeInt64( DirList.Items[ I ].nFileSizeLow,
\r
523 DirList.Items[ I ].nFileSizeHigh ) );
\r
529 function DirectoryHasSubdirs( const Path: String ): Boolean;
\r
531 Result := not CheckDirectoryContent( Path, TRUE, '*.*' );
\r
534 function GetFileList(const dir: string): PStrList;
\r
536 Srch: TWin32FindData;
\r
541 flag := FindFirstFile(PChar(dir), Srch);
\r
543 while succ do begin
\r
544 if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
\r
545 if Result = nil then begin
\r
546 Result := NewStrList;
\r
548 Result.Add(Srch.cFileName);
\r
550 succ := FindNextFile(Flag, Srch);
\r
555 function ExcludeTrailingChar( const S: String; C: Char ): String;
\r
558 if Result <> '' then
\r
559 if Result[ Length( Result ) ] = C then
\r
560 Delete( Result, Length( Result ), 1 );
\r
563 function IncludeTrailingChar( const S: String; C: Char ): String;
\r
566 if (Result = '') or (Result[ Length( Result ) ] <> C) then
\r
567 Result := Result + C;
\r
570 //---------------------------------------------------------
\r
571 // Following functions/procedures are created by Edward Aretino:
\r
572 // IncludeTrailingPathDelimiter, ExcludeTrailingPathDelimiter,
\r
573 // ForceDirectories, CreateDir, ChangeFileExt
\r
574 //---------------------------------------------------------
\r
575 function IncludeTrailingPathDelimiter(const S: string): string;
\r
577 {if CopyTail(S, 1) <> '\' then
\r
581 Result := IncludeTrailingChar( S, '\' );
\r
584 function ExcludeTrailingPathDelimiter(const S: string): string;
\r
587 if Length(Result) = 0 then Exit;
\r
589 if (CopyTail(Result, 1) = '\') then
\r
590 DeleteTail(Result, 1);}
\r
591 Result := ExcludeTrailingChar( S, '\' );
\r
594 function ForceDirectories(Dir: string): Boolean;
\r
596 Result := Length(Dir) > 0; {Centronix}
\r
597 If not Result then Exit;
\r
598 Dir := ExcludeTrailingPathDelimiter(Dir);
\r
599 If (Length(Dir) < 3) or DirectoryExists(Dir) or
\r
600 (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
\r
601 Result := ForceDirectories(ExtractFilePath(Dir)) and CreateDir(Dir);
\r
604 function CreateDir(const Dir: string): Boolean;
\r
606 Result := Windows.CreateDirectory(PChar(Dir), nil);
\r
609 function ChangeFileExt(FileName: String; const Extension: string): string;
\r
613 FileExt := ExtractFileExt(FileName);
\r
614 DeleteTail(FileName, Length(FileExt));
\r
615 Result := FileName+ Extension;
\r
618 {$IFDEF ASM_VERSION}
\r
620 {$DEFINE ASM_LStrFromPCharLen}
\r
622 {$ENDIF ASM_VERSION}
\r
624 {$IFDEF ASM_LStrFromPCharLen}
\r
625 {$DEFINE ASM_DIRDelimiters}
\r
628 {$IFDEF ASM_VERSION}
\r
629 {$DEFINE ASM_DIRDelimiters}
\r
630 {$ENDIF ASM_VERSION}
\r
632 {$IFDEF ASM_DIRDelimiters}
\r
634 DirDelimiters: PChar = ':\';
\r
637 {$IFDEF ASM_VERSION}
\r
638 function ExtractFileName( const Path : String ) : String;
\r
642 MOV EDX, [DirDelimiters]
\r
643 CALL __DelimiterLast
\r
645 CMP byte ptr [EAX], 0
\r
650 CALL System.@LStrFromPChar
\r
652 {$ELSE ASM_VERSION} //Pascal
\r
653 function ExtractFileName( const Path : String ) : String;
\r
656 P := __DelimiterLast( PChar( Path ), ':\' );
\r
662 {$ENDIF ASM_VERSION}
\r
664 {$IFDEF ASM_LStrFromPCharLen} // LStrFromPCharLen - there are no in D2
\r
665 function ExtractFilePath( const Path : String ) : String;
\r
668 MOV EDX, [DirDelimiters]
\r
671 CALL __DelimiterLast
\r
675 CMP byte ptr [EDX], CL
\r
683 CALL System.@LStrFromPCharLen
\r
686 function ExtractFilePath( const Path : String ) : String;
\r
690 P0 := PChar( Path );
\r
691 P := __DelimiterLast( P0, ':\' );
\r
695 Result := Copy( Path, 1, P - P0 + 1 );
\r
699 function ExtractFileNameWOext( const Path : String ) : String;
\r
701 Result := ExtractFileName( Path );
\r
702 Result := Copy( Result, 1, Length( Result ) - Length( ExtractFileExt( Result ) ) );
\r
705 {$IFDEF ASM_VERSION}
\r
707 ExtDelimeters: PChar = '.';
\r
709 function ExtractFileExt( const Path : String ) : String;
\r
712 MOV EDX, [ExtDelimeters]
\r
714 CALL __DelimiterLast
\r
717 CALL System.@LStrFromPChar
\r
719 {$ELSE ASM_VERSION} //Pascal
\r
720 function ExtractFileExt( const Path : String ) : String;
\r
723 P := __DelimiterLast( PChar( Path ), '.' );
\r
726 {$ENDIF ASM_VERSION}
\r
728 function ReplaceFileExt( const Path, NewExt: String ): String;
\r
730 Result := ExtractFilePath( Path ) +
\r
731 ExtractFileNameWOext( ExtractFileName( Path ) ) +
\r
735 function ExtractShortPathName( const Path: String ): String;
\r
737 Buffer: array[0..MAX_PATH - 1] of Char;
\r
739 SetString(Result, Buffer,
\r
740 GetShortPathName(PChar(Path), Buffer, SizeOf(Buffer)));
\r
743 function FilePathShortened( const Path: String; MaxLen: Integer ): String;
\r
745 Result := FilePathShortenPixels( Path, 0, MaxLen );
\r
748 function PixelsLength( DC: HDC; const Text: String ): Integer;
\r
752 Result := Length( Text )
\r
755 Windows.GetTextExtentPoint32( DC, PChar( Text ), Length( Text ), Sz );
\r
760 function FilePathShortenPixels( const Path: String; DC: HDC; MaxPixels: Integer ): String;
\r
761 var L0, L1: Integer;
\r
765 L0 := PixelsLength( DC, Result );
\r
766 while L0 > MaxPixels do
\r
769 L1 := pos( '\...\', Result );
\r
771 Result := ExcludeTrailingPathDelimiter( ExtractFilePath( Result ) )
\r
773 Result := Copy( Result, 1, L1 - 1 );
\r
774 if Result <> '' then
\r
775 Result := IncludeTrailingPathDelimiter( ExtractFilePath( Result ) ) + '...\' + ExtractFileName( Path );
\r
776 if (Result = '') or (Result = Prev) then
\r
778 L1 := Length( ExtractFilePath( Result ) );
\r
779 while (PixelsLength( DC, Result ) > MaxPixels) and (L1 > 1) do
\r
782 Result := Copy( Result, 1, L1 ) + '...\' + ExtractFileName( Result );
\r
784 if PixelsLength( DC, Result ) > MaxPixels then
\r
786 L1 := MaxPixels + 1;
\r
787 while ((MaxPixels > 0) and (L1 > 1) or (MaxPixels = 0) and (L1 > 0)) and
\r
788 (PixelsLength( DC, Result ) > MaxPixels) do
\r
791 Result := Copy( ExtractFileName( Path ), 1, L1 ) + '...';
\r
796 L0 := PixelsLength( DC, Result );
\r
800 procedure CutFirstDirectory(var S: String);
\r
831 function MinimizeName( const Path: String; DC: HDC; MaxPixels: Integer ): String;
\r
833 Drive, Dir, Name: String;
\r
836 Dir := ExtractFilePath(Result);
\r
837 Name := ExtractFileName(Result);
\r
839 if (Length(Dir) >= 2) and (Dir[2] = ':') then
\r
841 Drive := Copy(Dir, 1, 2);
\r
846 while ((Dir <> '') or (Drive <> '')) and (PixelsLength(DC, Result) > MaxPixels) do
\r
848 if Dir = '\...\' then
\r
853 else if Dir = '' then
\r
856 CutFirstDirectory(Dir);
\r
857 Result := Drive + Dir + Name;
\r
861 {$IFDEF ASM_VERSION}
\r
862 function FileSize( const Path : String ) : Integer;
\r
863 const size_TWin32FindData = sizeof( TWin32FindData );
\r
865 ADD ESP, - size_TWin32FindData
\r
867 //CALL System.@LStrToPChar // Path must not be ''
\r
876 MOV EAX, [ESP].TWin32FindData.nFileSizeLow
\r
878 ADD ESP, size_TWin32FindData
\r
880 {$ELSE ASM_VERSION} //Pascal
\r
881 function FileSize( const Path : String ) : Integer;
\r
882 var FD : TWin32FindData;
\r
885 FH := FindFirstFile( PChar( Path ), FD );
\r
887 if FH = INVALID_HANDLE_VALUE then exit;
\r
888 Result := FD.nFileSizeLow;
\r
889 if ((FD.nFileSizeLow and $80000000) <> 0) or
\r
890 (FD.nFileSizeHigh <> 0) then Result := -1;
\r
893 {$ENDIF ASM_VERSION}
\r
896 function FileTimeCompare( const FT1, FT2 : TFileTime ) : Integer;
\r
897 var ST1, ST2 : TSystemTime;
\r
899 FileTimeToSystemTime( FT1, ST1 );
\r
900 FileTimeToSystemTime( FT2, ST2 );
\r
901 Result := CompareSystemTime( ST1, ST2 );
\r
904 function GetSystemDir: String;
\r
905 var Buf: array[ 0..MAX_PATH ] of Char;
\r
907 GetSystemDirectory( @ Buf[ 0 ], MAX_PATH + 1 );
\r
908 Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
\r
912 function GetWindowsDir : string;
\r
913 var Buf : array[ 0..MAX_PATH ] of Char;
\r
915 GetWindowsDirectory( @Buf[ 0 ], MAX_PATH + 1 );
\r
916 Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
\r
919 function GetWorkDir : string;
\r
920 var Buf: array[ 0..MAX_PATH ] of Char;
\r
922 GetCurrentDirectory( MAX_PATH + 1, @ Buf[ 0 ] );
\r
923 Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
\r
927 function GetTempDir : string;
\r
928 var Buf : array[ 0..MAX_PATH ] of Char;
\r
930 Windows.GetTempPath( MAX_PATH + 1, @Buf[ 0 ] );
\r
931 Result := IncludeTrailingPathDelimiter( PChar( @ Buf[ 0 ] ) );
\r
934 function CreateTempFile( const DirPath, Prefix: String ): String;
\r
935 var Buf: array[ 0..MAX_PATH ] of Char;
\r
937 GetTempFileName( PChar( DirPath ), PChar( Prefix ), 0, Buf );
\r
941 function GetFileListStr(FPath{e.g.'c:\tmp\'}, FMask{e.g.'*.*'}: string): string;
\r
942 {* List of files in string, separating each path from others with semicolon (';').
\r
943 E.g.: 'c:\tmp\unit1.dcu;c:\tmp\unit1.~pa' (for use with DeleteFile2Recycle())}
\r
945 Srch: TWin32FindData;
\r
951 if (FPath<>'') and (FPath[length(FPath)]<>'\') then FPath:=FPath+'\';
\r
952 if (FMask<>'') and (FMask[1]='\') then FMask:=CopyEnd(FMask,2);
\r
954 flag := FindFirstFile(PChar(dir), Srch);
\r
956 while succ do begin
\r
957 if (not (Srch.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY > 0))then begin
\r
958 if Result<>''then Result:=Result+';';
\r
959 Result:=Result+FPath+Srch.cFileName;
\r
961 succ := FindNextFile(Flag, Srch);
\r
966 function DeleteFiles( const DirPath: String ): Boolean;
\r
967 var Files, Name: String;
\r
969 Files := GetFileListStr( ExtractFilePath( DirPath ), ExtractFileName( DirPath ) );
\r
971 while Files <> '' do
\r
973 Name := Parse( Files, ';' );
\r
974 Result := Result and DeleteFile( PChar( Name ) );
\r
979 function DeleteFile2Recycle( const Filename : String ) : Boolean;
\r
980 var FOS : TSHFileOpStruct;
\r
984 L := Length( Filename );
\r
985 GetMem( Buf, L + 2 );
\r
986 StrCopy( Buf, PChar( Filename ) );
\r
987 Buf[ L + 1 ] := #0;
\r
988 for L := L downto 0 do
\r
989 if Buf[ L ] = ';' then Buf[ L ] := #0;
\r
990 FillChar( FOS, Sizeof( FOS ), 0 );
\r
991 if Applet <> nil then
\r
992 FOS.Wnd := Applet.Handle;
\r
993 FOS.wFunc := FO_DELETE;
\r
995 FOS.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;
\r
996 FOS.fAnyOperationsAborted := True;
\r
997 FOS.lpszProgressTitle := PChar( 'Delete ' + Filename + ' to Recycle bin' );
\r
998 Result := SHFileOperation( FOS ) = 0;
\r
1000 Result := not FOS.fAnyOperationsAborted;
\r
1004 function CopyMoveFiles( const FromList, ToList: String; Move: Boolean ): Boolean;
\r
1005 var FOS : TSHFileOpStruct;
\r
1009 L := Length( FromList );
\r
1010 GetMem( Buf, L + 2 );
\r
1011 StrCopy( Buf, PChar( FromList ) );
\r
1012 Buf[ L + 1 ] := #0;
\r
1013 for L := L downto 0 do
\r
1014 if Buf[ L ] = ';' then Buf[ L ] := #0;
\r
1015 FillChar( FOS, Sizeof( FOS ), 0 );
\r
1016 if Applet <> nil then
\r
1017 FOS.Wnd := Applet.Handle;
\r
1020 FOS.wFunc := FO_MOVE;
\r
1021 FOS.lpszProgressTitle := PChar( 'Move files' );
\r
1025 FOS.wFunc := FO_COPY;
\r
1026 FOS.lpszProgressTitle := PChar( 'Copy files' );
\r
1029 FOS.pTo := PChar( ToList + #0 );
\r
1030 FOS.fFlags := FOF_ALLOWUNDO;
\r
1031 FOS.fAnyOperationsAborted := True;
\r
1032 Result := SHFileOperation( FOS ) = 0;
\r
1034 Result := not FOS.fAnyOperationsAborted;
\r
1039 function DiskFreeSpace( const Path: String ): I64;
\r
1040 type TGetDFSEx = function( Path: PChar; CallerFreeBytes, TotalBytes, FreeBytes: Pointer )
\r
1042 var GetDFSEx: TGetDFSEx;
\r
1044 V: TOSVersionInfo;
\r
1046 SpC, BpS, NFC, TNC: DWORD;
\r
1050 V.dwOSVersionInfoSize := Sizeof( V );
\r
1051 GetVersionEx( V );
\r
1053 if V.dwPlatformId = VER_PLATFORM_WIN32_NT then
\r
1055 Ex := V.dwMajorVersion >= 4;
\r
1058 if V.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS then
\r
1060 Ex := V.dwMajorVersion > 4;
\r
1062 if V.dwMajorVersion = 4 then
\r
1064 Ex := V.dwMinorVersion > 0;
\r
1066 Ex := LoWord( V.dwBuildNumber ) >= $1111;
\r
1071 Kern32 := GetModuleHandle( 'kernel32.dll' );
\r
1072 GetDFSEx := GetProcAddress( Kern32, 'GetDiskFreeSpaceExA' );
\r
1074 if Assigned( GetDFSEx ) then
\r
1075 GetDFSEx( PChar( Path ), @ FBA, @ TNB, @Result )
\r
1078 GetDiskFreeSpace( PChar( Path ), SpC, BpS, NFC, TNC );
\r
1079 Result := Mul64i( MakeInt64( SpC * BpS, 0 ), NFC );
\r
1085 function GetUniqueFilename( PathName: string ) : String;
\r
1086 var Path, Nam, Ext : String;
\r
1087 I, J, K : Integer;
\r
1089 Result := PathName;
\r
1090 Path := ExtractFilePath( PathName );
\r
1091 if not DirectoryExists( Path ) then Exit;
\r
1092 Nam := ExtractFileNameWOext( PathName );
\r
1095 if Path[ Length( Path ) ] = '\' then
\r
1096 Path := Copy( Path, 1, Length( Path ) - 1 );
\r
1100 Nam := ExtractFileNameWOext( PathName );
\r
1101 Ext := ExtractFileExt( PathName );
\r
1102 I := Length( Nam );
\r
1103 for J := I downto 1 do
\r
1104 if not (Nam[ J ] in [ '0'..'9' ]) then
\r
1109 K := Str2Int( CopyEnd( Nam, I + 1 ) );
\r
1110 while FileExists( Result ) do
\r
1113 Result := Path + Copy( Nam, 1, I ) + Int2Str( K ) + Ext;
\r
1117 {$IFDEF ASM_VERSION}
\r
1118 function GetStartDir : String;
\r
1130 CALL GetModuleFileName
\r
1132 LEA EDX, [ESP + EAX]
\r
1134 CMP byte ptr [EDX], '\'
\r
1138 MOV byte ptr [EDX], 0
\r
1142 CALL System.@LStrFromPChar
\r
1147 {$ELSE ASM_VERSION} //Pascal
\r
1148 function GetStartDir : String;
\r
1149 var Buffer:array[0..260] of Char;
\r
1152 I := GetModuleFileName( 0, Buffer, Sizeof( Buffer ) );
\r
1153 for I := I downto 0 do
\r
1154 if Buffer[ I ] = '\' then
\r
1156 Buffer[ I + 1 ] := #0;
\r
1161 {$ENDIF ASM_VERSION}
\r
1163 //{$ENDIF LINUX/WIN32}