2015-01-26 41 views
0

我用Delphi XE5,我有一个TPanel更改TPanel字体大小以适合标题

Caption: 0,00 USD 
Width: 185 
Height: 41 

什么,我需要做的是根据文本宽度/高度以适合面板来改变字体大小。

假设面板显示1.25美元,Fontsize将是25,但如果面板显示1.425,18美元,字体大小将自动为18。无论如何根据文本大小自动更改字体大小?

编辑:新增untpanel单元

我已经创建了下面的单元。我每次更新标题时都会打电话给FitPanel。它的工作原理,但它不工作完美。

unit untpanel; 

interface 

uses System.Classes, Vcl.ExtCtrls, Vcl.Graphics, Vcl.Controls; 

type 
    TPanel = class(Vcl.ExtCtrls.TPanel) 
    private 
    FScaleFont: boolean; 
    procedure SetScaleFont(const Value: boolean); 
    public 
    procedure FitPanel; 
    function TextHeight(Font: TFont; s: string): integer; 
    function TextWidth(Font: TFont; s: string): integer; 
    property ScaleFont: boolean read FScaleFont write SetScaleFont default false; 
    protected 
    procedure Resize; override; 
    end; 

implementation 

{ TPanel } 

function TPanel.TextWidth(Font: TFont; s: string): integer; 
var 
    b: TBitmap; 
begin 
    Result := 0; 
    b := TBitmap.Create; 
    try 
    b.Canvas.Font.Assign(Font); 
    Result := b.Canvas.TextWidth(s); 
    finally 
    b.Free; 
    end; 
end; 

function TPanel.TextHeight(Font: TFont; s: string): integer; 
var 
    b: TBitmap; 
begin 
    Result := 0; 
    b := TBitmap.Create; 
    try 
    b.Canvas.Font.Assign(Font); 
    Result := b.Canvas.TextHeight(s); 
    finally 
    b.Free; 
    end; 
end; 

procedure TPanel.SetScaleFont(const Value: boolean); 
begin 
    FScaleFont := Value; 
    if Value then 
    begin 
    FitPanel; 
    end; 
end; 

procedure TPanel.Resize; 
begin 
    inherited; 
    if ScaleFont then 
    FitPanel; 
end; 

procedure TPanel.FitPanel; 
var 
    w, a: integer; 
    c1, c2: boolean; 
    pnl: TPanel; 
begin 
    pnl := Self; 
    c1 := False; 
    c2 := False; 
    while True do 
    begin 
    w := TextWidth(pnl.Font, pnl.Caption); 
    a := TextHeight(pnl.Font, pnl.Caption); 
    if w < (pnl.ClientWidth - 5) then 
    begin 
     if c1 and c2 then 
     break; 
     if a < pnl.Height then 
     pnl.Font.Size := pnl.Font.Size + 1 
     else 
     break; 
     c1 := True; 
    end else 
    if w > (pnl.ClientWidth - 5) then 
    begin 
     if c1 and c2 then 
     break; 
     pnl.Font.Size := pnl.Font.Size - 1; 
     c2 := True; 
    end else 
     break; 
    end; 

end; 

end. 

感谢

+0

我想你会具有的代码了。使用文本测量功能来检查特定文本的大小,并调整文本大小以使文本变大,但不会太大。 – 2015-01-26 20:51:04

+0

我编辑过它 – blacksun 2015-01-26 21:07:29

回答

0

尝试,看看这是否是更好:

type 
    TPanel = class(Vcl.ExtCtrls.TPanel) 
    private 
    FScaleFont: boolean; 
    procedure SetScaleFont(const Value: boolean); 
    public 
    property ScaleFont: boolean read FScaleFont write SetScaleFont default false; 
    protected 
    procedure Paint; override; 
    end; 

... 

procedure TPanel.SetScaleFont(const Value: boolean); 
begin 
    if Value <> FScaleFont then begin 
    FScaleFont := Value; 
    Invalidate; 
    end; 
end; 

procedure TPanel.Paint; 
var 
    lf: TLogFont; 
    OldFont: HGDIOBJ; 
begin 
    if ScaleFont then begin 
    Canvas.Font := Font; 
    GetObject(Canvas.Font.Handle, SizeOf(lf), @lf); 
    lf.lfHeight := Height; 
    OldFont := SelectObject(Canvas.Handle, CreateFontIndirect(lf)); 
    while (Canvas.TextWidth(Caption) > ClientWidth) and (lf.lfHeight > 0) do begin 
     Dec(lf.lfHeight); 
     DeleteObject(SelectObject(Canvas.Handle, OldFont)); 
     OldFont := SelectObject(Canvas.Handle, CreateFontIndirect(lf)); 
    end; 
    inherited; 
    DeleteObject(SelectObject(Canvas.Handle, OldFont)); 
    end else 
    inherited; 
end;