Содержание материала

 

Code:

{ **** UBPFD *********** by delphibase.endimus.com ****

>> Поиск строки в редакторе Memo

 

Зависимости: Windows, Classes, StdCtrls

Автор:       Fenik, Этот адрес электронной почты защищён от спам-ботов. У вас должен быть включен JavaScript для просмотра., Новоуральск

Copyright:   Автор: Федоровских Николай

 

***************************************************** }

 

function FindInMemo(Memo: TMemo; const FindText: string;

FindDown, MatchCase: Boolean): Boolean;

 

{Если строка найдена, то результат True, иначе - False;

 

FindText : искомая строка;

FindDown : True - поиск вниз от курсора ввода;

            False - поиск вверх от курсора ввода;

MatchCase : True - с учетом регистра букв,

            False - не учитывая регистр бук.

 

Если у Memo стоит автоперенос слов, то могут

возникнуть проблемы - текст будет найден,

но выделен не там где надо. Так что, для нормального поиска

свойство ScrollBars у Memo ставить в ssBoth (ну или ssHorizontal)}

 

function PosR2L(const FindStr, SrcStr: string): Integer;

   {Поиск последнего вхождения подстроки FindStr в строку SrcStr}

var

   ps, L: Integer;

 

   function InvertSt(const S: string): string;

     {Инверсия строки S}

   var

     i: Integer;

   begin

     L := Length(S);

     SetLength(Result, L);

     for i := 1 to L do

       Result[i] := S[L - i + 1];

   end;

 

begin

   ps := Pos(InvertSt(FindStr), InvertSt(SrcStr));

   if ps <> 0 then

     Result := Length(SrcStr) - Length(FindStr) - ps + 2

   else

     Result := 0;

end;

 

function MCase(const s: string): string;

   {Перевод заглавных букв в строчные;

    Функция вызывается если регистр не учитывается}

var

   i: Integer;

begin

   Result := s;

   for i := 1 to Length(s) do

   begin

     case s[i] of

       'A'..'Z',

         'А'..'Я': Result[i] := Chr(Ord(s[i]) + 32);

       'Ё': Result[i] := 'ё';

       'Ѓ': Result[i] := 'ѓ';

       'Ґ': Result[i] := 'ґ';

       'Є': Result[i] := 'є';

       'Ї': Result[i] := 'ї';

       'І': Result[i] := 'і';

       'Ѕ': Result[i] := 'ѕ';

     end;

   end;

end;

 

var

Y, X, SkipChars: Integer;

FindS, SrcS: string;

P: TPoint;

begin

Result := False;

 

if MatchCase then

   FindS := FindText

else

   FindS := MCase(FindText);

 

P := Memo.CaretPos;

 

if FindDown then

   {Поиск вправо и вниз от курсора ввода}

   for Y := P.y to Memo.Lines.Count do

   begin

 

     if Y <> P.y then

       {Если это не строка, в которой курсор вода,

        то ищем во всей строке}

       SrcS := Memo.Lines[Y]

     else

       {иначе обрезаем строку от курсора до конца}

       SrcS := Copy(Memo.Lines[Y], P.x + 1,

         Length(Memo.Lines[Y]) - P.x + 1);

 

     if not MatchCase then

       SrcS := MCase(SrcS);

     X := Pos(FindS, SrcS);

     if X <> 0 then

     begin

       if Y = P.y then

         Inc(X, P.x);

       P := Point(X, Y);

       Result := True;

       Break; {Выход из цикла}

     end

   end

else

   {Поиск влево и вверх от курсора ввода}

   for Y := P.y downto 0 do

   begin

 

     if Y <> P.y then

       {Если это не строка, в которой курсор вода,

        то ищем во всей строке}

       SrcS := Memo.Lines[Y]

     else

       {иначе обрезаем строку от начала до курсора

        минус выделенный текст}

       SrcS := Copy(Memo.Lines[Y], 1, P.x - Memo.SelLength);

 

     if not MatchCase then

       SrcS := MCase(SrcS);

     X := PosR2L(FindS, SrcS);

     if X <> 0 then

     begin

       P := Point(X, Y);

       Result := True;

       Break; {Выход из цикла}

     end

   end;

 

if Result then

begin

   {Если текст найден - выделяем его}

   SkipChars := 0;

   for y := 0 to P.Y - 1 do

     Inc(SkipChars, Length(Memo.Lines[y]));

   Memo.SelStart := SkipChars + (P.Y * 2) + P.X - 1;

   Memo.SelLength := Length(FindText);

end;

end;

Пример использования:

 

procedure TForm1.FindDialog1Find(Sender: TObject);

begin

if not FindInMemo(Memo1,

   FindDialog1.FindText,

   frDown in FindDialog1.Options,

   frMatchCase in FindDialog1.Options) then

   Application.MessageBox('Поиск результатов не дал.',

     PChar(Application.Title),

     MB_OK or MB_ICONINFORMATION);

end;

 

Пришло мне письмо от Алексея. На этот раз он прислал (цитирую): "юнит для поиска строки(текста) в TEdit, TMemo, или других компонентах (дочерних TCustomEdit'у)." Так как тескт "авторский" (более того, здесь также присутствует наследование), помещаю его здесь в том виде, в котором он был прислан, т.е. без перевода. В случае каких-либо вопросов и недоразумений обращайтесь по вышеуказанносу адресу электронной почты.

 

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить