Как получить экранные координаты ячейки DBGrid

Я хочу показать всплывающую кнопку или необычное сообщение (с цветным фоном и т. д.) прямо под правым нижним углом конкретной ячейки текущей строки.

Пока я только понял, как получить координаты сетки:
x = DBGrid.DataSource.DataSet.RecNo
y = DBGrid.Columns[index]

Также есть TCustomGrid.CellRect, который будет делать то, что я хочу, но он защищен, и я не хочу наследовать и создавать еще один класс компонента.

Один сумасшедший обходной путь, который я могу придумать, - это сохранить TRect-s в событии onDrawColumnCell в какой-то массив.

Так что ты думаешь ?

EDIT
Как получить координаты экрана, скажем, второй ячейки в текущей строке?


person Alexander Malakhov    schedule 20.02.2012    source источник
comment
@downvoter: вопрос неконструктивный, слишком открытый или ненастоящий? Не могли бы вы уточнить, чтобы я мог улучшить его?   -  person Alexander Malakhov    schedule 20.02.2012
comment
Я не против, но я подозреваю, что это потому, что ваш вопрос не ясен. Вам нужна текущая выделенная ячейка, ячейка под мышью, ячейка, по которой щелкнули, или что-то еще?   -  person Ken White    schedule 20.02.2012
comment
@KenWhite: спасибо за отзыв. Сейчас лучше?   -  person Alexander Malakhov    schedule 20.02.2012
comment
Это немного лучше. Ни одно из ваших решений не будет работать, кстати. RecNo ничего не значит; Порядок индекса может повлиять на порядок строк, Columns[Index] дает вам столбец, но не строку, и сохранение координат в OnDrawColumnCell не поможет, так как он не имеет отношения к текущей строке в сетке, кроме как во время рисования ячейки. (У меня нет решения, которое я мог бы предложить (пока), но я вижу недостатки в том, что вы думаете сделать.)   -  person Ken White    schedule 20.02.2012


Ответы (1)


Получить текущие координаты ячейки можно, применив небольшой обман. :)

Потомкам компонента разрешен доступ к защищенным полям класса-предка. Поскольку нам не нужно ничего делать, кроме как получить доступ к защищенному методу CellRect метода TDBGrid, мы создадим интерпозер (ничего не делающий потомок), который просто позволит нам получить доступ к этому защищенному методу. Затем мы можем привести тип 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;

Как указал ОП в комментарии, более подробное описание того, как это работает, есть на delphi.about.com.

person Ken White    schedule 20.02.2012
comment
работает! Большое спасибо. Кстати, я видел это решение один или два раза, когда гуглил, но почему-то подумал, что это не так. - person Alexander Malakhov; 20.02.2012
comment
для тех, кому интересно, почему это работает, это называется Protected Hack. Этот метод использует тот факт, что защищенные члены класса видны всем методам, определенным в том же модуле, что и класс. Краткий пример здесь на SO, более подробный на от Zarko Gajic - person Alexander Malakhov; 20.02.2012
comment
Если это отвечает на ваш вопрос, могу ли я спросить, почему вы не считаете это правильным? - person Ken White; 20.02.2012
comment
на самом деле я принял это :), но потом решил немного подождать, чтобы другие ответили (и проголосовали за ваш ответ, кстати), может быть, кто-то придумает решение без взлома. Правда практически никто из желающих ответить не будет смотреть на закрытый вопрос. - person Alexander Malakhov; 20.02.2012
comment
на самом деле это лучшее решение. вы можете изменить THackDBGrid на TDBGridAccess, если это сделает вас менее напряженным :) литье TDrawGrid(DBGrid1).CellRect также сработает, но мне это решение нравится меньше, потому что реализация TDrawGrid.CellRect может измениться (на данный момент это Result := inherited CellRect(ACol, ARow)). - person kobik; 20.02.2012
comment
@kobik: if it makes you less stressed - я подумаю )) - person Alexander Malakhov; 21.02.2012
comment
@KenWhite: опечатка - CellRect(ColIndexYouWant, Row) --> CellRect(ColIndexYouWant, CurrRow) - person Alexander Malakhov; 22.02.2012
comment
Хороший улов. Я исправлю это для дальнейшего использования. Спасибо. :) - person Ken White; 22.02.2012