delphitrichedit

How to scroll to the 'found' word that the user has entered in the finddialog box


I have a rich edit on a delphi form that includes a finddialog box. The user enters the word to be found, and the program correctly highlights the 'found' word -this much works fine. What I want, however, is for the program to scroll so that the first occurrence of the found word appears on the first line in the richedit box. Should the user then click 'next,' (finddialog box)then the scrolling continues so that the next occurrence of the word then appears on the first line, and so on. Can anyone help me out here?

procedure tform3.FindDialog1Find(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 }
    findDialog1.Options := findDialog1.Options - [frFindNext];

  if not (frFindNext in FindDialog1.Options) then begin // is it a Find "First" ?
    sText := Richedit1.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(FindDialog1.Findtext);
    { Get text from the RichEdit, starting from StartFrom }
    sText := Copy(Richedit1.Text, StartFrom, Length(Richedit1.Text) - StartFrom + 1);
  end;

  if frMatchCase in FindDialog1.Options then   // case-sensitive search?
    { Search position of FindText in sText.
      Note that function Pos() is case-sensitive. }
    FoundPos := Pos(FindDialog1.FindText, sText)
  else
    { Search position of FindText, converted to uppercase,
      in sText, also converted to uppercase        }
    FoundPos := Pos(UpperCase(FindDialog1.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 }
    RichEdit1.SelStart := PreviousFoundPos - 1;
    RichEdit1.SelLength := Length(FindDialog1.FindText);
    RichEdit1.SetFocus;
  end
  else
    ShowMessage('Could not find "' + FindDialog1.FindText + '"');
end;

Solution

  • You can use the following code to scroll to the cursor position in the TRichEdit control:

    RichEdit1.SelStart := PreviousFoundPos - 1;
    RichEdit1.SelLength := Length(FindDialog1.FindText);
    RichEdit1.SetFocus;   
    
    // Now scroll to the current cursor position 
    RichEdit1.Perform(EM_SCROLLCARET, 0, 0);
    

    This sends the Windows message EM_SCROLLCARET to the control which will make the control scroll to the current cursor position.