I think you are making a logical error: the buttons are not moved when you scroll the grid. Though it may seem like they move, that is just the result of moving the device context contents due to an internal call to ScrollWindow
. The scroll bars in the string grid component are custom added, and do not work like those of e.g. a TScrollBox
.
To always show all buttons on the locations where they really are, repaint the string grid in the OnTopLeftChanged
event:
procedure TForm1.StringGrid1TopLeftChanged(Sender: TObject);
begin
StringGrid1.Repaint;
end;
When the row heights of all rows and the height of string grid never change, then it is sufficient to create all buttons only once, and let them stay where they are. This means that every button no longer is "attached" to a row, and storing them in the Objects
property has no significance any more. When a button is pressed, simply calculate the intended row index from the position of the button in combination with the TopRow
property of the string grid which specifies the index of the first visible scrollable row in the grid.
If the grid can resize, e.g. by anchors, then update the button count in the parent's OnResize event. And if the row count of the string grid may become less then the maximum visible row count, then also update the (visible) button count.
If you want more of an answer, then please update your question and explain how the MoveRowPlus
and the MoveRowMinus
routines are called due to interaction with the grid and or buttons, because now I do not fully understand what it is that you want.
And about CellRect
giving the wrong coordinates: that is because CellRect
only works on full (or partial) visible cells. To quote the documentation:
If the indicated cell is not visible, CellRect
returns an empty rectangle.
Best Answer
Better late than never... I use
WM_SETREDRAW
. For example: