BaseUtils.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. unit BaseUtils;
  2. {==================================================================
  3. Basic file handling utilities / Version 1.2 / 11.1999
  4. ========================================================
  5. Description:
  6. ============
  7. Basic utilities useful for handling files or directories.
  8. Used by the components TDriveView and TDirView.
  9. Author:
  10. =======
  11. (c) Ingo Eckel 5/1998
  12. Sodener Weg 38
  13. 65812 Bad Soden
  14. Germany
  15. Modifications (for WinSCP):
  16. ===========================
  17. (c) Martin Prikryl 2001, 2002
  18. {==================================================================}
  19. interface
  20. uses
  21. SysUtils, Windows, Forms, ShlObj, PIDL, Classes, Controls, DragDropFilesEx;
  22. type
  23. TDateTimePrecision = (tpNone, tpDay, tpMinute, tpSecond, tpMillisecond);
  24. // order choosen so that for previous bool value, false maps to fbNone,
  25. // and true maps to new default fbKilobytes, although functionaly it is fbShort
  26. TFormatBytesStyle = (fbNone, fbKilobytes, fbShort);
  27. function ExtractFileNameOnly(Name: string): string;
  28. function FileOrDirExists(FileName: string): Boolean;
  29. function FormatBytes(Bytes: Int64; Style: TFormatBytesStyle = fbShort; UseUnitsForBytes: Boolean = True): string;
  30. function FormatPanelBytes(Bytes: Int64; Style: TFormatBytesStyle): string;
  31. procedure FreePIDL(var PIDL: PItemIDList);
  32. function StrContains(Str1, Str2: string): Boolean;
  33. procedure ReduceDateTimePrecision(var DateTime: TDateTime;
  34. Precision: TDateTimePrecision);
  35. function SpecialFolderLocation(Folder: Integer; var Path: string;
  36. var PIDL: PItemIDList): Boolean; overload;
  37. function SpecialFolderLocation(Folder: Integer; var Path: string): Boolean; overload;
  38. function FormatLastOSError(Message: string): string;
  39. resourcestring
  40. SNoValidPath = 'Can''t find any valid path.';
  41. SByte = 'B';
  42. SKiloByte = 'KB';
  43. SMegaByte = 'MB';
  44. SGigaByte = 'GB';
  45. implementation
  46. uses
  47. IEDriveInfo, DateUtils, ShellApi, SysConst, PasTools, Math, CustomDirView, FileOperator, DragDrop;
  48. function StrContains(Str1, Str2: string): Boolean;
  49. var
  50. Index: Integer;
  51. begin
  52. for Index := 1 to Length(Str1) do
  53. if Pos(Str1[Index], Str2) <> 0 then
  54. begin
  55. Result := True;
  56. Exit;
  57. end;
  58. Result := False;
  59. end; {StringCountains}
  60. function FileOrDirExists(FileName: string): Boolean;
  61. begin
  62. Result := FileExists(FileName) or DirectoryExists(FileName);
  63. end; {FileOrDirExists}
  64. function ExtractFileNameOnly(Name: string): string;
  65. var
  66. Ext: string;
  67. begin
  68. Result := ExtractFileName(Name);
  69. Ext := ExtractFileExt(Name);
  70. if Ext <> '' then
  71. Delete(Result, Length(Result)-Length(Ext)+1, Length(Ext));
  72. end; {ExtractFileNameOnly}
  73. // Windows Explorer size formatting
  74. // size properties/status bar size column
  75. // 1023 1023 bytes 1 KB
  76. // 1 KB 1,00 KB 1 KB
  77. // 2 KB 2,00 KB 2 KB
  78. // 2 KB + 1 B 2,00 KB 3 KB
  79. // 2 KB + 12 B 2,01 KB 3 KB
  80. // 10 KB - 1B 9,99 KB 10 KB
  81. // 10 KB 10,0 KB 10 KB
  82. // 12 KB 12,0 KB 12 KB
  83. // 12 KB + 1 B 12,0 KB 13 KB
  84. // 12 KB + 12 B 12,0 KB 13 KB
  85. // 12 KB + 128 B 12,1 KB 13 KB
  86. // 100 KB 100 KB 100 KB
  87. // 100 KB + 1 B 100 KB 101 KB
  88. // 500 KB 500 KB 500 KB
  89. // 1000 KB - 1 B 999 KB 1 000 KB
  90. // 1000 KB 0,97 MB 1 000 KB
  91. // 1 MB 1,00 MB 1 024 KB
  92. // 1000 MB - 1 B 999 MB 1 024 000 KB
  93. // 1000 MB 0,97 GB 1 024 000 KB
  94. // 1 GB - 1 0,99 GB 1 048 576 KB
  95. // 1 GB 1,00 GB 1 048 576 KB
  96. // 1 GB + 10 MB 1,00 GB 1 058 816 KB
  97. // 1 GB + 12 MB 1,01 GB 1 060 864 KB
  98. function FormatBytes(Bytes: Int64; Style: TFormatBytesStyle; UseUnitsForBytes: Boolean): string;
  99. var
  100. SizeUnit: string;
  101. Value: Int64;
  102. Order: Int64;
  103. EValue: Extended;
  104. Format: string;
  105. begin
  106. if (Style = fbNone) or ((Style = fbShort) and (Bytes < Int64(1024))) then
  107. begin
  108. EValue := Bytes;
  109. Format := '#,##0';
  110. if UseUnitsForBytes then
  111. Format := Format + ' "' + SByte + '"';
  112. end
  113. else
  114. if Style = fbKilobytes then
  115. begin
  116. Value := Bytes div 1024;
  117. if (Bytes mod 1024) > 0 then
  118. Inc(Value);
  119. EValue := Value;
  120. Format := '#,##0 "' + SKiloByte + '"';
  121. end
  122. else
  123. begin
  124. if Bytes < Int64(1000*1024) then
  125. begin
  126. Order := 1024;
  127. SizeUnit := SKiloByte;
  128. end
  129. else
  130. if Bytes < Int64(1000*1024*1024) then
  131. begin
  132. Order := 1024*1024;
  133. SizeUnit := SMegaByte;
  134. end
  135. else
  136. begin
  137. Order := 1024*1024*1024;
  138. SizeUnit := SGigaByte;
  139. end;
  140. EValue := Bytes / Order;
  141. if EValue >= 100 then
  142. begin
  143. EValue := Floor(EValue);
  144. Format := '#,##0';
  145. end
  146. else
  147. if EValue >= 10 then
  148. begin
  149. EValue := Floor(EValue * 10) / 10;
  150. Format := '#0.0';
  151. end
  152. else
  153. begin
  154. EValue := Floor(EValue * 100) / 100;
  155. Format := '0.00';
  156. end;
  157. Format := Format + ' "' + SizeUnit + '"';
  158. end;
  159. Result := FormatFloat(Format, EValue);
  160. end;
  161. function FormatPanelBytes(Bytes: Int64; Style: TFormatBytesStyle): string;
  162. begin
  163. Result := FormatBytes(Bytes, Style, (Style <> fbNone));
  164. end;
  165. procedure FreePIDL(var PIDL: PItemIDList);
  166. begin
  167. if PIDL <> nil then
  168. begin
  169. try
  170. ShellMalloc.Free(PIDL);
  171. PIDL := NIL;
  172. except
  173. PIDL := NIL;
  174. end;
  175. end;
  176. end; {FreePIDL}
  177. // duplicated in RemoteFiles.cpp
  178. procedure ReduceDateTimePrecision(var DateTime: TDateTime;
  179. Precision: TDateTimePrecision);
  180. var
  181. Y, M, D, H, N, S, MS: Word;
  182. begin
  183. if Precision = tpNone then DateTime := 0
  184. else
  185. if Precision <> tpMillisecond then
  186. begin
  187. DecodeDateTime(DateTime, Y, M, D, H, N, S, MS);
  188. case Precision of
  189. tpDay:
  190. begin
  191. H := 0;
  192. N := 0;
  193. S := 0;
  194. MS := 0;
  195. end;
  196. tpMinute:
  197. begin
  198. S := 0;
  199. MS := 0;
  200. end;
  201. tpSecond:
  202. begin
  203. MS := 0;
  204. end;
  205. end;
  206. DateTime := EncodeDate(Y, M, D) + EncodeTime(H, N, S, MS);
  207. end;
  208. end;
  209. function SpecialFolderLocation(Folder: Integer; var Path: string;
  210. var PIDL: PItemIDList): Boolean;
  211. begin
  212. SetLength(Path, MAX_PATH);
  213. Result :=
  214. (not Failed(SHGetSpecialFolderLocation(Application.Handle, Folder, PIDL))) and
  215. SHGetPathFromIDList(PIDL, PChar(Path));
  216. if Result then
  217. begin
  218. SetLength(Path, StrLen(PChar(Path)));
  219. end
  220. else
  221. begin
  222. Path := '';
  223. end;
  224. end;
  225. function SpecialFolderLocation(Folder: Integer; var Path: string): Boolean;
  226. var
  227. PIDL: PItemIDList;
  228. begin
  229. Result := SpecialFolderLocation(Folder, Path, PIDL);
  230. end;
  231. function FormatLastOSError(Message: string): string;
  232. var
  233. LastError: Integer;
  234. begin
  235. Result := Message;
  236. LastError := GetLastError;
  237. if LastError <> 0 then
  238. Result := Result + #13#10 + #13#10 + Format(SOSError, [LastError, SysErrorMessage(LastError), '']);
  239. end;
  240. initialization
  241. end.