2011-08-10 54 views
7

在Delphi中,我希望在TRect中繪製文本。我希望以下功能:Delphi - 在矩形中心繪製文本多行

  1. 繪製文本的TRect
  2. 內垂直居中繪製TRect
  3. 中水平居中的文字如果有超過1行文本(使用的空間TRect的高度),繪製文本多行
  4. 如果文本不適合TRect(單行或多行),則將省略號附加到文本中。

我可以看到Windows.DrawText()函數幾乎涵蓋這個功能,但是寫文字,多和垂直居中時是互斥的。

我想知道這個功能是否內置到windows(2000+)?如果沒有,有沒有辦法做到這一點,而不寫我自己的功能?

+2

難道你不能使用TLabel?我認爲它具有所需的全部功能。 –

+1

是的,它可能會做,但我不想使用標籤,我有一個畫布可以畫畫。 – Simon

回答

16

對不起,這是以前的所有答案和評論的組合。但似乎OP需要更多幫助。

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

我不能看到deamon_x和這個版本之間的區別,但這個作品!感謝:) – Simon

+0

此行是關鍵:DT_END_ELLIPSIS或DT_NOPREFIX或DT_WORDBREAK或DT_EDITCONTROL或DT_CENTER; – Simon

+2

我知道原來是簡單的東西,但任何其他組合的標誌沒有工作! Woul split the points if if :) :) – Simon

5

使用DT_CALCRECT首先測量文本。通過DT_WORDBREAK指定啓用換行。這將允許您爲文本找到所需的高度。然後,您可以在代碼中計算垂直偏移量,該垂直偏移量使您可以垂直居中文本,並繪製到該偏移量。

+0

我試過這個方法,但是出於某種原因DT_WORD_ELLIPSIS在指定DT_WORDBREAK時會被忽略。這個例程目前不會在rect之外繪製文本(並且不顯示'...') – Simon

+0

有沒有一種方法可以準確得出哪些文本(或長度)被繪製? – Simon

+0

@Simon通過'DT_WORDBREAK'繪製所有文字。你沒有看到它可能是由於剪輯。 –