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

Вниз

Ширина стринга   Найти похожие ветки 

 
Alibaba ©   (2003-09-01 15:05) [0]

Всем привет!

У меня есть стринг:

var s: string;
begin
s:="kulik";
end;

Как мне получить ширину этого стринга, зная:
- Font.Size;
- Font.Style [fsBold, fsItalic];


 
Skier ©   (2003-09-01 15:08) [1]

Font.Canvas.TextWidth(...)


 
Игорь Шевченко ©   (2003-09-01 15:17) [2]

function GetTextWidthInPixels(AText: string; AControl: TControl): integer;
var
propInfo: PPropInfo;
thisFont: TFont;
begin
Result := 0;

propInfo := GetPropInfo(AControl.ClassInfo, "Font");

if propInfo <> nil then begin
thisFont := TFont(GetObjectProp(AControl, "Font"));

if Assigned(thisFont) then
with TControlCanvas.Create do
try
Control := AControl;
Font.Assign(thisFont);
Result := TextWidth(AText);
finally
Free;
end;
end;
end;

Или

function TextWidth (const Str : String; AFont : TFont);
var
DC : HDC;
OldFont : HFONT;
TextSize : SIZE;
begin
DC := GetDC (HWND_DESKTOP);
try
OldFont := SelectObject(DC, AFont.Handle);
try
if (not GetTextExtentPoint32(DC, PChar(Str), Length(Str)), TextSize)) then
RaiseLastWin32Error;
Result := TextSize.cx;
finally
SelectObject(DC, OldFont);
end;
finally
ReleaseDC (HWND_DESKTOP, DC);
end;
end;


 
Alibaba ©   (2003-09-01 15:34) [3]

>Игорь Шевченко © (01.09.03 15:17) [2]

Давайте поподробнее рассмотрим второй вариант.
function TextWidth (const Str : String; AFont : TFont)

Похоже это то что мне надо.
Но почему-то валится программа...


 
KSergey ©   (2003-09-01 15:38) [4]

Ну Шевченко и наворотил ;)

Вам же [1] Skier © (01.09.03 15:08) уже все сказал
Ну разве что перепутал маненько ;)

Canvas.Font.TextWidth(...) - и все!


 
Alibaba ©   (2003-09-01 15:40) [5]

>Игорь Шевченко © (01.09.03 15:17) [2]

У меня два вопроса:
1. Почему function TextWidth ( const Str : String; AFont : TFont);
2. AFont : TFont - необходимо прадварительно создать?


 
Е-Моё имя ©   (2003-09-01 15:40) [6]

>>Ну Шевченко и наворотил ;)
зато на винапи)


 
Skier ©   (2003-09-01 15:42) [7]

>KSergey © (01.09.03 15:38)

> Ну разве что перепутал маненько ;)


Да. Критика по существу.


 
KSergey ©   (2003-09-01 15:44) [8]

[6] Е-Моё имя © (01.09.03 15:40)
>>Ну Шевченко и наворотил ;)
зато на винапи)


Ага, конечно
Особенно String и TFont
Да и это применительно к десктопу сделаны функции. А автору не понятно на каком устройстве надо.


 
Alibaba ©   (2003-09-01 15:46) [9]

Такой вариант:
Skier © (01.09.03 15:08) [1]
не подходит.

Еще раз:
Мне нужна следующая функция:
function TextWidth(s: string; AFont: TFont): integer

Я передаю s: string ("Вася"), AFont.

AFont.Size:=8;
AFont.Style:=[fsBold];

Получаю - 20 (пикселей)


 
Palladin ©   (2003-09-01 15:48) [10]


> Alibaba © (01.09.03 15:46) [9]

ты ответы читай, ара.
Игорь Шевченко © (01.09.03 15:17) [2]


 
Alibaba ©   (2003-09-01 15:49) [11]

>KSergey © (01.09.03 15:44) [8]

А автору не понятно на каком устройстве надо.
Если Вам не понятно что-то со слов автора - всегда можно спросить.


 
Alibaba ©   (2003-09-01 15:52) [12]

>Skier © (01.09.03 15:42) [7]

С Канвасом все получается в случае, если работает с контролами (например: TLabel)

А если есть просто переменная s: string...


 
Vini   (2003-09-01 15:54) [13]

Удалено модератором


 
Alibaba ©   (2003-09-01 15:55) [14]

Удалено модератором


 
ZEE ©   (2003-09-01 15:56) [15]

Alibaba © (01.09.03 15:52) [12]
создавай временный Канвас...


 
Skier ©   (2003-09-01 15:58) [16]

>Alibaba © (01.09.03 15:52)

> А если есть просто переменная s: string...

Поясни.


 
Alibaba ©   (2003-09-01 16:07) [17]

>Skier © (01.09.03 15:58) [16]

