我们正在使用XE7。我们正在尝试将搜索和替换功能构建到TRichEdit
中。
我们希望它能像在 Delphi 编译器中一样工作。我们显示自己的搜索和替换对话框,我们没有使用Delphi替换对话框。
我们显示对话框,当用户单击Replace按钮时,对话框关闭,对于找到的每个示例,我们希望弹出一个消息对话框,询问用户是否要替换该示例。
当我们这样做时,用户看不到所选择的内容,并且如果他们在消息对话框中单击“是”,则不会替换任何内容。
我们的代码如下:
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;
1条答案
按热度按时间wlzqhblo1#
我发现您的程式码有许多问题:
select_text()
和MessageDlg()
时,您将输入焦点从TRichEdit
移开,因此请确保将TRichEdit.HideSelection
设置为False
(默认情况下为True
),以便实际查看所选内容。TRichEdit
上调用BeginUpdate()
,这将禁用它的屏幕重绘,包括Repaint()
。TRichEdit.SelText
之前,您不需要调用TRichEdit.ClearSelection()
。vwvars[curviewwin]^.sstartpos
时,您需要将其重置为fndAns
(当前选择的位置)加上vwvars[curviewwin]^.replace
(新文本)的长度,而不是vwvars[curviewwin]^.finddata
(旧文本)的长度。您没有将其移动到新文本之外,因此您在反复搜索旧文本。MessageDlg()
中选择“否”,则不会更新vwvars[curviewwin]^.sstartpos
以跳过用户不希望替换的文本。endpos
时,length(asciieditor.text)
可以改为asciieditor.gettextlen()
,以提高效率。但更重要的是,您根本不应该从endpos
中减去vwvars[curviewwin]^.sstartpos
。这样做的话,每次替换都将从搜索中 * 跳过 * 越来越多位于TRichEdit
末尾的文本。事实上,您应该只使用asciieditor
的当前文本长度作为每次搜索的结束位置,因此实际上根本不需要endpos
。TRichEdit
的大小及其内容,如果它启用了滚动条,则在每次找到匹配的文本时,在使用MessageDlg()
提示用户之前,应向TRichEdit
发送EM_SCROLLCARET
消息,以防匹配的文本不在屏幕上。话虽如此,尝试更像这样的东西: