Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.11.18;
Скачать: CL | DM;

Вниз

Как определить высоту текста в RichEdit е? Если текст набран   Найти похожие ветки 

 
Кен   (2002-10-12 06:43) [0]

разными шрифтами и размерами, то не очень понятно. Подскажите, а? Нужно, чтобы можно было подогнать размеры самого RichEdit"а под размеры текста в нём.


 
Song ©   (2002-10-12 11:26) [1]

Canvas.TextHeight()


 
Кен   (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 01:13) [4]

2MBo ©
Попробовал. Вроде получается но глючит.
Я поставил этот код на кнопку. В ричедит загружаю из файла текст в rtf формате.

Дальше жму на кнопку и размер окна подравнивается до предпоследней строки. Вместе с ним появляется ещё линейка прокрутки. Так вот стоит эту линейку чуть подвинуть, и сделать пересчёт размеров окна, как результат получается другой. И так каждый раз двигая линейку результаты получаем каждый раз разные. Как это обезглючить ?


Про последнююс строчку я честно сказать не очень понял. Как к ней применить .Canvas.TextHeight(); ? Какое начало у этого кода ?


 
Кен   (2002-10-23 03:39) [5]

Как бы решить проблему ?


 
Separator ©   (2002-10-23 08:17) [6]

Form1.Canvas.TextHeight()


 
Кен   (2002-10-30 03:05) [7]

2 Separator ©
Так определяется для Form1 , а у RichEdit1 так нельзя.
Такая строка : RichEdit1.Canvas.TextHeight() - не работает.

Так как же ТОЧНО определить высоту текста в 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]

GetSystemMetrics


 
Кен   (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 08: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) or (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);

end;

PS
Так как, воспользовавшись советом от MBo © (16.10.02 06:38) мы получаем координаты верхушки последней строчки вместо ее "низушки", что не есть требуемое, просто добавим фиктивную строчку (или даже две - не жадные же ведь :)). Тогда ее верхушка будет ниже "низушки" последней строки. Сие уже ближе к цели. На этой "военной хитрости" и построена процеДурка.
PPS
При необходимости вызов повторить :)
PPPS
Но надо бы идти другим путем...


 
Alex4444444444   (2002-11-01 10:03) [14]

Po moemu, u TRichEdit est" event, generiruyushijsya, kogda on hochet izmenit" svoj razmer. Mozhet, ego pojmat"? Ili posmotret", kak on realizovan (eto ved" prosto perehvat kakoj-to message; vpolne mozhet byt" i "dvojstvennaya" message). Ne isklyucheno takzhe, chto eto mozhet byt" svyazano s 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]

b-tbitmap

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]

> Нет ли какого нибудь универсального списка всего, что можно
> туда добавить ?

dir :)


 
MBo ©   (2002-11-07 13:16) [19]

uses richedit


 
Кен   (2002-11-08 04:05) [20]

MBo ©
Дельфи 5 ругается на строчку :
fr.hdc:=b.canvas.handle;
Пишет Project rised exception class ... и какие то большие цифры.

А как можно убрать самую последнюю строчку в RichEdit если она пуста ? Почему то в этом случае вместо неё убирается предпоследняя. А последняя пустая так и остаётся.


 
MBo ©   (2002-11-08 07:47) [21]

b- переменная TBitmap, которая, естественно, должна быть уже создана, например, в ONCreate формы


 
Кен   (2002-11-09 02: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;

Всё работает.

А как это можно теперь оформить в виде отдельного компонента, с такой полезной функцией ? Никогда не делал, поэтому не знаю даже с чего начать.

Посмотрел для примера файл RxRichEd.pas из RxLib, можно было бы прямо туда добавить этот код. Но вот только как и куда там ? Файл занимает 158кб разобраться в нём это наверно с ума можно сойти. Слишком уж много всего.



Страницы: 1 вся ветка

Текущий архив: 2002.11.18;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.036 c
1-59166
Warl
2002-11-08 23:37
2002.11.18
Как определить дату и/или время создания каталога?


6-59313
Flex
2002-08-02 09:37
2002.11.18
Как в Delphi скачать файл с сайта?


1-59174
Ag2002
2002-11-09 11:16
2002.11.18
Логика


1-59165
Кен
2002-10-12 06:43
2002.11.18
Как определить высоту текста в RichEdit е? Если текст набран


1-59259
vanek
2002-11-06 08:31
2002.11.18
Работа с listview...