Смотри...
У меня есть просто: (Alibaba © (01.09.03 15:05))
var
s: string;
i: integer;
begin
s:="Вася";
//Я хочу получить ширину этой строки в пикселях
i:=TextWidth(s,8);
//8 - это размер шрифта
end;

Существует решение:
var
s: string;
i: integer;
begin
s:="Вася";
label1.Caption:=s;
label1.Font.Size:=8;
//Я хочу получить ширину этой строки в пикселях
i:=label1.Width;
end;

Но это решение мне не подходит.
Я не могу пользоваться TLabel

Мне необходимо решение без использования TLabel.
Вот.


 
Alibaba ©   (2003-09-01 16:09) [18]

>ZEE © (01.09.03 15:56) [15]

Canvas:=TCanvas.Create и так далее..
Надо попробовать...


 
KSergey ©   (2003-09-01 16:18) [19]

Удалено модератором


 
Palladin ©   (2003-09-01 16:22) [20]

Ара - это дружеское обращение на кавказе.
Шевченко тебе привел код, стоило бы на него обратить внимание, почитать осмыслить.

ЗЫ
Не совсем понятны нападки в мою сторону. Интересно они чем то обоснованы? И какой такой "тот самый"?


 
Alibaba ©   (2003-09-01 16:27) [21]

>KSergey © (01.09.03 16:18) [19]

Тонкостей намного меньше если внимательно читать :)
Alibaba © (01.09.03 16:07) [17]
//Я хочу получить ширину этой строки в пикселях
Хотя в попугаях - это интерестно. :))

Но, к делу.
Прочитайте еще раз Alibaba © (01.09.03 16:07) [17]


 
Zheks ©   (2003-09-01 16:31) [22]

Удалено модератором


 
Vini   (2003-09-01 16:32) [23]

Удалено модератором
Примечание: Говорим по существу, пожалуйста


 
nikkie ©   (2003-09-01 16:33) [24]

Непонятно зачем требуется определять ширину "вообще".


 
Alibaba ©   (2003-09-01 16:35) [25]

В общем, народ, предлагаю дружить подьездами...
Хотя лучше домами! :)

Работает такой вариант:
var
FT: TFont;
begin
st:="Вася";
FT:=TFont.Create;
FT.Size:=8;
FT.Style:=[];
CWidth:=TextWidth(st,FT);
FT.Free;
end.

TextWidth - Игорь Шевченко © (01.09.03 15:17) [2]


 
Skier ©   (2003-09-01 16:35) [26]

Удалено модератором
Примечание: Skier, не подзадоривай


 
Alibaba ©   (2003-09-01 16:37) [27]

>nikkie © (01.09.03 16:33) [24]

Если сможеш - просто поверь.
Такая необходимость есть. :))


 
Zheks ©   (2003-09-01 16:48) [28]

Удалено модератором
Примечание: Весьма смелое утверждение..


 
Zheks ©   (2003-09-01 16:58) [29]

не, это для разрядки ситуации.


 
KSergey ©   (2003-09-01 17:15) [30]

[25] Alibaba © (01.09.03 16:35)
Работает такой вариант:


Понятно что работает, вот только всегда ли?...Вернее, при любых ли условиях он возвращает желаемый результат...

И все же, вы не ответили на главный вопрос: зачем определять ширину строки как таковую? Оторванно от мира?? Тем более, что смысла это не имеет.
Вот и в примере Шевчетко - определяется ширина при условии отрисовки на десктопе. Есил это нормально, то почему бы не взять свойство Canvas формы, например? Мне не понятно, чем оно хуже десктоповского...


 
Игорь Шевченко ©   (2003-09-01 17:24) [31]

Маленькие ошибки:
1)
function TextWidth (const Str : String; AFont : TFont) : Integer;
2)
if (not GetTextExtentPoint32(DC, PChar(Str), Length(Str), TextSize)) then

И все работает.

KSergey © (01.09.03 17:15)


> Вот и в примере Шевчетко - определяется ширина при условии
> отрисовки на десктопе.


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


 
KSergey ©   (2003-09-01 17:29) [32]

[31] Игорь Шевченко © (01.09.03 17:24)
Неа. Определяется ширина строки при условии рисования даннм шрифтом где угодно.


Я вам не верю ;)

На принтере эта величина будет совсем другой ;) Надеюсь, спорить вы не будете.
Да и для окна в данный момент времени я могу установить режим отображения, отличный от десктоповского, верно?


 
Alibaba ©   (2003-09-01 17:38) [33]

Мне необходима ширина строки вот для чего:
http://delphimaster.net/view/1-1062025438/

У меня есть список задач, представленный в TListBox.
Я хочу перетаскивая задачи в списке - в виде курсора иметь конкретную задачу, текст этой задачи.

