Board index » delphi » Searching text in a memo field

Searching text in a memo field

How can I search a text in a memo field?

Marcos Quezado

 

Re:Searching text in a memo field


Hi Marcos,

Heres a routine someone helped me with to find a word and make it bold in a
rich edit component.  The search and find should work for a memo field too.

procedure TfrmSearch.FindAndBold;
var
   FoundAt : LongInt;
   ToEnd : LongInt;
   oldSearchPos,SearchPos: LongInt;
   i: integer;
begin
   searchpos := 0;
   oldSearchPos := 0;
    for i := 0 to memBody.Lines.Count -1 do
    begin
        ToEnd := Length(memBody.Text) - oldSearchPos;
        FoundAt :=
memBody.FindText(txtWordSearch.Text,SearchPos,ToEnd,[stWholeWord]);
        if FoundAt <> -1 then
        begin
            SearchPos := FoundAt + length(txtWordSearch.Text);
            oldSearchPos := SearchPos;
            memBody.SetFocus;
            memBody.SelStart := FoundAt;
            memBody.SelLength := Length(txtWordSearch.Text);
            memBody.SelAttributes.Style := [Fsbold];
            memBody.SelAttributes.Color :=  clRed;
       end;
    end;
end;

Good luck.

--
Michael Glatz
mgl...@briefcase.com

Quote
Marcos Quezado wrote in message <6uot2h$k...@forums.borland.com>...
>How can I search a text in a memo field?

>Marcos Quezado

Re:Searching text in a memo field


Quote
> How can I search a text in a memo field?

Marcos,

the brute force method is this:

Function FindTextInMemo( aMemo: TMemo; Const aStr: String;
                        Var line, col: Integer ): Boolean;
Var
 n, i: Integer;
Begin
 Result := False;
 With aMemo Do
   (* durchsuche alle Zeilen des Memos *)
   For n:= 0 To Lines.Count-1 Do Begin
     col := Pos( aStr, Lines[n] ) - 1;
     If col >= 0 Then Begin
       (* wir haben was gefunden! Gib Zeile und Spalte zurck. *)
       Result := True;
       Line := n;
       Break;
     End;
   End;
End;

While simple it is none to fast since each access to the Lines property
sends a message to the control to fetch the lines text from the controls
internal buffer. A different approach is to get all of the text at once and
then search that.

Here is a different example i happen to have on stock, it shows how to
implement a find next using a TFindDialog with a memo:

to implement a find next you need to

 1. store the position of the last found word
 2. check in the OnFind handler if the frFindNext flag is set
 3. if so, modify the Pos statement so it will not search the
    full text but only the part after the last position.

So satisfy 1. we make SelPos a field of TForm1, named FSelPos. Before you
Execute the find dialog, set the FSelPos field to 0.  

procedure TForm1.FindDialog1Find(Sender: TObject);
 var
   S: String;
   startpos: Integer;
 begin
   with TFindDialog(Sender) do begin
     {If the stored position is 0 this cannot be a find next. }
     If FSelPos = 0 Then
       Options := Options - [frFindNext];

     { Figure out where to start the search and get the corresponding
       text from the memo. }
     If frfindNext In Options Then Begin
       { This is a find next, start after the end of the last found word. }
       StartPos := FSelPos + Length( Findtext ) ;
       S:= Copy( Memo1.Lines.Text, StartPos, MaxInt );
     End
     Else Begin
       { This is a find first, start at the, well, start. }
       S:= Memo1.Lines.Text;
       StartPos := 1;
     End;  
     { Perform a global case-sensitive search for FindText in S }
     FSelPos := Pos(FindText, S);
     if FSelPos > 0 then begin
       { Found something, correct position for the location of the start
         of search. }
       FSelPos := FSelPos + StartPos - 1;
       Memo1.SelStart := FSelPos - 1;
       Memo1.SelLength := Length(FindText);
     end
     else begin
       { No joy, show a message. }
       If frfindNext In Options Then
         S:= Concat('There are no further occurences of "', FindText,
                    '" in Memo1.')
       Else
         S:= Concat('Could not find "', FindText, '" in Memo1.');
       MessageDlg(S, mtError, [mbOk], 0);
     end;
   end;
end;

Peter Below (TeamB)  100113.1...@compuserve.com)
No e-mail responses, please, unless explicitely requested!

Other Threads