【问题标题】:Transparent color in StringGridStringGrid 中的透明颜色
【发布时间】:2016-10-12 13:10:08
【问题描述】:

我用 StringGrid 绿色填充单元格

procedure TForm1.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin

StringGrid.Canvas.Brush.Color := clGreen;
StringGrid.Canvas.FillRect(Rect);

StringGrid.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, AGrid.Cells[ACol, ARow]);

end;

我的 StringGrid 是黑色的。我想填充单元格透明颜色(例如 50%)。

我该怎么做?

我应该画矩形吗?或者我应该创建位图并放入单元格?

你能帮我吗?:)

意思是这样的效果:

【问题讨论】:

  • 我不明白你有什么,你想做什么......
  • 我想将单元格着色为透明的 - alpha,无论如何;)
  • 您的意思是要部分查看表单/面板的背景或插入网格的其他内容?
  • StringGrid.Color:=whatever 时 StringGrid 的最终背景;我有彩色单元格。
  • 看看this question-answer。结合使用 AR 和 NGLN 答案。

标签: delphi pascal lazarus freepascal stringgrid


【解决方案1】:

this post 的启发下,我首先创建了一个TStringGrid,背景中有一张图片。然后,我使用WinApi.Windows.AlphaBlend() 为选定的单元格添加了透明颜色,同样为固定单元格添加了透明颜色。最终结果是这样的:

透明的“选定”颜色作为 1 像素位图完成:

type
  TStringGrid = class(Vcl.Grids.TStringGrid)
  private
    FBackG: TBitmap;
    FForeG: TBitmap;
  ...

procedure TForm5.Button1Click(Sender: TObject);
begin
  sg.FForeG.Free;
  sg.FForeG := TBitmap.Create;
  sg.FForeG.SetSize(1, 1);
  sg.FForeG.PixelFormat := pf32bit;
  sg.FForeG.Canvas.Pixels[0, 0] := $00FF00;  // BGR
end;

并且位图应用于OnDrawCell事件中的“选定”单元格(gdSelected in State

procedure TForm5.sgDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
  State: TGridDrawState);
var
  sg: TStringGrid;
  r: TRect;
  success:boolean;
begin
  if not (Sender is TStringGrid) then Exit;
  sg := Sender as TStringGrid;

  r := Rect;
  r.Left := r.Left-4; // Might not be needed, depending on Delphi version?

  // Clear the cell
  sg.Canvas.Brush.Color := clBlack;
  sg.Canvas.FillRect(r);

  // Copy background to cell
  BitBlt(sg.Canvas.Handle,
    r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
    sg.FBackG.Canvas.Handle, r.Left, r.Top, SRCCOPY);

    // Draw fixed column or row cell(s)
  if gdFixed in State then
  begin
    success := Winapi.Windows.AlphaBlend(sg.Canvas.Handle,
      r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
      sg.FHeadG.Canvas.Handle, 0, 0, 1, 23, BlendFunc);
  end;

  // Draw selected cell(s)
  if gdSelected in State then
  begin
    success := Winapi.Windows.AlphaBlend(sg.Canvas.Handle,
      r.Left, r.Top, r.Right - r.Left, r.Bottom - r.Top,
      sg.FForeG.Canvas.Handle, 0, 0, 1, 1, BlendFunc);
  end;

  // Draw the text
  r := Rect;
  sg.Canvas.Brush.Style := bsClear;
  DrawText(sg.Canvas.Handle, sg.Cells[ACol, ARow],
    length(sg.Cells[ACol, ARow]), r,
    DT_SINGLELINE or DT_VCENTER or DT_END_ELLIPSIS);
end;

BlendFunc: _BLENDFUNCTION; 结构可以在TStringGrid 子类或其他可访问的地方声明,我在表单中声明它并在表单OnCreate 事件中对其进行初始化:

  BlendFunc.BlendOp := AC_SRC_OVER;
  BlendFunc.BlendFlags := 0;
  BlendFunc.SourceConstantAlpha := 128;  // This determines opacity
  BlendFunc.AlphaFormat := AC_SRC_ALPHA;

现在,您可能会问,1 像素位图是如何工作的,答案在 documentation 中为 AlphaBlend()

如果源矩形和目标矩形不相同 大小,源位图被拉伸以匹配目标 矩形。

这很有用,因为单元格矩形的大小通常不同。

OnDrawCell 条件if gdFixed in State 中类似地绘制标题行和列,这里使用另一个位图。它是我在图形绘图程序中单独制作的一个 1 像素宽和 23 像素高的位图。

是的!上面的小东西是图像。

【讨论】:

    猜你喜欢
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2013-09-02
    • 2015-04-17
    相关资源
    最近更新 更多