[原创]让RichEdit支持中文搜索、向上查找、区分大小写!(花费一个多星期的成果)!

           RichEdit组件本身为文本搜索提供了FindText()方法,但FindText()方法有一个最大的缺点是不支持中文查找,如果在要搜索的字符串中含有'中文',哪是无论如何也搜不到的,英文则没有任何问题。并且它只提供了向下查找,不只持向上查找。具体原因你看一下VCL源码就知道了。
    如果没有一个好的中文搜索,哪么查找,替换功能就无法实现(事实也确实如此)。只支持英文搜索有什么用呢?大家平时主要看的用的都是中文。如果不实现中文搜索,感觉RichEdit就像'鸡肋',甚至我感觉RichEdit只是Borland制造的一个半成品!
    解决方法:
    本来想直接试改造FindText()方法,但发现要改的地方太多了,有些要改的地方甚至在TWinControl,TControl中,最后才想到用这种思路要实现付出的代价太大,而且效果也不会太好(有可能做出的东西会有BUG或者兼容性差)
    换一种思路解决问题就简单多了,在RichEdit中保留FindText()方法,新增加一个FindTextW()新方法,创建一个新的RichEdit组件--TRichEditW,完整代码如下:

Unit RichEditW;

Interface

Uses
  SysUtils, Classes, Controls, StdCtrls, ComCtrls, RichEdit, Dialogs, StrUtils;

Type
  TrichEditW = Class(TRichEdit)
  Private
    { Private declarations }
  Protected
    { Protected declarations }
  Public
    Function FindTextW(SearchStr: String; Options: TFindOptions): Integer;
  Published
    { Published declarations }
  End;

Implementation

{ TrichEditW }

Function TrichEditW.FindTextW(SearchStr: String; Options: TFindOptions): Integer;
Var
  FoundAt: Integer;
  LastFoundAt: Integer;
  SearchStrLen: Integer;
  AllText: String;
Begin //"查找下一个" 算法
  Result := -1;
  FoundAt := 0;

  If frDown In Options Then //"向下" 查找,找出搜索范围
    AllText := System.Copy(Text, SelStart + SelLength + 1, Length(Text))
  Else //"向上" 查找,找出搜索范围
    AllText := System.Copy(Text, 1, SelStart);

  If Not (frMatchCase In Options) Then //非大小写敏感
  Begin
    AllText := UpperCase(AllText);
    SearchStr := UpperCase(SearchStr);
  End;

  If frDown In Options Then //执行"向下查找"
  Begin
    FoundAt := Pos(SearchStr, AllText);
    If FoundAt = 0 Then
      Exit;
    //定位光标到指定的字符串
    FoundAt := SelStart + SelLength + FoundAt - 1;
  End;

  If Not (frDown In Options) Then //执行"向上查找"
  Begin
    SearchStrLen := Length(SearchStr);
    FoundAt := Pos(SearchStr, AllText);
    If FoundAt = 0 Then //整个部分没找到
      Exit
    Else //至少找至一个相符的字串
    Begin
      LastFoundAt := FoundAt; //保存搜到的"第1个字串"位置
      Repeat
        FoundAt := Posex(SearchStr, AllText, FoundAt + SearchStrLen);
        If FoundAt <> 0 Then
          LastFoundAt := FoundAt;
      Until FoundAt = 0;
      FoundAt := LastFoundAt - 1;
    End;
  End;

  Result := FoundAt;

End;

End.


     好了,这下用这个新的TRichEditW完全可以代替原来的RichEdit组件,在需要在文本中查询的时候,用新的FindTextW()代替原来的FindText()方法:对于英文,中文查询完全没有问题,并且支持向上,向下,区分大小写(英文)功能。
     当然,原来的FindText()也还保留着,对于英文字符的向下搜索应该也是很好的。

   上面代码是我在D7,Win2000下做的。Xp下测试也没有问题。欢迎大家继续试用,讨论这个组件。。。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值