Delphi StringGrid with picture in background

2019-02-15 06:24发布

Hi does anyone know if it is possible to display a picture as a background to a string grid, Or is anyone aware of any free Grid component that can do this.

Thanks

colin

3条回答
祖国的老花朵
2楼-- · 2019-02-15 07:04

You could use a TDrawGrid (or a TStringGrid), which supports owner-drawing, and do

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

where FBg is a TBitmap (in the form class, for instance), and then do

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

查看更多
三岁会撩人
3楼-- · 2019-02-15 07:10

While actually answering here the explicit question of rossmcm in his comment to the code of Andreas Rejbrand, it also complements hís answer to the original question.

Drawing the image beyond the grid boundary, but still within the StringGrid control bounds could be achieved as follows:

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;

If you want to draw the image in the cells as well, then combine both techniques. That they do not follow the same approach, for Andreas uses events where I declare a descendant, should not lead to great difficulty with merging.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-02-15 07:26

Yes, it is possible. TStringGrid inherits from TDrawGrid and does all drawing on its own. You can use the OnDrawCell event to do custom drawing.

查看更多
登录 后发表回答