Delphi StringGrid with picture in background

后端 未结 3 795
再見小時候
再見小時候 2021-01-06 18:10

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

相关标签:
3条回答
  • 2021-01-06 18:32

    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.

    0 讨论(0)
  • 2021-01-06 18:34

    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.

    0 讨论(0)
  • 2021-01-06 18:38

    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 Sample Screenshot Sample Screenshot

    0 讨论(0)
提交回复
热议问题