• delphi调用EverythingSdk实现快速搜索
  • ListView秒加载数据
unit UnitMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls, ImgList, UnitEverything, XPMan,
  IniFiles, UnitPopupMenuShell, Menus;

type
  TDataListItem = class;

  TDataList = class(TList)
  protected
    function Get(Index: Integer): TDataListItem;
    procedure Put(Index: Integer; Item: TDataListItem);
  public
    destructor Destroy; override;
    procedure Clear; virtual;
    function Add(Item: TDataListItem): Integer;
    function IndexOf(Item: TDataListItem): Integer;
    function Remove(Item: TDataListItem): Integer;
    property Items[Index: Integer]: TDataListItem read Get write Put; default;
  end;

  TDataListItem = class(TObject)
  private
    FFileSize: Integer;
    FFileName: string;
    FFileDate: TDateTime;
    FFilePath: string;
    procedure SetFilePath(const Value: string);
  public
  published
    property FileName: string read FFileName write FFileName;
    property FileSize: Integer read FFileSize write FFileSize;
    property FileDate: TDateTime read FFileDate write FFileDate;
    property FilePath: string read FFilePath write SetFilePath;
  end;

  TFileListItem = class(TDataListItem);

  TFrmMain = class(TForm)
    Panel1: TPanel;
    edtContent: TEdit;
    lvFiles: TListView;
    StatusBar1: TStatusBar;
    XPManifest1: TXPManifest;
    cbbFilter: TComboBox;
    ImageList1: TImageList;
    PopupMenu1: TPopupMenu;
    procedure lvFilesData(Sender: TObject; Item: TListItem);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure edtContentChange(Sender: TObject);
    procedure lvFilesDblClick(Sender: TObject);
    procedure cbbFilterChange(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
  private
    { Private declarations }
    BasePath: string;
    FFileList: TDataList;
    function FileTimeToDateTime(ATime: TFileTime): TDateTime;
    function GetWindowsSystemDir: string;
  public
    function SearchFiles(aValue: string): Boolean;
  end;

var
  FrmMain: TFrmMain;

implementation

uses
  FileCtrl, ShellAPI;

{$R *.dfm}

procedure TFrmMain.lvFilesData(Sender: TObject; Item: TListItem);
var
  FileSize: Integer;
  ADateTime: TDateTime;
begin
  if Item.Index > FFileList.Count then
    exit;

  Item.Caption := FFileList.Items[Item.Index].FileName;
  Item.SubItems.Add(FFileList.Items[Item.Index].FilePath);
  FileSize := FFileList.Items[Item.Index].FileSize;
  if FileSize = 0 then
  begin
    Item.SubItems.Add('');
  end
  else
  begin
    FileSize := (FileSize div 1024) + 1;
    Item.SubItems.Add(FormatFloat('###,##0 KB', FileSize));
  end;
  ADateTime := FFileList.Items[Item.Index].FileDate;
  Item.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:nn', ADateTime));
 
//  Item.ImageIndex := Item.Index;
end;

{ TDataList }

destructor TDataList.Destroy;
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
  begin
    Items[i].Free;
  end;
  inherited;
end;

procedure TDataList.Clear;
var
  i: Integer;
begin
  for i := 0 to Count - 1 do
  begin
    Items[i].Free;
  end;
  inherited;
end;

procedure TDataList.Put(Index: Integer; Item: TDataListItem);
begin
  inherited Items[Index] := Item;
end;

function TDataList.Get(Index: Integer): TDataListItem;
begin
  Result := TDataListItem(inherited Items[Index]);
end;

function TDataList.Add(Item: TDataListItem): Integer;
begin
  Result := inherited Add(Item);
end;

function TDataList.IndexOf(Item: TDataListItem): Integer;
begin
  Result := inherited IndexOf(Item);
end;

function TDataList.Remove(Item: TDataListItem): Integer;
begin
  Result := inherited Remove(Item);
end;

procedure TFrmMain.FormCreate(Sender: TObject);
var
  myini: TIniFile;
  Filters: TStrings;
  i: Integer;
begin
  myini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'Everything.ini');
  Filters := TStringList.Create;
  try
    myini.ReadSection('Filter', Filters);
    for i := 0 to Filters.Count - 1 do
    begin
      cbbFilter.Items.Add(Filters.Strings[i]);
    end;
  finally
    FreeAndNil(myini);
    FreeAndNil(Filters);
  end;
  FFileList := TDataList.Create;
  cbbFilter.ItemIndex := 0;
  cbbFilterChange(cbbFilter);
end;

function TFrmMain.FileTimeToDateTime(ATime: TFileTime): TDateTime;
var
  SystemTime: TSystemTime;
  TempTime: TFileTime;
