Подтвердить что ты не робот

Могу ли я сделать собственный размер TMemo для содержащегося в нем текста?

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

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

4b9b3361

Ответ 1

Установите для свойства 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

Это отлично работает для меня. Константа, добавленная (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;

Ответ 3

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

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

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

Font.Size - 4 + (Lines.Count + 1) * -1 * (Font.Height - 3)

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

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

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

[скриншот]

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

Гротес, Боб Сварт

Ответ 4

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;

Ответ 5

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

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