Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Поиск в отдельном потоке фразы в файлах

Delphi , Файловая система , Файлы

Поиск в отдельном потоке фразы в файлах

Автор: Xavier Pacheco


unit Main;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, Menus, SrchIni,
  SrchU, ComCtrls, AppEvnts;

type
  TMainForm = class(TForm)
    lbFiles: TListBox;
    StatusBar: TStatusBar;
    pnlControls: TPanel;
    PopupMenu: TPopupMenu;
    FontDialog: TFontDialog;
    pnlOptions: TPanel;
    gbParams: TGroupBox;
    LFileSpec: TLabel;
    LToken: TLabel;
    lPathName: TLabel;
    edtFileSpec: TEdit;
    edtToken: TEdit;
    btnPath: TButton;
    edtPathName: TEdit;
    gbOptions: TGroupBox;
    cbCaseSensitive: TCheckBox;
    cbFileNamesOnly: TCheckBox;
    cbRecurse: TCheckBox;
    cbRunFromAss: TCheckBox;
    pnlButtons: TPanel;
    btnSearch: TBitBtn;
    btnClose: TBitBtn;
    btnPrint: TBitBtn;
    btnPriority: TBitBtn;
    Font1: TMenuItem;
    Clear1: TMenuItem;
    Print1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    ApplicationEvents: TApplicationEvents;
    procedure btnSearchClick(Sender: TObject);
    procedure btnPathClick(Sender: TObject);
    procedure lbFilesDrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure Font1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure btnPrintClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure lbFilesDblClick(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure btnPriorityClick(Sender: TObject);
    procedure edtTokenChange(Sender: TObject);
    procedure Clear1Click(Sender: TObject);
    procedure ApplicationEventsHint(Sender: TObject);
  private
    procedure ReadIni;
    procedure WriteIni;
  public
    Running: Boolean;
    SearchPri: Integer;
    SearchThread: TSearchThread;
    procedure EnableSearchControls(Enable: Boolean);
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

uses Printers, ShellAPI, StrUtils, FileCtrl, PriU;

procedure PrintStrings(Strings: TStrings);
{ This procedure prints all of the strings in the Strings parameter }
var
  Prn: TextFile;
  I: Integer;
begin
  if Strings.Count = 0 then // Are there strings?
    raise Exception.Create('No text to print!');
  AssignPrn(Prn); // assign Prn to printer
  try
    Rewrite(Prn); // open printer
    try
      for I := 0 to Strings.Count - 1 do // iterate over all strings
        WriteLn(Prn, Strings.Strings[I]); // write to printer
    finally
      CloseFile(Prn); // close printer
    end;
  except
    on EInOutError do
      MessageDlg('Error Printing text.', mtError, [mbOk], 0);
  end;
end;

procedure TMainForm.EnableSearchControls(Enable: Boolean);
{ Enables or disables certain controls so options can't be modified }
{ while search is executing. }
begin
  btnSearch.Enabled := Enable; // enable/disable proper controls
  cbRecurse.Enabled := Enable;
  cbFileNamesOnly.Enabled := Enable;
  cbCaseSensitive.Enabled := Enable;
  btnPath.Enabled := Enable;
  edtPathName.Enabled := Enable;
  edtFileSpec.Enabled := Enable;
  edtToken.Enabled := Enable;
  Running := not Enable; // set Running flag
  edtTokenChange(nil);
  with btnClose do
  begin
    if Enable then
    begin // set props of Close/Stop button
      Caption := '&Close';
      Hint := 'Close Application';
    end
    else
    begin
      Caption := '&Stop';
      Hint := 'Stop Searching';
    end;
  end;
end;

procedure TMainForm.btnSearchClick(Sender: TObject);
{ Called when Search button is clicked.  Invokes search thread. }
begin
  EnableSearchControls(False); // disable controls
  lbFiles.Clear; // clear listbox
  { start thread }
  SearchThread := TSearchThread.Create(cbCaseSensitive.Checked,
    cbFileNamesOnly.Checked, cbRecurse.Checked, edtToken.Text,
    edtPathName.Text, edtFileSpec.Text);
end;

procedure TMainForm.edtTokenChange(Sender: TObject);
begin
  btnSearch.Enabled := not Running and (edtToken.Text <> '');
end;

procedure TMainForm.btnPathClick(Sender: TObject);
{ Called when Path button is clicked.  Allows user to choose new path. }
var
  ShowDir: string;
begin
  ShowDir := edtPathName.Text;
  if SelectDirectory('Choose a search path...', '', ShowDir) then
    edtPathName.Text := ShowDir;
end;

procedure TMainForm.lbFilesDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
{ Called in order to owner draw listbox. }
var
  CurStr: string;
begin
  with lbFiles do
  begin
    CurStr := Items.Strings[Index];
    Canvas.FillRect(Rect); // clear out rect
    if not cbFileNamesOnly.Checked then // if not filename only...
      { if current line is filename... }
      if (Pos('File ', CurStr) = 1) and
        (CurStr[Length(CurStr)] = ':') then
        with Canvas.Font do
        begin
          Style := [fsUnderline]; // underline font
          Color := clRed; // paint red
        end
      else
        Rect.Left := Rect.Left + 15; // otherwise, indent
    DrawText(Canvas.Handle, PChar(CurStr), Length(CurStr), Rect,
      DT_SINGLELINE);
  end;
end;

procedure TMainForm.Font1Click(Sender: TObject);
{ Allows user to pick new font for listbox }
begin
  { Pick new listbox font }
  if FontDialog.Execute then
    lbFiles.Font := FontDialog.Font;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
{ OnDestroy event handler for form }
begin
  WriteIni;
end;

procedure TMainForm.FormCreate(Sender: TObject);
{ OnCreate event handler for form }
begin
  ReadIni; // read INI file
end;

procedure TMainForm.btnPrintClick(Sender: TObject);
{ Called when Print button is clicked. }
begin
  if MessageDlg('Send search results to printer?', mtConfirmation,
    [mbYes, mbNo], 0) = mrYes then
    PrintStrings(lbFiles.Items);
end;

procedure TMainForm.btnCloseClick(Sender: TObject);
{ Called to stop thread or close application }
begin
  // if thread is running then terminate thread
  if Running then
    SearchThread.Terminate
      // otherwise close app
  else
    Close;
end;

procedure TMainForm.lbFilesDblClick(Sender: TObject);
{ Called when user double-clicks in listbox. Invokes viewer for }
{ highlighted file. }
var
  ProgramStr, FileStr: string;
  RetVal: THandle;
begin
  { if user clicked on a file.. }
  if (Pos('File ', lbFiles.Items[lbFiles.ItemIndex]) = 1) then
  begin
    { load text editor from INI file.  Notepad is default. }
    ProgramStr := SrchIniFile.ReadString('Defaults', 'Editor', 'notepad');
    FileStr := lbFiles.Items[lbFiles.ItemIndex]; // Get selected file
    FileStr := Copy(FileStr, 6, Length(FileStr) - 5); // Remove prefix
    if FileStr[Length(FileStr)] = ':' then // Remove ":"
      DecStrLen(FileStr, 1);
    if cbRunFromAss.Checked then
      { Run file from shell association }
      RetVal := ShellExecute(Handle, 'open', PChar(FileStr), nil, nil,
        SW_SHOWNORMAL)
    else
      { View file using text editor }
      RetVal := ShellExecute(Handle, 'open', PChar(ProgramStr),
        PChar(FileStr), nil, SW_SHOWNORMAL);
    { Check for error }
    if RetVal < 32 then
      RaiseLastWin32Error;
  end;
end;

procedure TMainForm.FormResize(Sender: TObject);
{ OnResize event handler. Centers controls in form. }
begin
  { divide status bar into two panels with a 1/3 - 2/3 split }
  with StatusBar do
  begin
    Panels[0].Width := Width div 3;
    Panels[1].Width := Width * 2 div 3;
  end;
end;

procedure TMainForm.btnPriorityClick(Sender: TObject);
{ Show thread priority form }
begin
  ThreadPriWin.Show;
end;

procedure TMainForm.ReadIni;
{ Reads default values from Registry }
begin
  with SrchIniFile do
  begin
    edtPathName.Text := ReadString('Defaults', 'LastPath', 'C:\');
    edtFileSpec.Text := ReadString('Defaults', 'LastFileSpec', '*.*');
    edtToken.Text := ReadString('Defaults', 'LastToken', '');
    cbFileNamesOnly.Checked := ReadBool('Defaults', 'FNamesOnly', False);
    cbCaseSensitive.Checked := ReadBool('Defaults', 'CaseSens', False);
    cbRecurse.Checked := ReadBool('Defaults', 'Recurse', False);
    cbRunFromAss.Checked := ReadBool('Defaults', 'RunFromAss', False);
    Left := ReadInteger('Position', 'Left', Left);
    Top := ReadInteger('Position', 'Top', Top);
    Width := ReadInteger('Position', 'Width', Width);
    Height := ReadInteger('Position', 'Height', Height);
  end;
end;

procedure TMainForm.WriteIni;
{ writes current settings back to Registry }
begin
  with SrchIniFile do
  begin
    WriteString('Defaults', 'LastPath', edtPathName.Text);
    WriteString('Defaults', 'LastFileSpec', edtFileSpec.Text);
    WriteString('Defaults', 'LastToken', edtToken.Text);
    WriteBool('Defaults', 'CaseSens', cbCaseSensitive.Checked);
    WriteBool('Defaults', 'FNamesOnly', cbFileNamesOnly.Checked);
    WriteBool('Defaults', 'Recurse', cbRecurse.Checked);
    WriteBool('Defaults', 'RunFromAss', cbRunFromAss.Checked);
    WriteInteger('Position', 'Left', Left);
    WriteInteger('Position', 'Top', Top);
    WriteInteger('Position', 'Width', Width);
    WriteInteger('Position', 'Height', Height);
  end;
end;

procedure TMainForm.Clear1Click(Sender: TObject);
begin
  lbFiles.Items.Clear;
end;

procedure TMainForm.ApplicationEventsHint(Sender: TObject);
{ OnHint event handler for Application }
begin
  { Display application hints on status bar }
  StatusBar.Panels[0].Text := Application.Hint;
end;

end.
Скачать весь проект

Программа на Delphi, которая ищет конкретный фразе в нескольких файлах и отображает результаты в списке. Поиск может выполняться на отдельном потоке, что позволяет оставить пользовательский интерфейс доступным для использования во время процесса поиска.

Вот обзор компонентов и их функциональности:

  1. TMainForm: это основная форма приложения. Она содержит различные контролы, такие как поля ввода, чекбоксы, кнопки и список.
  2. lbFiles: это список, который отображает результаты поиска.
  3. edtPathName, edtFileSpec и edtToken: эти поля ввода позволяют пользователю указать путь для поиска, спецификацию файла и фразу для поиска.
  4. cbCaseSensitive, cbFileNamesOnly и cbRecurse: эти чекбоксы контролируют параметры поиска.
  5. btnSearch: это кнопка, которая запускает процесс поиска.
  6. btnPath: это кнопка, которая позволяет пользователю выбрать новый путь для поиска.
  7. btnPrint: это кнопка, которая печатает результаты поиска на принтере.
  8. btnClose: это кнопка, которая останавливает процесс поиска или закрывает приложение.

Класс TSearchThread отвечает за выполнение поиска в отдельном потоке. Он принимает четыре параметра: чувствительность к регистру, только имена файлов, рекурсия и фраза для поиска. Процесс поиска читает файлы из указанного пути, ищет фразу и добавляет результаты в список.

Процедура PrintStrings печатает содержимое списка на принтере. Событийный обработчик btnPrintClick вызывает эту процедуру при нажатии кнопки "Печать".

Процедуры ReadIni и WriteIni читают и записывают значения по умолчанию из/в файл INI. Это позволяет приложению запоминать свои настройки между сессиями.

Процедуры FormDestroy и FormCreate обрабатывают события создания и уничтожения формы, соответственно.

В целом, это проект демонстрирует, как выполнять операцию поиска в отдельном потоке с помощью Delphi, а также как сохранять и загружать настройки приложения из файла INI.

Поиск в отдельном потоке фразы в файлах.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Файлы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:59:22/0.0063111782073975/1