unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TFound = record
    position, length: word;
  end;
  TSOption = (sWholeWord,sMatchCase);
  TOptions = set of TSOption;
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    FindDialog1: TFindDialog;
    ReplaceDialog1: TReplaceDialog;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FindDialog1Find(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ReplaceDialog1Replace(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  function Search(Options: TOptions; search, text: String; StartPos: word): TFound;
  procedure Mark(Memo: TMemo; text: TFound);
  //function GetOptions(Dialog: TFindDialog):TOptions;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
     FindDialog1.Execute;
end;

function Search(Options: TOptions; search, text: String; StartPos: word): TFound;
         function Charak(c:Char): Boolean;
         begin
              case c of 'A'..'Z','a'..'z','0'..'9': result:=true ;
                   else result:=false;
              end;
         end;
var i,j : word;
begin
     i:= StartPos; j:=0;
     While (i < (Length(text)-Length(search))) and (j < Length(search)) do
     begin
          j:=0;
          While (j < Length(search))
                and (i+j <= Length(text))
                and (  (UpCase(search[j+1])=UpCase(text[i+j]))
                    or ( (search[j+1] = text[i+j]) and (sMatchCase in Options) )  )
                do inc(j);
          if ( (sWholeWord in Options)and (Charak(text[i-2]) or Charak(text[i+j-1])) )
             then j:=0;
          inc(i);
     end;
     if j = Length(search) then
     begin
          //showmessage('gefunden');
          result.position:=i-1; result.length:=j;
     end else
     begin
          showmessage(search+' couldn''t be found');
          result.position:=0; result.length:=0;
     end;
end;

procedure Mark(Memo: TMemo; text: TFound);
begin
     SendMessage(Memo.Handle,EM_SETSEL,text.position-1,text.position+text.length-1);
     SendMessage(Memo.Handle,WM_KEYDOWN,VK_RIGHT,0);
     SendMessage(Memo.Handle,EM_SETSEL,text.position-1,text.position+text.length-1);
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
          function GetOptions(Dialog: TFindDialog):TOptions;
          begin
               result:=[];
               with Dialog do
               begin
                    if frWholeWord in Options then result:=result+[sWholeWord];
                    if frMatchCase in Options then result:=result+[sMatchCase];
               end;
          end;
var foptions: TOptions; sStr, tStr: String; sPos: word;
begin
     sStr:=TFindDialog(Sender).FindText; tStr:= Memo1.Text;
     sPos:=Memo1.SelStart+Memo1.SelLength;
     foptions:=GetOptions(FindDialog1);
     Mark(Memo1,Search(foptions,sStr,tStr,sPos));
end;

function GetOptions(Dialog: TFindDialog):TOptions;
begin
     result:=[];
     with Dialog do
     begin
          if frWholeWord in Options then result:=result+[sWholeWord];
          if frMatchCase in Options then result:=result+[sMatchCase];
     end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var test: TFound;
begin
 test.position:=2; test.length:=4;
 Mark(Memo1,test);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
     ReplaceDialog1.Execute;
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);
          procedure ReplaceIt;
          begin
               if Memo1.SelLength<>0 then
                  SendMessage(Memo1.Handle,EM_REPLACESEL,0,LongINt(PChar(ReplaceDialog1.ReplaceText)));
               FindDialog1Find(sender);
          end;
          procedure ReplaceAll;
          begin
               ReplaceIt;
               While Memo1.SelLength<>0 do
               begin
                  SendMessage(Memo1.Handle,EM_REPLACESEL,0,LongINt(PChar(ReplaceDialog1.ReplaceText)));
                  FindDialog1Find(sender);
               end;
          end;
begin
     if frReplaceAll in ReplaceDialog1.Options then ReplaceAll
     else ReplaceIt;
end;

end.