Re: Delphi FindDialog with a RichEdit

Posted by webmaster Guido on June 04, 2005

In Reply to: Beginner FindDialog question posted by joe90 on June 01, 2005

: I'm wanting to implement a FindDialog in the notepad application i'm writing. I was wondering if someone could tell me how to do this. I'm a complete beginner to programming, so a good break down would be appreciated.

Below is the Delphi source code for a simple FindDialog in combination with a RichEdit. Not all of the options of the FindDialog will work with this code, only the "Match Case" is functional. Within a few days, we'll publish a complete tutorial in DelphiLand's Code Snips section. I'll send you a note when it's ready :)

1. Let's start with a form and add the following components:
- a RichEdit, enter some text in its Lines property, and name it RE (just to shorten the source code a bit);
- a FindDialog, name it FD (same reason);
- a Button, named btnFind.

2. Add a global variable at the beginning of the Implementation section, as follows:

implementation
{$R *.DFM}
var
  PreviousFoundPos: integer;

3. Create an OnClick event handler for the button and complete its code as follows:

procedure TForm1.btnFindClick(Sender: TObject);
begin
  PreviousFoundPos := 0;
  FD.Execute;
end;

4. Create an OnFind event handler for the FindDialog and complete its code as follows:

procedure TForm1.FDFind(Sender: TObject);
var
  sText: string;
  StartFrom, FoundPos: integer;
begin
  { If saved position is 0, this must be a "Find First" operation. }
  if PreviousFoundPos = 0 then
    { Reset the frFindNext flag of the FindDialog }
    FD.Options := FD.Options - [frFindNext];

  if not (frFindNext in FD.Options) then begin // is it a Find "First" ?
    sText := RE.Text;
    StartFrom := 1;
  end
  else begin // it's a Find "Next"
    { Calculate from where to start searching:
      start AFTER the end of the last found position. }
    StartFrom := PreviousFoundPos + Length(FD.Findtext);
    { Get text from the RichEdit, starting from StartFrom }
    sText := Copy(RE.Text, StartFrom, Length(RE.Text) - StartFrom + 1);
  end;

  if frMatchCase in FD.Options then   // case-sensitive search?
    { Search position of FindText in sText.
      Note that function Pos() is case-sensitive. }
    FoundPos := Pos(FD.FindText, sText)
  else
    { Search position of FindText, converted to uppercase,
      in sText, also converted to uppercase        }
    FoundPos := Pos(UpperCase(FD.FindText), UpperCase(sText));

  if FoundPos > 0 then begin
    { If found, calculate position of FindText in the RichEdit }
    PreviousFoundPos := FoundPos + StartFrom - 1;
    { Highlight the text that was found }
    RE.SelStart := PreviousFoundPos - 1;
    RE.SelLength := Length(FD.FindText);
    RE.SetFocus;
  end
  else
    ShowMessage('Could not find "' + FD.FindText + '"');
end;


Related Articles and Replies: