|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Поиск текста в RichEdit через FindDialog
Здравствуйте, уважаемые форумчане!
Сразу оговорюсь - ПОИСК РАБОТАЕТ! Есть только один нюанс, который мне не побороть. Проблема связана с поиском в окне RichEdit, в котором строки выходят за размеры самого окна (Настройка ползунка установлена в ssBoth). При повторном нажатии кнопки "Поиск", если искомое слово находится за пределами окна, ползунок не сдвигается вниз и, следовательно, найденный текст не видно. Кнопка вызова окна поиска Код:
procedure TForm1.Button5Click(Sender: TObject); begin SPos := RichEdit1.SelStart; { Запоминание позиции курсора } with FindDialog1 do begin FindText := RichEdit1.SelText; { Начальное значение текста поиска - текст, выделенный в RichEdit } Position := Point(Form1.Left, Form1.Top + RichEdit1.Top + RichEdit1.Height); { Позиционирование окна диалога внизу RichEdit } Execute; { Выполнение } end; end; Процедура обработки поиска текста Код:
procedure TForm1.FindDialog1Find(Sender: TObject); begin with FindDialog1 do begin RichEdit1.SelStart := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(RichEdit1.Lines.Text, SPos + 1, Length(RichEdit1.Lines.Text)))) + SPos - 1; if RichEdit1.SelStart >= SPos then begin RichEdit1.SelLength := Length(FindText); { Выделение найденного текста } SPos := RichEdit1.SelStart + RichEdit1.SelLength + 1; { Изменение начальной позиции поиска } end else if MessageDlg('Текст "' + FindText + '" не найден. Продолжать поиск?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; end; RichEdit1.SetFocus; end; Заранее признателен за любую помощь! |
#2
|
||||
|
||||
Видимо после { Выделение найденного текста } можно попросить рича прокрутиться до него, типа как RichEdit1.Perform(EM_SCROLLCARET, 0, 0)
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (21.03.2017)
|
#3
|
|||
|
|||
не уверен, что в RichEdit сработает, но для Memo можно было просто установить SelStart на соотв. символ и контрол сам проматывался до нужной позиции. Ну и можно так же поставить selLength, и тогда найденный текст будет сразу выделен.
|
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
ffpereverzev (21.03.2017)
|
#4
|
||||
|
||||
Откорректировал процедуру поиска текста:
Код:
procedure TForm1.FindDialog1Find(Sender: TObject); begin with FindDialog1 do begin RichEdit1.SelStart := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(RichEdit1.Lines.Text, SPos + 1, Length(RichEdit1.Lines.Text)))) + SPos - 1; if RichEdit1.SelStart >= SPos then begin RichEdit1.SelLength := Length(FindText); { Выделение найденного текста } SPos := RichEdit1.SelStart + RichEdit1.SelLength + 1; { Изменение начальной позиции поиска } RichEdit1.Perform(EM_SCROLLCARET,0,0); RichEdit1.SetFocus; end else if MessageDlg('Текст "' + FindText + '" не найден. Продолжать поиск?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; end; RichEdit1.SetFocus; end; Теперь скроллбар прокручивается нормально, но появилась новая напасть: пока поиск идет в видимой части RichEdit, то выделение слова полностью соответствует искомому, но как только поиск начинается за видимой областью, то каретка (и выделение) начинают свое движение. То есть выделение сдвигается относительно искомого слова вправо. И чем дальше поиск - тем больше сдвиг. |
#5
|
||||
|
||||
Хм...выяснил, что все работает и без танцев с бубнами простой настройкой окна RichEdit (изменение опции hideSelection в False). Но проблема со смещающимся выделением осталась. Видимо это проблема обработки текста. Был бы признателен за советы мудрых и бывалых.
На текущий момент процедуру вернул обратно: Код:
procedure TForm1.FindDialog1Find(Sender: TObject); begin with FindDialog1 do begin RichEdit1.SelStart := Pos(AnsiLowerCase(FindText), AnsiLowerCase(Copy(RichEdit1.Lines.Text, SPos + 1, Length(RichEdit1.Lines.Text)))) + SPos - 1; if RichEdit1.SelStart >= SPos then begin RichEdit1.SelLength := Length(FindText); { Выделение найденного текста } SPos := RichEdit1.SelStart + RichEdit1.SelLength + 1; { Изменение начальной позиции поиска } //RichEdit1.Perform(EM_SCROLLCARET,0,0); //RichEdit1.SetFocus; end else if MessageDlg('Текст "' + FindText + '" не найден. Продолжать поиск?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then CloseDialog; end; RichEdit1.SetFocus; end; |
#6
|
||||
|
||||
То есть получается вот какая штука:
1. Я запускаю поиск не трогая текст в окне RichEdit (не спуская видимый текст ползунком) - в этом случае текст ищется нормально, полностью соответствуя параметрам поиска (например, я ищу слово "Архив" длиной в 5 символов, тогда при поиске, в видимой части, выделяется слово "Архив", без смещений); 2. Если я сдвигаю ползунок вниз и устанавливаю курсор в появившуюся область, то при поиске появляется сдвиг (ищу слово "Архив", а нахожу, например "хивов" или "хиват". То есть количество выделяемых символов верное, но идет сдвиг +2); 3. При дальнейшем поиске сдвиг увеличивается, причем всегда на число, кратное 2-ум. Последний раз редактировалось ffpereverzev, 22.03.2017 в 06:21. |
#7
|
||||
|
||||
Кто-нибудь сталкивался с таким? Можете поделиться информацией?
|
#8
|
||||
|
||||
В общем, заработал поиск. Спасибо всем за советы и предложения! Выкладываю рабочий код для FindDialog. Авось, кому пригодится:
Код:
// Вызов окна поиска procedure TForm1.Button5Click(Sender: TObject); begin SPos := RichEdit1.SelStart; { Запоминание позиции курсора } with FindDialog1 do begin FindText := RichEdit1.SelText; { Начальное значение текста поиска - текст, выделенный в RichEdit } Position := Point(Form1.Left, Form1.Top + RichEdit1.Top + RichEdit1.Height); { Позиционирование окна диалога внизу RichEdit } Execute; { Выполнение } end; end; // Обработка поискового запроса procedure TForm1.FindDialog1Find(Sender: TObject); var FoundAt: LongInt; StartPos, ToEnd: Integer; mySearchTypes : TSearchTypes; begin mySearchTypes := []; with RichEdit1 do begin if frMatchCase in FindDialog1.Options then mySearchTypes := mySearchTypes + [stMatchCase]; if frWholeWord in FindDialog1.Options then mySearchTypes := mySearchTypes + [stWholeWord]; { Начать поиск с текущего положения каретки } { в противном случае начать с начала текста} if SelLength <> 0 then StartPos := SelStart + SelLength else StartPos := 0; ToEnd := Length(Text) - StartPos; FoundAt := FindText(FindDialog1.FindText, StartPos, ToEnd, mySearchTypes); if FoundAt <> -1 then begin SetFocus; SelStart := FoundAt; SelLength := Length(FindDialog1.FindText); end else Application.MessageBox ('Поиск окончен!', 'Результат', mb_Ok + mb_IconAsterisk); end; end; |
#9
|
||||
|
||||
В файле справки есть код поиска. Этот очень похож на него)))
Пишу программы за еду. __________________ |
#10
|
||||
|
||||
Да? К сожалению, при попытке вызова файла справки меня перекидывает на сайт support.microsoft.com, где появляется окно "Error opening Help in Windows-based programs: "Feature not included" or "Help not supported" в связи с тем, что среда разработки Delphi 7 установлена в ОС Windows 10. Поэтому все приходится искать с помощью поисковых систем и форумов поддержки. Извиняюсь, за глупые вопросы, но по-другому мне ответы не найти. Благодарю за Ваши ответы!
|
#11
|
||||
|
||||
Но переменная mySearchTypes есть в коде файла справки который идет с Delphi XE5. Или вот на оф. сайте http://docwiki.embarcadero.com/CodeE...t_%28Delphi%29. Кстати на сайте переменная myFindOptions тоже объявлена и не используется. Пишу программы за еду. __________________ Последний раз редактировалось NumLock, 26.03.2017 в 17:20. |
Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
ffpereverzev (26.03.2017)
|
#12
|
||||
|
||||
Хм...интересно...а у меня даже в режиме совместимости справка не работает...
Цитата:
Цитата:
За ссылку отдельное спасибо! |
#13
|
|||
|
|||
Цитата:
Delphi 7? Там надо доставить WinHelp - собственно именно на эту страницу и должно перекидывать - качаешь соотв. KB#######, ставишь и старая справка начинает работать. Кстати, у Embarcadero есть on-line вариант справки, так что можно и там посмотреть. Идти отсюда: http://docwiki.embarcadero.com/RADSt...7/en/Main_Page там все начинается для текущей версии, но можно переключить и на предыдущие, если есть какое отличие. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
ffpereverzev (26.03.2017)
|
#14
|
||||
|
||||
Цитата:
Нет ни одной версии, которая бы установилась "как есть". Попробовал все варианты, учитывая неполадки совместимости. Буду пользоваться онлайн-помощником. Спасибо за советы! |