Codrut
Codrut

Reputation: 332

How can I select the second copy of a text in a TMemo

I have a TMemo with text inside it, for example:

Text1
Hello World!
Sky
Text123

I use a simple function to select the first time a text was found

Memo1.SelStart := Pos(AnsiLowerCase('Text'), AnsiLowerCase(Memo1.Text)) - 1;
    Memo1.SelLength := Length('Text');
    Memo1.SetFocus;

I used AnsiLowerCase so I can find text without the need for proper capitalization.

So, how can I select the second time "text" appears in the Memo?

Upvotes: 1

Views: 2374

Answers (1)

Fabrizio
Fabrizio

Reputation: 8043

You can use the Offset parameter of the Pos function in order to avoid starting search from the beginning and skip the first occurrence.

Locates a substring in a given string.

The Pos method returns the index of the first occurence of Substr in Str, starting the search at Offset.

This method returns zero if Substr is not found or Offset is invalid (for example, if Offset exceeds the String length or is less than 1).

The Offset argument is optional. Offset is set to 1 by default, if no value for Offset is specified it takes the default value to start the search from the beginning.

Notes:

Pos uses one-based array indexing even in platforms where the strings are zero-based.

Pos method is equivalent to System.StrUtils.PosEx.

For example:

Picture displaying an example form with a memo, text edit and findnext button

procedure SearchNext(AMemo : TMemo; const ATextToSearch : string; ACycle : Boolean = True);
var
  Offset : Integer;
begin
  //adjusting offset
  Offset := AMemo.SelStart + AMemo.SelLength + 1;
  if(Offset >= Length(AMemo.Text)) then
    Offset := 1;

  //searching
  Offset := Pos(AnsiLowerCase(ATextToSearch), AnsiLowerCase(AMemo.Text), Offset);
  if(Offset > 0) then
  begin
    //selecting found text
    AMemo.SelStart := Offset - 1;
    AMemo.SelLength := Length(ATextToSearch);
    AMemo.SetFocus;
  end else
  begin
    //recursion from the beginning
    if(ACycle and (AMemo.SelStart + AMemo.SelLength <> 0)) then
    begin
      AMemo.SelStart := 0;
      SearchNext(AMemo, ATextToSearch, True);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SearchNext(Memo1, Edit1.Text);
end;

Upvotes: 1

Related Questions