Delphi - 绘制到字符串网格中选定单元格的画布 - 可能吗?
我想在字符串网格中的单元格的画布上绘制。这将位于预加载到字符串网格中的图像之上。
我所得到的
目前,我不是在图像顶部绘制,而是加载第二个透明图像,然后在单元格顶部绘制。这是我使用的代码并且它有效。
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);
这在一定程度上有效,它确实将图像绘制到单元格上,但是图像具有不透明的背景/画布,因此单元格是白色的,上面有圆圈,下面的图像不可见。我做了一些研究,但找不到使图像画布透明的方法。
我能想到的最后一件事是编写一个算法来定位当前单元格的左上角,然后从那里直接绘制到画布,但这可能会很麻烦,并且在重新绘制字符串网格时会产生问题。
有人能找到解决我的问题的方法吗?
提前致谢, 乔什
I want to draw on the canvas of a cell in a string grid. This is going to be on top of an image preloaded into the string grid.
What I've got
Currently instead of drawing on top of the image, I am loading a second transparent image and then painting on top of the cell. This is the code I use and it works.
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;
The procedure first draws the image referenced to the cell. If there is a "player" present it will then draw the player piece on top. Because the "player piece" image is a transparent .PNG image the original image underneath is still visible.
What I want
The draw back of this method is that the "player piece" is in a set position within the cell due to the image being constant. I want to be able to draw the "player piece" in a different position within the cell depending on which cell is selected. I have around 200 cells so I dont really want to manually create that many images with different positions.
What I've tried
I've tried drawing directly to the canvas of the stringgrid within the drawcell procedure but that appeared to reference the entire stringgrid rather than the current cell that was being drawn.
StringGrid.Canvas.ellipse(10,10,50,50);
I've looked but I cant seem to be able to reference the canvas of the current cell - I presume it doesn't exist?
The next thing I tried was drawing to a temporary image and then drawing the image to the cell.
TempImage.Canvas.Ellipse(10,10,50,50);
StringGrid.Canvas.StretchDraw(Rect, TempImage.Picture.Graphic);
This worked to an extent, it did draw the image to the cell, however the image had an opaque background/canvas so the cell was white with the circle on it, the image beneath was not visible. I did a bit of research but couldn't find a way to make the canvas of the image transparent.
The last thing I can think of trying is to write an algorithm to locate the top left point of the current cell and then draw direct to the canvas from there, but that could be sloggy and create issues when redrawing the stringgrid.
Can anyone see a way around my issue?
Thanks in advance,
Josh
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
OnDrawCell 的 Rect 参数指定特定单元格相对于网格客户端坐标系的边界。因此,您需要绘制位于该矩形内的坐标。在你的事件处理程序中尝试这样的事情:
The
Rect
parameter to OnDrawCell specifies the bounds of the particular cell, relative to the grid's client coordinate system. So you need to draw to coordinates that lie within this rectangle. Try something like this in your event handler:只有一张画布,即控件的画布。每个单元格只是画布内的一个矩形。找到当前单元格在画布中的位置很简单。事实上,这就是 Rect 参数的用途。
Rect.Left
是单元格的 x 坐标,Rect.Top
是单元格的 y 坐标。或者我误解了你的问题?
There is only one canvas, the control's canvas. Each cell is merely a rectangle inside this canvas. It is trivial to find the position of the current cell in the canvas. Indeed, this is what the
Rect
parameter is for.Rect.Left
is the x coordinate of the cell, andRect.Top
is the y coordinate of the cell.Or did I misinterpret your question?