| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > Длина строки шириной N пикселов. |
| Автор: tripsin 17.5.2005, 21:18 |
| Как определить, сколько максимально символов заданного шрифта (TrueType или системного) поместится на ширине в пикселах? Т.е. ширина компонента известна, надо определсить длину строки, чтобы она заняла всю ширину компонента. |
| Автор: Yanis 17.5.2005, 21:43 | ||
Добавлено @ 21:44 Подсчёт маскимального кол-ва символов помещающихся на Canvas'е TImage. |
| Автор: s-mike 17.5.2005, 23:17 |
| Вместо придумывания велосипеда для переноса текста можно воспользоватся функцией DrawText. |
| Автор: tripsin 17.5.2005, 23:27 |
| Спасибо Yanis А что делать, если у окошка известно тольно hWnd? Я тут покопался в MSDN и нашел, что с помощью GetTextMetrics можно получить структуру TTextMetric, а в ней есть поля tmAveCharWidth: Longint;(ср.ширина символа) и tmMaxCharWidth: Longint;(макс.ширина символа) в относительных единицах. Спрашивается: как эти единицы в пикселы перевести? Добавлено @ 23:28 s-mike Мне вот именно надо велосипед придумать |
| Автор: s-mike 17.5.2005, 23:33 | ||
Функция DrawText может и TextWidth заменить. И в качестве входного параметра ей как раз и нужно DC окна. |
| Автор: tripsin 18.5.2005, 11:47 | ||
А что общественность думает по поводу вот этого кода? :
|
| Автор: s-mike 18.5.2005, 11:53 | ||
Больше напоминает изобретание велосипеда |
| Автор: tripsin 18.5.2005, 11:57 |
| Мне кажется это лучше, чем простой подбор. |
| Автор: s-mike 18.5.2005, 12:08 |
| tripsin, ну зачем же простой подбор? DrawText с флагом DT_CALCRECT возвращает точные размеры текста. |
| Автор: tripsin 18.5.2005, 16:34 |
| Мне нужно разбить длинную строку, на кусочки такой ширины, чтобы они влезали в окно (вручную). Выводить их сразу не надо и DrawText (при всех его достоинчтвах) мне не нужен. З.Ы. С DT_CALCRECT расчитывается прямоугольник вывода, а он как раз известен. |
| Автор: s-mike 18.5.2005, 17:07 |
| tripsin, ты все таки не понял, DrawText нужно вычислять длину строки. Она тебе возвратит минимальный прямоугольник, необходимый для вывода строки. Вот и найди ширину этого прямоугольника. Это и будет ширина строки. Есть еще GetTextExtentPoint32, используемая для TextWidth. |
| Автор: tripsin 18.5.2005, 18:36 |
| s-mike Это ты не понял. Задача в точности до наоборот. У меня уже есть прямоугольник, и надо посчитать сколько символов заданного шрифта влезет в этот прямоугольник по ширине. На выходе должно быть количество символов, а не размеры прямоугольника. |
| Автор: s-mike 19.5.2005, 00:07 |
| tripsin, я говорю, что с помощью этих функций, написанных всего одной строкой, можно заменить код, приведенный тут: http://forum.vingrad.ru/index.php?showtopic=52406&view=findpost&p=413987. Я думаю, что использовать среднюю ширину символов не стоит, тут нужна точность. Я думаю так. У нас есть слова, разделенные пробелом. Читаем последовательно слова, суммируем их ширину. При добавлении каждого следующего слова, если слова превышают максимальную длину строки, то новое слово не добавляем, а переходим на следующую строку. Я бы и код написал, жаль времени сейчас нет, поздно уже. |
| Автор: tripsin 19.5.2005, 08:57 | ||
Хм... Я подожду |
| Автор: tripsin 19.5.2005, 09:11 | ||
То, что ты описал делает функция WrapText.
Вот ее-то как раз и надо найти. |
| Автор: s-mike 19.5.2005, 09:33 | ||
Добавлено @ 09:35 Но она немного не тем занимается, она по буквам разбивает, а не по ширине слов. |
| Автор: tripsin 19.5.2005, 10:36 |
| Тем-тем. Все зависит от переданных параметров. function WrapText(const Line, BreakStr: string; BreakChars: TSysCharSet; MaxCol: Integer): string;overload; По умолчанию BreakChars = [' ', ' -' , #9], т.е. как раз на слова и разбивается. Но считает она не ширину строки в пикселах, а просто, что бы количество символов было меньше MaxCol. |
| Автор: s-mike 19.5.2005, 10:55 | ||||
Я об этом и говорю:
|
| Автор: Girder 19.5.2005, 12:27 | ||
| Мдя... уж! tripsin обрати внимание на следующие функции: GetCharWidth32, GetCharABCWidths. Вот например простейший пример для GetCharWidth32:
|
| Автор: tripsin 19.5.2005, 13:53 |
| Girder Твой код не работает! Ты сам-то пробовал. Он до строки "Caption:=IntToStr(i-1); //Типо... ответ" - даже не доходит. GetCharWidth32(DC,0,255,a); - это че за вызов-то? Вставь проверку: if not GetCharWidth32(DC,0,255,a) then ShowMessage('Хрена! Не работает!'); Кста. В твоем коде в DC надо выбирать шрифт с помощью SelectObject, иначе будет использоваться системный шрифт. Ну блииииин!! Короче нужна функция такого вида: function Number_Of_Chars_In_Pixel_Width(Pixel_Width_Of_window: Integer; WindowFont: TFont): Integer; Может хоть так понятнее. Как определить ширину имеющейся строки я и так знаю. Пока у этой задачи я нашел 2 ответа: 1. Подбор ширины строки в цикле, как показал Yanis(по "среднему" символу, или с помошью функций группы GetCharWidth (но для них нужен конкретный текст) 2. Мой вариант с использованием метрик тескта. Мне только интересно - корректный это код или нет (работает точно). |
| Автор: Girder 19.5.2005, 14:02 | ||||||||||
1.
2.
3.
|
| Автор: Guest 19.5.2005, 15:18 |
| Это я, tripsin Girder Ты уж не обижайся |
| Автор: Girder 19.5.2005, 15:27 | ||
Лови... примерную реализацию
|