Recent

Author Topic: Scrolling TStringGrid  (Read 1979 times)

big_M

  • Jr. Member
  • **
  • Posts: 95
Scrolling TStringGrid
« on: September 27, 2023, 12:17:00 pm »
So, how can I scroll a TStringGrid per code?

First I tried to use TStringGrid.ScrollBy(), which apparently is a no-no, and for internal purposes only. (Renders not correctly and doesn't update scroll bars)


Then I tried LCLIntf.GetScrollPos,  LCLIntf.SetScrollPos

Code: Pascal  [Select][+][-]
  1.    
  2. var
  3.   pos: integer;
  4. begin
  5.   pos:=LCLIntf.GetScrollPos(sg.Handle, 0);
  6.   LCLIntf.SetScrollPos(sg.Handle, 0, pos+100, true);
  7.  

That does move the scroll bar, but has no effect on the grid.


Then I tried LCLIntf.GetScrollInfo, LCLIntf.SetScrollInfo

Code: Pascal  [Select][+][-]
  1. var
  2.   si, siCurr: TScrollInfo;
  3. begin
  4.  
  5.   LCLIntf.GetScrollInfo(sg.Handle, 0, siCurr);
  6.   si.cbSize:= SizeOf(si);
  7.   si.fMask:= SIF_POS;
  8.   si.nMin:= siCurr.nMin;
  9.   si.nMax:= siCurr.nMax;
  10.   si.nPage:= siCurr.nPage;
  11.   si.nPos:= siCurr.nPos+100;
  12.   LCLIntf.SetScrollInfo(sg.Handle, 0, si, True);  
  13.  

That works for one scrolling event but then stops (Probably stupid mistake?). But it also doesn't move the grid.

Any ideas? Am I missing a step to make the grid apply the changes? Repainting does nothing.
« Last Edit: September 27, 2023, 12:23:40 pm by big_M »

zeljko

  • Hero Member
  • *****
  • Posts: 1670
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Scrolling TStringGrid
« Reply #1 on: September 27, 2023, 12:59:12 pm »
Are you sure that Pos + 100 isn't > than Max ?

big_M

  • Jr. Member
  • **
  • Posts: 95
Re: Scrolling TStringGrid
« Reply #2 on: September 27, 2023, 01:17:51 pm »
Hm, siCurr.nMax always reports to be 1 :/

I tried to change it like this, but that has no effect, nMax is still 1. Hmm
Code: Pascal  [Select][+][-]
  1.  
  2.   LCLIntf.GetScrollInfo(sg.Handle, 0, siCurr);
  3.   si.cbSize:= SizeOf(si);
  4.   si.fMask:= SIF_RANGE;
  5.   si.nMin:= siCurr.nMin;
  6.   si.nMax:= 1000;
  7.   si.nPage:= siCurr.nPage;
  8.   si.nPos:= siCurr.nPos;
  9.   LCLIntf.SetScrollInfo(sg.Handle, 0, si, True);
  10.  

Zvoni

  • Hero Member
  • *****
  • Posts: 2754
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

big_M

  • Jr. Member
  • **
  • Posts: 95
Re: Scrolling TStringGrid
« Reply #4 on: September 27, 2023, 02:13:07 pm »
TopRow? https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tcustomgrid.toprow.html

Ah, yes, sorry I failed to mention it. TopRow or LeftCol work. The problem is that I don't want to use that, because that doesn't allow partial scrolling of the cells.

big_M

  • Jr. Member
  • **
  • Posts: 95
Re: Scrolling TStringGrid
« Reply #5 on: September 27, 2023, 03:36:43 pm »
Okay, so some more tests.

When I use the combination of GetScrollPos and GetScrollRange (from LCLIntf), the min and max values of the range get at least reported correctly. Now I tried to scroll both a grid and a memo to see if there are any differences.

Now, on both gtk2 and win32, when I use SetScrollPos, the scrollbar moves correctly as mentioned before, but for both components (grid and memo), it doesn't move the content.

On qt5 however, in the case of the memo it works as expected, moving both the scrollbar and the content. Here the grid however doesn't work, updating the scroll bar only once (but not the content).

I attached an example project. Not sure if I should open another report?

zeljko

  • Hero Member
  • *****
  • Posts: 1670
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Scrolling TStringGrid
« Reply #6 on: September 27, 2023, 05:51:19 pm »
https://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.Controls.TWinControl.ScrollBy
Seem that ScrollBy is broken from the end of 2015. See this:
https://lists.lazarus-ide.org/pipermail/lazarus/2015-November/225755.html

It's easy to fix it for all qt widgetsets, but I don't know if there will be problems with TScrollingWinControl.
As I can see viewport.Scroll() is wrong for TCustomControl and higher since it does not scroll as Delphi docs stated, also ScrollBy for TQtAbstractScrollArea have wrong sign for DeltaX and DeltaY when it's applied to scrollbars position.
In any case must have good test case with TCustomControl, TScrollBox, TScrollingWinControl and TCustomMemo to start work on it.

zeljko

  • Hero Member
  • *****
  • Posts: 1670
    • http://wiki.lazarus.freepascal.org/User:Zeljan
Re: Scrolling TStringGrid
« Reply #7 on: September 27, 2023, 09:30:32 pm »
TStringGrid.Options, enabling goThumbTracking works with qt5.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Scrolling TStringGrid
« Reply #8 on: September 27, 2023, 10:43:02 pm »
I think there is some confusion here, last time I looked the ScrollBy was a ScrollDC and all that does is simple scrolls the context of the surface, moves pixels, it does not have anything to do with anything else.

 I'll check back later for a scroll example on the StringGrid.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Scrolling TStringGrid
« Reply #9 on: September 28, 2023, 12:34:38 am »
The LCL, in this case uses the WM_VSCROLL to update the system.

Here is a simple example of scrolling up the items. This all comes from the LCL cross supported units so it should work.
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8. Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Grids, StdCtrls,LclIntF,LclType,LMessages;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     StringGrid1: TStringGrid;
  17.     procedure Button1Click(Sender: TObject);
  18.   private
  19.  
  20.   public
  21.  
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. { TForm1 }
  32.  
  33. procedure TForm1.Button1Click(Sender: TObject);
  34. Var
  35.   I:integer;
  36. begin
  37.   I:= LclIntF.GetScrollPos(StringGrid1.Handle, sb_Vert);
  38.   Inc(I,1);
  39.   SendMessage(StringGrid1.Handle, LM_VScroll,MakeLong(SB_ThumbPosition,I),0);
  40. end;
  41.  
  42. end.
  43.  
  44.  
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 12476
Re: Scrolling TStringGrid
« Reply #10 on: September 28, 2023, 01:11:57 am »
Picking up jamie's solution you can use the following code to scroll the grid horizontally with the mouse wheel:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1MouseWheel(Sender: TObject; Shift: TShiftState;
  2.   WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
  3. const
  4.   STEP = 8;
  5. Var
  6.   I:integer;
  7. begin
  8.   I:= LclIntF.GetScrollPos(StringGrid1.Handle, SB_HORZ);
  9.   if WheelDelta < 0 then
  10.     inc(I, STEP)
  11.   else
  12.   if I > 0 then
  13.     dec(I, STEP);
  14.   SendMessage(StringGrid1.Handle, LM_HScroll, MakeLong(SB_ThumbPosition,I),0);
  15.   Handled := true;
  16. end;

big_M

  • Jr. Member
  • **
  • Posts: 95
Re: Scrolling TStringGrid
« Reply #11 on: September 28, 2023, 02:48:43 pm »
Unfortunately this solution seems to only work with win32. On Linux with gtk2 and qt5 this does move both the content and the scroll bar, however it jumps straight to the end regardless of the step size. Maybe that has something to do with the wrongly reported max value of the range from GetScrollInfo?

For my use case wp's solution in Lazarus trunc works great. (I assume wp is Werner Pamler?)
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/40523#note_1582003246

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Scrolling TStringGrid
« Reply #12 on: September 30, 2023, 11:01:01 pm »
Maybe the other widgets should be fixed because that is standard code for positioning native scroll bars and the contents.
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018