Есть BCB60 и есть приложение, в котором используется стандартный компонент VCL RichEdit. В этот RichEdit постоянно выводятся строки (т.е. он работает как-бы в режиме терминала, а не в режиме редактирования текста). При этом внутренний буфер строк (который, как известно, в RichEdit представлен классом TString) постоянно растет. Память не резиновая, поэтому этот буфер нужно периодически чистить. Сейчас это сделано так: при очередной записи в RichEdit процедура записи проверяет текущее количество строк в TString и если это количество строк больше некоторой константы (скажем 25000 строк), то нулевая строка из TString удаляется методом Delete. Все бы хорошо, но когда вызывается метод Delete визуальная часть компонента начинает отрабатывать удаление (скроллбар прыгает в начало текста строка удаляется потом скроллбар прыгает в конец текста). Эта процедура приводит к резкому замедлению печати и морганию экрана. Попытки сделать компонент RichEdit невидимым на время удаления тоже приводят к морганию. Попытки удалять не по одной строке, а по нескольку строк также приводят к морганию.
Вопросы:
1. Можно ли как-то контролировать (ограничить) кол-во строк в RichEdit не прибегая к методу Delete? Т.е. чтобы компонент сам следил за размером своего буфера и при переполнении удалял самые старые строки? Это было бы идеальным решением.
2. Если RichEdit не может сам контролировать (ограничить) кол-во строк, как организовать удаление строк так, чтобы компонент не моргал и не мотал туда-сюда скролл-баром.
3. Может есть какие-то другие компоненты для организации терминала.
Здравствуйте, Basil
извените а зачем использовать richedit для простого терминала если можно использовать Memo? или терминал не так прост как мне кажется
Здравствуйте, Аноним, Вы писали:
А>3. Может есть какие-то другие компоненты для организации терминала.
Если терминал — это список строк в StringList, то можно сделать его и на ScrollBox-е. Единственное, что будет чуть сложнее сделать — это выделение и копирование текста. Зато всё остальное не будет дёргаться и будет реагировать со скоростью света.
Re[2]: Удаление строк из RichEdit VCL.
От:
Аноним
Дата:
28.08.09 14:48
Оценка:
Здравствуйте, NMDSOFT, Вы писали:
NMD>Здравствуйте, Basil NMD>извените а зачем использовать richedit для простого терминала если можно использовать Memo? или терминал не так прост как мне кажется
Memo тоже хранит данные в TString. Так что проблема удаления лишних строк остается.
Basil
Re[2]: Удаление строк из RichEdit VCL.
От:
Аноним
Дата:
28.08.09 15:01
Оценка:
Здравствуйте, Dimonka, Вы писали:
D>Здравствуйте, Аноним, Вы писали:
А>>3. Может есть какие-то другие компоненты для организации терминала.
D>Если терминал — это список строк в StringList, то можно сделать его и на ScrollBox-е. Единственное, что будет чуть сложнее сделать — это выделение и копирование текста. Зато всё остальное не будет дёргаться и будет реагировать со скоростью света.
Насколько я понял ScrollBox это компонент для хранения-отображения других компонентов, а не массива строк. Он не поддерживает работу с текстом и у него нет инструментов для работы с текстом, таких какие есть в RichEdit (добавить строку, убрать строку, цвет строки, загрузка-выгрузка из-в файл и т.д.).
Здравствуйте, Аноним, Вы писали:
А>>>3. Может есть какие-то другие компоненты для организации терминала.
D>>Если терминал — это список строк в StringList, то можно сделать его и на ScrollBox-е. Единственное, что будет чуть сложнее сделать — это выделение и копирование текста. Зато всё остальное не будет дёргаться и будет реагировать со скоростью света.
А>Насколько я понял ScrollBox это компонент для хранения-отображения других компонентов, а не массива строк. Он не поддерживает работу с текстом и у него нет инструментов для работы с текстом, таких какие есть в RichEdit (добавить строку, убрать строку, цвет строки, загрузка-выгрузка из-в файл и т.д.).
А ты разделяй понятие "компонент со свойством списком строк" и просто список строк. Текст можно отображать вообще везде, где есть доступ к канве.
Я бы сделал следующим образом:
1) Завел бы себе наследника от TStringList с дополнительным свойством CountLineLimit:integer, где бы хранил, сколько максимально строк мне нужно для отображения.
2) Завел бы свойство TNotifyEvent вроде OnLineAdded()
3) Перекрыл бы у него метод Add() примерно так:
Function TTerminalLines.Add(const S: String):integer;
begin
if Count+1>FCountLineLimit then Delete(0);
Result:=inherited Add(S);
if Assigned(FOnLineAdded) then FOnLineAdded(Self);
end;
4) По приходу эвента передергивал бы отображаемые данные
Procedure TForm1.OnLineAdded(Sender:TObject);
begin
Memo1.Lines.Text:=MyTerminalStrings.Text;
end;
Решение конечно на универсальность не претендует, но вполне сгодится, чтобы собрать терминал на коленке.
P.S. Если нужна раскраска линий — я бы взял не TMemo, а SynEdit, но это уже дело вкуса.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[4]: Удаление строк из RichEdit VCL.
От:
Аноним
Дата:
28.08.09 17:37
Оценка:
Здравствуйте, DarkMaster, Вы писали:
DM>Здравствуйте, Аноним, Вы писали:
А>>>>3. Может есть какие-то другие компоненты для организации терминала.
D>>>Если терминал — это список строк в StringList, то можно сделать его и на ScrollBox-е. Единственное, что будет чуть сложнее сделать — это выделение и копирование текста. Зато всё остальное не будет дёргаться и будет реагировать со скоростью света.
А>>Насколько я понял ScrollBox это компонент для хранения-отображения других компонентов, а не массива строк. Он не поддерживает работу с текстом и у него нет инструментов для работы с текстом, таких какие есть в RichEdit (добавить строку, убрать строку, цвет строки, загрузка-выгрузка из-в файл и т.д.).
DM>А ты разделяй понятие "компонент со свойством списком строк" и просто список строк. Текст можно отображать вообще везде, где есть доступ к канве.
DM>Я бы сделал следующим образом: DM> 1) Завел бы себе наследника от TStringList с дополнительным свойством CountLineLimit:integer, где бы хранил, сколько максимально строк мне нужно для отображения. DM> 2) Завел бы свойство TNotifyEvent вроде OnLineAdded() DM> 3) Перекрыл бы у него метод Add() примерно так: DM>
DM> Function TTerminalLines.Add(const S: String):integer;
DM> begin
DM> if Count+1>FCountLineLimit then Delete(0);
DM> Result:=inherited Add(S);
DM> if Assigned(FOnLineAdded) then FOnLineAdded(Self);
DM> end;
DM>
DM> 4) По приходу эвента передергивал бы отображаемые данные DM>
DM> Procedure TForm1.OnLineAdded(Sender:TObject);
DM> begin
DM> Memo1.Lines.Text:=MyTerminalStrings.Text;
DM> end;
DM>
DM>Решение конечно на универсальность не претендует, но вполне сгодится, чтобы собрать терминал на коленке.
DM>P.S. Если нужна раскраска линий — я бы взял не TMemo, а SynEdit, но это уже дело вкуса.
И что же, каждый раз переписывать 25тыщ строк из внутреннего компонента TStringList в Мемо?
Здравствуйте, Аноним, Вы писали:
А>И что же, каждый раз переписывать 25тыщ строк из внутреннего компонента TStringList в Мемо?
Все зависит от ограничений. Если надо 25 тыщ — пиши (фигасе терминальчик ага?). Хотя обычно достаточно где-то в районе 30-40 строк. Ставим себе лимит в 25 строк и у тебя в списке будет всегда 25 строк.
WBR, Dmitry Beloshistov AKA [-=BDS=-]
Re[6]: Удаление строк из RichEdit VCL.
От:
Аноним
Дата:
29.08.09 18:23
Оценка:
Здравствуйте, DarkMaster, Вы писали:
DM>Здравствуйте, Аноним, Вы писали:
А>>И что же, каждый раз переписывать 25тыщ строк из внутреннего компонента TStringList в Мемо?
DM>Все зависит от ограничений. Если надо 25 тыщ — пиши (фигасе терминальчик ага?). Хотя обычно достаточно где-то в районе 30-40 строк. Ставим себе лимит в 25 строк и у тебя в списке будет всегда 25 строк.
В том то и дело, что нужно именно 25 тыщ строк. Этот терминал работает целый день и в него постоянно идет вывод. Набирается много. Вобщем десятки тысяч строк и набирается. И периодически надо отмотать историю и разбираться, что там произошло в этом протоколе. Ну вобщем пока что я сделал выгрузку содержимого в файл после 25 тыщ строк и очистку буфера RichEdit-a. Очистка оказалось довольно быстрой операцией.
Здравствуйте, Аноним, Вы писали:
DM>>Все зависит от ограничений. Если надо 25 тыщ — пиши (фигасе терминальчик ага?). Хотя обычно достаточно где-то в районе 30-40 строк. Ставим себе лимит в 25 строк и у тебя в списке будет всегда 25 строк.
А>В том то и дело, что нужно именно 25 тыщ строк. Этот терминал работает целый день и в него постоянно идет вывод. Набирается много. Вобщем десятки тысяч строк и набирается. И периодически надо отмотать историю и разбираться, что там произошло в этом протоколе. Ну вобщем пока что я сделал выгрузку содержимого в файл после 25 тыщ строк и очистку буфера RichEdit-a. Очистка оказалось довольно быстрой операцией.
Не, ну разделите же RichEdit (или любой другой компонент для отображения) и лог операций. То, что ты отображаешь в окне терминала — суть кусок лога. 20-30-50 строк должно хватать. Все остальное (полный лог) — хоть в файл записывай для дальнейшего (периодического разбора полетов).
Здравствуйте, Аноним, Вы писали:
D>>Если терминал — это список строк в StringList, то можно сделать его и на ScrollBox-е. Единственное, что будет чуть сложнее сделать — это выделение и копирование текста. Зато всё остальное не будет дёргаться и будет реагировать со скоростью света.
А>Насколько я понял ScrollBox это компонент для хранения-отображения других компонентов, а не массива строк. Он не поддерживает работу с текстом и у него нет инструментов для работы с текстом, таких какие есть в RichEdit (добавить строку, убрать строку, цвет строки, загрузка-выгрузка из-в файл и т.д.).
Ты не мешай в кучу данные и их отображение и тогда вё станет гораздо яснее. Данные — это набор строк, могут быть StringList-ом или чем-то другим, более продвинутым, а отображать эти данные тоже можно по-разному. Например, RichEdit-ом, как сделал ты, а можно и ScrollBox-ом, добавив несколько строк для отрисовки текста и несколько строк для выделения и копирования.
Можно так же в RichEdit показывать не весь лог, а нужную его часть и сделать свой скроллбар. Так он будет реагировать чуть быстрее, но в целом это тормознутый компонент.