【问题标题】:Delphi StringGrid with picture in backgroundDelphi StringGrid 与背景图片
【发布时间】:2011-03-12 21:37:02
【问题描述】:

您好,有谁知道是否可以将图片显示为字符串网格的背景,或者是否有人知道任何可以做到这一点的免费网格组件。

谢谢

科林

【问题讨论】:

    标签: image delphi tstringgrid


    【解决方案1】:

    您可以使用支持所有者绘图的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;
    

    【讨论】:

    • 好答案,但这也适用于 TStringGrid,因为它继承自 TDrawGrid。
    • @David 等人:我不确定:首先我认为我需要确保我不会尝试让BitBlt 读取源中不存在的像素位图,但似乎该函数能够以最友好的方式处理这种输入,即纠正“不正确”的输入(如Copy,您经常将MaxInt指定为细绳)。能否请您就这个问题赐教?
    • 我认为这仅适用于创建的 TDrawGrid 单元格。如果要求将背景图像扩展到 TDrawGrid 中未被单元格覆盖的部分,即在最后一行或最后一列之后怎么办?
    • @rossmcm:查看附加答案。
    【解决方案2】:

    虽然在他对 Andreas Rejbrand 的代码的评论中实际回答了 rossmcm 的明确问题,但它也补充了他对原始问题的回答。

    绘制超出网格边界但仍在 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;
    

    如果您还想在单元格中绘制图像,则将这两种技术结合起来。他们不遵循相同的方法,因为 Andreas 使用我声明后代的事件,不应该导致合并有很大困难。

    【讨论】:

    • 请注意,将 tstringgrid 代码移动到一个单独的单元(比如 nglncontrol)可以很好地用于设计时表单,如果您将单元放在 USES 子句的最后,或者使用类型别名(类型 TStringGrid= nglncontrol.TStringGrid 在表单声明之前)。我使用后者。
    【解决方案3】:

    是的,这是可能的。 TStringGrid 继承自 TDrawGrid 并自行完成所有绘图。您可以使用 OnDrawCell 事件进行自定义绘图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2013-08-16
      • 2022-07-21
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多