![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Поиск и замена [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]Задача несложная.
определяем, не поиск ли это далее.
если нет, начинаем с первой записи, если да - с сохраненного номера записи.
проверяем, не вышли ли мы за границы количества записей, если вышли - то поиск завершен.
сравниваем.
если нашли, то сохраняем номер записи, выводим результат, если не нашли - переходим на следующую запись.