Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I disable the scroll-into-view behavior of TScrollBox?

Tags:

scroll

delphi

I have a TScrollBox that has a RichEdit that is bigger than the scrollbox, so both side scrollbars appear in the scrollbox. Then I have a function DoTask that calls RichEdit.SetFocus.

When I scroll down to where I want to see part of the text control, and then call DoTask, the ScrollBox will automatically scroll to the top of the RichEdit. How can I avoid that?

like image 848
XBasic3000 Avatar asked Feb 03 '23 15:02

XBasic3000


2 Answers

As you wish, here are some suggestions:

  • Override SetFocusedControl in the form:

    function TForm1.SetFocusedControl(Control: TWinControl): Boolean;
    begin
      if Control = RichEdit then
        Result := True
      else
        Result := inherited SetFocusedControl(Control);
    end;
    

    Or:

    type
      TCustomMemoAccess = class(TCustomMemo);
    
    function TForm1.SetFocusedControl(Control: TWinControl): Boolean;
    var
      Memo: TCustomMemoAccess;
      Scroller: TScrollingWinControl;
      Pt: TPoint;
    begin
      Result := inherited SetFocusedControl(Control);
      if (Control is TCustomMemo) and (Control.Parent <> nil) and
        (Control.Parent is TScrollingWinControl) then
      begin
        Memo := TCustomMemoAccess(Control);
        Scroller := TScrollingWinControl(Memo.Parent);
        SendMessage(Memo.Handle, EM_POSFROMCHAR, Integer(@Pt), Memo.SelStart);
        Scroller.VertScrollBar.Position := Scroller.VertScrollBar.Position +
          Memo.Top + Pt.Y;
      end;
    end;
    
  • Interpose TScrollBox:

    type
      TScrollBox = class(Forms.TScrollBox)
      protected
        procedure AutoScrollInView(AControl: TControl); override;
      end;
    
    procedure TScrollBox.AutoScrollInView(AControl: TControl);
    begin
      if not (AControl is TCustomMemo) then
        inherited AutoScrollInView(AControl);
    end;
    

    Or:

    procedure TScrollBox.AutoScrollInView(AControl: TControl);
    begin
      if (AControl.Top > VertScrollBar.Position + ClientHeight) xor
          (AControl.Top + AControl.Height < VertScrollBar.Position) then
        inherited AutoScrollInView(AControl);
    end;
    

Or use any creative combination of all of the above. How and when you like it to be scrolled only you know.

like image 121
NGLN Avatar answered Mar 02 '23 00:03

NGLN


the simpliest solution would be

var a, b : Integer;
begin
  a := ScrollBox1.VertScrollBar.Position;
  b := ScrollBox1.HorzScrollBar.Position;
  richEdit1.SetFocus;
  ScrollBox1.VertScrollBar.Position:=a ;
  ScrollBox1.HorzScrollBar.Position:=b ;
end;
like image 36
ertx Avatar answered Mar 01 '23 23:03

ertx