Текущий архив: 2005.07.25;
Скачать: CL | DM;
Вниз
string to string Найти похожие ветки
← →
maxim______m (2005-07-06 15:37) [0]привет, народ!
я почти написал преобразование из richEdita
в html. Но написал с помощью string
что вызывает ужасные тормоза.
т.е. я делаю пробеги по richEdit
и всё время наращиваю строку
htmlStr := htmlStr + str1r;
в хелпе нашёл strcat, но она работает в pchar
что ж мне теперб всё на пчар переводить?
А зачем тогда стринг вообще?
← →
Virgo_Style © (2005-07-06 15:48) [1]Кажется, была статья на эту тему.
К сожалению, string плохо приспособлен к постоянному добавлению символов к ней. Кстати, я совсем не уверен, что использование pchar исправит ситуацию.
Сделай строке один раз SetLength и затем ее заполняй, обращаясь к символам (htmlStr[i]). Или делай SetLength время от времени с каким-то запасом.
← →
Erik1 © (2005-07-06 15:52) [2]Ну положим без головы любая технология боком выдет. Ты предстовляеш себе, что происходит при htmlStr := htmlStr + str1r? А происхоит перераспределение памяти, это очень медленая операция! Вот если бы ты зарение выделил памать(Setlength(htmlStr), Size) то проблем бы небыло. А записывать в такую строку нужно через указатель(Move(PChar(str1)^, PHtml^, Length(str1))) незабывая PHtml сдвигать.
Так что строки в Delphi очень удобная и нужная вещь.
← →
TUser © (2005-07-06 16:17) [3]Вообще, правильнее было бы не строку наращивать, а помнить позицию начала существующего стиля выделения. Примерно так
function GetStyle (RE: TRichEdit; Pos: integer): TFontStyles;
begin
RE.SelStart:=Pos-1;
RE.SelLength:=1;
result:=RE.SelAttributes.Style;
end;
function Descript (Style: TFontStyles; Open: boolean): string;
procedure Put (C: char);
begin
if Open then
result:=result+"<"+C+">"
else
result:=result+"</"+C+">";
end;
begin
result:="";
if fsBold in Style then Put("B");
if fsItalic in Style then Put("I");
if fsUnderline in Style then Put("U");
end;
procedure RichToHTML (RE: TRichEdit; SL: TStrings);
var s, e: integer;
style, temp: TFontStyles;
len: integer;
begin
SL.Clear;
len:=length(RE.Text);
if len = 0 then Exit;
s:=1; style:=GetStyle(RE,1);
e:=2;
while e <= len do begin
temp:=GetStyle(RE,e);
if temp <> style then begin
SL.Add(Descript(style,true)+
StringReplace(copy(RE.Text,s,e-s),#13#10,"<br>",[rfReplaceAll])+
Descript(style,false));
s:=e; style:=temp;
end;
inc (e);
end;
SL.Add(Descript(style,true)+
StringReplace(copy(RE.Text,s,e-s),#13#10,"<br>",[rfReplaceAll])+
Descript(style,false));
end;
procedure TForm1.Button1Click(Sender: TObject);
var SL: TStringList;
begin
SL:=TStringList.Create;
RichEdit1.Lines.BeginUpdate;
try
RichToHTML(RichEdit1,SL);
WebBrowser1.Navigate("about:"+SL.Text);
finally
SL.Free;
RichEdit1.Lines.EndUpdate;
end;
end;
procedure Incl (S: TFontStyle);
begin
with Form1.RichEdit1.SelAttributes do
Style:=Style+[S];
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Incl(fsBold);
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
Incl(fsItalic);
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
Incl(fsUnderline);
end;
← →
maxim______m (2005-07-06 19:10) [4]я к сожалению уже написал большую программу, которая основана на добавлении к строке. помню что кто-то писал о том как можно быстро это делать, но не помню как именно.
← →
Андрей © (2005-07-06 19:13) [5]
> maxim______m
> ...
> и всё время наращиваю строку
> htmlStr := htmlStr + str1r;
А как насчет того, чтобы собирать не в стоку, а в TStringList ?
Когда все собрано, выводить циклом
Твой вариант легко дорабатывается до этого
← →
maxim______m (2005-07-06 19:52) [6]to Андрей © (06.07.05 19:13) [5]
как Вам такое?
<
h
t
m
l
>
<
h
e
a
d
>
<
m
e
t
a
h
t
t
p
-
e
q
u
i
v
=
"
c
o
n
t
e
n
t
-
t
y
p
e
"
c
o
n
t
e
n
t
=
"
t
e
x
t
/
h
t
m
l
;
c
h
a
r
s
e
t
=
w
i
n
d
o
w
s
-
1
2
5
1
"
>
<
m
e
t
a
h
t
t
p
-
e
q
u
i
v
=
"
c
o
n
t
e
n
t
-
l
a
n
g
u
a
g
e
"
c
o
n
t
e
n
t
=
"
r
u
-
r
u
"
>
<
m
e
t
a
n
a
m
e
=
"
d
e
s
c
r
i
p
t
i
o
n
"
c
o
n
t
e
n
t
=
"
или выковыривать переводы строк оттуда?
← →
Virgo_Style © (2005-07-06 19:56) [7]Цикл
Если текущая позиция больше длины строки,
то увеличить длину строки на 100 (1000, 10000 - по вкусу)
Записать в текущую позицию символ
Сместить дальше текущую позицию
Обрезать строку до "текущая позиция".
Ничего сложного...
← →
vertal © (2005-07-06 21:09) [8]Для постепенного наращивания строки можно использовать например такую процедуру. Что быстрее - эта процедура или TStringList, навскидку сказать затрудняюсь.
procedure dStrCat(var str1: string; const str2: string; var str1_len: Integer);
const
InitialStrLen: Integer = 255;
var
NewStr1_Len: Integer;
begin
NewStr1_Len := str1_len + Length(str2);
while Length(str1) < NewStr1_Len do
if Length(str1) <> 0 then
SetLength(str1, Length(str1) shl 1)
else
SetLength(str1, InitialStrLen);
Move(PChar(str2)^, PChar(PChar(str1) + str1_len)^, NewStr1_Len - str1_len);
str1_len := NewStr1_Len;
end;
И неплохо еще не забывать заменять символы &>< на < > и т.д., то есть я бы в варианте [3] вместо
StringReplace(copy(RE.Text,s,e-s),#13#10,"
",[rfReplaceAll])
поставил бы собственную функцию, которая бы имела массив типа const
Escape: array[Char] of string = ...
, Escape[c] = c , но Escape[">"] = ">" и т.д., и на выходе каждый входной символ заменяет на соотв. строку из массива.
← →
vertal © (2005-07-06 21:12) [9]В предыдущем сообщении следует читать:
заменять символы &>< на & > <
но Escape[">"] = ">"
← →
vertal © (2005-07-06 21:13) [10]Не удается добиться отображения амперсанда, но в общем вы поняли
← →
ferr © (2005-07-06 21:17) [11]в свете
> я к сожалению уже написал большую программу, которая
> основана на добавлении к строке.
может написать класс строки с методом добавления обычной строки. Класс должен будет изменять длину строки, также как и TList (25%).
Страницы: 1 вся ветка
Текущий архив: 2005.07.25;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.011 c