用户名:  密码:   
您当前的位置:首页 > 程序设计 >  Delphi > 

Memo控件增加搜索功能强逻辑

上次修改时间: 2024-03-27 17:29:04      来源:网络总结      作者:钢铁长陈
上一页      路径:DSD\Learn\Delphi语言\常用控件使用说明\      下一页

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;