Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.11.18;
Скачать: [xml.tar.bz2];

Вниз

Как определить высоту текста в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.008 c
1-59212
Sergic
2002-11-06 14:14
2002.11.18
создание собственных типов при использовании COM


3-59008
koks
2002-10-29 11:55
2002.11.18
QuantumGrid: 2 вопроса


1-59130
Acorus
2002-11-07 19:57
2002.11.18
Integer и Longint в D2


4-59499
Дмитрий Иванов
2002-10-04 16:24
2002.11.18
HOT-KEY в чужом окне


1-59268
йцукен
2002-11-07 14:00
2002.11.18
Access violation





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский