2011-08-10 37 views
7

Delphiでは、テキストをTRect内に描画したいと考えています。私は、次の機能のために期待しています:Delphi - 矩形の中心に複数行テキストを描画する

  1. はTRectのを使用して(テキストの1つの以上のラインのためのスペースがある場合は、テキストがTRect内に水平
  2. を中心に描画したテキストは、TRect
  3. 内で垂直中心
  4. を描きます高さ)、テキストを複数行描く
  5. テキストがTRect(1行または複数行のいずれか)に収まらない場合は、テキストに省略記号を追加します。テキストを書くとき、私は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はポイントを分割します:) – Simon

5

最初にDT_CALCRECTを使用してテキストを測定します。 DT_WORDBREAKを渡して、折り返しが有効になっていることを指定します。これにより、テキストの必要な高さを見つけることができます。次に、コード内で、垂直方向の中央に配置されたテキストを与える垂直オフセットを計算し、そのオフセットに描画することができます。

+0

このメソッドを試しましたが、何らかの理由でDT_WORDBREAKが指定されているときにDT_WORD_ELLIPSISが無視されます。このルーチンは現在、rectの外側にテキストをペイントしません(そして、 '...'を表示しません) – Simon

+0

正確にどのテキスト(または長さ)を描くことができる方法はありますか? – Simon

+0

@Simon 'DT_WORDBREAK'ではすべてのテキストが描画されます。あなたはおそらくクリッピングのためにそれを見ていません。 –

関連する問題