2015-05-19 2 views
0

Я делаю приложение, которое заменяет разные слова двух очень похожих говорящих языков. Количество слов по времени, вероятно, достигнет не менее 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; 
+2

управления редактирования может иметь только один выбор. Думаю, вы ищете способ выделить текст, а не выбирать. Если это так, вы можете использовать для этого расширенный контроль редактирования. – TLama

+0

Да, я ищу способ выделить текст. –

+0

Возможно, сторонний элемент управления редактированием - это то, что вам нужно –

ответ

3

Ни 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; 
+0

Это то, что мне нужно. Большое спасибо! :) –

Смежные вопросы