Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Глюки TMemo [D6, WinXP]


saNat ©   (2004-10-25 02:11:00) 

Доброго времени суток...
Помогите разобраться с проблемой. Есть Memo. Я выравниваю в нем строки - в первом абзаце по центру, в остальных - по ширине. Задача нижеуказанной функции - определить границу первого абзаца. Проблема в том, что IMHO не верно указывается ширина Memo в пикселях.

Function TDeskTop.FindEnter:Integer;
Var
 SymbolNumber:Integer; //Текущий символ
 TextBuffer:String; //Буфер - копия текста из Memo
 WordBuffer:String; //Буфер - текущее слово
 LineBuffer:STring; //Буфер - текущая строка (входит по длине в ширину Memo
 SpaceCount:Integer; //Количество прробелов в строке
 alCenter:Boolean; //Параметр - текущий абзац первый или нет
 alCenterNumber:Integer; //Строка, на которой оканчивается первый абзац
Begin
SymbolNumber:=1;  //Становимся на первый символ
TextBuffer:=TextEdit.Lines.Text; //Копируем текст в буфер из Memo
WordBuffer:=''; //Очищаем буфер слова
LineBuffer:='';  //Очищаем буфер строки
SpaceCount:=0; //Сбрасываем количество пробелов
alCenter:=True; //Работаем с первым абзацем
alCenterNumber:=-1; //Окончание первого абзаца неизвестно
TextEdit.Clear; //Очишаем Memo
While (SymbolNumber<=Length(TextBuffer)) Do //Пока не переберем все символы в буфере текста
 Begin
  Case TextBuffer[SymbolNumber] Of //Если текущий символ...
    #13: Begin //...конец абзаца
          TextEdit.Lines.Add(LineBuffer+WordBuffer); //Вставляем в Memo текущую строку и текущее слово
          If (alCenter=True) //если работаем с первым абзацем...
           Then //...то
            Begin
             alCenterNumber:=TextEdit.Lines.Count; //записываем номер строки окончания первого абзаца
             alCenter:=False; //сбрасываем флаг
            End;
          WordBuffer:=''; //очищаем буфер слова
          LineBuffer:=''; //очищаем буфер строки
          SpaceCount:=0; //количество пробелов в 0
          Inc(SymbolNumber); //переход на следующий символ - #10
         End;
    #32: Begin //...пробел
          WordBuffer:=WordBuffer+TextBuffer[SymbolNumber]; //прибавляем пробел к текущему слову
          LineBuffer:=LineBuffer+WordBuffer; //вставляем текущее слово в текущую строку
          WordBuffer:=''; //очищаем буфер слова
          Inc(SpaceCount); //увеличиваем счетчик пробелов
         End;
   Else  Begin //...если другие символы
          //Если длина текущей строки+текущего слова+текущего символа больше или равна клиентской ширине Memo
          If (Canvas.TextWidth(LineBuffer+WordBuffer+TextBuffer[SymbolNumber])>=TextEdit.ClientWidth)
           Then //...то
            Begin
             If (SpaceCount=0) //если в строке нет пробелов
              Then
               Begin
                TextEdit.Lines.Add(WordBuffer); //вставляем в Memo буфер слова
                WordBuffer:=''; //сбрасываем буфер слова
               End
              Else //..иначе
               Begin
                TextEdit.Lines.Add(LineBuffer); //вставляем буфер строки
                LineBuffer:=''; //сбрасываем буфер строки
                SpaceCount:=0; //сбрасываем количество пробелов
               End;
            End;
          WordBuffer:=WordBuffer+TextBuffer[SymbolNumber]; //в любом случае прибавляем текущий символ к буферу слова
         End;
  End;
  Inc(SymbolNumber); //переходим к следующему символу
 End; //конец цикла
If (Length(WordBuffer)<>0) //если буфер слова не пустой (всего 1 абзац)
 Then
  Begin
   TextEdit.Lines.Add(WordBuffer); //вставляем буфер слова
  End;
