Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Поиск и замена [D7, XP]


AlexanderMS ©   (2006-05-06 18:50:00) 

Подскажите, пожалуйста: как организовать поиск фрагмента по массиву так, чтобы при поиске можно было использовать "Найти далее", "Только слово целиком" и т.п. Массив типа Record: название элемента и значение (оба string). При выборе строки названия из ListBox справа в Edit отображается редактируемое название, а под ним, в Memo, - значение. Поиск должен идти и в названии, и в значении (везде). Задача довольно сложная, может, в Delphi предусмотрены для этого функции? Заранее спасибо.


ЛшдлуттнСфе   (2006-05-06 20:39:00) [1]

Вот, нашел в делфиворде (не проверял)

procedure TForm1.FindDialog1Find(Sender: TObject);
var
 Buff, P, FT: PChar;
 BuffLen: Word;
begin
 with Sender as TFindDialog do
 begin
   GetMem(FT, Length(FindText) + 1);
   StrPCopy(FT, FindText);
   BuffLen := Memo1.GetTextLen + 1;
   GetMem(Buff, BuffLen);
   Memo1.GetTextBuf(Buff, BuffLen);
   P := Buff + Memo1.SelStart + Memo1.SelLength;
   P := StrPos(P, FT);
   if P = nil then
     MessageBeep(0)
   else
   begin
     Memo1.SelStart := P - Buff;
     Memo1.SelLength := Length(FindText);
   end;
   FreeMem(FT, Length(FindText) + 1);
   FreeMem(Buff, BuffLen);
 end;
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);
begin
 with Sender as TReplaceDialog do
   while True do
   begin
     if Memo1.SelText <> FindText then
       FindDialog1Find(Sender);
     if Memo1.SelLength = 0 then
       Break;
     Memo1.SelText := ReplaceText;
     if not (frReplaceAll in Options) then
       Break;
   end;
end;


ЛшдлуттнСфе   (2006-05-06 20:28:00) [2]

это моя ошибка...


AlexanderMS   (2006-05-06 20:00:00) [3]

AlexanderMS ©   (06.05.06 19:57) [11]
Понял, у меня Memo, а не RichEdit.


Джо   (2006-05-06 20:00:00) [4]

> [11] AlexanderMS ©   (06.05.06 19:57)
> Ошибочка вышла:
>
> [Error] FRGoTo.pas(140): Undeclared identifier: 'FindText'.

Это метод TRichEdit.


AlexanderMS   (2006-05-06 19:57:00) [5]

Ошибочка вышла:

[Error] FRGoTo.pas(140): Undeclared identifier: 'FindText'.


AlexanderMS   (2006-05-06 19:34:00) [6]


> Впрочем, в ListBox тоже можно.

Но мне не нужно. А насчёт FindDialog: у меня свой, со своими опциями.


> FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd,
>  [stMatchCase]);
>
> Вот эта строчка Вам будет наиболее интересна.


Спасибо за строчку.


> Kilkennycat ©   (06.05.06 19:16) [5]


Спасибо за код.
Благодарю за помощь, буду пробовать.


Джо   (2006-05-06 19:23:00) [7]

> [6] AlexanderMS ©   (06.05.06 19:17)

Тогда см. [4]. Впрочем, в ListBox тоже можно.


KilkennyCat   (2006-05-06 19:19:00) [8]


> (не в ListBox, не получится)


И в нем тоже можно.


AlexanderMS   (2006-05-06 19:17:00) [9]


> Выделить элемент в ListBox'е — свойство ItemIndex.

Это я знаю. У меня поиск фрагмента. Допустим, строка "Hello". При поиске "el" этот фрагмент должен быть выделен (не в ListBox, не получится) справа, в Edit (см. [1]).


KilkennyCat   (2006-05-06 19:17:00) [10]

FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, [stMatchCase]);

Вот эта строчка Вам будет наиболее интересна.


Kilkennycat   (2006-05-06 19:16:00) [11]

Да, совсем вылетело из памяти: можно воспользоваться TFindDialog,  вот пример из справки Делфи:

his example requires a TRichEdit, a TButton, and a TFindDialog.
Clicking the button click will display a Find Dialog to the right of the edit control.  Filling in the "Find what" text and pressing the Find Next button will select the first matching string in the Rich Edit control that follows the previous selection.

procedure TForm1.Button1Click(Sender: TObject);

begin
 FindDialog1.Position := Point(RichEdit1.Left + RichEdit1.Width, RichEdit1.Top);
 FindDialog1.Execute;
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
 FoundAt: LongInt;
 StartPos, ToEnd: Integer;
begin
 with RichEdit1 do
 begin
   { begin the search after the current selection if there is one }
   { otherwise, begin at the start of the text }
   if SelLength <> 0 then

     StartPos := SelStart + SelLength
   else

     StartPos := 0;

   { ToEnd is the length from StartPos to the end of the text in the rich edit control }

   ToEnd := Length(Text) - StartPos;

   FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, [stMatchCase]);
   if FoundAt <> -1 then
   begin
     SetFocus;
     SelStart := FoundAt;
     SelLength := Length(FindDialog1.FindText);
   end;
 end;
end;


ЛшдлуттнСфе   (2006-05-06 19:13:00) [12]


> выделить искомый фрагмент, найдя его в тексте


SelStart, SelLength


Джо   (2006-05-06 19:12:00) [13]

> [2] AlexanderMS ©   (06.05.06 19:11)
>
> > Задача несложная.
>
> Теперь согласен. Но как выделить искомый фрагмент, найдя
> его в тексте?

Выделить элемент в ListBox'е — свойство ItemIndex.


AlexanderMS   (2006-05-06 19:11:00) [14]


> Задача несложная.

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


Лшдлуттнсфе   (2006-05-06 19:01:00) [15]

Задача несложная.

определяем, не поиск ли это далее.
если нет, начинаем с первой записи, если да - с сохраненного номера записи.
проверяем, не вышли ли мы за границы количества записей, если вышли - то поиск завершен.
сравниваем.
если нашли, то сохраняем номер записи, выводим результат, если не нашли - переходим на следующую запись.


Наверх

Титульная страница Поиск, карта сайта Написать письмо