我想在字符串网格中的单元格的画布上绘制。这将在预先加载到字符串网格中的图像之上。
目前我没有在图像上绘图,而是加载第二个透明图像,然后在单元格顶部绘画。这是我使用的代码,它可以工作。
procedure TfrmCavern.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
index : integer;
I : integer;
begin
// Calculate the corresponding linear index
index := LinearIndexOf(ARow, ACol);
//Draw image referenced to cell
StringGrid.Canvas.StretchDraw(Rect, CellDetails[index].Images.Picture.Graphic);
//if player present draw corresponding player image
for I := 0 to frmWelcome.NoofPlayers - 1 do
begin
if index = Players[I].pIndex then StringGrid.Canvas.StretchDraw(Rect,Players[I].UserImage.Picture.Graphic);
end;
end;
end;
该过程首先绘制参考单元格的图像。如果有“玩家”存在,则会将玩家的棋子画在上面。因为“播放器片段”图像是透明的.PNG图像,所以下面的原始图像仍然可见。
这种方法的缺点是由于图像是恒定的,“玩家作品”处于单元格内的设定位置。我希望能够根据选择的单元格在单元格内的不同位置绘制“播放器块”。我有大约200个单元格,所以我真的不想手动创建具有不同位置的许多图像。
我已经尝试直接绘制到drawcell过程中的stringgrid的画布,但是它似乎引用了整个stringgrid而不是正在绘制的当前单元格。
StringGrid.Canvas.ellipse(10,10,50,50);
我看了但是我似乎无法引用当前单元格的画布 - 我认为它不存在?
接下来我尝试绘制临时图像,然后将图像绘制到单元格中。
TempImage.Canvas.Ellipse(10,10,50,50);
StringGrid.Canvas.StretchDraw(Rect, TempImage.Picture.Graphic);
这在一定程度上起作用,它确实将图像绘制到单元格,但是图像具有不透明的背景/画布,因此单元格为白色,其上有圆圈,下面的图像不可见。我做了一些研究,但找不到使图像画布透明的方法。
我能想到的最后一件事就是编写一个算法来定位当前单元格的左上角,然后从那里直接绘制到画布上,但这可能是泥泞的,并且在重新绘制stringgrid时会产生问题。 / p>
任何人都能看到我的问题吗?
提前致谢, 约什
答案 0 :(得分:4)
只有一个画布,即控件的画布。每个单元格只是该画布内的一个矩形。在画布中找到当前单元格的位置是微不足道的。实际上,这是Rect
参数的用途。 Rect.Left
是单元格的x坐标,Rect.Top
是单元格的y坐标。
或者我误解了你的问题?
答案 1 :(得分:3)
OnDrawCell的Rect
参数指定特定单元格相对于网格客户端坐标系的边界。所以你需要绘制到这个矩形内的坐标。在事件处理程序中尝试这样的事情:
StringGrid.Canvas.Pen.Color := clBlack;
StringGrid.Canvas.Brush.Style := bsClear;
StringGrid.Canvas.Ellipse(
Rect.Left+5,
Rect.Top+5,
Rect.Left+15,
Rect.Top+15
);