7

我想在字符串网格中的单元格的画布上绘制。这将位于预加载到字符串网格中的图像之上。

我有什么

目前,我不是在图像顶部绘制,而是加载第二个透明图像,然后在单元格顶部绘制。这是我使用的代码,它可以工作。

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);

这在一定程度上起作用,它确实将图像绘制到单元格,但是图像具有不透明的背景/画布,因此单元格是白色的,上面有圆圈,下面的图像不可见。我做了一些研究,但找不到使图像的画布透明的方法。

我能想到的最后一件事是编写一个算法来定位当前单元格的左上角,然后从那里直接绘制到画布上,但这可能会很麻烦,并且在重绘字符串网格时会产生问题。

任何人都可以看到解决我的问题的方法吗?

在此先感谢,乔希

4

2 回答 2

4

只有一个画布,即控件的画布。每个单元格只是此画布内的一个矩形。在画布中找到当前单元格的位置很简单。实际上,这就是Rect参数的用途。Rect.Left是单元格的 x 坐标, 是单元格Rect.Top的 y 坐标。

还是我误解了你的问题?

于 2011-03-05T14:31:55.263 回答
3

RectOnDrawCell的参数指定特定单元格的边界,相对于网格的客户端坐标系。因此,您需要绘制位于该矩形内的坐标。在您的事件处理程序中尝试这样的事情:

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
);
于 2011-03-05T14:35:33.563 回答