Могу ли я сделать размер TMemo для текста, который он содержит? - PullRequest
11 голосов
/ 01 июня 2009

Когда вы редактируете заголовок TLabel в конструкторе форм, он изменяет размер TLabel для вас. Можно ли как-нибудь заставить TMemo сделать это во время выполнения?

Я бы хотел иметь возможность взять TMemo, назначить что-то его свойству .lines.text, а затем сказать ему, чтобы он изменял свой размер и не превышал определенной ширины, хотя он может быть настолько высоким, насколько он хочет. Кто-нибудь знает, как это сделать?

Ответы [ 5 ]

7 голосов
/ 01 июня 2009

Это прекрасно работает для меня. Добавленная константа (8) может зависеть от того, используете ли вы рамку и / или скос, поэкспериментируйте с ней.

procedure TForm1.Memo1Change(Sender: TObject);
var
  LineHeight: Integer;
  DC: HDC;
  SaveFont : HFont;
  Metrics : TTextMetric;
  Increase: Integer;
  LC: Integer;
begin
  DC := GetDC(Memo1.Handle);
  SaveFont := SelectObject(DC, Memo1.Font.Handle);
  GetTextMetrics(DC, Metrics);
  SelectObject(DC, SaveFont);
  ReleaseDC(Memo1.Handle, DC);
  LineHeight := Metrics.tmHeight;
  Increase := Memo1.Height;
  LC := Memo1.Lines.Count;
  if LC < 1 then
    LC := 1;
  Memo1.Height := LC * LineHeight + 8;
  Increase := Memo1.Height - Increase;
  Memo1.Parent.Height := Memo1.Parent.Height + Increase;
end;
6 голосов
/ 01 июня 2009

Установите для свойства WordWrap TMemo значение true, поместите в него текст, подсчитайте количество строк и установите высоту, равную произведению количества строк и высоты строки, но вам необходимо знать строку высота.

TMemo не предоставляет свойства высоты строки, но если вы не меняете шрифт или размер шрифта во время выполнения, вы можете определить высоту строки экспериментально во время разработки.

Вот код, который я использовал, чтобы установить высоту TMemo, которая имела высоту строки 13 пикселей. Я также обнаружил, что мне нужна небольшая константа для учета верхней и нижней границ TMemo. Я ограничил высоту 30 строками (396 пикселей), чтобы сохранить ее в форме.

// Memo.WordWrap = True (at design time)
Memo.Text := <ANY AMOUNT OF TEXT>;
Memo.Height := Min(19 + Memo.Lines.Count * 13, 396); 

Если вам абсолютно необходимо извлечь высоту строки из объекта во время выполнения, тогда вы можете использовать Чей-то ответ . Или вы можете использовать TRichEdit, у которого есть свойство SelAttributes, содержащее свойство Height, дающее высоту строки.

-Аль.

2 голосов
/ 04 ноября 2011

Я реализовал саморазвивающуюся TMemo как хороший пример LiveBindings (один из немногих полезных примеров, которые я мог бы придумать для LiveBindings в VCL).

Цитата из моего учебного руководства по Delphi XE2 Development Essentials:

"Чтобы построить этот пример, поместите компонент TMemo в форму VCL, откройте свойство LiveBindings и выберите параметр« New LiveBinding ». Выберите вариант TBindExpression. Откройте BindExpressionMemo11 в Инспекторе объектов и установите SourceComponent для Memo1 и SourceExpression в Lines.Count * 22. Чтобы получить лучший результат во время выполнения, установите SourceExpression на более точное выражение

Размер шрифта - 4 + (количество строк + 1) * -1 * (высота шрифта - 3)

Наконец, в обработчике события OnChange TMemo напишите одну строку кода:

BindingsList1.Notify (Отправитель, '');

Вот и все. Скомпилируйте и запустите, чтобы увидеть растущую заметку в действии.

[скриншот]

Изначально элемент управления TMemo будет иметь высоту в две строки (строку с содержимым и следующую строку), и всякий раз, когда мы нажимаем клавишу ввода или перенос слов, мы переносим нас на следующую строку, элемент управления TMemo будет увеличиваться по высоте (растет на самом деле, поэтому убедитесь, что в форме достаточно места для расширения TMemo). "

Groetjes, Боб Сварт

1 голос
/ 04 ноября 2011
procedure TTmpMessage.edMsgChange (Sender: TObject);
var
    LineHeight : Integer;
    DC         : HDC;
    SaveFont   : HFont;
    Metrics    : TTextMetric;
begin
    DC := GetDC ( TRxRichEdit (Sender).Handle );
    SaveFont := SelectObject ( DC, TRxRichEdit (Sender).Font.Handle );
    GetTextMetrics (DC, Metrics);
    SelectObject (DC, SaveFont);
    ReleaseDC ( TRxRichEdit (Sender).Handle, DC );
    LineHeight := Metrics.tmHeight;
    Height := TRxRichEdit (Sender).Lines.Count * LineHeight + 32;
end;
0 голосов
/ 16 апреля 2014

А почему не просто:

Memo1.Height := Memo1.ContentBounds.Height + 5;
...