Result:=0; //возврат значения пока не важен
End;

Разберем на примере. Пусть есть строка, состоящая из 87 единиц. При данном шрифте ширина каждой - 7 пикселей (смотрел отладчиком). При этом клиентская часть Memo - 611 пикселей. => 87*7=609 пикселей и строка должна войти в 1 линию (Lines) Memo. Как бы не так. Одна единица не помещается.
Из-за чего? И как быть.
Параметры Memo:
Шрифт: Comic Sans MS 12 размера обычный кирилический
Длина Memo (Width): 632 пикселя
Полосы прокрутки (ScrollBars): ssVertical

С уважением...


saNat   (2004-10-26 09:31:00) [1]

Вообщем, сделал я программку. Пришлось добавлять к длине строки некоторое количество пикселей, принудительно вызывая перенос. Остановился на значении 21. Однако вопрос остался открытым - почему так. Или уж если выкручиваться, то как определить количество пикселей... Типа по-научному :о))

С уважением...


saNat   (2004-10-25 22:58:00) [2]

Мастера, помогите пожалуйста.


saNat   (2004-10-25 20:49:00) [3]

Тем не менее...


Amoeba   (2004-10-25 19:34:00) [4]


> saNat ©   (25.10.04 19:12) [11]
> Постановка задачи на курсовое проектирование... Выравнивание
> нужно сделать ручками, а не при помощи компонент

Memo, кстати, такой же стандартный компонент (обертка), как и RichEdit.
Садизм какой-то. Заставляют делать через ж...у.


saNat   (2004-10-25 19:12:00) [5]

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

С уважением


Amoeba   (2004-10-25 19:09:00) [6]

A чем RichEdit не нравится? Откуда такая зацикленность на Memo, не предназначенное для таких задач?


saNat   (2004-10-25 19:04:00) [7]

Up


saNat   (2004-10-25 05:33:00) [8]

Спасибо за помошь...
Еще мнения, варианты?


kostan   (2004-10-25 05:21:00) [9]

ну тады PASS:(


saNat   (2004-10-25 05:14:00) [10]

С моноширным работает... Но это противоречит задаче, да и вопрос остается открытым... Все равно непонятно, почему ошибка. По любому в примере с 1 на Comic шрифте длина текста 609<611 - шлиентская ширина Мемо. А он, урод, ее не помещает и принудительно переносит. Куда деваются 2 пикселя?.


kostan   (2004-10-25 04:16:00) [11]

извини TextEdit.ClientWidth точно без скрола,
но всетаки проверь тогда с моноширинными шрифтами [ими все равно красивее форматировать]
(если с ними будет OK тогда дело в определении ширины Canvas.TextWidth)


saNat   (2004-10-25 04:04:00) [12]

Ну по идее (моей), клиентская часть на то и клиентская, чтобы выдавать доступную пользователю область. Иначе откуда мне знать ширину скролла...

С уважением...


kostan   (2004-10-25 03:54:00) [13]

тогда может TextEdit.ClientWidth берется с шириной Полосы прокрутки (ScrollBars): ssVertical + еще пар-тройка pix на границы
(и имхо надо уменьшать на это значение?)


saNat   (2004-10-25 03:13:00) [14]

kostan © (25.10.04 02:40) [1]
1) ну может как вариант сделать запас пикселей в 5-10 при  проверке
Допустим, но возникает вопрос - а сколько прибавить и отчего зависит
2) использовать моноширинные шрифты (Courier, Lucida Cons)
Не прокатит. Шрифты можно менять.


kostan   (2004-10-25 02:40:00) [15]

1) ну может как вариант сделать запас пикселей в 5-10 при  проверке
(форматирование наверно не требует большей точности)
2) использовать моноширинные шрифты (Courier, Lucida Cons)


Наверх

Титульная страница Поиск, карта сайта Написать письмо