dummzeuch 1515 Posted March 29 (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); var info: TScrollInfo; begin FillChar(info, SizeOf(info), 0); with info do begin 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" end; SetScrollInfo(StringGrid1.Handle, SB_VERT, info, True); end; 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: ///<summary> /// 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); var Info: TScrollInfo; Size: Integer; begin 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); end; (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 March 29 by dummzeuch Share this post Link to post
FrankB99 0 Posted July 23 HI, I'm working every now and then on ExifToolGui. https://github.com/FrankBijnen/ExifToolGui I had a request from someone to change the scrollbar of the Metadatalist to a proportional one. The metadatalist is a TValueListEditor and a descendant of TStringGrid. And thus has the same problems as the TStringGrid. My solution, until I find something better, is to: Set ScrollBars to ssNone, so the problematic code in Vcl.Grids is bypassed. (I only care about the Vertical ScrollBar) Override: procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED; procedure WMSize(var Msg: TWMSize); message WM_SIZE; procedure SizeChanged(OldColCount, OldRowCount: Longint); override; And set the parameters myself. Override: procedure TopLeftChanged; override; And reposition the scrollbar accordingly Override: procedure WMVScroll(var Msg: TWMVScroll); message WM_VSCROLL; And reposition the grid. The code can be enabled by setting the property ProportionalVScroll to true. The complete source can be found here: https://github.com/FrankBijnen/ExifToolGui/blob/main/Source/ExifToolsGui_ValEdit.pas (It contains some more additions, that you can ignore) Hope this helps, And of course if you have tips, dont hesitate.... Frank Share this post Link to post