Under Win32 scrolling TScrollBox is not possible now when AutoScroll := true
Scrollbox area jumps a little and then all window freeze (the only way is to wait or switch focus to another application and back to unfreeze)
TScrollBox.Range is calculated on each click on scrollbar !

Attached is my proposition of fix.Please analyze it.
There are still two problems which remain after applying this patch :



1.When controls placed on TScrollBox and aligned , they are scrolled down instead of up (I feel that it was caused by changes done 2007-11-01)

2. When TScrollBox is scrolled a little and then parent window is resized - controls placed on scrollbox are moved (usually a little but sometimes more) - I feel that it worked once I tested but still today was so many changes in that area :-(


In other cases it works like a charm , for example check lazreport designer :-)

Regards
Bogusław Brandys
Index: lcl/forms.pp
===================================================================
--- lcl/forms.pp        (revision 12682)
+++ lcl/forms.pp        (working copy)
@@ -89,8 +89,6 @@
     FRange: Integer;
     FSmooth : Boolean;
     FVisible: Boolean;
-    FOldScrollInfo: TScrollInfo;
-    FOldScrollInfoValid: Boolean;
   protected
     FControl: TWinControl;
     function ControlAutoScroll: boolean; virtual;
@@ -116,7 +114,6 @@
     procedure SetSmooth(const Value: Boolean); virtual;
     procedure SetVisible(const Value: Boolean); virtual;
     procedure UpdateScrollBar; virtual;
-    procedure InvalidateScollInfo;
   {$ifdef VerboseScrollingWinControl}
     function DebugCondition: Boolean;
   {$endif}
@@ -1821,3 +1818,6 @@
 
 
 
+
+
+
Index: lcl/include/controlscrollbar.inc
===================================================================
--- lcl/include/controlscrollbar.inc    (revision 12682)
+++ lcl/include/controlscrollbar.inc    (working copy)
@@ -68,13 +68,10 @@
   // scroll content of FControl
   OldPosition := FPosition;
   FPosition := Value;
-  if FControl is TScrollingWinControl then
-    TScrollingWinControl(FControl).ScrollbarHandler(Kind, OldPosition);
 
   // check that the new position is also set on the scrollbar
   if HandleAllocated and (GetScrollPos(ControlHandle, IntfBarKind[Kind]) <> 
FPosition) then
   begin
-    InvalidateScollInfo;
     {$IFDEF VerboseScrollingWinControl}
     if DebugCondition then
       DebugLn(['TControlScrollBar.SetPosition FPosition=',FPosition]);
@@ -82,6 +79,13 @@
     // send position to interface and store it back to FPosition (this way LCL 
will have actual position value)
     FPosition := SetScrollPos(ControlHandle, IntfBarKind[Kind], FPosition, 
Visible);
   end;
+  
+  if OldPosition = FPosition then Exit;
+
+
+  if (FControl is TScrollingWinControl)  then
+    TScrollingWinControl(FControl).ScrollbarHandler(Kind, OldPosition);
+  
 end;
 
 function TControlScrollBar.SmoothIsStored: boolean;
@@ -102,7 +106,6 @@
   begin
     ScrollInfo.fMask := SIF_PAGE;
     GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
-    InvalidateScollInfo;
     FPage := ScrollInfo.nPage;
   end;
   Result := FPage;
@@ -116,7 +119,6 @@
   begin
     ScrollInfo.fMask := SIF_POS;
     GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
-    InvalidateScollInfo;
     FPosition := ScrollInfo.nPos;
   end;
   Result := FPosition;
@@ -130,7 +132,6 @@
   begin
     ScrollInfo.fMask := SIF_Range + SIF_Page;
     GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
-    InvalidateScollInfo;
     FRange := ScrollInfo.nMax - ScrollInfo.nMin - integer(ScrollInfo.nPage);
   end;
   Result := FRange;
@@ -144,10 +145,7 @@
 function TControlScrollBar.GetVisible: Boolean;
 begin
   if HandleAllocated and (not (FControl is TScrollingWinControl)) then
-  begin
-    InvalidateScollInfo;
     FVisible := GetScrollbarVisible(Controlhandle, IntfBarKind[Kind]);
-  end;
   Result := FVisible;
 end;
 
@@ -178,10 +176,8 @@
   else
     KindID := SM_CXVSCROLL;
   if HandleAllocated then
-  begin
-    Result := LCLIntf.GetScrollBarSize(ControlHandle,KindID);
-    InvalidateScollInfo;
-  end else
+    Result := LCLIntf.GetScrollBarSize(ControlHandle,KindID)
+  else
     Result := GetSystemMetrics(KindID);
 end;
 
@@ -295,12 +291,8 @@
     ScrollInfo.nPos := FPosition;
     ScrollInfo.nPage := FPage;
     ScrollInfo.nTrackPos := FPosition;
-    if (not FOldScrollInfoValid) or (not 
CompareMem(@ScrollInfo,@FOldScrollInfo,SizeOf(TScrollInfo))) then
-    begin
-      FOldScrollInfo:=ScrollInfo;
-      FOldScrollInfoValid := true;
-      SetScrollInfo(FControl.Handle, IntfBarKind[Kind], ScrollInfo, FVisible);
-    end;
+    SetScrollInfo(FControl.Handle, IntfBarKind[Kind], ScrollInfo, FVisible);
+
     {$IFDEF VerboseScrollingWinControl}
     if DebugCondition then
       DebugLn(['TControlScrollBar.UpdateScrollBar ',DbgSName(FControl),' 
',DbgSName(Self),' FVisible=',FVisible,' Range=',FRange,' 
FPosition=',FPosition,' FPage=',FPage,' FAutoRange=',FAutoRange]);
@@ -318,10 +310,6 @@
   end;
 end;
 
-procedure TControlScrollBar.InvalidateScollInfo;
-begin
-  FOldScrollInfoValid:=false;
-end;
 
 {$ifdef VerboseScrollingWinControl}
 function TControlScrollBar.DebugCondition: Boolean;
@@ -372,7 +360,6 @@
     NewPos := 0;
   if NewPos > FRange then
     NewPos := FRange;
-  InvalidateScollInfo;
   SetPosition(NewPos);
 end;
 
Index: lcl/include/scrollingwincontrol.inc
===================================================================
--- lcl/include/scrollingwincontrol.inc (revision 12682)
+++ lcl/include/scrollingwincontrol.inc (working copy)
@@ -52,20 +52,25 @@
 procedure TScrollingWinControl.AlignControls(AControl: TControl;
   var ARect: TRect);
 begin
+  inherited AlignControls(AControl, ARect);
   if (HorzScrollBar=nil) or (VertScrollBar=nil) then exit;
-  inherited AlignControls(AControl, ARect);
-  HorzScrollBar.AutoCalcRange;
-  VertScrollBar.AutoCalcRange;
   if not AutoScroll then
     UpdateScrollBars;
+
 end;
 
 procedure TScrollingWinControl.DoOnResize;
 begin
   inherited DoOnResize;
+  if (HorzScrollBar=nil) or (VertScrollBar=nil) then exit;
   if AutoScroll or HorzScrollBar.Visible or VertScrollBar.Visible
   then
+  begin
+    HorzScrollBar.AutoCalcRange;
+    VertScrollBar.AutoCalcRange;
     UpdateScrollBars;
+  end;
+
 end;
 
 class function TScrollingWinControl.GetControlClassDefaultSize: TPoint;

Reply via email to