Jump to content

Configuring the vertical scroll bar of TStringGrid

Recommended Posts

Posted (edited)

Given a TStringGrid with

FixedRows = 1

FixedCols = 0

RowCount = 51 (50 data rows)

ColCount = 3

I want to configure the vertical scroll bar so that the thumb represents the part of the string grid that is visible relative to the full height.


I found an article on SwissDelphiCenter which gives the folowing code:

procedure TForm1.Button1Click(Sender: TObject);
  info: TScrollInfo;
  FillChar(info, SizeOf(info), 0);
  with info do
    cbsize := SizeOf(info);
    fmask  := SIF_ALL;
    GetScrollInfo(StringGrid1.Handle, SB_VERT, info);
    fmask := fmask or SIF_PAGE;
    nPage := 5 * (nmax - nmin) div StringGrid1.RowCount;
    // whatever number of cells you consider a "page"
  SetScrollInfo(StringGrid1.Handle, SB_VERT, info, True);

As far as I understand this, it sets the thumb size to represent 5 rows.

I looked up the documentation of GetScrollInfo and SetScrollInfo and came up with a slightly modified version:

/// Sets the thumb of the scroll bar of a TStringGrid to represent the visible area relative to the full area.
/// @param GridHandle is the window handle of a TStringGrid
/// @param Which is either SB_VERT or SB_HORZ
/// @Param VisibleCount is TStringGrid.VisibleRows (for SB_VERT) or .VisibleCols (for SB_HORZ)
/// @param DataCount is number of non-fixed rows (for SB_VERT) or columns (for SB_HORZ) </summary>
procedure TStringGrid_AdjustScrollBarPage(_GridHandle: HWND; _Which: Integer; _VisibleCount, _DataCount: Integer);
  Info: TScrollInfo;
  Size: Integer;
  Size := SizeOf(Info);
  ZeroMemory(@Info, Size);
  Info.cbSize := Size;
  Info.fMask := SIF_ALL;
  GetScrollInfo(_GridHandle, _Which, Info);
  Info.fMask := SIF_PAGE or SIF_RANGE;
  Info.nPage := _VisibleCount;
  Info.nMin := 1;
  Info.nMax := _DataCount;
  SetScrollInfo(_GridHandle, _Which, Info, True);

(I can probably get rid of the call to GetScrollInfo, as I don't need the values of nMin and nMax to calculate nPage)

I call it in the form's Resize event like this:

TStringGrid_AdjustScrollBarPage(TheGrid.Handle, SB_VERT, TheGrid.VisibleRowCount, TheGrid.RowCount - TheGrid.FixedRows);

(Which sets nPage to 10, nMin to 1 and nMax to 50.)


And it seems to work ...


... at least visually. Unfortunately moving the thumb down to the bottom no longer shows the last lines of the grid:


(Remember: There are 50 data rows + 1 fixed row)


What am I doing wrong here? Is there some other value I need to adjust?


Edit: The culprit seems to be the code in TCustomGrid.ModifyScrollBar which calculates the new NewTopLeft value wrongly. Possibly because it makes some assumptions that are no longer true when the scrollbar parameters are set like this. So I either need to figure out a different way to set those parameters or handle the WM_VSCROLL message myself.

Edited by dummzeuch

Share this post

Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now