2009-06-01 11 views
11

Cuando edite un título de TLabel en el diseñador de formularios, cambiará el tamaño de TLabel por usted. ¿Hay alguna forma de que pueda obtener un TMemo para hacer eso, en tiempo de ejecución?¿Puedo hacer un tamaño de TMemo en sí mismo para el texto que contiene?

Me gustaría poder tomar un TMemo, asignarle algo a su propiedad .lines.text, y luego decirle que cambie de tamaño y que no exceda un cierto ancho, aunque puede llegar a ser tan alto como lo desee. . ¿Alguien sabe cómo hacer eso?

Respuesta

6

Establecer la propiedad WordWrap del TMemo true, volcar su texto en él, contar las líneas, y ajustar la altura al producto del número de líneas y la altura de la línea, pero lo que necesita saber la línea altura.

TMemo no expone una propiedad de altura de línea, pero si no cambia la fuente o el tamaño de fuente en tiempo de ejecución, puede determinar la altura de línea experimentalmente en tiempo de diseño.

Aquí está el código que utilicé para establecer la altura del TMemo que tenía una altura de línea de 13 píxeles. También encontré que necesitaba una pequeña constante para tener en cuenta los bordes superiores e inferiores de TMemo. Limité la altura a 30 líneas (396 píxeles) para mantenerlo en el formulario.

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

Si es absolutamente necesario extraer la altura de la línea del objeto en tiempo de ejecución, entonces es posible utilizar Someone's answer. O bien, puede usar TRichEdit, que tiene la propiedad SelAttributes que contiene una propiedad Height que proporciona la altura de la línea.

-Al.

+0

Debería haberlo pensado. Estoy demasiado acostumbrado a trabajar con TStringLists, que realizan saltos de línea en CRLF, que nunca se me ocurrió que la propiedad WordWrap en realidad pondría líneas envolventes en diferentes cadenas .Lines. ¡Gracias! –

+0

Font.Height tiene un número negativo que cuenta el número de píxeles en una línea de texto. También podría llamar a Canvas.TextExtent para calcular el alto del texto. –

7

Esto funciona bien para mí. La constante agregada (8) puede variar dependiendo de si está usando un borde y/o bisel, experimente con él.

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; 
+0

Nice answer. Elegí el otro porque era más simple, pero esto funciona bastante bien. Por cierto, no necesita preocuparse por el +8; puede asignar ClientHeight y dejar que el sistema cumpla con el límite. –

+0

Sé que esto es viejo, pero probé la sugerencia de @MasonWheeler y nunca funcionó bien. Creo que porque ClientHeight incluye el relleno interno que tiene el Memo. Por lo tanto, incluso configurando ClientHeight, debe realizar una llamada a EM_GETRECT para calcular realmente el ajuste de tamaño. – Tony

1
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; 
2

he implementado un auto-crecimiento TMemo como un buen ejemplo de LiveBindings (uno de los pocos ejemplos útiles que podría subir por LiveBindings en VCL).

una cita de mi Delphi XE2 Desarrollo Fundamentos Manual didáctico:.

"Para construir este ejemplo, colocar un componente TMemo en un formulario VCL, abra la propiedad LiveBindings, y seleccione la opción‘Nueva LiveBinding’Escoge . TBindExpression elección abierta BindExpressionMemo11 en el inspector de objetos y establecer SourceComponent a Memo1 y SourceExpression a Lines.Count * 22. para obtener un mejor resultado en tiempo de ejecución, establecido SourceExpression a la expresión más exacta

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

Finalmente, en el controlador de eventos OnChange del TMemo, escriba una línea de código:

BindingsList1.Notify (Sender, '');

Eso es todo. Compila y ejecuta para ver el memo creciente en acción.

[pantalla]

Inicialmente, el control TMemo será de dos líneas de alta (la línea con el contenido, y una línea siguiente), y cada vez que pulsa enter o el ajuste de texto nos avanza a la siguiente línea, la Control TMemo crecerá en altura (crece hacia abajo en realidad, así que asegúrese de dejar suficiente espacio en el formulario para el TMemo se expanda en sí) "

Groetjes, Bob Swart

+0

Estaba muy entusiasmado con esta respuesta, pero ya no parece ser una opción a partir del XE10 Berlin. – Tony

0

Y ¿por qué no:.

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

porque no es fmx –

Cuestiones relacionadas