delphi 使用FindNextFile时是否按句柄获取搜索路径?

wpx232ag  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(179)

我使用FindFirstFile()FindNextFile()来列出一个目录的文件。当我调用FindFirstFile()时,我必须给予它一个搜索路径。它返回一个可以被FindNextFile()使用的句柄。是否有一个WinAPI函数可以通过句柄获得先前给定的路径?

disbfnqx

disbfnqx1#

只需像存储搜索句柄一样存储该信息即可:然后为FindFirstFileA()FindNextFileA()创建您自己的 Package 函数:

type
  // What you want to give back per file system object
  TMyFindInfo= record  // Whatever you want to do here on your own
    wfd: Windows.WIN32_FIND_DATAA;  // Just provide this as-is because it already everything
  end;

  // Not only storing the handle, but also other details
  TMyFindHandle= record
    h: THandle;  // Search resource
    sFilter: String;  // Original query
    iMatches,  // How often did the search yield a file system object?
    iError: Cardinal;  // Which error has occured? 0=ERROR_SUCCESS.
  end;

function MyFindFile1st
( const sFilter: String
; out vInfo: TMyFindInfo
): TMyFindHandle;
begin
  result.sFilter:= sFilter;
  result.h:= Windows.FindFirstFileA( PChar(sFilter), vInfo.wfd );
  if result.h= INVALID_HANDLE_VALUE then begin
    result.iError:= Windows.GetLastError();
    case result.iError of
      ERROR_FILE_NOT_FOUND: ;  // The only error we don't need to display
    else  // Most likely ERROR_PATH_NOT_FOUND
      Windows.MessageBoxA
      ( Form1.Handle
      , PChar('Error initializing search "'+ result.sFilter
        + '": 0x'+ IntToHex( result.iError, 8 ))  // Get text message elsewhere
      , PChar('Error')
      , MB_ICONSTOP
      );
    end;

    result.iMatches:= 0;
    ZeroMemory( @vInfo, SizeOf( vInfo ) );  // Nothing to see here
  end else begin
    result.iError:= ERROR_SUCCESS;
    result.iMatches:= 1;
  end;
end;

function MyFindFile2nd
( var vHandle: TMyFindHandle
; out vInfo: TMyFindInfo
): Boolean;
begin
  result:= Windows.FindNextFileA( vHandle.h, vInfo.wfd );
  if not result then begin
    vHandle.iError:= Windows.GetLastError();
    case vHandle.iError of
      ERROR_SUCCESS,  // The only errors we don't need to display
      ERROR_NO_MORE_FILES: ;
    else
      Windows.MessageBoxA
      ( Form1.Handle
      , PChar('Error during search "'+ vHandle.sFilter  // Original filter from 1st call
        + '" after '+ IntToStr( vHandle.iMatches )+ ' elements occured: 0x'
        + IntToHex( vHandle.iError, 8 ))
      , PChar('Error')
      , MB_ICONSTOP
      );
    end;
    Windows.ZeroMemory( @vInfo, SizeOf( vInfo ) );  // Nothing to see here

    if not Windows.FindClose( vHandle.h ) then begin  // Release resource
      vHandle.iError:= Windows.GetLastError();
      case vHandle.iError of
        ERROR_SUCCESS: ;
      else  // Yes, this can fail, too
        Windows.MessageBoxA
        ( Form1.Handle
        , PChar('Error finalizing search "'+ vHandle.sFilter  // Original filter from 1st call
          + '" after '+ IntToStr( vHandle.iMatches )+ ' elements occured: 0x'
          + IntToHex( vHandle.iError, 8 ))
        , PChar('Error')
        , MB_ICONSTOP
        );
      end;
    end;
  end else Inc( vHandle.iMatches );  // One more match
end;

// Now the example on how to use it
procedure TForm1.Button1Click(Sender: TObject);
var
  vHandle: TMyFindHandle;
  vInfo: TMyFindInfo;
begin
  vHandle:= MyFindFile1st( 'C:\Windows\*.exe', vInfo );
  while vHandle.iError= ERROR_SUCCESS do begin
    Memo1.Lines.Add( vInfo.wfd.cFileName );
    MyFindFile2nd( vHandle, vInfo );  // Don't even need the Boolean result here
  end;
  Memo1.Lines.Add( '= '+ IntToStr( vHandle.iMatches )+ ' FS objects' );  // Not only files
end;

在任何时候都不需要通过句柄重新请求详细信息,因为您可以将该详细信息与需要处理的句柄保持在一起。只需将两者放在一个记录中,并将其传递给您自己的函数。
我的代码是用于演示的目的(尽管我认为这是一个相当琐碎的整体情况)。我不鼓励在这些函数中显示对话框窗口,而是在调用这些函数的地方对vHandle.iError包含的内容做出React。

相关问题