Например: Task1, Task2 и т.д.


 
Игорь Шевченко ©   (2003-09-01 17:38) [34]

KSergey © (01.09.03 17:29)


> На принтере эта величина будет совсем другой ;) Надеюсь,
> спорить вы не будете


Буду спорить. Не будет она совсем другой. В пикселях. На принтере пиксели меньше.


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


Поподробнее на эту тему, пожалуйста


 
Alibaba ©   (2003-09-01 18:00) [35]

Почему я не пользуюсь:

var
s: string;
i: integer;
begin
s:=lb.Items[lb.ItemIndex];
i:=lb.Canvas.TextWidth(lb.Items[lb.ItemIndex]);
//Создаю курсор
screen.cursors[1]:=CreateTxtCursor(lb.Items[lb.ItemIndex],i);
end

Потому что такой вариант почему то работает не стабильно.
Чуть-чуть обрезанный текст получается.


 
KSergey ©   (2003-09-02 08:51) [36]

[35] Alibaba © (01.09.03 18:00)
Потому что такой вариант почему то работает не стабильно.
Чуть-чуть обрезанный текст получается.


Ну для курсора наверняка действительно определении по десктопу - самое то ;) Вот сразу бы конкретизировать - и было бы здорово ;)

К стати, кратенько пример кода можно как это делается? (создание текстового курсора)? Впрочем, код уже риведен, его бы дополнить кодом уничтожения созданного курсора - и вообще клево. ли это не надо делать? По какой причине?
В общем думать лень, если напишете - буду весьма признателен.

То, что по канве листбокса размер не совсем тот - странно. Но я не спорю. Возможно. Хотя причин и не вижу, но не шибко-то в том секу.

[34] Игорь Шевченко © (01.09.03 17:38)
> На принтере эта величина будет совсем другой ;) Надеюсь,
> спорить вы не будете
Буду спорить. Не будет она совсем другой. В пикселях. На принтере пиксели меньше.


Я не знаю.. Если вам охота - можно, конечно, эксперимент поставить, я не против, а вот думать лень ;). Но есть у меня подозрение, что значения (и как раз в пикселах!) будут отличаться, т.к. Font.Size - это величина в пунктах, которые, вообще говоря, хрен поймешь как пересчитываются в реальные величины (ну про хрен поймешь- это я уж так, загнул конечно, но в пикселах это даст разные результат в зависимости от величины точек/дюйм для конкретного устройства. Так ведь?

> Да и для окна в данный момент времени я могу установить
> режим отображения, отличный от десктоповского, верно?
Поподробнее на эту тему, пожалуйста


Я немного не понял про что подробнее. Не мне вам рассказывать про SetMapMode ;)


 
AD ©   (2003-09-02 09:18) [37]

Функция DrawText(HDC hDC, LPCTSTR lpString, int nCount, R, DT_CALCRECT) вернет R: TRect, необходимый для вывода строки lpString на hDC текущим шрифтом. Из него можем найти и ширину. Пример:
var
R: TRect;
fWidth: integer; // ширана строки
DC: hDC;
...
DC := GetDC(Button1.Handle);
DrawText(DC, PChar(Button1.Caption), Length(Button1.Caption), R, DT_CALCRECT);
DeleteDC(DC);
fWidth := R.Right - R.Left;


 
nikkie ©   (2003-09-02 13:17) [38]

В поддержку мнения KSergey, что результат вычисления ширины строки зависит от DC. Цитата из доки на GetTextExtentPoint32:

The calculated string width takes into account the intercharacter spacing set by the SetTextCharacterExtra function.

Таким образом, заведомо DC с разными установленными CharacterExtra должны дать разные результаты.

Кроме того, размеры текста вычисляются in logical units, а не пикселях. А дальше смотрим функцию SetMapMode.

MM_TEXT Each logical unit is mapped to one device pixel. Positive x is to the right; positive y is down.

MM_LOMETRIC Each logical unit is mapped to 0.1 millimeter. Positive x is to the right; positive y is up.


и т.д. Попробуйте сами такой код:

var
sz: SIZE;
begin
SetMapMode(Canvas.Handle, MM_TEXT);
GetTextExtentPoint32(Canvas.Handle, "abcdefgh", 8, sz);
ShowMessage(inttostr(sz.cx) + " - " + inttostr(sz.cy));
SetMapMode(Canvas.Handle, MM_LOMETRIC);
GetTextExtentPoint32(Canvas.Handle, "abcdefgh", 8, sz);
ShowMessage(inttostr(sz.cx) + " - " + inttostr(sz.cy));
SetMapMode(Canvas.Handle, MM_HIMETRIC);
GetTextExtentPoint32(Canvas.Handle, "abcdefgh", 8, sz);
ShowMessage(inttostr(sz.cx) + " - " + inttostr(sz.cy));
end;


