Recent

Author Topic: Smooth scrolling a TDrawGrid programmatically?  (Read 11293 times)

Manlio

  • Full Member
  • ***
  • Posts: 164
  • Pascal dev
Smooth scrolling a TDrawGrid programmatically?
« on: April 01, 2024, 08:18:04 pm »
When the smooth scrolling option of a TDrawGrid component is set, we can scroll it down pixel by pixel.

But can we also do that programmatically?

I thought there must be a way, but I could not find it. The scroll bars are not exposed,  ScrollBy doesn't seem to have any effect, and so on - anything I tried didn't work.

Can anyone show me an example of how to scroll up and down by a few pixels?

If possible, something that works on Windows and Mac.

Thank you.
manlio mazzon gmail

jamie

  • Hero Member
  • *****
  • Posts: 6137
Re: Smooth scrolling a TDrawGrid programmatically?
« Reply #1 on: April 02, 2024, 01:14:30 am »
Use the "GetScrollInfo" first and from that, make your changes and then use the SetScrollInfo.

These are Windows API's but they should be supported via the LclTinf unit.

You may also need to use the lclType unit

The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6137
Re: Smooth scrolling a TDrawGrid programmatically?
« Reply #2 on: April 02, 2024, 02:02:34 am »
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,lcltype,
  9.   lclIntf,Lmessages;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     DrawGrid1: TDrawGrid;
  19.     procedure Button1Click(Sender: TObject);
  20.   private
  21.  
  22.   public
  23.  
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. {$R *.lfm}
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.Button1Click(Sender: TObject);
  36. Var
  37.   S:TScrollinfo;
  38. begin
  39.   S.fMask :=SIF_Pos;
  40.   GetScrollInfo(DrawGrid1.Handle,sb_Vert,S);
  41.   inc(S.nPos,1);//<< The amount;
  42.   SetScrollInfo(DrawGrid1.Handle,sb_Vert,S,true);
  43.   PostMessage(DrawGrid1.Handle, LM_VScroll,sb_ThumbTrack,0);
  44.  
  45. end;
  46.  
  47. end.
  48.  
  49.  
The only true wisdom is knowing you know nothing

Manlio

  • Full Member
  • ***
  • Posts: 164
  • Pascal dev
Re: Smooth scrolling a TDrawGrid programmatically?
« Reply #3 on: April 02, 2024, 02:58:47 pm »
Thank you Jamie, it works perfectly. Very appreciated!

And while I'm here, may I ask another question, also related to TDrawGrid scrolling:

Is it possible to be notified when the user moves the scroll bar?

(And thanks again!)
manlio mazzon gmail

jamie

  • Hero Member
  • *****
  • Posts: 6137
Re: Smooth scrolling a TDrawGrid programmatically?
« Reply #4 on: April 03, 2024, 12:58:03 am »
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,Lmessages,lclType,lclintf;
  9.  
  10. type
  11.  TDrawGrid = Class(Grids.TDrawGrid)
  12.    Procedure WMVScroll(Var Msg:TLmessage) Message LM_VScroll;
  13.  end;
  14.  
  15.   { TForm1 }
  16.  
  17.   TForm1 = class(TForm)
  18.     DrawGrid1: TDrawGrid;
  19.   private
  20.  
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31. Procedure TDrawGrid.WMVScroll(Var Msg:TLmessage);
  32. Var
  33.   S:TScrollInfo;
  34.  Begin
  35.    IF (Msg.lParam =0) Then Begin
  36.       S.cbSize := SizeOf(S);
  37.       S.fMask :=sif_All;
  38.       GetScrollInfo(Handle, SB_Vert, S);
  39.       Form1.Caption := S.nPos.Tostring;
  40.    end;
  41.    inherited;
  42.  end;
  43.  
  44. end.
  45.  
  46.  

The above code will detect a veritical change via the user or even when posted via software, which leads to the next issue.

If you use a Postmessage..... To send a LM_VSCROLL message, like in the first example, you will need to define the last parameter of the message to something other than 0. This way this current snippet of code can tell the difference, because this event will receive both messages Via user or when you post it.

 I can't say if this is going to work across the targets but that is up to you to try.

Jamie

The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018