首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Trichedit中搜索和替换

在Trichedit中搜索和替换
EN

Stack Overflow用户
提问于 2022-07-08 01:14:23
回答 1查看 215关注 0票数 0

我们正在与XE7合作。我们正在尝试构建一个搜索功能并将其替换为一个TRichEdit

我们希望它能像在Delphi编译器中一样工作。我们显示我们自己的搜索和替换对话框,我们没有使用Delphi替换对话框。

我们显示对话框,当用户单击“替换”按钮时,对话框将关闭,对于找到的每个实例,我们希望弹出一个消息对话框,询问用户是否要替换该事件。

当我们这样做时,用户无法看到所选择的内容,如果他们在消息对话框上单击“是”,则不会替换任何内容。

我们的代码如下:

代码语言:javascript
复制
procedure Tviewform.select_text(fndpos:integer);
begin
   setfocus;
   asciieditor.selstart:=fndpos;
   asciieditor.sellength:=length(vwvars[curviewwin]^.finddata);
end;

procedure Tviewform.search_and_replace;
var position,endpos,fndans,cont:integer; foptions:tsearchtypes; msgques,stopall:word;
begin
  with asciieditor do
  begin
    endpos:=length(asciieditor.text)-vwvars[curviewwin]^.sstartpos;
    foptions:=[];
    stopall:=0;
    cont:=0;
    if findinfo.onbut.checked then foptions:=foptions+[stMatchCase];
    lines.beginupdate;
    fndans:=findtext(vwvars[curviewwin]^.finddata,vwvars[curviewwin]^.sstartpos,endpos,foptions);
    while (fndans<>-1) and (stopall=0) do
    begin
      select_text(fndans);
      msgques:=mainform.silang1.messagedlg('Replace with '+vwvars[curviewwin]^.replace+'?.',mtinformation,[mbyes,mbno,mbcancel],0);
      if msgques=mryes then
      begin
        asciieditor.clearselection;
        seltext:=vwvars[curviewwin]^.replace;
      end else
      begin
        if msgques=mrcancel then
        begin
          cont:=0;
          stopall:=1;
        end else cont:=1;
      end;
      asciieditor.Repaint;
      if cont=1 then
      begin
        inc(vwvars[curviewwin]^.sstartpos,length(vwvars[curviewwin]^.finddata));
        endpos:=length(asciieditor.text)-vwvars[curviewwin]^.sstartpos;
        fndans:=findtext(vwvars[curviewwin]^.finddata,vwvars[curviewwin]^.sstartpos,endpos,foptions);
      end;
    end;
    lines.endupdate;
  end;
end;
EN

回答 1

Stack Overflow用户

发布于 2022-07-08 01:50:47

我在您的代码中看到了一些问题:

  • --当调用select_text()MessageDlg()时,将输入焦点从TRichEdit移开,因此确保TRichEdit.HideSelection设置为False (默认情况下为True ),以便实际查看所选内容。

您正在调用的Repaint().上的

  • ,它禁用了屏幕重绘功能,包括BeginUpdate()

设置TRichEdit.SelText.之前不需要调用TRichEdit.ClearSelection()

  • 在每次替换后更新vwvars[curviewwin]^.sstartpos时,需要将其重置为fndAns (当前选择的位置)加上vwvars[curviewwin]^.replace的长度(新文本),而不是vwvars[curviewwin]^.finddata (旧文本)的长度。您不会将它移到新文本之外,因此您正在一遍又一遍地搜索旧文本。

  • 如果用户在MessageDlg()中选择No,则不更新vwvars[curviewwin]^.sstartpos以通过用户不想替换的文本。

  • 设置endpos时,length(asciieditor.text)可以改为asciieditor.gettextlen(),以提高效率。但更重要的是,您根本不应该从vwvars[curviewwin]^.sstartpos中减去endpos。通过这样做,您将从搜索中跳过越来越多的TRichEdit末尾的文本,并进行每一次替换。事实上,您应该只使用asciieditor的当前文本长度作为每次搜索的结束位置,因此您实际上根本不需要endpos

根据您的

  • 的大小及其内容,如果它启用了滚动条,则应该在每次找到匹配的文本时并在提示用户使用MessageDlg()之前向TRichEdit发送EM_SCROLLCARET消息,以防匹配的文本离开屏幕。

说到这里,尝试更像这样的东西:

代码语言:javascript
复制
procedure Tviewform.search_and_replace;
var
  fndAns: Integer;
  fOptions: TSearchTypes;
  msgQues: Word;

  procedure select_text;
  begin
    {AsciiEditor.}SetFocus;
    AsciiEditor.SelStart := fndAns;
    AsciiEditor.SelLength := Length(vwvars[curviewwin]^.finddata);
    AsciiEditor.Perform(EM_SCROLLCARET, 0, 0);
    AsciiEditor.Update;
  end;

begin
  fOptions := [];
  if FindInfo.OnBut.Checked then Include(fOptions, stMatchCase);
  repeat
    fndAns := AsciiEditor.FindText(vwvars[curviewwin]^.finddata, vwvars[curviewwin]^.sstartpos, AsciiEditor.GetTextLen, fOptions);
    if fndAns = -1 then Break;
    select_text;
    msgQues := MainForm.SiLang1.MessageDlg('Replace with ' + vwvars[curviewwin]^.replace + '?', mtinformation, [mbYes,mbNo,mbCancel], 0);
    if msgQues = mrYes then
    begin
      AsciiEditor.SelText := vwvars[curviewwin]^.replace;
      AsciiEditor.Update;
      Inc(fndAns, Length(vwvars[curviewwin]^.replace));
    end
    else if msgQues = mrNo then
    begin
      Inc(fndAns, Length(vwvars[curviewwin]^.finddata));
    end else
      Break;
    vwvars[curviewwin]^.sstartpos := fndAns;
  until False;
end;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72905719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档