Форум по программированию Delphi Sources

 



Вернуться   Форум по программированию Delphi Sources > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 20.03.2017, 13:24
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Поиск текста в 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  
Старый 20.03.2017, 14:17
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 2,760
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Видимо после { Выделение найденного текста } можно попросить рича прокрутиться до него, типа как RichEdit1.Perform(EM_SCROLLCARET, 0, 0)
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
ffpereverzev (21.03.2017)
  #3  
Старый 20.03.2017, 19:35
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 6,952
Репутация: 49086
По умолчанию

не уверен, что в RichEdit сработает, но для Memo можно было просто установить SelStart на соотв. символ и контрол сам проматывался до нужной позиции. Ну и можно так же поставить selLength, и тогда найденный текст будет сразу выделен.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
ffpereverzev (21.03.2017)
  #4  
Старый 21.03.2017, 09:06
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Откорректировал процедуру поиска текста:

Код:
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  
Старый 21.03.2017, 09:14
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Хм...выяснил, что все работает и без танцев с бубнами простой настройкой окна 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  
Старый 21.03.2017, 09:45
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

То есть получается вот какая штука:

1. Я запускаю поиск не трогая текст в окне RichEdit (не спуская видимый текст ползунком) - в этом случае текст ищется нормально, полностью соответствуя параметрам поиска (например, я ищу слово "Архив" длиной в 5 символов, тогда при поиске, в видимой части, выделяется слово "Архив", без смещений);
2. Если я сдвигаю ползунок вниз и устанавливаю курсор в появившуюся область, то при поиске появляется сдвиг (ищу слово "Архив", а нахожу, например "хивов" или "хиват". То есть количество выделяемых символов верное, но идет сдвиг +2);
3. При дальнейшем поиске сдвиг увеличивается, причем всегда на число, кратное 2-ум.

Последний раз редактировалось ffpereverzev, 22.03.2017 в 06:21.
Ответить с цитированием
  #7  
Старый 23.03.2017, 11:44
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Кто-нибудь сталкивался с таким? Можете поделиться информацией?
Ответить с цитированием
  #8  
Старый 26.03.2017, 14:54
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

В общем, заработал поиск. Спасибо всем за советы и предложения! Выкладываю рабочий код для 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  
Старый 26.03.2017, 15:38
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,391
Версия Delphi: 7, XE5
Репутация: 59585
По умолчанию

В файле справки есть код поиска. Этот очень похож на него)))
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #10  
Старый 26.03.2017, 17:05
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Да? К сожалению, при попытке вызова файла справки меня перекидывает на сайт support.microsoft.com, где появляется окно "Error opening Help in Windows-based programs: "Feature not included" or "Help not supported" в связи с тем, что среда разработки Delphi 7 установлена в ОС Windows 10. Поэтому все приходится искать с помощью поисковых систем и форумов поддержки. Извиняюсь, за глупые вопросы, но по-другому мне ответы не найти. Благодарю за Ваши ответы!
Ответить с цитированием
  #11  
Старый 26.03.2017, 17:17
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,391
Версия Delphi: 7, XE5
Репутация: 59585
По умолчанию



Но переменная mySearchTypes есть в коде файла справки который идет с Delphi XE5.

Или вот на оф. сайте http://docwiki.embarcadero.com/CodeE...t_%28Delphi%29. Кстати на сайте переменная myFindOptions тоже объявлена и не используется.
__________________
Пишу программы за еду.
__________________

Последний раз редактировалось NumLock, 26.03.2017 в 17:20.
Ответить с цитированием
Этот пользователь сказал Спасибо NumLock за это полезное сообщение:
ffpereverzev (26.03.2017)
  #12  
Старый 26.03.2017, 17:49
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Хм...интересно...а у меня даже в режиме совместимости справка не работает...

Цитата:
Сообщение от NumLock
Но переменная mySearchTypes есть в коде файла справки который идет с Delphi XE5.
Вот эту строчку не понял. У меня нет Delphi XE5.

Цитата:
Сообщение от NumLock
Или вот на оф. сайте http://docwiki.embarcadero.com/CodeE...t_%28Delphi%29.

За ссылку отдельное спасибо!
Ответить с цитированием
  #13  
Старый 26.03.2017, 21:43
Аватар для lmikle
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 6,952
Репутация: 49086
По умолчанию

Цитата:
Сообщение от ffpereverzev
Хм...интересно...а у меня даже в режиме совместимости справка не работает...

Delphi 7? Там надо доставить WinHelp - собственно именно на эту страницу и должно перекидывать - качаешь соотв. KB#######, ставишь и старая справка начинает работать.

Кстати, у Embarcadero есть on-line вариант справки, так что можно и там посмотреть. Идти отсюда: http://docwiki.embarcadero.com/RADSt...7/en/Main_Page
там все начинается для текущей версии, но можно переключить и на предыдущие, если есть какое отличие.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
ffpereverzev (26.03.2017)
  #14  
Старый 26.03.2017, 22:03
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Прохожий
 
Регистрация: 14.02.2017
Сообщения: 48
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Delphi 7? Там надо доставить WinHelp - собственно именно на эту страницу и должно перекидывать - качаешь соотв. KB#######, ставишь и старая справка начинает работать.

Кстати, у Embarcadero есть on-line вариант справки, так что можно и там посмотреть. Идти отсюда: http://docwiki.embarcadero.com/RADSt...7/en/Main_Page
там все начинается для текущей версии, но можно переключить и на предыдущие, если есть какое отличие.

Нет ни одной версии, которая бы установилась "как есть".



Попробовал все варианты, учитывая неполадки совместимости.

Буду пользоваться онлайн-помощником. Спасибо за советы!
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 06:01.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources", 2004-2017

ВКонтакте   Facebook   Twitter