StringGrid 中的透明色
Transparent color in StringGrid
我用 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%)。
我该怎么做?
我应该画矩形吗?或者我应该创建位图并放入单元格?
你能帮帮我吗?:)
我的意思是这样的效果:
在 this post 的启发下,我首先创建了一个 TStringGrid
背景图像。然后我使用 WinApi.Windows.AlphaBlend()
为选定的单元格添加透明颜色,类似地为固定单元格添加透明颜色。最终结果是这样的:
透明 "selected" 颜色作为 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] := [=10=]FF00; // BGR
end;
位图应用于 OnDrawCell
事件中的 "selected" 个单元格 (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
子类中或者其他可以访问的地方,我在form中声明,并在formsOnCreate
事件中初始化:
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := 128; // This determines opacity
BlendFunc.AlphaFormat := AC_SRC_ALPHA;
现在,您可能会问,1 像素位图如何工作,答案在 documentation for AlphaBlend()
:
If the source rectangle and destination rectangle are not the same
size, the source bitmap is stretched to match the destination
rectangle.
这很有用,因为单元格矩形的大小通常不同。
header 行和列在条件 if gdFixed in State
的 OnDrawCell
中类似地绘制,这里使用了另一个位图。这是我在图形绘图程序中单独制作的1像素宽23像素高的位图。
是的!上面那个小东西就是图片
我用 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%)。
我该怎么做?
我应该画矩形吗?或者我应该创建位图并放入单元格?
你能帮帮我吗?:)
我的意思是这样的效果:
在 this post 的启发下,我首先创建了一个 TStringGrid
背景图像。然后我使用 WinApi.Windows.AlphaBlend()
为选定的单元格添加透明颜色,类似地为固定单元格添加透明颜色。最终结果是这样的:
透明 "selected" 颜色作为 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] := [=10=]FF00; // BGR
end;
位图应用于 OnDrawCell
事件中的 "selected" 个单元格 (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
子类中或者其他可以访问的地方,我在form中声明,并在formsOnCreate
事件中初始化:
BlendFunc.BlendOp := AC_SRC_OVER;
BlendFunc.BlendFlags := 0;
BlendFunc.SourceConstantAlpha := 128; // This determines opacity
BlendFunc.AlphaFormat := AC_SRC_ALPHA;
现在,您可能会问,1 像素位图如何工作,答案在 documentation for AlphaBlend()
:
If the source rectangle and destination rectangle are not the same size, the source bitmap is stretched to match the destination rectangle.
这很有用,因为单元格矩形的大小通常不同。
header 行和列在条件 if gdFixed in State
的 OnDrawCell
中类似地绘制,这里使用了另一个位图。这是我在图形绘图程序中单独制作的1像素宽23像素高的位图。
是的!上面那个小东西就是图片