2
votes

I'm making a simple application in Delphi XE2 which uses specifically the "Carbon" style. There's a large String Grid which has thousands of rows. I have a process which loops through the records of this grid, does some work, and makes some changes in the grid. As the process loops, the row which is being currently processed gets highlighted (by setting TStringGrid.Row).

The problem is that when I apply the style to this grid, the scroll bar doesn't change position as the row is changed. The loop does properly highlight each row as it's being processed, but by the time it gets towards the end of the list, the scroll bar on the right is still all the way at the top.

How do I make the grid's scroll bar move along with it?

Here's a sample of how I'm looping:

procedure TForm1.Button1Click(Sender: TObject);
var
  X: Integer;
begin
  FStop:= False;
  for X:= 1 to Grid.RowCount - 1 do begin
    if FStop then Break; //Ability to stop loop
    Grid.Row:= X; //Highlight current row
    DoSomeLenghyWork;
    ChangeSomethingOnGrid;
    Application.ProcessMessages; //Keep program responding
  end;
end;

Everything works just fine when I'm not using any styles.

2
This sounds like a bug to me. Invalidate is the way to force a paint cycle. I think I'd be inclined to do the processing in the background and use a virtual control (e.g. list view in virtual mode) to update UI. Update the UI on a timer, e.g. every second. - David Heffernan
I am converting it to process each item in a thread anyway, and am putting messages for various events. I can have one MSG_BEGIN, MSG_END, MSG_NEXT, MSG_ERROR etc. - Jerry Dodge
You should have a thread to do the work and then run a timer in the main thread to get the UI updates. Use a virtual list view to display. Syncronisation with a lock is probably sufficient. - David Heffernan
VirtualTreeView would be far better (working as a virtual grid in this case) than TStringGrid. - Warren P

2 Answers

2
votes
  1. If invalidate and repaint don't do anything for you, try resizing the string grid:

    Grid.Width := Grid.Width - 1; Grid.Width := Grid.Width + 1;

  2. Try playing with the string grid options that hide and show the scrollbars. Hide them before you update and show them after. Perhaps that will force them to repaint.

  3. Try moving the scroll position and moving it back to the original position.

2
votes

This worked for me - it forces windows to repaint the border area of the StringGrid:

SetWindowPos(Grid.Handle, 0, 0, 0, Grid.Width, Grid.Height, SWP_DRAWFRAME);