首页  编辑  

搜索和替换文本内容

Tags: /超级猛料/VCL/Memo&Edit&Richedit/   Date Created:
搜索并选择找到的文本内容
下面的代码搜索并选定找到的文本内容:
procedure SearchText(wnd: HWND; Text: pchar; Down, Sense, Whole: Bool);
var
 REdit   : HWND;
 Flags   : integer;
 FindRec : TFindText;
 FindPos : integer;
 ErrMsg  : array[0..4096]of Char;
begin
 REdit := GetDlgItem(wnd,IDC_EDIT);
 if(REdit <> 0) then begin
   SendMessage(REdit,EM_EXGETSEL,0,LPARAM(@FindRec.chrg));
   if(not Down) then FindRec.chrg.cpMin := FindRec.chrg.cpMax - 1
     else FindRec.chrg.cpMin   := FindRec.chrg.cpMax;
   FindRec.chrg.cpMax   := -1;
   FindRec.lpstrText    := Text;
   Flags                := 0;
   if(Down) then Flags  := FR_DOWN;
   if(Sense) then Flags := Flags or FR_MATCHCASE;
   if(Whole) then Flags := Flags or FR_WHOLEWORD;
   FindPos              := SendMessage(REdit,EM_FINDTEXT,
     Flags,LPARAM(@FindRec));
   if(FindPos > 0) then begin
     FindRec.chrg.cpMin := FindPos;
     FindRec.chrg.cpMax := FindPos + lstrLen(Text);
     SendMessage(REdit,EM_EXSETSEL,0,LPARAM(@FindRec.chrg));
   end else begin
     lstrcpy(ErrMsg,pchar('"' + Text + '"'));
     lstrcat(ErrMsg,CANNOT_FINDTEXT);
     MessageBox(wnd,ErrMsg,APPNAME,MB_ICONINFORMATION);
   end;
 end;
end;

//------------------------------------------------------------------------------
// [2006-12-27]Kingron: 查找并替换指定RichEdit中的文本内容
//   wnd: Richedit控件的句柄
//   OldText:需要被替换的文本
//   NewText: 替换后的文本
//   Down:是否向前搜索
//   Sense:是否大小写匹配
//   Whole:是否全字匹配
//   返回值:找到的总次数
//------------------------------------------------------------------------------
function SearchAndReplaceText(wnd: HWND; const OldText, NewText: WideString;
                              Down, Sense, Whole: Bool): Integer;
const
 FR_DOWN = 1;
var
 Flags   : integer;
 FindRec : TFindTextExW;
 FindPos : integer;  /// 查找位置
 Ranged : Boolean;  /// 表明用户当前是否选择了一些文本,如果是,为True
begin
 Result := 0;
 Ranged := False;
 if wnd = 0  then Exit;
 /// 获取当前选择的内容的范围
 FillChar(FindRec, SizeOf(FindRec), 0);
 SendMessage(wnd, EM_EXGETSEL, 0, LPARAM(@FindRec.chrg));
 Ranged := FindRec.chrg.cpMin <> FindRec.chrg.cpMax;
 if not Ranged then
 begin /// 没有选择一个范围,默认从当前位置开始替换
   if down then /// 如果向下查找,那么范围就是从当前位置到最大的范围
     FindRec.chrg.cpMin := FindRec.chrg.cpMax + 1;
   FindRec.chrg.cpMax := -1;
 end
 else if not Down then   /// 如果选择内容了,并且向上查找,则需要调换cpMax和cpMin
 begin
   FindPos := FindRec.chrg.cpMax;
   FindRec.chrg.cpMax := FindRec.chrg.cpMin;
   FindRec.chrg.cpMin := FindPos;
 end;
 FindRec.lpstrText := PWideChar(OldText);
 /// 搜索模式
 Flags := 0;
 if Down then Flags := FR_DOWN;
 if Sense then Flags := Flags or FT_MATCHCASE;
 if Whole then Flags := Flags or FT_WHOLEWORD;
 /// 查找第一个
 FindPos := SendMessageW(wnd, EM_FINDTEXTEXW,  Flags, LPARAM(@FindRec));
 while (FindPos > 0) do  /// 不断查找
 begin
   Inc(Result);  /// 统计替换次数
   if Ranged then  /// 替换后,文本内容长度变化,所以选择内容变化
     if Down then
       Inc(FindRec.chrg.cpMax, Length(NewText) - Length(OldText))
     else
       Inc(FindRec.chrg.cpMin, Length(NewText) - Length(OldText));
   SendMessage(wnd, EM_EXSETSEL, 0, LPARAM(@FindRec.chrgText)); /// 选择找到的文本
   /// 替换选定的文本
   SendMessageW(wnd, EM_REPLACESEL, Ord(True), LPARAM(PWideChar(NewText)));
   /// 继续查找直到找不到为止
   FindPos := SendMessageW(wnd, EM_FINDTEXTEXW,  Flags, LPARAM(@FindRec));
 end;
 if Ranged then
   SendMessage(wnd, EM_EXSETSEL, 0, LPARAM(@FindRec.chrg)); /// 选择原来的内容
end;