Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2215
  • Last Modified:

TScrollbox: How can I prevent automatic "scrollintoview" of large components?

Hi, a very annoying problem using BDS2006:

I have a Form with a Scrollbox containing two TStringGrids aligned vertically.
The StringGrids are sized so that the bottom one is only partly displayed on the Form, the ScrollBox allows accessing the whole StringGrid.

The problem: if I click the bottom StringGrid (which is partly visible), the Scrollbox "jumps" so that the clicked StringGrid scrolls into view completely. I want to be able to click the StringGrid without any "jump effect" on the scrollbox!
How can I do this?
unit1.pas
==============================
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids;
 
type
  TForm1 = class(TForm)
    ScrollBox1: TScrollBox;
    StringGrid1: TStringGrid;
    StringGrid2: TStringGrid;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
end.
==============================
 
unit1.dfm
==============================
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 533
  ClientWidth = 742
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object ScrollBox1: TScrollBox
    Left = 0
    Top = 0
    Width = 742
    Height = 533
    Align = alClient
    TabOrder = 0
    ExplicitWidth = 688
    object StringGrid1: TStringGrid
      Left = 5
      Top = 5
      Width = 668
      Height = 300
      RowCount = 20
      TabOrder = 0
    end
    object StringGrid2: TStringGrid
      Left = 5
      Top = 311
      Width = 668
      Height = 400
      RowCount = 20
      TabOrder = 1
    end
  end
end
==============================

Open in new window

0
waeberd
Asked:
waeberd
  • 3
  • 3
  • 2
2 Solutions
 
Russell LibbySoftware Engineer, Advisory Commented:
You can create a component derived by TScrollBox, and then override the TScrollingWinControl.AutoScrollInView.

Eg:

--------------------------------
unit ScrollBoxEx;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TScrollBoxEx      =  class(TScrollBox)
  private
     // Private declarations
  protected
     // Protected declarations
     procedure      AutoScrollInView(AControl: TControl); override;
  public
     // Public declarations
  published
     // Published declarations
     property       Align;
     property       Anchors;
     property       AutoScroll;
     property       AutoSize;
     property       BiDiMode;
     property       BorderStyle;
     property       Constraints;
     property       DockSite;
     property       DragCursor;
     property       DragKind;
     property       DragMode;
     property       Enabled;
     property       Color nodefault;
     property       Ctl3D;
     property       Font;
     property       ParentBiDiMode;
     property       ParentColor;
     property       ParentCtl3D;
     property       ParentFont;
     property       ParentShowHint;
     property       PopupMenu;
     property       ShowHint;
     property       TabOrder;
     property       TabStop;
     property       Visible;
     property       OnCanResize;
     property       OnClick;
     property       OnConstrainedResize;
     property       OnContextPopup;
     property       OnDblClick;
     property       OnDockDrop;
     property       OnDockOver;
     property       OnDragDrop;
     property       OnDragOver;
     property       OnEndDock;
     property       OnEndDrag;
     property       OnEnter;
     property       OnExit;
     property       OnGetSiteInfo;
     property       OnMouseDown;
     property       OnMouseMove;
     property       OnMouseUp;
     property       OnMouseWheel;
     property       OnMouseWheelDown;
     property       OnMouseWheelUp;
     property       OnResize;
     property       OnStartDock;
     property       OnStartDrag;
     property       OnUnDock;
  end;

procedure Register;

implementation

procedure TScrollBoxEx.AutoScrollInView(AControl: TControl);
begin
  // No-op
end;

procedure Register;
begin
  RegisterComponents('Win32', [TScrollBoxEx]);
end;

end.

-------------------

- Save component source
- Install the component
- Change the dfm (view as text) to read:

 object ScrollBox1: TScrollBoxEx

- Change the form declaration to read

type
  TForm1 = class(TForm)
    ScrollBox1: TScrollBoxEx;

----------

Regards,
Russell




 
0
 
HypoCommented:
The auto scrolling is generated by the function AutoScrollInView, which is called from the SetFocusedControl function (which is called when you change focus, like clicking in the other grid). You can disable this by deriving the TScrollBox class locally in your unit, with the same name, and then override the AutoScrollInView with an empty function. I don't know if it is the best way to do it in this case, but it works.
Setting the TScrollBox.AutoScroll property to false prevents auto scrolling, but it also removes the scroll bars, and I don't think that's what you are looking for.

regards
Hypo
Add this type to above your form declaration in your unit... 
type
  TScrollBox = class(Forms.TScrollBox)
   protected
    procedure AutoScrollInView(AControl: TControl); Override;
  end;
 
  TForm1 = class(TForm)... 
 
...
// Then add code this to your implementation part
procedure TScrollBox.AutoScrollInView(AControl: TControl);
begin
  // Do nothing 
end;
  

Open in new window

0
 
HypoCommented:
Damn, I was slow... :)
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
Russell LibbySoftware Engineer, Advisory Commented:
Hypo,

Your method is actually simpler to implement (both do the same thing by stubbing the method).

Russell
0
 
HypoCommented:
Yeah,
It's a quick n' dirty sollution I saw somewhere on this forum a couple of months ago, it was another control, but the principals was the same; and It's a nice way to tweak your standard VCL's when you need to change their behaviour to test something quickly. :)

regards
Hypo
0
 
Russell LibbySoftware Engineer, Advisory Commented:
I have used it before, but my delphi is starting to get rusty from too much C++ work ;-)

Russell
0
 
waeberdAuthor Commented:
wow, thanks a million!
0
 
waeberdAuthor Commented:
Thanks a lot! Fast, helpful answers!
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 3
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now