Recent

Author Topic: Synchronize scrolling for two components  (Read 941 times)

wcage03

  • New member
  • *
  • Posts: 5
Synchronize scrolling for two components
« on: November 08, 2018, 12:44:19 am »
I am trying to have multiple TDBGrid components on a page and have them all scroll horizontally in sync (i.e. if the horizontal scroll bar is moved left or right on any one of the components, all will move accordingly).  I have searched for a couple of days on this and I can find the topic in numerous places for other components (mainly TMemo), but I unable to get the examples to work.

Conceptually, I need to be notified that a component is scrolling; capture the scroll position and push that out to the others.  I am not making progress.  I have one example that I found that I have focused on, without luck.  Again, it is for a TMemo, but I figure once I get a solution I can fit it into another component (or at least know that it won't work, if that is the case).  I have attached the code that I found in my search that seemed most straightforward.  When I compile, I get an error in the overridden create method where the handler is being replaced.

If anyone could point me in the right direction with this sample code or toward something more appropriate i would appreciate it.

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, msghandler,
  9.   LCLType, LCLIntf, Buttons, Messages;
  10.  
  11. type
  12.  
  13.   TMemo=class(StdCtrls.TMemo) // Just to add things to TMemo class only for this unit
  14.   private
  15.      BusyUpdating:Boolean; // To avoid circular stack overflow
  16.      SyncMemo:TMemo; // To remember the TMemo to be sync
  17.      Old_WindowProc:TWndMethod; // To remember old handler
  18.      procedure New_WindowProc(var Mensaje:TMessage); // The new handler
  19.   public
  20.      constructor Create(AOwner:TComponent);override; // The new constructor
  21.      destructor Destroy;override; // The new destructor
  22.   end;
  23.  
  24.   { TForm1 }
  25.  
  26.   TForm1 = class(TForm)
  27.     Memo1: TMemo;
  28.     Memo2: TMemo;
  29.     procedure FormCreate(Sender: TObject);
  30.   private
  31.     procedure pnlMemo2Resize(Sender: TObject);
  32.   public
  33.  
  34.   end;
  35.  
  36. var
  37.   Form1: TForm1;
  38.  
  39. implementation
  40.  
  41. {$R *.lfm}
  42. procedure TMemo.New_WindowProc(var Mensaje:TMessage);
  43. begin
  44.      Old_WindowProc(Mensaje); // Call the real handle before doing anything
  45.      if  (WM_PAINT<>Mensaje.Msg) // If not when need to be repainted to improve speed
  46.        or
  47.          BusyUpdating // To avoid circular stack overflow
  48.        or
  49.          (not Assigned(SyncMemo)) // If not yet set (see TForm1.FormCreate bwlow)
  50.      then Exit; // Do no more and exit the procedure
  51.      BusyUpdating:=True; // Set that object is busy in our special action
  52.      SyncMemo.Perform(WM_HSCROLL,SB_THUMBPOSITION+65536*GetScrollPos(Handle,SB_HORZ),0); // Send to the other TMemo a message to set its horizontal scroll as it is on this TMemo
  53.      BusyUpdating:=False; // Set that the object is no more busy in our special action
  54. end;
  55.  
  56. constructor TMemo.Create(AOwner:TComponent); // The new constructor
  57. begin
  58.      inherited Create(AOwner); // Call real constructor
  59.      BusyUpdating:=False; // Initialize as not being in use, to let enter
  60.      Old_WindowProc:=WindowProc; // Remember old handler
  61.      WindowProc:=New_WindowProc; // Replace handler with new one
  62. end;
  63.  
  64. destructor TMemo.Destroy; // The new destructor
  65. begin
  66.      WindowProc:=Old_WindowProc; // Restore the original handler
  67.      inherited Destroy; // Call the real destructor
  68. end;
  69.  
  70. procedure TForm1.FormCreate(Sender: TObject);
  71. begin
  72.      Memo1.SyncMemo:=Memo2; // Tell Memo1 what TMemo must sync (Memo2)
  73.      Memo2.SyncMemo:=Memo1; // Tell Memo2 what TMemo must sync (Memo1)
  74. end;
  75.  
  76. procedure TForm1.pnlMemo2Resize(Sender: TObject);
  77. begin
  78.      //Memo2.Height:=pnlMemo2.Height+20; // Make height enough big to cause horizontal scroll bar be out of TPanel visible area, so it will not be seen by the user
  79. end;
  80.  
  81. end.        
  82.