Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 05/29/23 in all areas

  1. 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"
  2. programmerdelphi2k

    File Search

    You have to consider this, because the search must know the full path, to avoid excluding the search in a different subdirectory, for example: c:\Windows and c:\Other\Windows <--- are different things!
  3. programmerdelphi2k

    File Search

    my tip: Avoid the excessive usage of "SetLenght()", try define a conditicional for it, like: each 100...n items, use SetLenght()! that way, if exists 1000 object, then you'll have 10 SetLength()
  4. That is an extremely old version of OpenSSL. You should be using openssl-1.0.2u-i386-win32.zip instead. Or, you can use this SSLIOHandler (work in progress) and then you can use a newer OpenSSL 1.1.x version instead.
  5. programmerdelphi2k

    Using inline variables inside loops

    firstly, I think that not right way to do it, but, as the var is allocated on stack, and the var-life is "short"! then, the next round, var will "dead", and create a new var on memory same address (if not used yet)!
  6. Stefan Glienke

    Use case or if else ?

    Turn the strings into an enum or an index and put the functions into a const array over that enum/index.
  7. The TBitmap.ScanLine property getter handles top-down vs bottom-up differences for you. You can use scanline indexes as if the bitmap were always top-down, like a normal array, and the property getter will access the raw pixels as needed based on whether the bitmap is top-down or bottom-up. In other words, ScanLine[0] always represents the 1st line of pixels, ScanLine[1] always represents the 2nd line of pixels, and so on. function TBitmap.GetScanLine(Row: Integer): Pointer; begin Changing(Self); with FImage.FDIB, dsbm, dsbmih do begin if (Row < 0) or (Row >= bmHeight) then InvalidOperation(@SScanLine); DIBNeeded; GDIFlush; if biHeight > 0 then // bottom-up DIB Row := biHeight - Row - 1; Result := PByte(bmBits) + Row * BytesPerScanline(biWidth, biBitCount, 32); end; end; That means if you want a raw pointer to the entire image buffer as a whole, then you have to use ScanLine[0] for a top-down bitmap, and ScanLine[Height-1] for a bottom-up bitmap. But, if you just want to access the individual lines one at a time, then you can loop through ScanLine[0]..ScanLine[Height-1] without regard to whether the bitmap is top-down or bottom-up.
×