南方的人 发表于 2013-12-21 16:44:14

delphi第28课中的记事本搜索功能请教

代码如下所示:
看了一下午还是不明白,请大神一步一步分析,在此跪谢。
procedure TForm1.FindDialog1Find(Sender: TObject);
var
i, j, PosReturn, SkipChars: Integer;
begin
For i:= 0 to Memo1.Lines.Count do
begin
    PosReturn:= Pos(FindDialog1.FindText, Memo1.Lines);//我的理解:这里返回的是搜索到的字符在文本中的位置,即第几位。
    If PosReturn <> 0 then
    begin
      Skipchars:= 0;
      For j:= 0 to i-1 do
      Skipchars:= Skipchars + Length(Memo1.Lines);
      SkipChars:= SkipChars + (i*2);
      SkipChars:= SkipChars + PosReturn - 1;
      Memo1.SetFocus;
      Memo1.SelStart:= SkipChars; //上面的posreturn可以直接使用到这里啊,为什么要使用skipchars呢?
      Memo1.SelLength:= Length(FindDialog1.FindText);
      Break;
    end;
end;
end;

comeheres 发表于 2013-12-21 16:44:15

本帖最后由 comeheres 于 2013-12-22 13:20 编辑

var
i, j, PosReturn, SkipChars: Integer;
begin
For i := 0 to Memo1.Lines.Count do
// 循环遍历memo控件内的每一行文本,其实应该是 i:= 0 to Memo1.Lines.Count-1
begin
    PosReturn := Pos(FindDialog1.FindText, Memo1.Lines【i】);//【】换成[],不然帖子格式有问题
// 查找第i行,返回搜索内容在该行的位置(第几位),用于判断该行是否存在搜索内容
    If PosReturn <> 0 then // 如果PosReturn大于0,说明第i行存在我们需要搜索的内容
    begin

      SkipChars := 0; // Skipchars设置为0

      { 计算从0行到i-1行的所有文本长度,赋值给Skipchars }
      For j := 0 to i - 1 do // 遍历第i行之前的所有行数
            SkipChars := SkipChars + Length(Memo1.Lines); // Skipchars加上第j行的文本长度

      SkipChars := SkipChars + (i * 2); // 第i行之前有i个换行符,所以把所有的换行符长度也累加上

      SkipChars := SkipChars + (PosReturn - 1); // (PosReturn - 1)是第i行的搜索内容前面的文本

      Memo1.SetFocus; // memo1控件获得鼠标焦点

      Memo1.SelStart := SkipChars;
      // 上面的posreturn可以直接使用到这里啊,为什么要使用skipchars呢?回复:因为posreturn只是搜索内容在第i行的所在位置,而memo1的鼠标焦点起始位置是从memo1的第一个字符算起的,所以得加上 前面几行文本+换行符 长度

      Memo1.SelLength := Length(FindDialog1.FindText); // 设置鼠标选中的字符串长度
      Break;
    end;
end;
end;


举个例子:
我是沙发
板凳也不错的
我是地板吗?
楼上的鱼友都好迅速
我下地域了!!比如我们需要搜索“鱼友”这个内容,程序执行步骤是这样的:
1.执行PosReturn := Pos('鱼友', Memo1.Lines),搜索第一行“我是沙发”,返回0
2.执行PosReturn := Pos('鱼友', Memo1.Lines),搜索第二行“板凳也不错的”,返回0
3.执行PosReturn := Pos('鱼友', Memo1.Lines),搜索第三行“我是地板吗?”,返回0
4.执行PosReturn := Pos('鱼友', Memo1.Lines),搜索第四行“楼上的鱼友都好迅速?”,返回4,此时PosReturn不等于0,符合if条件,进入if执行
5.设置SkipChars为0,SkipChars加上第一行“我是沙发”的字符串长度,此时SkipChars为4;SkipChars加上第二行“板凳也不错的”的字符串长度,此时SkipChars为4+6=10;SkipChars加上第三行“我是地板吗?”的字符串长度,此时SkipChars为10+6=16;因为第四行前面含有3个换行符,每个换行符占2个长度,故SkipChars+3*2=22
6.“鱼友”前面的“楼上的”长度是PosReturn-1,即4-1=3,所以SkipChars为22+3=25
7.memo1获得焦点,鼠标位置在memo1的第25个字符长度处,即“鱼友”前,然后鼠标选中“鱼友”的字符串长度2,便是搜索结束的效果



向往青莲 发表于 2013-12-22 09:56:10

混个脸熟啊

南方的人 发表于 2013-12-22 13:14:47

...,没人 能解答吗?

南方的人 发表于 2013-12-22 13:22:13

comeheres 发表于 2013-12-22 13:18 static/image/common/back.gif
var
i, j, PosReturn, SkipChars: Integer;
begin


受教受教。。鱼币奉上,请笑纳

南方的人 发表于 2013-12-24 10:13:54

ryan0632 发表于 2013-12-24 09:58 static/image/common/back.gif
土豪 我们做朋友吧

好啊,可惜我不是土豪

nanrenne 发表于 2021-5-19 13:44:14

搜索按下Enter之后焦点聚在了搜索到的文字上,无法再次Enter,否则文字被回车替换了
页: [1]
查看完整版本: delphi第28课中的记事本搜索功能请教