Может есть и другие моменты, влияющие на результат GetTextExtentPoint32, я не знаю.

В конце концов, тот факт, что использование канвы листбокса дает другой результат, разве не говорит о том, что DC влияет на размер?


 
Игорь Шевченко ©   (2003-09-02 13:30) [39]

nikkie © (02.09.03 13:17)

Угу, с MapMode убедил. Но, сдается мне, это уже не относится к задаче, поставленной автором :))


> В конце концов, тот факт, что использование канвы листбокса
> дает другой результат, разве не говорит о том, что DC влияет
> на размер?


А я наверное, что-то пропустил насчет канвы ListBox"а и другого результата ?


 
KSergey ©   (2003-09-02 13:51) [40]

[39] Игорь Шевченко © (02.09.03 13:30)
А я наверное, что-то пропустил насчет канвы ListBox"а и другого результата ?

Никогда не поздно подняться вверх по страничке ;) Впрочем, как раз вот в данном случае что-то странное. По идее результат должнен быть одинаков.

Еще одно замечание, если позволите.

Игорь Шевченко © (01.09.03 17:24)
Неа. Определяется ширина строки при условии рисования даннм шрифтом где угодно.


Вам должно быть стыдно такое писать. А как же быть вот с этим:

DC := GetDC (HWND_DESKTOP); ? ;)


 
nikkie ©   (2003-09-02 13:53) [41]

> А я наверное, что-то пропустил насчет канвы ListBox"а и
> другого результата ?

смотри Alibaba © (01.09.03 18:00)


 
nikkie ©   (2003-09-02 14:23) [42]

> Впрочем, как раз вот в данном случае что-то странное. По
> идее результат должнен быть одинаков.

Согласен, странно. Только что проверил - у меня результат один и тот же.


 
PVOzerski ©   (2003-09-02 15:03) [43]

Из моих запасов:
function GetSize(DC:tHandle;s:string):tSize;
var
size:tSize;
begin
if s="" then
s:="|";
GetTextExtentPoint(DC,pChar(s),length(s),Size);
GetTextExtentPoint32(DC,pChar(s),length(s),Result);
if Result.cx<Size.cx then
Result.cx:=Size.cx;
if Result.cy<Size.cy then
Result.cy:=Size.cy;
end;

Правда, у меня стояла задача определить оптимальную длину Edit-Box"а. Вызов обеих функций - и рекомендуемой GetTextExtentPoint32, и "устаревшей" GetTextExtentPoint - объясняется тем, что первая у меня ошибалась (занижала ширину) под NT4 при шрифте italic not true-type, а вторая работала в этой ситуации более корректно.


 
KSergey ©   (2003-09-02 15:12) [44]

[43] PVOzerski © (02.09.03 15:03)
Вызов обеих функций - и рекомендуемой GetTextExtentPoint32, и "устаревшей" GetTextExtentPoint - объясняется тем, что первая у меня ошибалась (занижала ширину) под NT4 при шрифте italic not true-type, а вторая работала в этой ситуации более корректно.

Для общего развития: а вторая - нгикогда не занижала? Так может ее и только использовать? Или занижала то одна, то другая?

PS
К стати, про шрифты в начертании Italic верно подмечено: TextWidth пожалуй не всегда верно определяет их ширину. Это видно даже в редакторе IDE дельфи: часто последние буквы в строчках, для которых включен наклонный шрифт обрезаются. С TLabel при AutoSize та же ерунда. (D5) Впрочем, здесь видимо ошибка в DrawText с DT_CALCRECT - именно ею определяется размер лейбла.


 
PVOzerski ©   (2003-09-02 15:50) [45]

>Для общего развития: а вторая - нгикогда не занижала? Так может ее и только использовать?
Врала тоже, кажется, наоборот, с TrueType, хотя деталей уже не помню. Помню, правда, что соблазн использовать только GetTextExtentPoint у меня тоже был, но от этой идеи пришлось отказаться.


 
Игорь Шевченко ©   (2003-09-02 15:52) [46]

KSergey © (02.09.03 13:51)

Мне, как ни странно, не стыдно. Потому как экранный контекст устройства в большинстве случаев совместим с контекстами устройств окон по Mapping Mode, CharacterExtra и т.д. :)



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

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

Наверх




Память: 0.6 MB
Время: 0.021 c
14-48751
Kost
2003-08-28 12:58
2003.09.15
Помогите с проблемой...


4-48821
Still Swamp
2003-07-16 17:45
2003.09.15
Позиция клиентского RECT для окна


3-48424
Кирилл
2003-08-25 16:25
2003.09.15
Ув. мастера, Как определить размер записи?


1-48505
Evgeniy_K
2003-09-02 17:49
2003.09.15
маленькая альтернатива MessageBox


1-48635
Star Wars
2003-09-03 09:09
2003.09.15
Массив динамических массивов