TRichEdit и удаление последней пустой строки

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Всем доброго времени суток!

Вопрос следующий. Есть
MyRichView : TRichView;
AnyText : String;

Хочется в MyRichView видеть AnyText. Делается
RichView.Lines.Text := AnyText;

После чего RichView.Lines.Text имеет значение AnyText + #13#10, в результате чего в MyRichView в конце появляется лишняя пустая строка, которой не было в AnyText. От нее очень хочется избавиться. Пытался откусывать через Copy() два последних символа из RichView.Lines.Text - результат нулевой. Испробовал метод научного тыка и быстрый наскок на хелп. В результате умылся, но заметил, что такое добавление лишней строки происходит, вроде, со всеми TStrings, после присвоения им текста. Как-то можно это победить? Или хотя бы сделать, чтобы визуально не было этой пустой строки в конце MyRichView. Тем паче, что из под интерфейса эта лишняя строка спокойно удаляется.
 

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
Не знаю что такое TRichView, но для TRichEdit (оно же TMemo, TcxMemo, TcxRichEdit) я тоже так и не решил проблему.

Более того, там длинная строка разбивается на несколько - очень неудобно.

Думаю, надо либо искать другой компонент (или писать свой). Либо забить и считать, что это правильно.
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Ну да, это я описался в попыхах, TRichEdit конечно.

Длинная строка разбивается только если WordWrap := True, как я понимаю.

А оконечную пустую строку я в старых версиях Delphi как-то убирал, и вроде именно через Copy(). А вот в D2010 не прокатывает. А так как строка эта убирается из под интерфейса при редактировании RichEdit, то и программно это можно реализовать. Выделение последних символов через SelStart и SelLength и их удаление. Но только это уже какое-то ректальное программирование. А хочется красоты, гармонии и совершенства )))
 

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
Автоматическое добавление перевода строки - это, строго говоря, фишка не компонента, а TStrings (например, метода SetTextStr - в нем автоматически добавляется CRLF).

Поэтому любое присвоение строки всегда будет заканчиваться CRLF.

Так что либо "ректальное программирование" (классный термин, кстати :D ), либо свой компонент без TStrings.

А можно узнать - зачем вообще это надо? Может и ладно, что есть перевод строки.
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Угу, я понял, что все растет из TStrings. Но жить легче не стало )))


Ректальный вариант решения проблемы:
Code:
MyRichEdit : TRichEdit;
AnyText : String;
...
  MyRichEdit.Lines.Text := AnyText; // или как-то еще
  MyRichEdit.SelStart := Length(MyRichEdit.Text) - MyRichEdit.Lines.Count - 1;
  MyRichEdit.SelLength := 1;
  MyRichEdit.SelText := '';
  MyRichEdit.SelStart := 0;


На счет того, зачем надо. RichEdit сделан размером с обычный Edit (видна одна строка) и имеет вертикальную прокрутку. В нем лежит список фалов. Обычно один, реже 2-3. Щелкая по стрелочкам скрола, юзер по одному (если их несколько) может просматривать названия файлов. При надобности быстро там что-то исправить ручками (поэтому ListView или что-то подобное не пойдет). А лишняя пустая строка в конце ... ну, удивит его, наверное )))) И я даже догадываюсь, что он скажет, когда ее увидит ))))

P.S. Неохота сейчас с этим разбираться самому, но может кто подскажет простой способ, как задавать высоту RichEdit (на Create формы), чтобы на данном компе была видна именно одна строчка?
 
Last edited by a moderator:

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
Хм. Предположим убрали последнюю пустую строку. А не будет ли юзера смущать, что можно например, самостоятельно добавить/вставить пустую строку? Или вообще превратить этот список файлов в бардак.

Может лучше использовать Grid?

Высоту текста можно определить так: Canvas.TextHeight('T') (вместо T - какую-нибудь высокую букву). Ну плюс надо приплюсовывать бордеры.
Либо, к примеру, создать компонент TEdit в рантайме и посмотреть его размеры.
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
> ... превратить этот список файлов в бардак.

