2011-08-10 2 views
7

Delphi'de bir TRect'in içine metin çizmek istiyorum. Aşağıdaki işlevsellik için umuyorum:Delphi - Metnin ortasında çok satırlı metin çizme

  1. metin TRect
  2. içinde dikey merkezli çizin metin (kullanmanın 1'den fazla hat için uzay TRect en varsa TRect
  3. içinde yatay olarak ortalanmış metin çizin yükseklik), metin çok satırlı çizin
  4. Metin, Metin kutusuna sığmıyorsa (tek veya çoklu satırda), ardından metne elips ekleyiniz.

Ben Windows.DrawText() işlevini neredeyse görebilirsiniz metin, satırlı yazma ve dikey merkezli zaman ancak birbirini dışladığı, bu işlevlerini kapsamaktadır.

Bu işlevin pencerelere (2000+) eklenmiş olup olmadığını merak ediyordum? Eğer değilse, kendi işlevimi yazmadan bunu yapmanın bir yolu var mı?

+2

TLabel kullanabilir misiniz? Gereken tüm işlevselliğe sahip olduğunu düşünüyorum. –

+1

Evet muhtemelen yapabilir, ancak bir etiket kullanmak istemiyorum, çekmek için bir tuvalim var. – Simon

cevap

16

Üzgünüm, bu önceki tüm cevaplar ve yorumlara bir bileşimdir. Ancak OP'nin daha fazla yardıma ihtiyacı var gibi görünüyor.

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

Ben deamon_x's ve bu sürüm arasındaki farkı göremiyorum ama bu çalışır !!Teşekkürler :) – Simon

+0

Bu satır şu anahtardır: DT_END_ELLIPSIS veya DT_NOPREFIX veya DT_WORDBREAK veya DT_EDITCONTROL veya DT_CENTER; – Simon

+2

Ben basit bir şey olduğu ortaya çıktı biliyorum, ama bayrakların herhangi bir kombinasyonu işe yaramadı! Woul, eğer ben yapabilirim :) – Simon

5

Metni önce DT_CALCRECT kullanarak ölçün. Kelime kaydırmanın etkinleştirildiğini belirtmek için DT_WORDBREAK'u geçin. Bu, metniniz için gereken yüksekliği bulmanızı sağlayacaktır. Ardından, kodunuzda dikey olarak ortalanmış metin veren dikey ofseti hesaplayabilir ve bu ofseti çizebilirsiniz.

+0

Bu yöntemi denedim, ancak DT_WORDBREAK belirtildiğinde DT_WORD_ELLIPSIS yok sayılıyor. Bu rutin şu anda rect dışında metin çizmiyor (ve '...' göstermiyor) – Simon

+0

Tam olarak hangi metnin (veya uzunluğun) çizildiğini görebilmemin bir yolu var mı? – Simon

+0

@Simon "DT_WORDBREAK" ile tüm metinler çizilir. Muhtemelen kırpma nedeniyle görmüyorsun. –