Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Медленная работа TJvRichEdit при PlainText:=true [WinXP]


SergejM ©   (2009-06-01 14:58:00) 

Здравствуйте.
Возможно, у меня ошибка в 17 строке, но пока я ее не нашел.
Проблема возникает при переключении свойства PlainText в TJvRichEdit. Это переключение занимает неоправданно большое время. Проблема проявилась в реальном проекте, но отлично воспроизводится и в тестовом.
Тестовый проект выглядит так: на форме TRichEdit, TJvRichEdit и кнопка. Код кнопки:
procedure TMainForm.btnStartClick(Sender: TObject);
var
 cntMilliseconds: Cardinal;
 logList:TStringList;
 i: Integer;
begin
 logList := TStringList.Create;
 try
   Application.Minimize;
   wndJVEditor.Lines.BeginUpdate;
   wndEditor.Lines.BeginUpdate;
   logList.Add('Работа с jvRichEdit');
   cntMilliseconds:=GetTickCount;
   wndJVEditor.Lines.LoadFromFile('src.txt');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Загрузка txt (Plain text:=true). Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndJVEditor.PlainText:=false;
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Переключение PlainText := false. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndJVEditor.Lines.SaveToFile('testjv.rtf');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Сохранение rtf. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndJVEditor.PlainText:=true;
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Переключение PlainText := true. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndJVEditor.Lines.SaveToFile('testjv.txt');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Сохранение txt. Затрачено %d мс',[cntMilliseconds]));
   logList.Add('Работа с RichEdit');
   cntMilliseconds:=GetTickCount;
   wndEditor.Lines.LoadFromFile('src.txt');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Загрузка txt (Plain text:=true). Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndEditor.PlainText:=false;
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Переключение PlainText := false. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndEditor.Lines.SaveToFile('test.rtf');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Сохранение rtf. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndEditor.PlainText:=true;
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Переключение PlainText := true. Затрачено %d мс',[cntMilliseconds]));
   cntMilliseconds:=GetTickCount;
   wndEditor.Lines.SaveToFile('test.txt');
   cntMilliseconds:=GetTickCount-cntMilliseconds;
   logList.Add(Format('Сохранение txt. Затрачено %d мс',[cntMilliseconds]));
   wndJVEditor.Lines.EndUpdate;
   wndEditor.Lines.EndUpdate;
 finally
   logList.SaveToFile('result.txt');
   logList.Free;
   FlashWindow(Application.Handle,true);
   ShowMessage('Работа окончена');
 end;
end;

А вот результат работы программы:
Работа с jvRichEdit
Загрузка txt (Plain text:=true). Затрачено 364671 мс
Переключение PlainText := false. Затрачено 21282 мс
Сохранение rtf. Затрачено 359 мс
Переключение PlainText := true. Затрачено 495547 мс
Сохранение txt. Затрачено 16 мс
Работа с RichEdit
Загрузка txt (Plain text:=true). Затрачено 125 мс
Переключение PlainText := false. Затрачено 0 мс
Сохранение rtf. Затрачено 250 мс
Переключение PlainText := true. Затрачено 0 мс
Сохранение txt. Затрачено 15 мс

Хотелось бы не тратить столько времени на преобразование текста. Пока я вижу один обходной путь — создавать временный StringList, загружать в него текст и уже оттуда сохранять в текстовом формате, а св-во PlainText не изменять. Но, возможно, есть и другой вариант?


SergejM   (2009-06-01 17:07:00) [1]

Да, загрузка через EM_STREAMIN. Как я вижу (возможно, что-то и просмотрел), все, что делается — это определение, в каком формате будет загружен текст.


clickmaker   (2009-06-01 16:53:00) [2]

> Загрузка и там, и там осуществляется методами TStrings

а в JV ничего попутно не делается с текстом? Загрузка там через EM_STREAMIN?


SergejM   (2009-06-01 16:29:00) [3]

Вот не вижу, что может приводить к такой разнице. Загрузка и там, и там осуществляется методами TStrings. Есть различие в установке самого флага PlainText —в VCL используется простое присвоение полученного значения в наследнике от TStrings, в JVCL присвоение выполняется посылкой сообщения EM_SETEXTMODE, с сохранением содержимого, его очисткой и последующим восстановлением. Но опять-таки не вижу, где тут может возникнуть такая задержка.
В качестве вишенки на торте — при работе с большими текстами в режиме простого текста этот самый текст портится. Т.е, в тестовой программе использовался файл, состоящий из 20 тысяч раз повторенной фразы. После сохранения, если файл грузился в режиме обычного текста, части файла оказываются испорченными. В rtf-файле посреди текста возникают иероглифы (и при просмотре структуры файла видно, что группы символов записаны не в ANSI, а в юникоде), а в txt, соответственно, непечатаемые символы. Причем этот сбой портит текст с некоторой периодичностью — скажем, каждый четвертый абзац.
В общем, пока другого способа, как через временный stringlist, грузить и сохранять обычный текст в JvRichEdit, я не вижу. Но какой тогда толк от наличия свойства PlainText?..


clickmaker   (2009-06-01 15:25:00) [4]

> Работа с jvRichEdit
> Загрузка txt (Plain text:=true).

а сравнением исходников jv и vcl не удастся выяснить?


Наверх

Титульная страница Поиск, карта сайта Написать письмо