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

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

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

5 ответов


установить 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 свойство, дающее высоту линии.

-Al.


это работает просто отлично для меня. Добавленная константа (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;

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

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

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

шрифт.Размер - 4 + (Строки.Count + 1) * -1 * (Шрифт.Высота - 3)

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

BindingsList1.Сообщить ("Отправитель", ");


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;

и почему бы просто не:

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