

Memo控件增加搜索功能强逻辑
逻辑难,搞了一天
主要解决的问题
1. 当向下搜索时,是从下一行开始,而不是从本行开始
2. 程序首次运行时向下搜索时没反应,但在Memo框点一下就正常了
原因:首次运行时StartLine值随机时远大于最大行,
3. 调试时添加断点后只在首次调用该过程有效,再次点Button调用时不能断下
解决:全程都不要按F9,只通过F4与F8来调试,先F4运行到断点处,再F8单步,再F4运行,循环
***主要调试技巧:按行前单击下断天,代码中双击变量后按C+F5添加多个变量到列表,F4,F8,运行或单后查看变量列表中变量的值变化
4. 如何实现向后搜索到最后一行时再从头开始搜索,向前搜索到第一行后再从尾部开始
设置当前行等最后一行时,将光标移动第一行, 当前行为第0行时,将光标移动到最后一行
例: if CurrentLine = EndLine then Memo.CaretPos := p1;
5. ***如何设置判断搜索时先搜索当前行,这里逻辑最难整,每次搜索都是一个重新开始,重新开始又在当前行找到了,始终停留在当前行。
设个全局变量,默认为True,搜索当前行后置为false,当搜索框内容改变或单击Memo改变当前行后再置为True
6. Break和Exit的区别
Break只是退出当前循环,而Exit将退出整个过程和函数, 这里Break只退出for循环,循环后面的代码还要执行,Exit则退出整个过程,循环后的代码也不执行了
procedure TNoteBookFr.SearchMemo(Memo: TMemo; SearchText: string; val: Boolean);
var
LinePos, TotalLines, CurrentLine, StartLine, EndLine: Integer; //总行数,当前行,开始行,结束行
p1, p2: TPoint;
begin
SearchText := Trim(SearchText);
CurrentLine := Memo.CaretPos.Y;
TotalLines := Memo.Lines.Count;
p1.X := 0;
p1.Y := 0;
p2.X := 0;
p2.Y := TotalLines;
if val = True then
begin
if (CurrentLine >= 0) and (CurrentLine <= TotalLines) then
begin
if yesno then
begin
StartLine := CurrentLine;
yesno := false;
end
else
StartLine := CurrentLine + 1;
EndLine := TotalLines;
end
else
begin
StartLine := 0;
EndLine := TotalLines;
end;
if StartLine >= TotalLines then
StartLine := 0;
// 根据指定的方向在 Memo 中搜索字符串
for CurrentLine := StartLine to EndLine do
begin
LinePos := Pos(SearchText, Memo.Lines[CurrentLine]);
if LinePos > 0 then
Break; // 找到第一个匹配后退出搜索
if CurrentLine = EndLine then
begin
// ShowMessage('已到达文档底部,未找到匹配字符串。');
Memo.CaretPos := p1;
Exit;
end;
end;
end
else
begin
if (CurrentLine >= 0) and (CurrentLine <= TotalLines) then
begin
if yesno then
begin
StartLine := CurrentLine;
yesno := false;
end
else
StartLine := CurrentLine - 1;
EndLine := 0;
end
else
begin
StartLine := TotalLines;
EndLine := 0;
end;
if StartLine < 0 then
StartLine := TotalLines;
// 根据指定的方向在 Memo 中搜索字符串
for CurrentLine := StartLine downto EndLine do
begin
LinePos := Pos(SearchText, Memo.Lines[CurrentLine]);
if LinePos > 0 then
Break; // 找到第一个匹配后退出搜索
if CurrentLine = 0 then //不能小于0,因为CurrentLine要在StartLine到EndLine之间在执行这个循环,
begin
// ShowMessage('已到达文档底部,未找到匹配字符串。');
Memo.CaretPos := p2;
Exit;
end;
end;
end;
// 找到字符串后,将光标移动到找到的位置
Memo.SelStart := Memo.Perform(EM_LINEINDEX, CurrentLine, 0) + LinePos - 1;
Memo.SelLength := Length(SearchText);
Memo.SetFocus;
SBar1.Panels[0].Text := '当前行: ' + inttostr(CurrentLine);
// SBar1.Panels[0].Text := '当前列: ' + inttostr(Memo.CaretPos.X);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SearchMemo(Memo1,Edit1.Text,True);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
SearchMemo(Memo1,Edit1.Text,False);
end;