2009-09-03 51 views
2

好吧,這是一個嘮叨的問題,我看不到一個明確的答案。 如何查找和標記單詞的所有實例?標記一個單詞的所有實例(德爾福,RichText)

我的意思是,我搜索一個詞(說:人)。如果這個單詞存在,我用richedit標記(使用紅色或其他顏色)該單詞的所有實例。如果我按Esc鍵,則會取消選擇。

任何想法?

代碼表示讚賞。

回答

2

wonderer,我寫了這個代碼,我希望這將是有用的:

Procedure MarkString(RichEdit:TRichEdit;strtomark : string); 
Var 
FoundAt : integer; 
begin 
    FoundAt:=RichEdit.FindText(strtomark,0,maxInt,[stWholeWord]); 
    while FoundAt <> -1 do 
    begin 
      RichEdit.SelStart := FoundAt; 
      RichEdit.SelLength := Length(strtomark); 
      RichEdit.SelAttributes.Style := [fsBold]; 
      RichEdit.SelAttributes.Color := clRed; 
      RichEdit.SelText :=strtomark; 
      FoundAt:=RichEdit.FindText(strtomark,FoundAt + length(strtomark),maxInt,[stWholeWord]); 
    end; 
end; 


Procedure UnMarkString(RichEdit:TRichEdit;strtomark : string); 
Var 
FoundAt : integer; 
begin 
    FoundAt:=RichEdit.FindText(strtomark,0,maxInt,[stWholeWord]); 
    while FoundAt <> -1 do 
    begin 
      RichEdit.SelStart := FoundAt; 
      RichEdit.SelLength := Length(strtomark); 
      RichEdit.SelAttributes.Style := []; 
      RichEdit.SelAttributes.Color := clBlack; 
      RichEdit.SelText :=strtomark; 
      FoundAt:=RichEdit.FindText(strtomark,FoundAt + length(strtomark),maxInt,[stWholeWord]); 
    end; 
end; 


MarkString(RichEdit1,'delphi'); //To Mark a string 

UnMarkString(RichEdit1,'delphi'); //To UnMark a string 

再見。

+0

太棒了!謝謝。現在我需要對它進行一些修改,以便在該字符串上設置背景顏色,並且我都已設置完畢。 – wonderer 2009-09-04 14:09:40

3

以下代碼將在豐富的編輯控件中搜索給定單詞(區分大小寫)的所有匹配項,將字體顏色更改爲紅色,並最終恢復控件的原始選擇(全部儘可能少的閃爍)希望):

procedure TForm1.FindWord(const AWord: string; AOptions: TSearchTypes); 
var 
    OrigSelStart, OrigSelLen: integer; 
    Start, Found: integer; 
begin 
    if AWord = '' then 
    exit; 

    OrigSelStart := RichEdit1.SelStart; 
    OrigSelLen := RichEdit1.SelLength; 

    RichEdit1.Perform(WM_SETREDRAW, 0, 0); 
    try 
    Start := 0; 
    Found := RichEdit1.FindText(AWord, Start, MaxInt, AOptions); 
    while Found <> -1 do begin 
     RichEdit1.SelStart := Found; 
     RichEdit1.SelLength := Length(AWord); 
     // TODO: save start of search match and original font colour 
     RichEdit1.SelAttributes.Color := clRed; 
     Start := Found + Length(AWord); 
     Found := RichEdit1.FindText(AWord, Start, MaxInt, AOptions); 
    end; 
    finally 
    RichEdit1.SelStart := OrigSelStart; 
    RichEdit1.SelLength := OrigSelLen; 
    RichEdit1.Perform(WM_SETREDRAW, 1, 0); 
    RichEdit1.Repaint; 
    end; 
end; 

現在你只需要到比賽保存加上原有的文本屬性的列表,並使用這些信息在此列表中恢復所有對Esc新聞界的變化。然而,如果你認爲這些匹配可能包含不同的字體樣式,顏色等,這可能會非常難以正確執行。因此,我沒有提供任何代碼來保存格式,這取決於您的要求。

哦,確保在文本可以再次更改之前刪除突出顯示的匹配項,否則您將無法正確恢復原始文本格式。

+0

爲了幫助避免閃爍並加快處理速度,您還應該使用EM_SETEVENTMASK消息禁用RichEdit的內部通知給自己,或者將其重新啓用,這在此類文本處理過程中不是必需的。 – 2009-09-03 21:49:25

+0

@Remy:這[http://msdn.microsoft.com/en-us/library/bb774366(VS.85).aspx]建議RichEdit的默認掩碼是ENM_NONE,所以我的印象可能是不必要的。儘管如此,嘗試有意義,並且看起來EM_GETEVENTMASK將提供當前掩碼,在使用EM_SETEVENTMASK(EM_NONE)並進行更新後可以保存該掩碼以進行恢復。只是爲了防止我錯過了某些東西而放置這些東西。 – Argalatyr 2009-09-04 01:33:22

+0

只需對此進行跟蹤 - 它看起來像VCL修改了事件掩碼,這意味着當您按原樣使用TRichEdit組件時,默認EM_NONE不適用:閃爍。爲了減少閃爍 - 最好的解決辦法似乎是按照Remy的建議將EM_SETEVENTMASK發送給none。這樣做會產生相當好的結果。執行BeginUpdate/EndUpdate內的所有更新似乎更糟糕。在.Perform(WM_SETREDRAW,0,0).. .Perform(WM_SETREDRAW,1,0)內部進行更新.Repaint似乎也一樣糟糕。似乎沒有真正好的解決方案,這個控制不是雙緩衝的。 – 2011-04-16 06:21:59