2011-08-10 16 views
7

En Delphi deseo dibujar texto dentro de un TRect. Estoy esperando para la siguiente funcionalidad:Delphi - Dibujar texto multilínea en el centro de una rect

  1. dibujar el texto centrado verticalmente dentro de la TRect
  2. Dibujar el texto centrado horizontalmente dentro del TRect
  3. Si no hay espacio para más de 1 línea de texto (usando TRect de altura), dibuje el texto multilínea
  4. Si el texto no cabe en el TRect (ya sea en una línea individual o múltiple), a continuación, agregue puntos suspensivos al texto.

puedo ver la función Windows.DrawText() casi cubre esta funcionalidad, sin embargo, cuando la escritura de texto, multilínea y centrada verticalmente son mutuamente excluyentes.

Me preguntaba si esta funcionalidad está integrada en Windows (2000+)? Si no, ¿hay alguna manera de hacerlo sin escribir mi propia función?

+2

¿No puedes usar TLabel? Creo que tiene toda la funcionalidad requerida. –

+1

Sí, probablemente sí, pero no quiero usar una etiqueta, tengo un lienzo para dibujar. – Simon

Respuesta

16

Disculpa, esto es una combinación de todas las respuestas y los comentarios anteriores. Pero parece que OP necesita más ayuda.

function DrawTextCentered(Canvas: TCanvas; const R: TRect; S: String): Integer; 
var 
    DrawRect: TRect; 
    DrawFlags: Cardinal; 
    DrawParams: TDrawTextParams; 
begin 
    DrawRect := R; 
    DrawFlags := DT_END_ELLIPSIS or DT_NOPREFIX or DT_WORDBREAK or 
    DT_EDITCONTROL or DT_CENTER; 
    DrawText(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags or DT_CALCRECT); 
    DrawRect.Right := R.Right; 
    if DrawRect.Bottom < R.Bottom then 
    OffsetRect(DrawRect, 0, (R.Bottom - DrawRect.Bottom) div 2) 
    else 
    DrawRect.Bottom := R.Bottom; 
    ZeroMemory(@DrawParams, SizeOf(DrawParams)); 
    DrawParams.cbSize := SizeOf(DrawParams); 
    DrawTextEx(Canvas.Handle, PChar(S), -1, DrawRect, DrawFlags, @DrawParams); 
    Result := DrawParams.uiLengthDrawn; 
end; 

procedure TForm1.FormPaint(Sender: TObject); 
const 
    S = 'This is a very long text as test case for my paint routine.'; 
var 
    R: TRect; 
begin 
    SetRect(R, 100, 100, 200, 140); 
    Canvas.Rectangle(R); 
    InflateRect(R, -1, -1); 
    Caption := Format('%d characters drawn', [DrawTextCentered(Canvas, R, S)]); 
end; 
+0

¡No puedo ver la diferencia entre deamon_x y esta versión, pero esto funciona!Gracias :) – Simon

+0

Esta línea es la clave: DT_END_ELLIPSIS o DT_NOPREFIX o DT_WORDBREAK o DT_EDITCONTROL o DT_CENTER; – Simon

+2

Sé que resultó ser algo simple, ¡pero ninguna otra combinación de banderas funcionó! Woul dividiría los puntos si pudiera :) – Simon

5

Mida primero el texto con DT_CALCRECT. Pase DT_WORDBREAK para especificar que el ajuste de palabras esté habilitado. Esto le permitirá encontrar la altura requerida para su texto. Luego puede, en su código, calcular el desplazamiento vertical que le da texto centrado verticalmente, y dibujar a ese desplazamiento.

+0

Intenté este método, pero parece que por alguna razón el DT_WORD_ELLIPSIS se ignora cuando se especifica DT_WORDBREAK. Esta rutina Actualmente no pinta texto fuera de la rect (y imposible mostrar la '...') – Simon

+0

¿Hay alguna manera puedo obtener exactamente qué texto (o longitud) fue dibujado? – Simon

+0

@Simon Con 'DT_WORDBREAK' se dibuja todo el texto. No lo está viendo presumiblemente debido a recorte. –

Cuestiones relacionadas