Так за ради бога. Хочет превратить, пущай. Главное, что он это делает сам, своими руками ))) Там есть диалог выбора файлов, откуда он может все добавить по-честному. Может вбить что-то руками, если так проще. А заботится о физическом существовании файла здесь ни к чему. Он все-равно должен быть строго определенного формата, чтобы обработался. Так что, пущай пищут хоть пустую строку, если им это зачем-то надо )))


А на счет бордеров, можно, наверное, так сделать, чтобы не париться:
MyRichEdit.ClientHeight := Canvas.TextHeight('Ty');
P.S. Кривоватенько немного получается. Высота текста определяется, но расстояние между строками не учитывается. По-хорошему, его бы тоже надо прибавлять.
 
Last edited by a moderator:

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
>
P.S. Кривоватенько немного получается. Высота текста определяется, но расстояние между строками не учитывается. По-хорошему, его бы тоже надо прибавлять.

RichEdit1.Height := TEdit.Create(Self).Height;

Вот так вроде правильная высота получается (на потерянную ссылку не обращайте внимание)
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Работать будет и так)
Мне не надо, чтобы работало. Мне надо, чтобы работало как надо.


RichEdit1.Height := TEdit.Create(Self).Height;

Вот так вроде правильная высота получается (на потерянную ссылку не обращайте внимание)
Да, наверное, так и буду делать. Есть еще EM_GETPARAFORMAT Message, который возвращает формат текущего параграфа в RichEdit, но это уж чересчур, по-моему )))
 

dustypup

Member
Joined
Nov 27, 2008
Messages
21
Reaction score
1
Не понятно зачем тут нужен RichEdit, а не обычный Memo.

Ректальный способ будет работать. Я тоже подобное у себя использую. :)
Только нужно еще запретить сохранение в "undo" чтобы потом юзер контрол-зедом не вставил обратно пустую строку.

Запретить сохранение "undo" можно так:
MyRichEdit.Perform(EM_SETUNDOLIMIT, 0, 0);
Разрешить так:
MyRichEdit.Perform(EM_SETUNDOLIMIT, 100, 0);
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Не понятно зачем тут нужен RichEdit, а не обычный Memo.

Чтобы не было прокрутки, когда в нем только одна строка.
 

dustypup

Member
Joined
Nov 27, 2008
Messages
21
Reaction score
1
Чтобы не было прокрутки, когда в нем только одна строка.

procedure TForm1.Memo1Change(Sender: TObject);
begin
with TMemo(Sender) do
if (Abs(Font.Height) + 4) * Lines.Count > Height then
ScrollBars := ssVertical
else
ScrollBars := ssNone;
end;
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Зачем писать код, если можно обойтись без него вообще?
 

dustypup

Member
Joined
Nov 27, 2008
Messages
21
Reaction score
1
Зачем использовать навороченные компоненты, если можно обойтись простыми? :)
Тем более, что при этом приходиться использовать "ректальные" методы.
 

Ognev

ex-Team DUMPz
Joined
Aug 20, 2018
Messages
2,103
Reaction score
902
Age
25
Ректальный метод придется использовать и для Memo и для RichEdit, потому что этот перевод строки наследие TStrings. А на счет того, какой компонент здесь нужен, так я никого не уговариваю. Нравится вам Memo, используйте его. А я буду использовать RichEdit )))
 

dustypup

Member
Joined
Nov 27, 2008
Messages
21
Reaction score
1
Ректальный метод придется использовать и для Memo
Не поленился и проверил. Нет такой проблемы у TMemo.
 

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
Не поленился и проверил. Нет такой проблемы у TMemo.

Какой проблемы? Добавление пустой строки?

Есть! Я проверял.
Уже озвучивали, что это дело не в компоненте, а в реализации TStrings
 

demav

Member
Joined
Nov 20, 2018
Messages
299
Reaction score
53
Age
39
Проверьте еще раз.

Вот блин. И правда для TMemo не добавляется строка.
Я наверное проверял на TRichEdit, вот код, проверьте:

Code:
 RichEdit1.Lines.Clear;
 RichEdit1.Lines.Text := 'ABCD';
 Showmessage('|' + RichEdit1.Lines.Text + '|');

Я посмотрю почему в TMemo не так, ведь там тоже по идее TStrings.SetTextStr используется.

Хотя, нет, не стану. Что-то мы на какую-то фигню скатываемся :)
 
Top