begin
  try
    FileTimeToLocalFileTime(ATime, TempTime);
    FileTimeToSystemTime(TempTime, SystemTime);
    Result := SystemTimeToDateTime(SystemTime);
  except
    Result := 0;
  end;

end;

function TFrmMain.GetWindowsSystemDir: string;
var
  Str: string;
  Len: Integer;
begin
  Len := GetSystemDirectory(nil, 0);
  SetLength(Str, Len);
  GetSystemDirectory(PChar(Str), Len);
  Result := IncludeTrailingPathDelimiter(Str);
end;

procedure TFrmMain.FormDestroy(Sender: TObject);
begin
  FreeAndNil(FFileList);
end;

{ TDataListItem }

procedure TDataListItem.SetFilePath(const Value: string);
begin
  FFilePath := Value;
end;

procedure TFrmMain.edtContentChange(Sender: TObject);
begin
  SearchFiles(edtContent.Text);
end;

procedure TFrmMain.lvFilesDblClick(Sender: TObject);
var
  item: TListItem;
  CmdLine: string;
begin
  item := lvFiles.Selected;
  if item <> nil then
  begin
    CmdLine := item.SubItems.Strings[0] + '\' + item.Caption;
    ShellExecute(handle, 'open', PAnsiChar(CmdLine), nil, nil, SW_SHOWNORMAL);
  end;
end;

function TFrmMain.SearchFiles(aValue: string): Boolean;
var
  i, icnt: Integer;
  FItem: TFileListItem;
  s: string;
  size: PINT;
  FileDate: PFileTime;
  SHInfo: TSHFileInfo;
  Icon: TIcon;
begin
  statusBar1.SimpleText := '正在搜索...';
  statusBar1.Update;
  Everything_SetSearchW(PWideChar(widestring(aValue)));
  Everything_SetRequestFlags(EVERYTHING_REQUEST_FILE_NAME or EVERYTHING_REQUEST_PATH or EVERYTHING_REQUEST_SIZE or EVERYTHING_REQUEST_DATE_MODIFIED);
  Everything_SetSort(EVERYTHING_SORT_DATE_MODIFIED_DESCENDING);
  Everything_QueryW(true);
  lvFiles.Items.BeginUpdate;
  lvFiles.Items.Count := 0;
  icnt := Everything_GetNumResults();
  FFileList.Clear;
  for i := 0 to icnt - 1 do
  begin
    FItem := TFileListItem.Create;
    FItem.FilePath := Everything_GetResultPathW(i);
    FItem.FileName := Everything_GetResultFileNameW(i);
    new(FileDate);
    Everything_GetResultDateModified(i, FileDate);
    FItem.FileDate := FileTimeToDateTime(FileDate^);
    Dispose(FileDate);
    new(size);
    if Everything_IsFileResult(i) then
    begin
      Everything_GetResultSize(i, size);
    end
    else
    begin
      size^ := 0;
    end;
    FItem.FileSize := size^;
    Dispose(size);
//    Icon := TIcon.Create;
//    try
//      SHGetFileInfo(PChar(FItem.FilePath + FItem.FileName), 0, SHInfo, SizeOf(SHInfo), SHGFI_SMALLICON or SHGFI_ICON or SHGFI_SHELLICONSIZE);
//      Icon.Handle := SHInfo.hIcon;
////      ImageList1.AddIcon(Icon);
//    finally
//      Icon.Free;
//    end;
    FFileList.Add(FItem);
    Application.ProcessMessages;
  end;
  lvFiles.Items.Count := icnt;
  StatusBar1.SimpleText := FormatFloat('###,##0 个对象', icnt);
  lvFiles.Items.EndUpdate;
end;

procedure TFrmMain.cbbFilterChange(Sender: TObject);
var
  myini: TIniFile;
  Filters: TStrings;
  i: Integer;
  content: string;
begin
  myini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'Everything.ini');
  Filters := TStringList.Create;
  try
    content := myini.ReadString('Filter', cbbFilter.Text, '');
    SearchFiles(content);
  finally
    FreeAndNil(myini);
    FreeAndNil(Filters);
  end;
end;

procedure TFrmMain.PopupMenu1Popup(Sender: TObject);
var
  item: TListItem;
  CmdLine: string;
  pt: TPoint;
begin
  GetCursorPos(pt);
  item := lvFiles.Selected;
  if item <> nil then
  begin
    CmdLine := item.SubItems.Strings[0] + '\' + item.Caption;
    DisplayContextMenu(0, CmdLine, pt);
  end;
end;

end.


posted on 2022-05-09 21:51  陆战队  阅读(348)  评论(2)    收藏  举报