Jump to content

KodeZwerg

Members
  • Content Count

    289
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by KodeZwerg

  1. KodeZwerg

    File Search

    Let me tell it that way @programmerdelphi2k, with my posted source I was able to enter "documents" as an included folder-name and "*.pdf" as a file-mask (also "c:\windows" to exclude that folder) and as a result i get all "*.pdf" files that are inside of any "documents" folder. exemplary "c:\users\documents\manual.pdf" or "c:\users\public\documents\another.pdf" or "c:\users\username\documents\etc.pdf" ... How-to with your way?
  2. KodeZwerg

    Find String in TstringList

    @Lars Fosdal In first post he tried to search for something, than he wanted a search for specific things, that will my code do.
  3. KodeZwerg

    File Search

    @programmerdelphi2k I am happy when you are happy. To me your way is useless, you lost what I was needing, finding specific files in specific folders.
  4. KodeZwerg

    Find String in TstringList

    Take a guess 😛
  5. KodeZwerg

    Find String in TstringList

    program Project12; {$APPTYPE CONSOLE} {$R *.res} uses System.Classes, System.SysUtils; function ContainsString(const AStringList: TStringList; const ASearchFor: string): Boolean; begin Result := (AStringList.IndexOf(ASearchFor) <> -1); end; var sl: TStringList; begin try sl := TStringList.Create; try sl.Sorted := False; sl.Duplicates := dupIgnore; sl.CaseSensitive := True; sl.Add('some'); sl.Add('some.xyz'); WriteLn(ContainsString(sl, 'some')); // True WriteLn(ContainsString(sl, 'Some')); // False WriteLn(ContainsString(sl, 'yxz')); // False finally sl.Free; end; ReadLn; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.
  6. KodeZwerg

    File Search

    Does it now works for you? Feel free to remove 🤭
  7. KodeZwerg

    Form Creation

    Makes not much sense right now.
  8. KodeZwerg

    File Search

    unit uFindEx; interface uses Winapi.Windows, System.SysUtils; type // My variant of an "StringList" TFindArray = TArray<string>; // array of WideString; function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; implementation const // missing FindEx flags FIND_FIRST_EX_CASE_SENSITIVE = $00000001; FIND_FIRST_EX_LARGE_FETCH = $00000002; FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY = $00000004; // Small helper to add strings in my "StringList" procedure AddFindArray(var AFindArray: TFindArray; const AString: string); inline; var i: Integer; begin i := Length(AFindArray); SetLength(AFindArray, Succ(i)); AFindArray[i] := AString; end; // This method will crawl thru a folder and collect their names // The ExclusionList should contain full path names that be total excluded from search, by default everything is included // IncludeSubFolders switch will get every folder, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path function FindExFolders(const ABasePath: string = ''; const AExclusionList: TFindArray = []; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp : TFindArray; i, ii : Integer; s:string; begin SetLength(Result, 0); if ((ABasePath = '') or (not DirectoryExists(ABasePath))) then Exit; FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + '*.*') ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..')) and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then begin if (Length(AExclusionList) > 0) then begin for i := Low(AExclusionList) to High(AExclusionList) do if (0 = Pos(UpperCase(AExclusionList[i]), UpperCase(IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName))) then AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end else AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end; until (not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData)); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Result) to High(Result) do begin tmp := FindExFolders(Result[i], AExclusionList, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddFindArray(Result, tmp[ii]); end; SetLength(tmp, 0); end; // This method will crawl thru a folder and collect their filenames // IncludeSubFolders switch will get every filename, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path + filename function FindExFiles(const ABasePath: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp, Folders : TFindArray; i, ii : Integer; begin SetLength(Result, 0); if ((ABasePath = '') or (not DirectoryExists(ABasePath))) then Exit; SetLength(Folders, 0); SetLength(tmp, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + AFileMask) ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..'))) then begin if (0 = (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)) then AddFindArray(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); if (AIncludeSubFolders and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then AddFindArray(Folders, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end; until (not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData)); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Folders) to High(Folders) do begin tmp := FindExFiles(Folders[i], AFileMask, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddFindArray(Result, tmp[ii]); end; SetLength(Folders, 0); SetLength(tmp, 0); end; // My variant of how a file search method can be done for windows systems // BasePath = where do we start at? eg "C:\Users" // FoldersMustExist = what foldername is a must for results? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // ExludedFolders = in what foldername you do not want to search? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // FileMask = what files you hunt for? eg "*.pas" // IncludeSubFolders = yes or no, you choose. False by default // based upon my "FindExFolders" and "FindExFiles" methods function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var tmp, Folders, Files: TFindArray; splitIncluded, splitExcluded: TFindArray; i, ii: Integer; begin SetLength(Result, 0); SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); // prepare splittings if (Length(AFoldersMustExist) > 0) then begin if (0 <> Pos(';', AFoldersMustExist)) then splitIncluded := AFoldersMustExist.Split([';']) else AddFindArray(splitIncluded, AFoldersMustExist); end; if (Length(AExludedFolders) > 0) then begin if (0 <> Pos(';', AExludedFolders)) then splitExcluded := AExludedFolders.Split([';']) else AddFindArray(splitExcluded, AExludedFolders); end; // collect folder(s) to work on if AIncludeSubFolders then tmp := FindExFolders(ABasePath, splitExcluded, AIncludeSubFolders) else AddFindArray(tmp, ABasePath); // sieve out folders that match criteria if (Length(splitIncluded) > 0) then begin for i := Low(tmp) to High(tmp) do for ii := Low(splitIncluded) to High(splitIncluded) do if (0 <> Pos(UpperCase(splitIncluded[ii]), UpperCase(tmp[i]))) then AddFindArray(Folders, tmp[i]); end else Folders := tmp; // get files that matching the criteria for i := Low(Folders) to High(Folders) do begin if (Length(AFileMask) > 0) then tmp := FindExFiles(Folders[i], AFileMask) // do not enable the IncludeSubFolders switch here (!) else tmp := FindExFiles(Folders[i]); for ii := Low(tmp) to High(tmp) do AddFindArray(Files, tmp[ii]); end; Result := Files; SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); end; end. Fixed the "Folder must included" thingy, now it works pretty well for me.
  9. KodeZwerg

    File Search

    "Folder must exist" is currently not working, I will update but not today 😛
  10. KodeZwerg

    File Search

    unit uFindEx; interface uses Winapi.Windows, System.SysUtils; type // My variant of an "StringList" TFindArray = TArray<string>; // array of WideString; function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; implementation const // missing FindEx flags FIND_FIRST_EX_CASE_SENSITIVE = $00000001; FIND_FIRST_EX_LARGE_FETCH = $00000002; FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY = $00000004; // Small helper to add strings in my "StringList" procedure AddStrArr(var AArr: TFindArray; const AString: string); inline; var i: Integer; begin i := Length(AArr); SetLength(AArr, Succ(i)); AArr[i] := AString; end; // This method will crawl thru a folder and collect their names // IncludeSubFolders switch will get every folder, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path function FindExFolders(const ABasePath: string; const AInclusionList, AExclusionList: TFindArray; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp : TFindArray; i, ii : Integer; s:string; begin SetLength(Result, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + '*.*') ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..')) and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then begin if (Length(AInclusionList) > 0) then begin for i := Low(AInclusionList) to High(AInclusionList) do if (0 <> Pos(UpperCase(AInclusionList[i]), UpperCase(IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName))) then AddStrArr(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end else AddStrArr(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); if (Length(AExclusionList) > 0) then begin for i := High(Result) downto Low(Result) do for ii := Low(AExclusionList) to High(AExclusionList) do if (0 <> Pos(UpperCase(AExclusionList[ii]), UpperCase(Result[i]))) then Delete(Result, i, 1); end; end; until not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Result) to High(Result) do begin tmp := FindExFolders(Result[i], AInclusionList, AExclusionList, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddStrArr(Result, tmp[ii]); end; SetLength(tmp, 0); end; // This method will crawl thru a folder and collect their filenames // IncludeSubFolders switch will get every filename, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path + filename function FindExFiles(const ABasePath: string; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFindexInfoLevels; FindExSearchOps : TFindexSearchOps; AdditionalFlags : DWORD; tmp, Folders : TFindArray; i, ii : Integer; begin SetLength(Result, 0); SetLength(Folders, 0); SetLength(tmp, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Winapi.Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(ABasePath) + AFileMask) ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then begin repeat if ((Win32FindData.cFileName <> string('.')) and (Win32FindData.cFileName <> string('..'))) then begin if (0 = (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)) then AddStrArr(Result, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); if (AIncludeSubFolders and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then AddStrArr(Folders, IncludeTrailingBackslash(ABasePath) + Win32FindData.cFileName); end; until not Winapi.Windows.FindNextFileW(FindExHandle, Win32FindData); Winapi.Windows.FindClose(FindExHandle); end; if AIncludeSubFolders then for i := Low(Folders) to High(Folders) do begin tmp := FindExFiles(Folders[i], AFileMask, AIncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddStrArr(Result, tmp[ii]); end; SetLength(Folders, 0); SetLength(tmp, 0); end; // My variant of how a file search method can be done for windows systems // BasePath = where do we start at? eg "C:\Users" // FoldersMustExist = what foldername is a must for results? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // ExludedFolders = in what foldername you do not want to search? eg "Documents", can be left empty for all (seperate with ";" if more than 1) // FileMask = what files you hunt for? eg "*.pas" // IncludeSubFolders = yes or no, you choose. False by default // based upon my "FindExFolders" and "FindExFiles" methods function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var tmp, Folders, Files: TFindArray; splitIncluded, splitExcluded: TFindArray; i, ii: Integer; begin SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); if (Length(AFoldersMustExist) > 0) then begin if (0 <> Pos(';', AFoldersMustExist)) then splitIncluded := AFoldersMustExist.Split([';']) else AddStrArr(splitIncluded, AFoldersMustExist); end; if (Length(AExludedFolders) > 0) then begin if (0 <> Pos(';', AExludedFolders)) then splitExcluded := AExludedFolders.Split([';']) else AddStrArr(splitExcluded, AExludedFolders); end; // collect folder(s) to work on if AIncludeSubFolders then Folders := FindExFolders(ABasePath, splitIncluded, splitExcluded, AIncludeSubFolders) else AddStrArr(Folders, ABasePath); // get files that matching the criteria for i := Low(Folders) to High(Folders) do begin if (Length(AFileMask) > 0) then tmp := FindExFiles(Folders[i], AFileMask) // do not enable the IncludeSubFolders switch here (!) else tmp := FindExFiles(Folders[i]); for ii := Low(tmp) to High(tmp) do AddStrArr(Files, tmp[ii]); end; Result := Files; SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); end; end. Can you retry please @programmerdelphi2k @robertjohns, just replace the full units code with above. Thanks for tipp about SetLength() @programmerdelphi2k, will be added later, in above i put now the exclusions right into the searching job, should be in theory faster now 😛 Ps: Now it is working with a full given pathname for exclusion, eg: "c:\windows"
  11. KodeZwerg

    File Search

    Please not use a full path at excluding, for that my code ain't designed yet.
  12. KodeZwerg

    File Search

    function FindEx(const ABasePath: string; const AFoldersMustExist: string = ''; AExludedFolders: string = ''; const AFileMask: string = '*.*'; const AIncludeSubFolders: Boolean = False): TFindArray; var tmp, Folders, Files: TFindArray; splitIncluded, splitExcluded: TFindArray; i, ii: Integer; begin SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); SetLength(splitIncluded, 0); SetLength(splitExcluded, 0); if (Length(AFoldersMustExist) > 0) then begin if (0 <> Pos(';', AFoldersMustExist)) then splitIncluded := AFoldersMustExist.Split([';']) else AddStrArr(splitIncluded, AFoldersMustExist); end; if (Length(AExludedFolders) > 0) then begin if (0 <> Pos(';', AExludedFolders)) then splitExcluded := AExludedFolders.Split([';']) else AddStrArr(splitExcluded, AExludedFolders); end; // collect folder(s) to work on if AIncludeSubFolders then tmp := FindExFolders(ABasePath, AIncludeSubFolders) else AddStrArr(tmp, ABasePath); // sieve out folders that match criteria if (Length(splitIncluded) > 0) then begin for i := Low(tmp) to High(tmp) do for ii := Low(splitIncluded) to High(splitIncluded) do if (0 <> Pos(UpperCase(splitIncluded[ii]), UpperCase(tmp[i]))) then AddStrArr(Folders, tmp[i]); end else Folders := tmp; // remove unwanted folders from search if (Length(splitExcluded) > 0) then for i := High(Folders) downto Low(Folders) do for ii := Low(splitExcluded) to High(splitExcluded) do if (0 <> Pos(PathDelim + UpperCase(splitExcluded[ii]), UpperCase(Folders[i]))) then Delete(Folders, i, 1); SetLength(tmp, 0); // get files that matching the criteria for i := Low(Folders) to High(Folders) do begin if (Length(AFileMask) > 0) then tmp := FindExFiles(Folders[i], AFileMask) // do not enable the IncludeSubFolders switch here (!) else tmp := FindExFiles(Folders[i]); for ii := Low(tmp) to High(tmp) do AddStrArr(Files, tmp[ii]); end; Result := Files; SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); end; I apology, please update that method like shown above and now it really should work, I've not tested it much with extra large filesystems, on a small one it works like it should. You can enter "Windows" or "windows" or just "win", everything that has this in name will be excluded from the deeper file search mechanism. When I got more free time I will continue making it better.
  13. KodeZwerg

    File Search

    Please compare with my approach, I posted earlier a full demo app that works straight out of the box, would like to see time results and if my way would also benefit of a full exclusion from giving names.
  14. KodeZwerg

    File Search

    Yes, it was very complicated to fix. Uploaded a fully working Demo application based on my above mentioned code, added "Exclude" capabilities as you wanted. FindEx.zip
  15. KodeZwerg

    File Search

    type _FINDEX_INFO_LEVELS = (FindExInfoStandard, FindExInfoBasic, FindExInfoMaxInfoLevel); TFINDEX_INFO_LEVELS = _FINDEX_INFO_LEVELS; _FINDEX_SEARCH_OPS = (FindExSearchNameMatch, FindExSearchLimitToDirectories, FindExSearchLimitToDevices, FindExSearchMaxSearchOp); TFINDEX_SEARCH_OPS = _FINDEX_SEARCH_OPS;
  16. KodeZwerg

    File Search

    Here is my way on Windows to search for files or folders by using fastest method. There is still space for optimizations. Written and tested with FreePascal. unit uMain; {$mode objfpc}{$H+} interface uses Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type { TfrmMain } TfrmMain = class(TForm) btnStart: TButton; cbSubFolder: TCheckBox; edtBase: TEdit; edtFolder: TEdit; edtMask: TEdit; lblResult: TLabel; lbFiles: TListBox; pnlOptions: TPanel; pnlResult: TPanel; procedure btnStartClick(Sender: TObject); private public end; var frmMain: TfrmMain; implementation {$R *.lfm} type // My variant of an "StringList" TStrArr = array of WideString; const // missing FindEx flags FIND_FIRST_EX_CASE_SENSITIVE = $00000001; FIND_FIRST_EX_LARGE_FETCH = $00000002; FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY = $00000004; // Small helper to add strings in my "StringList" procedure AddStrArr(var AArr: TStrArr; const AString: WideString); inline; var i: Integer; begin i := Length(AArr); SetLength(AArr, Succ(i)); AArr[i] := AString; end; // This method will crawl thru a folder and collect their names // IncludeSubFolders switch will get every folder, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path function FindExFolders(const BasePath: WideString; const IncludeSubFolders: Boolean = False): TStrArr; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFINDEX_INFO_LEVELS; FindExSearchOps : TFINDEX_SEARCH_OPS; AdditionalFlags : DWORD; tmp : TStrArr; i, ii : Integer; begin SetLength(Result{%H-}, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(BasePath) + '*.*') ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then repeat if ((Win32FindData.cFileName <> '.') and (Win32FindData.cFileName <> '..') and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then AddStrArr(Result{%H-}, IncludeTrailingBackslash(BasePath) + Win32FindData.cFileName); until not Windows.FindNextFileW(FindExHandle, Win32FindData); Windows.FindClose(FindExHandle); if IncludeSubFolders then for i := Low(Result) to High(Result) do begin tmp := FindExFolders(Result[i], IncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddStrArr(Result, tmp[ii]); end; SetLength(tmp, 0); end; // This method will crawl thru a folder and collect their filenames // IncludeSubFolders switch will get every filename, False by default // Based upon very fast FindEx Api (Windows) // The result will contain full path + filename function FindExFiles(const BasePath: WideString; const FileMask: WideString = '*.*'; const IncludeSubFolders: Boolean = False): TStrArr; var FindExHandle : THandle; Win32FindData : TWin32FindDataW; FindExInfoLevels: TFINDEX_INFO_LEVELS; FindExSearchOps : TFINDEX_SEARCH_OPS; AdditionalFlags : DWORD; tmp, Folders : TStrArr; i, ii : Integer; begin SetLength(Result{%H-}, 0); SetLength(Folders{%H-}, 0); SetLength(tmp{%H-}, 0); FindExInfoLevels := FindExInfoBasic; FindExSearchOps := FindExSearchLimitToDirectories; AdditionalFlags := FIND_FIRST_EX_LARGE_FETCH or FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY; FindExHandle := Windows.FindFirstFileExW( PWideChar(IncludeTrailingBackslash(BasePath) + FileMask) ,FindExInfoLevels, @Win32FindData, FindExSearchOps, nil ,AdditionalFlags); if (FindExHandle <> INVALID_HANDLE_VALUE) then repeat if ((Win32FindData.cFileName <> '.') and (Win32FindData.cFileName <> '..')) then begin if (0 = (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY)) then AddStrArr(Result, IncludeTrailingBackslash(BasePath) + Win32FindData.cFileName); if (IncludeSubFolders and (0 <> (Win32FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY))) then AddStrArr(Folders, IncludeTrailingBackslash(BasePath) + Win32FindData.cFileName); end; until not Windows.FindNextFileW(FindExHandle, Win32FindData); Windows.FindClose(FindExHandle); if IncludeSubFolders then for i := Low(Folders) to High(Folders) do begin tmp := FindExFiles(Folders[i], FileMask, IncludeSubFolders); for ii := Low(tmp) to High(tmp) do AddStrArr(Result, tmp[ii]); end; SetLength(Folders, 0); SetLength(tmp, 0); end; // My variant of how a file search method can be done for windows systems // BasePath = where do we start at? eg "C:\Users" // BaseFolder = what foldername is a must for results? eg "Documents", can be left empty for all // FileMask = what files you hunt for? eg "*.pas" // IncludeSubFolders = yes or no, you choose. False by default // based upon my "FindExFolders" and "FindExFiles" methods function FindEx(const BasePath: WideString; const BaseFolder: WideString = ''; const FileMask: WideString = '*.*'; const IncludeSubFolders: Boolean = False): TStrArr; var tmp, Folders, Files: TStrArr; i, ii: Integer; begin SetLength(tmp{%H-}, 0); SetLength(Folders{%H-}, 0); SetLength(Files{%H-}, 0); // collect folder(s) to work on if IncludeSubFolders then tmp := FindExFolders(BasePath, IncludeSubFolders) else AddStrArr(tmp, BasePath); // sieve out folders that match criteria if (BaseFolder <> '') then begin for i := Low(tmp) to High(tmp) do if (0 <> Pos(UpperCase(BaseFolder), UpperCase(tmp[i]))) then AddStrArr(Folders, tmp[i]); end else Folders := tmp; SetLength(tmp, 0); // get files that matching the criteria for i := Low(Folders) to High(Folders) do begin tmp := FindExFiles(Folders[i], FileMask); // do not enable the IncludeSubFolders switch here (!) for ii := Low(tmp) to High(tmp) do AddStrArr(Files, tmp[ii]); end; Result := Files; SetLength(tmp, 0); SetLength(Folders, 0); SetLength(Files, 0); end; { TfrmMain } procedure TfrmMain.btnStartClick(Sender: TObject); var i: Integer; List: TStrArr; begin lblResult.Caption := 'Search in progress, program may freeze, please wait...'; lblResult.Refresh; List := FindEx(WideString(edtBase.Text), WideString(edtFolder.Text), WideString(edtMask.Text), cbSubFolder.Checked); lbFiles.Items.BeginUpdate; lbFiles.Clear; for i := Low(List) to High(List) do lbFiles.Items.Add(AnsiString(List[i])); lbFiles.Items.EndUpdate; lblResult.Caption := 'Found ' + IntToStr(lbFiles.Count) + ' file(s).'; SetLength(List, 0); end; end. It should be easy to adapt any different kind of specifications, like excluding a defined folder. Enjoy!
  17. All of that is not needed, just do it in the Object Inspector like I told.
  18. Just create first column without caption and set its width to 0. The others do what you want to do.
  19. How about using an ImageViewer control, put your bitmap in and give the control the "BestFit" property.
  20. Welcome to forum! I am no clairvoyant and I assume nobody here is. So without showing anything how you do, what you think we can say? Watch line 123 there at call xyz you did something wrong?! Best practice would be a small demo zipped that shows us what you do and how you try to achieve that.
  21. Delphi 11 Community Edition based on 11.3.1 Pro
  22. KodeZwerg

    Library path problem on IDE

    Delphi version 1 had no FMX and would probably not run under Windows 11 at all. (16bit)
  23. KodeZwerg

    How many people use Delphi?

    That "double don't" mean you do use Delphi for that, right?
  24. KodeZwerg

    How many people use Delphi?

    Pascal is dead - long live pascal!
×