Как да намерите и изберете всяко срещане на конкретна дума в Memo?

Правя приложение, което замества различни думи от два много сходни говорещи езика. Броят на думите във времето вероятно ще достигне поне 10 000+. Няма големи разлики в думите, това са почти еднакви езици, но въпреки това съществуват разлики.

И така, успях да заменя думите в Memo достатъчно бързо, но това, което не знам, е как да избера всички заменени думи в Memo, за да може да се види кои думи са заменени. Възможно ли е това?

Ето как се заменят думите:

procedure TForm1.TranslateExecute(Sender: TObject);
var i: integer;
    S, OldPattern, NewPattern: string;
begin
  S:= Memo1.Lines.Text;

  for i := 0 to (StrListV.Count - 1) do  {StrListV is created earlier, contains words that should be replaced}
  begin        
    OldPattern:= StrListV.Strings[i];
    NewPattern:= StrListV1.Strings[i]; {StrListV1 contains new words}
    S:= FastStringReplace(S, OldPattern, NewPattern,[rfReplaceAll]);
  end;

  Memo1.BeginUpdate;
  Memo1.Clear;
  Memo1.Lines.Text:= S;
  Memo1.EndUpdate;
end;

person Srdjan Vukmirica    schedule 19.05.2015    source източник
comment
Контролите за редактиране могат да имат само един избор. Предполагам, че търсите начин да маркирате текста, а не да изберете. Ако е така, можете да използвате богат контрол за редактиране за това.   -  person TLama    schedule 19.05.2015
comment
Да, търся начин да маркирам текст.   -  person Srdjan Vukmirica    schedule 19.05.2015
comment
Може би контролът за редактиране на трета страна е това, от което се нуждаете   -  person David Heffernan    schedule 19.05.2015
comment
Например обикновената богата контрола за редактиране (TRichEdit) може да направи това, но ще трябва да намерите къде е всяка дума, която трябва да бъде осветена, в съдържанието на контролата, за да я осветите (естествено, простото заместване на низ на съдържание не е достатъчно за цялостната ви задача).   -  person TLama    schedule 19.05.2015


Отговори (1)


Нито TMemo, нито TRichEdit поддържат множество селекции, така че всъщност не можете да маркирате думите, които са били заменени. Но с TRichEdit това, което МОЖЕТЕ да направите, е да промените цветовете на преден план/фон на думите, които замествате.

TRichEdit има метод FindText() (който обвива съобщението EM_FINDTEXT), който връща индекса на низ за търсене. Извикайте го в цикъл и всяка намерена дума можете да изберете, да зададете оцветяването й и да я замените с новия текст. Повторете, докато FindText() не намери повече съвпадения.

Опитайте нещо подобно:

uses
  RichEdit, CommDlg;

procedure TForm1.TranslateExecute(Sender: TObject);
var
  I, Pos: Integer;
  EventMask: LRESULT;
  OldPattern, NewPattern: string;
  Find: RichEdit.FINDTEXT;
  Rng: RichEdit.CHARRANGE;
  Fmt: RichEdit.CHARFORMAT2;
begin
  EventMask := SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, 0);
  RichEdit1.Lines.BeginUpdate;
  try
    for I := 0 to StrListV.Count - 1 do
    begin        
      OldPattern := StrListV.Strings[I];
      NewPattern := StrListV1.Strings[I];
      Pos := 0;
      repeat
        Find.chrg.cpMin := Pos;
        Find.chrg.cpMax := -1;
        Find.lpstrText := PChar(OldPattern);
        Pos := SendMessage(RichEdit1.Handle, EM_FINDTEXT, FR_DOWN or FR_WHOLEWORD, LPARAM(@Find));
        if Pos = -1 then Break;

        Rng.cpMin := Pos;
        Rng.cpMax := Pos + Length(OldPattern);

        ZeroMemory(@Fmt, SizeOf(Fmt));
        Fmt.cbSize := SizeOf(Fmt);
        Fmt.dwMask := CFM_COLOR or CFM_BACKCOLOR;
        Fmt.crTextColor := ColorToRGB(clHighlightText);
        Fmt.crBackColor := ColorToRGB(clHighlight);

        SendMessage(RichEdit1.Handle, EM_EXSETSEL, 0, LPARAM(@Rng));
        SendMessage(RichEdit1.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Fmt));
        SendMessage(RichEdit1.Handle, EM_REPLACESEL, 0, LPARAM(PChar(NewPattern)));

        Inc(Pos, Length(NewPattern));
      until False;
    end;
  finally
    RichEdit1.Lines.EndUpdate;
    SendMessage(RichEdit1.Handle, EM_SETEVENTMASK, 0, EventMask);
  end;
end;
person Remy Lebeau    schedule 19.05.2015
comment
Това ми трябваше. Благодаря ти много! :) - person Srdjan Vukmirica; 20.05.2015