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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.6 MB
Время: 0.011 c
1-48494
ksan
2003-09-02 19:36
2003.09.15
отображение компонента


14-48713
Maxim Pshevlotsky
2003-08-28 11:12
2003.09.15
{Хочу заняться...}


1-48553
Хозявин М
2003-09-01 07:20
2003.09.15
О разработке нового компонента


1-48496
jack128
2003-09-02 19:11
2003.09.15
Инициализация переменных


1-48612
McSimm2
2003-09-03 13:35
2003.09.15
Проскакивает выражение





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский