【问题标题】:How do I get screen coordinates of the DBGrid cell如何获取 DBGrid 单元格的屏幕坐标
【发布时间】:2012-02-20 02:38:46
【问题描述】:

我想在当前行的特定单元格的右下角显示弹出按钮或花哨的消息(带有彩色背景等)。

目前我只知道如何获取网格坐标:
x = DBGrid.DataSource.DataSet.RecNo
y = DBGrid.Columns[索引]

还有TCustomGrid.CellRect,它可以做我想做的事,但它是受保护的,我不想继承和创建另一个组件类。

我能想到的一个疯狂的解决方法是将 onDrawColumnCell 事件中的 TRect-s 保存到某个数组中。

那么,你怎么看?

编辑
如何获取当前行中第二个单元格的屏幕坐标?

【问题讨论】:

  • @downvoter:问题是不是建设性的或过于开放的问题或不是一个真正的问题?你能详细说明一下,以便我改进它吗?
  • 我不是反对者,但我怀疑这是因为您的问题不清楚。你想要当前选中的单元格、鼠标下的单元格、被点击的单元格,还是别的什么?
  • @KenWhite:感谢您的反馈。现在好点了吗?
  • 稍微好一点。顺便说一句,您的任何解决方案都不起作用。 RecNo 并不一定意味着什么;索引顺序会影响行顺序,Columns[Index] 给你列而不是行,在OnDrawColumnCell 中保存坐标将无济于事,因为它与网格中的当前行没有关系,除非在绘制单元格期间. (我(还)没有提供解决方案,但我可以看到你正在考虑做的事情的缺陷。)

标签: delphi delphi-6 tdbgrid


【解决方案1】:

你可以得到当前的单元格坐标,使用一点欺骗。 :)

允许组件的后代访问祖先类的受保护字段。因为除了获得对TDBGrid 的受保护的CellRect 方法的访问权之外我们不需要做任何事情,我们将创建一个插入器(不做任何事的后代),它只允许我们访问该受保护的方法。然后我们可以将TDBGrid 类型转换为新的后代类,并使用它来访问受保护的方法。我使用THack 作为前缀命名后代,以明确后代的唯一目的是获得对祖先类的访问(“破解”)。

// implementation
type
  THackDBGrid=class(TDBGrid);

// Where you need the coordinates
var
  CurrRow: Integer;
  Rect: TRect;
begin
  CurrRow := THackDBGrid(DBGrid1).Row;
  Rect := THackDBGrid(DBGrid1).CellRect(ColIndexYouWant, CurrRow);
  // Rect now contains the screen coordinates you need, or an empty
  // rectangle if there is no cell at the col and row specified.
end;

正如 OP 在评论中指出的那样,delphi.about.com 有关于其工作原理的更详细描述。

【讨论】:

  • 有效!非常感谢。顺便说一句,我在谷歌搜索时见过这个解决方案一两次,但不知何故认为不是
  • 对于那些对为什么会起作用感兴趣的人,它被称为“受保护的黑客”。该技术利用了这样一个事实,即类的受保护成员对于在与该类相同的单元中定义的所有方法都是可见的。简短的例子here on SO,更详细的在by Zarko Gajic
  • 如果这回答了您的问题,请问您为什么不接受它是正确的?
  • 实际上我已经接受了 :),但后来决定稍等片刻,让其他人回答(顺便说一句,并为你的答案投票),也许有人会想出没有破解的解决方案。事实上,几乎没有人愿意回答会看封闭的问题。
  • 其实这是最好的解决方案。您可以将THackDBGrid 更改为TDBGridAccess,如果它可以减轻您的压力:) 转换TDrawGrid(DBGrid1).CellRect 也可以,但我不太喜欢这种解决方案,因为TDrawGrid.CellRect 的实现可能会改变(现在是Result := inherited CellRect(ACol, ARow))。跨度>
猜你喜欢
  • 2021-04-23
  • 2013-03-20
  • 1970-01-01
  • 2021-10-22
  • 2015-08-01
  • 2011-08-15
  • 1970-01-01
  • 2016-02-29
  • 1970-01-01
相关资源
最近更新 更多