Як визначити висоту тексту в RichEdit? Якщо текст набраний
різними шрифтами та розмірами, то не дуже зрозуміло. Підкажіть, га? Потрібно, щоб можна було підігнати розміри самого RichEdit а під розміри тексту в ньому.
←→Song (2002-10-12 11:26) [1]
←→Кен (2002-10-16 01:25) [2]
2 Song А як це повністю написати ? Висота Тексту: = RichEdit1. (що тут?). Canvas.TextHeight();
Я пробував, але чогось нічого не виходить. Проблема у різних розмірах шрифтів. Одна літера велика, інша маленька, як порахувати загальну висоту тексту ? Адже як вона вважається, для лінійки прокрутки, наприклад. Але як ?
←→MBo (2002-10-16 06:38) [3]
var p: Tpoint; begin Richedit1.Perform(em_posfromchar,Integer(@p),Length(Richedit1.Text)); caption:=inttostr(p.x)+" "+inttostr(p.y); Це верхня точка останнього символу, так що до p.y треба ще додати висоту останнього рядка, обчислену вказаним Song способом
←→Кен (2002-10-20 1:13) [4]
Далі стискаю кнопку і розмір вікна підрівнюється до передостаннього рядка. Разом із ним з'являється ще лінійка прокручування. Так ось варто цю лінійку трохи посунути і зробити перерахунок розмірів вікна, як результат виходить інший. І так щоразу рухаючи лінійку результати отримуємо щоразу різні. Як це обезглючити?
Про останній рядок я чесно сказати не дуже зрозумів. Як застосувати .Canvas.TextHeight(); ? Який початок у цього коду?
←→Кен (2002-10-23 3:39) [5]
Як би вирішити проблему?
←→Separator (2002-10-23 08:17) [6]
←→Кен (2002-10-30 3:05) [7]
Так як же точно визначити висоту тексту в RichEdit ? Невже це таканерозв'язна проблема?
←→Nick N A (2002-10-30 05:31) [8]
У нього можна визначити висоту буквально, або рядково, спробуйте:
Єдиний спосіб отримати властивості тексту - виділити його за допомогою SelStart, і SelLength=1, потім SelAttributes містить у собі докладну інфо про виділеному фрагменті тексту, сумніваюся, що якщо виділено більше однієї літери - він правильно видасть інфо. RichEdit1.SelAttributes.Height-висота. SelText-виділений текст Можливо достатньо виміряти висоту кожного рядка тексту.
←→Кен (2002-11-01 07:41) [9]
2 Nick N AЯ загалом зробив підрахунок висоти кожної літери в рядку і обчислення таким чином загальної висоти рядків за найвищою літерою в них. Але результат не точний. Обчислюється лише висота шрифту, а висота проміжку між рядками не враховується. Як її визначити?
Спочатку спробував прийняти, що вона дорівнює двом, але погравшись виявилося, що чим більше висотра шрифту, тим більше проміжок між рядками. Причому імперічно обчислити не виходить.
Як же бути ? Як обчислити висоту проміжку між рядками?
←→MBo (2002-11-01 07:47) [10]
←→Кен (2002-11-01 08:01) [11]
2 MBo А які метрики? Адже шрифт щоразу різний. Як це робити ?
←→MBo (2002-11-01 08:02) [12]
знаходити шрифт найбільшого розміру в останньому рядку - саме по ньому розраховується відступ
←→Alx2 (2002-11-01 09:14) [13]
>Кен (01.11.02 8:01) Недовго думаючи, пропоную дещо хуліганське рішення за мотивами постів MBo: procedure TForm1.Button1Click(Sender: TObject); var p1, p2: tpoint; correct: integer; begin RichEdit.Lines.Add("!"); RichEdit.Lines.Add("!");
Richedit.Perform(em_posfromchar, Integer(@p1), Length(Richedit.Text)); Richedit.Perform(em_posfromchar, Integer(@p2), 0); if (RichEdit.ScrollBars = ssBoth) або (RichEdit.ScrollBars = ssHorizontal) then correct := GetSystemMetrics(SM_CXHSCROLL) else correct := 0; RichEdit.Height: = p1.Y - p2.y + correct; RichEdit.Selstart: = 1;
RichEdit.Lines.Delete(RichEdit.Lines.Count - 1); RichEdit.Lines.Delete(RichEdit.Lines.Count - 1);
←→Alex4444444444 (2002-11-01 10:03) [14]
Po moemu, u TRichEdit est" event, generiruyushijsya, kogda on hochet izmenit" свій razmer. Может, ego pojmat"? Ili posmotret", як on realizovan (eto ved "просто переехать какой-то message; вполне mozhet byt" і "двуственная" message). Не знайдено также, що це може бути" виявлено з ClientHeight.
←→MBo (2002-11-01 12:19) [15]
Є таке - EM_REQUESTRESIZE, воно має генерувати паренту WM_NOTIFY c EN_REQUESTRESIZE, проте при перевірці у мене EN_REQUESTRESIZE не приходило; ( SETEVENTMASK робив. Може, хтось копався?
←→MBo (2002-11-01 14:32) [16]
procedure TForm1.RichEdit1Change(Sender: TObject); var fr: TFormatRange; r: TRect; begin r:=rect(0,0,RichEdit1.Width*screen.Pixelsperinch, RichEdit1.Height*screen.Pixelsperinch); fr.hdc:=b.canvas.handle; fr.hdctarget:=b.canvas.handle; fr.rc:=r; fr.rcpage:=r; fr.chrg.cpMin:=0; fr.chrg.cpMax:=-1; Sendmessage(RichEdit1.handle,EM_FORMATRANGE,1,longint(@fr)); Richedit1.Height:=Trunc(screen.Pixelsperinch*fr.rc.bottom/1440)+8; Sendmessage(RichEdit1.handle,WM_VSCROLL,SB_TOP,0); end;
←→Кен (2002-11-07 01:19) [17]
2 Alx2Я схожим способом скористався. Додаю рядок, визначаю розмір та видаляю рядок.
procedure TForm1.Button1Click(Sender: TObject); var p:Tpoint; begin RxRichEdit1.Lines.Add("!"); Sendmessage(RxRichEdit1.Handle,WM_VSCROLL,SB_TOP,0); RxRichedit1.Perform(em_posfromchar,Integer(@p),Length(RxRichedit1.Text)); RxRichEdit1.Lines.Delete(RxRichEdit1.Lines.Count-1); RxRichedit1.Height := p.y; end;
Sendmessage тут потрібен, щоб провернути текст нагору, інакше визначення розмірів глючить. Але виникла інша проблема. Коли робиш спочатку RxRichEdit1.Lines.Add(""); а потім RxRichEdit1.Lines.Delete(RxRichEdit1.Lines.Count-1); то чомусь до тексту додається порожній рядок. І видалити її не виходить. Замість неї видаляється передостанній рядок. Як цього іди0тск0г0 глюка позбутися я так і не зрозумів.
MBoКоли намагаюся це зробити, то Дельфі лається на TFormatRange . Я розумію, що щось треба додати в Uses, щоб код заробив, але тільки що не знаю. Як взагалі в таких випадках можна дізнаватися, що додати в Uses? Чи немає якогось універсального списку всього, що можна туди додати?
←→Alex4444444444 ( 2002-11-07 01:29 ) [18]
> Чи немає якогось універсального списку всього, що можна > туди додати?
←→MBo (2002-11-07 13:16) [19]
←→Кен (2002-11-08 04:05) [20]
А як можна прибрати останній рядок в RichEdit якщо вона порожня? Чомусь у цьому випадку замість неї забирається передостання. А остання пуста так і залишається.
←→MBo (2002-11-08 07:47) [21]
b-змінна TBitmap, яка, природно, повинна бути вже створена, наприклад, в ONCreate форми
←→Кен (2002-11-09 2:10) [22]
2 MBOЗрозуміло. Ось так ось вийшло: procedure TForm1.Button1Click(Sender: TObject); Var fr : TFormatRange; r: TRect; b: TBitmap; begin b:=TBitmap.create; r:= rect(0, 0, RichEdit1.Width*screen.Pixelsperinch, RichEdit1.Height*screen.Pixelsperinch); fr.hdc := b.canvas.handle; fr.hdctarget:=b.canvas.handle; fr.rc:=r; fr.rcpage:=r; fr.chrg.cpMin:=0; fr.chrg.cpMax:=-1; Sendmessage(RichEdit1.handle,EM_FORMATRANGE,1,longint(@fr)); Richedit1.Height:=Trunc(screen.Pixelsperinch*fr.rc.bottom/1440)+8; Sendmessage(RichEdit1.handle,WM_VSCROLL,SB_TOP,0); b.Destroy; end; Все працює.
А як це можна тепер оформити у вигляді окремого компонента з такою корисною функцією? Ніколи не робив, тож не знаю навіть з чого почати.