![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Медленная работа 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 не удастся выяснить?