Как сделать автопрокрутку до конца RichEdit?

Раньше мне никогда не приходилось использовать TRichEdit, я всегда использовал TMemo.

Я бы хотел, чтобы RichEdit автоматически прокручивался до конца, когда я добавляю текст, например TMemo. Посмотрите, как это выглядит после добавления некоторых данных:

введите здесь описание изображения

Как видите, полоса прокрутки остается вверху, но я бы хотел, чтобы она оставалась внизу, когда я добавляю текст.

Я «гуглил» решения, но не смог найти хорошего и надежного.


person Daniel Grillo    schedule 16.06.2011    source источник
comment
Я не вижу разницы. Я пробовал Memo1.Lines.Add('test') и RichEdit1.Lines.Add('test'), и они ведут себя одинаково. Вам нужно указать более подробную информацию.   -  person Andreas Rejbrand    schedule 16.06.2011
comment
@Андреас, я добавил больше деталей. Надеюсь теперь стало понятнее.   -  person Daniel Grillo    schedule 16.06.2011
comment
@Daniel: Очевидно, вы не добавляете текст, выполняя RichEdit1.Lines.Add('text'). Вы используете SelText := 'text' вместо этого?   -  person Andreas Rejbrand    schedule 16.06.2011
comment
@Андреас, я использую RichEdit1.Lines.Add('text')   -  person Daniel Grillo    schedule 16.06.2011
comment
@Andreas: Если мы также используем метод RichEdit1.Lines.Add(), результат будет таким же, как указано выше (в D2006)   -  person Bharat    schedule 16.06.2011
comment
Да, теперь я вижу! Я попробовал RichEdit1.Lines.Add('text') в OnClick формы, поэтому Rich Edit (или памятка) все время был в центре внимания. А затем и Rich Edit, и прокрутка заметок. Но если элемент управления не имеет фокуса (например, использовать OnClick из TButton), то прокручивается только памятка! Интересный...   -  person Andreas Rejbrand    schedule 16.06.2011


Ответы (3)


Попробуйте этот код

RichEdit1.SetFocus;
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.Perform(EM_SCROLLCARET, 0, 0);
person Bharat    schedule 16.06.2011
comment
Спасибо. Оно работает! Я немного отредактировал ваш ответ, если вы не возражаете. - person Daniel Grillo; 16.06.2011
comment
@Daniel: я не уверен на 100 %, но подозреваю, что RichEdit1.GetTextLength намного быстрее, чем Length(RichEdit1.Text). Первый отправляет только сообщение WM_GETTEXTLENGTH в окно Rich Edit (как хочет Microsoft), тогда как другой сначала должен получить весь текст в виде строки (потенциально очень медленно?), а затем считывает его длину ( очень быстро). ОБНОВЛЕНИЕ: Извините, вы хотели использовать GetTextLen, а Бхарат использовал Length. Я тебя перепутал! - person Andreas Rejbrand; 16.06.2011
comment
Что ж, именно BugFinder хотел использовать GtTextLen AFAICS, но теперь все смешалось. - person Sertac Akyuz; 16.06.2011
comment
Я не знаю, зависит ли это от версии Windows или Delphi, но с Delphi 2007 на Windows XP и 7 все, что мне было нужно, это строка .Perform. Это работало даже без фокусировки TRichEdit. - person Chad N B; 16.05.2013
comment
Просто хотел добавить, что с помощью RichEdit1.Perform(EM_SCROLLCARET, 0, 0); сам по себе отлично работал у меня (Delphi XE2) - person KeyszerS; 09.02.2014
comment
Да, мне пришлось внести некоторые серьезные изменения в соответствии с этим SetFocus требованием. То, что я делал, - это журнал, и в этом случае все в форме отключается во время записи журнала. Поэтому мне пришлось вручную отключать отдельные элементы управления, а не весь контейнер (потому что вы не можете установить фокус на отключенные элементы управления). - person Jerry Dodge; 01.11.2015

Вот гораздо более простое и быстрое решение:

В обработчике события OnChange просто:

SendMessage(RichEdit1.handle, WM_VSCROLL, SB_BOTTOM, 0);

Исходный ответ от: https://www.experts-exchange.com/questions/21002277/Richedit-autoscrolling.html

person Niki    schedule 13.08.2018

Короче говоря, вам нужно поставить курсор в конец или отправить код для прокрутки вниз.

Ты пытался

Richedit1.SelStart :=RichEdit1.GetTextLength();
SendMessage(RichEdit1.handle, EM_SCROLLCARET,0,0);
person BugFinder    schedule 16.06.2011
comment
Я пробовал, и это не сработало. Вы должны поставить RichEdit1.SetFocus раньше. И по крайней мере в Delphi 2010 вы должны использовать GetTextLen вместо GetTextLength - person Daniel Grillo; 16.06.2011
comment
Это немного раздражает, я удивлен, что это требует внимания. (getTextLength был по памяти, поэтому я не слишком удивлен, извините) - person BugFinder; 16.06.2011