2011-03-12 46 views
3

嗨有誰知道是否有可能顯示圖片作爲字符串網格的背景,或者是任何人都知道任何可以做到這一點的免費網格組件。德爾福StringGrid與背景圖片

感謝

科林

回答

12

你可以使用一個TDrawGrid(或TStringGrid),支持業主繪圖,做

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    FBg := TBitmap.Create; 
    FBg.LoadFromFile('C:\Users\Andreas Rejbrand\Pictures\Sample.bmp'); 
end; 

其中FBgTBitmap(在窗體類,例如),然後做

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; 
    Rect: TRect; State: TGridDrawState); 
var 
    r: TRect; 
begin 
    if not (Sender is TStringGrid) then Exit; 
    BitBlt(TStringGrid(Sender).Canvas.Handle, 
     Rect.Left, 
     Rect.Top, 
     Rect.Right - Rect.Left, 
     Rect.Bottom - Rect.Top, 
     FBg.Canvas.Handle, 
     Rect.Left, 
     Rect.Top, 
     SRCCOPY); 
    if gdSelected in State then 
    InvertRect(TStringGrid(Sender).Canvas.Handle, Rect); 
    r := Rect; 
    TStringGrid(Sender).Canvas.Brush.Style := bsClear; 
    DrawText(TStringGrid(Sender).Canvas.Handle, 
      TStringGrid(Sender).Cells[ACol, ARow], 
      length(TStringGrid(Sender).Cells[ACol, ARow]), 
      r, 
      DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS); 
end; 

Sample Screenshot http://privat.rejbrand.se/drawgridbg.png Sample Screenshot http://privat.rejbrand.se/drawgrid2.png Sample Screenshot http://privat.rejbrand.se/drawgrid3.png

+5

好的答案,但是這也適用於TStringGrid,因爲它從TDrawGrid繼承。 – GolezTrol 2011-03-12 21:49:17

+0

@GolezTrol:好點。 – 2011-03-12 21:50:12

+0

@David,等:我不確定:首先,我認爲我需要確保我不會嘗試使BitBlt讀取像素不在源位圖中,但它看起來像函數能夠以最有效的方式處理這種輸入,即糾正「錯誤」輸入(例如'Copy',其中您經常將'MaxInt'指定爲字符串的長度)。你能否在這個問題上給我啓發? – 2011-03-12 22:42:18

1

是的,這是可能的。 TStringGrid從TDrawGrid繼承,並自行繪製。您可以使用OnDrawCell事件來執行自定義繪圖。

4

雖然在他對Andreas Rejbrand的代碼的評論中實際回答了rossmcm的明確問題,但它也補充了hís對原始問題的回答。

繪畫不只是網格邊界圖像,但仍StringGrid控制範圍內可以按如下方式實現:

type 
    TStringGrid = class(Grids.TStringGrid) 
    private 
    FGraphic: TGraphic; 
    FStretched: Boolean; 
    function BackgroundVisible(var ClipRect: TRect): Boolean; 
    procedure PaintBackground; 
    protected 
    procedure Paint; override; 
    procedure Resize; override; 
    procedure TopLeftChanged; override; 
    public 
    property BackgroundGraphic: TGraphic read FGraphic write FGraphic; 
    property BackgroundStretched: Boolean read FStretched write FStretched; 
    end; 

    TForm1 = class(TForm) 
    StringGrid: TStringGrid; 
    Image: TImage; 
    procedure FormCreate(Sender: TObject); 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TStringGrid } 

function TStringGrid.BackgroundVisible(var ClipRect: TRect): Boolean; 
var 
    Info: TGridDrawInfo; 
    R: TRect; 
begin 
    CalcDrawInfo(Info); 
    SetRect(ClipRect, 0, 0, Info.Horz.GridBoundary, Info.Vert.GridBoundary); 
    R := ClientRect; 
    Result := (ClipRect.Right < R.Right) or (ClipRect.Bottom < R.Bottom); 
end; 

procedure TStringGrid.Paint; 
begin 
    inherited Paint; 
    PaintBackground; 
end; 

procedure TStringGrid.PaintBackground; 
var 
    R: TRect; 
begin 
    if (FGraphic <> nil) and BackgroundVisible(R) then 
    begin 
    with R do 
     ExcludeClipRect(Canvas.Handle, Left, Top, Right, Bottom); 
    if FStretched then 
     Canvas.StretchDraw(ClientRect, FGraphic) 
    else 
     Canvas.Draw(0, 0, FGraphic); 
    end; 
end; 

procedure TStringGrid.Resize; 
begin 
    inherited Resize; 
    PaintBackground; 
end; 

procedure TStringGrid.TopLeftChanged; 
begin 
    inherited TopLeftChanged; 
    PaintBackground; 
end; 

{ TForm1 } 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    // Usage: 
    StringGrid.BackgroundGraphic := Image.Picture.Graphic; 
    StringGrid.BackgroundStretched := True; 
end; 

如果你想畫在細胞中的形象好,然後再結合這兩種技術。他們不遵循同樣的方法,因爲安德烈亞斯使用我聲明後代的事件,不應該導致合併時的困難。

+0

請注意,將tstringgrid代碼移動到一個單獨的單元(如nglncontrol)可以很好地處理designtime表單,如果要麼將單元放在USES子句中,要麼使用typealias(在表單聲明前鍵入TStringGrid = nglncontrol.TStringGrid )。我使用後者。 – 2013-01-09 14:21:51