![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Часто встречается вопросы про добавление форматированной строки в Richedit. Ответ есть, через управление SelAttributes, но сам код при этом становится не очень наглядным. Есть компонент, но он платный. Когда мне тоже понадобилось, покорпел, наскреб процедуру, которая решает задачу, хоть и не полностью. Короче вот:
Код:
uses StrUtils; Код:
var Form1: TForm1; RichEdit_text : string; Вот процедура Код:
procedure RichEdit_add_text; // процедура RichEdit_add_text добавляет текстовую строку RichEdit_text с тегами в RichEdit1 function HtmlColorToTColor(Color: string):TColor ; const DelphiColorConst = 'clblack, clmaroon, clgreen, clolive, clnavy, clpurple, clteal, clgray, clsilver, clred, cllime, clyellow, clblue, clfuchsia, claqua, clwhite'; var rColor: TColor; begin try if ansipos(AnsiLowerCase(Color),DelphiColorConst)>0 then begin result := StringToColor('CL' + Color); exit; end; delete(Color,1,1); if (length(color) >= 6) then begin {незабудьте, что TColor это bgr, а не rgb: поэтому необходимо изменить порядок} color := '$00' + copy(color,5,2) + copy(color,3,2) + copy(color,1,2); rColor := StrToInt(color); end; result := rColor; except result := $000000; end; end; function before_tag_symbol_delete(sssr:string; n:integer):string; var k : integer; res : string; begin k:=0; res:=''; while k<n do begin inc(k); if sssr[k] = '<' then while sssr[k] <> '>' do begin inc(k); end; if sssr[k] = '>' then continue; res:=res + sssr[k]; end; before_tag_symbol_delete:=res + copy(sssr,n, length(sssr)- n + 1); end; var st, zvet, sssr, raspad_sssr, rf : string; raspad_count, k, mm, k_beg, k_end, k_end_color, globbegin, tag_color, tag_bf, tag_italic, tag_, Line : integer; color : Tcolor; pole_zvetov : string; arbeiten: integer; begin sssr := RichEdit_text; st:=''; k:=1; while k<=length(sssr) do begin if sssr[k]<>'<' then begin st:=st+sssr[k]; end else while sssr[k]<>'>' do inc(k); inc(k); end; Line:= Form1.Richedit1.Lines.Count; st:= StringReplace(st, '<', '<', [rfReplaceAll, rfIgnoreCase]); st:= StringReplace(st, '>', '>', [rfReplaceAll, rfIgnoreCase]); Form1.Richedit1.Lines.Add(st); sssr:= StringReplace(RichEdit_text, '<', '!', [rfReplaceAll, rfIgnoreCase]); sssr:= StringReplace(sssr, '>', '!', [rfReplaceAll, rfIgnoreCase]); sssr:= StringReplace(sssr, '< ', '<', [rfReplaceAll, rfIgnoreCase]); sssr:= StringReplace(sssr, ' >', '>', [rfReplaceAll, rfIgnoreCase]); globbegin:= SendMessage(Form1.RichEdit1.Handle, EM_LINEINDEX, Line, 0); raspad_sssr:=sssr; arbeiten:=0; tag_:= ansipos('</', raspad_sssr); // ищем ближайший закрывающий тег if tag_>0 then if raspad_sssr[tag_+ 2] = 'f' then arbeiten:=1 // </font> else if raspad_sssr[tag_+ 2] = 'b' then arbeiten:=2 // </b> else if raspad_sssr[tag_+ 2] = 'i' then arbeiten:=3; // </i> while arbeiten >0 do begin case arbeiten of 1: BEGIN k_end_color:=ansipos('<font color=',raspad_sssr); rf:= before_tag_symbol_delete(raspad_sssr, k_end_color); k_beg:=ansipos('<font color=',rf); mm:=posex('>',rf, k_beg); k_end_color:=ansipos('</font>',rf); zvet:='CL' + copy(rf, k_beg+7+5, mm-k_beg-7-5); zvet:=copy(rf, k_beg+7+5, mm-k_beg-7-5); k_end:=k_end_color-(mm-k_beg)-2; Form1.Richedit1.SelStart := globbegin + k_beg - 1; Form1.Richedit1.SelLength:= k_end-k_beg+1; Form1.Richedit1.SelAttributes.Color := HtmlColorToTColor(zvet); k_beg:=ansipos('<font color=',raspad_sssr); mm:=posex('>',raspad_sssr, k_beg); k_end_color:=ansipos('</font>',raspad_sssr); k_end:=k_end_color-(mm-k_beg)-2; delete(raspad_sssr, k_end_color, 7); delete(raspad_sssr, k_beg, length(zvet)+13); END; 2: BEGIN k_end_color:=ansipos('<b>',raspad_sssr); rf:= before_tag_symbol_delete(raspad_sssr, k_end_color); k_beg:=ansipos('<b>',rf); mm:=posex('>',rf, k_beg); k_end_color:=ansipos('</b>',rf); k_end:=k_end_color-(mm-k_beg)-2; Form1.Richedit1.SelStart := globbegin + k_beg - 1; Form1.Richedit1.SelLength:= k_end-k_beg+1; Form1.RichEdit1.SelAttributes.Style :=Form1.RichEdit1.SelAttributes.Style + [fsBold]; k_beg:=ansipos('<b>',raspad_sssr); mm:=posex('>',raspad_sssr, k_beg); k_end_color:=ansipos('</b>',raspad_sssr); k_end:=k_end_color-(mm-k_beg)-2; delete(raspad_sssr, k_end_color, 4); delete(raspad_sssr, k_beg, 3); END; 3: BEGIN k_end_color:=ansipos('<i>',raspad_sssr); rf:= before_tag_symbol_delete(raspad_sssr, k_end_color); k_beg:=ansipos('<i>',rf); mm:=posex('>',rf, k_beg); k_end_color:=ansipos('</i>',rf); k_end:=k_end_color-(mm-k_beg)-2; Form1.Richedit1.SelStart := globbegin + k_beg - 1; Form1.Richedit1.SelLength:= k_end-k_beg+1; Form1.RichEdit1.SelAttributes.Style :=Form1.RichEdit1.SelAttributes.Style + [fsItalic]; k_beg:=ansipos('<i>',raspad_sssr); mm:=posex('>',raspad_sssr, k_beg); k_end_color:=ansipos('</i>',raspad_sssr); k_end:=k_end_color-(mm-k_beg)-2; delete(raspad_sssr, k_end_color, 4); delete(raspad_sssr, k_beg, 3); END; end; arbeiten:=0; tag_:= ansipos('</', raspad_sssr); // ищем ближайший закрывающий тег if tag_>0 then if raspad_sssr[tag_+ 2] = 'f' then arbeiten:=1 // </font> else if raspad_sssr[tag_+ 2] = 'b' then arbeiten:=2 // </b> else if raspad_sssr[tag_+ 2] = 'i' then arbeiten:=3; // </i> end; end; Код:
procedure TForm1.Button1Click(Sender: TObject); begin RichEdit_text:= 'Обычный текст'; RichEdit_add_text; RichEdit_text:= 'Текст с<font color=red><b><i>жирным, курсивным и красным</i></b></font>словом'; RichEdit_add_text; RichEdit_text:= 'Текст с<i><b><font color=#ffd700>золотистым, курсивным и жирным</font></b></i>словом'; RichEdit_add_text; RichEdit_text:= 'Текст с<font color=#4B0082><i>курсивным и цвета индиго</i></font>словом'; RichEdit_add_text; RichEdit_text:= 'Текст с<b><font color=Fuchsia>бирюзовым и жирным</font></b>словом'; RichEdit_add_text; RichEdit_text:= 'Доказать, что <font color=blue><b><i>c>d</i></b></font> Задать...'; RichEdit_add_text; RichEdit_text:= 'Доказать, что <font color=#4B0082><b><i>a<b</i></b></font> Найти...'; RichEdit_add_text; RichEdit_text:= 'Все вместе<i>курсивом</i>потом<b>жирным</b>потом<font color=green>зеленым</font>снова<b>жирным</b>опять<i>курсивом</i>еще<font color=red>красным</font>и обычным'; RichEdit_add_text; RichEdit_text:= 'Опять обычный текст'; RichEdit_add_text; end; Есть плюсик - при сохранении отображаемого текста в html. Буду рад отзывам... Вложенность тегов реализована. Добавлена поддержка html цветов. Разрешено указывать имена системных цветов в Delphi без приставки CL Понятно, что нужно строго следить за вложенностью тегов, иначе результат непредсказуем. Знаки '<', '>' писать через соответствующие html-теги. Последний раз редактировалось alexan0308, 29.07.2013 в 21:46. Причина: Добавил случай вложенности тегов |
#2
|
|||
|
|||
![]() Что значит:
Цитата:
Если надо добавить строку, то я делаю так: Код:
RichEdit1.Lines.Add('Это наш текст'); RichEdit1.SelAttributes.Color:=clRead; RichEdit1.SelText('Это наш текст'); RichEdit1.Lines.Delete(1); RichEdit1.Lines.Add(''); Не знаю как другие свойства - не пробовал, но думаю так-же... Все смелые до begin... Последний раз редактировалось DrGeorg, 02.05.2013 в 04:36. |
#3
|
|||
|
|||
![]() [OFF]admin, на панели инструментов нету кнопки для кода Delphi. [/OFF]
|
#4
|
|||
|
|||
![]() Цитата:
Код:
procedure TForm1.BitBtn1Click(Sender: TObject); begin RichEdit1.SelAttributes.Color:=clRed; RichEdit1.SelText:='Это красный текст'; RichEdit1.SelAttributes.Color:=clblack; Richedit1.SelAttributes.Style:=[fsBold]; RichEdit1.SelText:='Это жирный текст'; Richedit1.SelAttributes.Style:=Richedit1.SelAttributes.Style - [fsBold]; RichEdit1.SelAttributes.Style:=[fsItalic]; RichEdit1.SelText:='Это наклонный текст'; Richedit1.SelAttributes.Style:=Richedit1.SelAttributes.Style - [fsItalic]; RichEdit1.Lines.Add(''); end; Код:
procedure TForm1.BitBtn2Click(Sender: TObject); begin RichEdit_text:= '<font color=red>Это красный текст</font>' + '<b>Это жирный текст</b>' + '<i>Это наклонный текст</i>'; RichEdit_add_text; end; Последний раз редактировалось alexan0308, 02.05.2013 в 09:50. |
#5
|
||||
|
||||
![]() к чему этот огород в 1-ом сообщении? чем традиционный способ не угодил? и какая проблема с потоками? все-равно в Synchronize добавлять.
Пишу программы за еду. __________________ |
#6
|
|||
|
|||
![]() Цитата:
|
#7
|
||||
|
||||
![]() Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ComCtrls; type TRichEditThread = class(TThread) private FRichEdit: TRichEdit; FNum: Integer; FColor: TColor; procedure AddToRichEdit; protected procedure Execute; override; public constructor Create(ARichEdit: TRichEdit; ANum: Integer; AColor: TColor); end; TForm1 = class(TForm) RichEdit1: TRichEdit; procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TRichEditThread } procedure TRichEditThread.AddToRichEdit; begin FRichEdit.SelAttributes.Color:=FColor; FRichEdit.SelText:=' TRichEditThread = '+IntToStr(FNum)+' '; end; constructor TRichEditThread.Create(ARichEdit: TRichEdit; ANum: Integer; AColor: TColor); begin inherited Create(True); FreeOnTerminate:=True; FRichEdit:=ARichEdit; FNum:=ANum; FColor:=AColor; Resume; end; procedure TRichEditThread.Execute; begin while True do begin Sleep(100+Random(400)); Synchronize(AddToRichEdit); end; end; procedure TForm1.FormCreate(Sender: TObject); begin TRichEditThread.Create(RichEdit1, 1, clRed); TRichEditThread.Create(RichEdit1, 2, clGreen); TRichEditThread.Create(RichEdit1, 3, clBlue); TRichEditThread.Create(RichEdit1, 4, clYellow); TRichEditThread.Create(RichEdit1, 5, clLime); TRichEditThread.Create(RichEdit1, 6, clFuchsia); end; end. Пишу программы за еду. __________________ |
#8
|
|||
|
|||
![]() Это все хорошо, когда добавляется однородный текст. А если нужно добавлять в потоке разные строки? Например:
... 1. проверка орфографии Ошибка в слове теливизор. Правильно - телевизор 2. проверка пунктуации После между прочим должна стоять запятая! ... |
#9
|
||||
|
||||
![]() и в чем проблема? надо - добавляй разнородный.
Пишу программы за еду. __________________ |
#10
|
|||
|
|||
![]() Цитата:
|
#11
|
||||
|
||||
![]() ну не зашкаливает же:
Код:
procedure TRichEditThread.AddText(Text: String; Color: TColor = clBlack; Style: TFontStyles = []); begin FRichEdit.SelAttributes.Color:=Color; FRichEdit.SelAttributes.Style:=Style; FRichEdit.SelText:=Text; end; procedure TRichEditThread.AddToRichEdit; begin AddText(' TRichEditThread = '+IntToStr(FNum)+' ', FColor, []); AddText('procedure ', clBlue, [fsBold]); AddText('TRichEditThread.AddToRichEdit ', clLime, []); AddText('begin'#13#10, clBlack); AddText('end'); end; http://www.delphisources.ru/forum/sh...ad.php?t=18236 http://www.delphisources.ru/forum/sh...ad.php?t=18196 Пишу программы за еду. __________________ |
#12
|
|||
|
|||
![]() Цитата:
Цитата:
|
#13
|
||||
|
||||
![]() твой пример на много проще просто грузить из .rtf файла или ресурса. когда же требуется добавлять динамический текст, как например в CodeShow и Spamka, городить строки с тэгами нет смысла.
Пишу программы за еду. __________________ |
#14
|
|||
|
|||
![]() Текст у меня динамический. Выполняется более десятка разных по смыслу действий, по проверке документов.
... 1. проверка орфографии // обработка Ошибка в слове теливизор. Правильно - телевизор 2. проверка пунктуации // обработка После между прочим должна стоять запятая! 3. проверка полей // обработка Левое поле 30 мм - в норме. Правое поле 15 мм - должно быть 10 мм. 4. проверка стиля шрифта // обработка Запрещено использовать курсив: Это явление называется интерференцией. Жирным выделять только заголовки: Это явление называется дифракцией. ... Без тегов я утону в коде. Последний раз редактировалось alexan0308, 02.05.2013 в 15:16. |
#15
|
||||
|
||||
![]() тогда нужно полностью менять подход к задаче.
Пишу программы за еду. __________________ |