diff --git a/lcl/include/scrollbar.inc b/lcl/include/scrollbar.inc index 197ff21499..96832794b2 100644 --- a/lcl/include/scrollbar.inc +++ b/lcl/include/scrollbar.inc @@ -59,10 +59,11 @@ var begin inherited CreateWnd; if not HandleAllocated then RaiseGDBException('TCustomScrollBar.CreateWnd HandleAllocated=false'); - SetScrollRange(Handle, SB_CTL, FMin, FMax, False); ScrollInfo.cbSize := SizeOf(ScrollInfo); + ScrollInfo.nMin := FMin; + ScrollInfo.nMax := FMax + FPageSize; ScrollInfo.nPage := FPageSize; - ScrollInfo.fMask := SIF_PAGE; + ScrollInfo.fMask := SIF_PAGE or SIF_Range; SetScrollInfo(Handle, SB_CTL, ScrollInfo, False); if NotRightToLeft then SetScrollPos(Handle, SB_CTL, FPosition, True) @@ -101,18 +102,28 @@ begin end; end; -procedure TCustomScrollBar.SetParams(APosition, AMin, AMax: Integer); +procedure TCustomScrollBar.SetParams(APosition, AMin, AMax, APageSize: Integer); +var + ScrollInfo: TScrollInfo; begin if AMax < AMin then raise EInvalidOperation.Create(rsScrollBarOutOfRange); if APosition < AMin then APosition := AMin; if APosition > AMax then APosition := AMax; - if (FMin <> AMin) or (FMax <> AMax) then + if APageSize < 0 then APageSize := 0; + if (FMin <> AMin) or (FMax <> AMax) or (APageSize <> FPageSize) then begin FMin := AMin; FMax := AMax; + FPageSize := APageSize; if HandleAllocated then - SetScrollRange(Handle, SB_CTL, AMin, AMax, FPosition = APosition); + begin + ScrollInfo.fMask := SIF_PAGE or SIF_Range; + ScrollInfo.nMin := AMin; + ScrollInfo.nMax := AMax + APageSize; + ScrollInfo.nPage := APageSize; + SetScrollInfo(Handle, SB_CTL, ScrollInfo, FPosition = APosition); + end; end; if FPosition <> APosition then begin @@ -125,37 +136,29 @@ begin Change; end; + if HandleAllocated then TWSScrollBarClass(WidgetSetClass).SetParams(Self); end; procedure TCustomScrollBar.SetPosition(Value: Integer); begin - SetParams(Value, FMin, FMax); + SetParams(Value, FMin, FMax, FPageSize); end; procedure TCustomScrollBar.SetPageSize(Value: Integer); -var - ScrollInfo: TScrollInfo; begin - if (FPageSize = Value) or (FPageSize > FMax) then exit; - FPageSize := Value; - if HandleAllocated then begin - ScrollInfo.cbSize := SizeOf(ScrollInfo); - ScrollInfo.nPage := Value; - ScrollInfo.fMask := SIF_PAGE; - SetScrollInfo(Handle, SB_CTL, ScrollInfo, True); - end; + SetParams(FPosition, FMin, FMax, Value); end; procedure TCustomScrollBar.SetMin(Value: Integer); begin - SetParams(FPosition, Value, FMax); + SetParams(FPosition, Value, FMax, FPageSize); end; procedure TCustomScrollBar.SetMax(Value: Integer); begin - SetParams(FPosition, FMin, Value); + SetParams(FPosition, FMin, Value, FPageSize); end; procedure TCustomScrollBar.Change; diff --git a/lcl/interfaces/gtk/gtkwsstdctrls.pp b/lcl/interfaces/gtk/gtkwsstdctrls.pp index 022cf5f505..12938b5e32 100644 --- a/lcl/interfaces/gtk/gtkwsstdctrls.pp +++ b/lcl/interfaces/gtk/gtkwsstdctrls.pp @@ -322,7 +322,7 @@ begin //set properties for the range Adjustment := gtk_range_get_adjustment (GTK_RANGE(Pointer(Handle))); Adjustment^.lower := Min; - Adjustment^.Upper := Max; + Adjustment^.Upper := Max + PageSize; Adjustment^.Value := Position; Adjustment^.step_increment := SmallChange; Adjustment^.page_increment := LargeChange; diff --git a/lcl/interfaces/win32/win32winapi.inc b/lcl/interfaces/win32/win32winapi.inc index 827e9c0577..b9752dd25a 100644 --- a/lcl/interfaces/win32/win32winapi.inc +++ b/lcl/interfaces/win32/win32winapi.inc @@ -2967,6 +2967,8 @@ Begin //With ScrollInfo Do // Assert(False, Format('Trace:> [TWin32WidgetSet.SetScrollInfo] Mask:0x%x, Min:%d, Max:%d, Page:%d, Pos:%d', [FMask, NMin, NMax, NPage, NPos])); ScrollInfo.cbSize:=sizeof(ScrollInfo); + if (ScrollInfo.fMask and SIF_Range > 0) then + ScrollInfo.nMax := Max(ScrollInfo.nMin, ScrollInfo.nMax - 1); Result := Windows.SetScrollInfo(Handle, SBStyle, @ScrollInfo, BRedraw); With ScrollInfo Do Assert(False, Format('Trace:> [TWin32WidgetSet.SetScrollInfo] --> %d', [Result])); diff --git a/lcl/interfaces/win32/win32wsstdctrls.pp b/lcl/interfaces/win32/win32wsstdctrls.pp index badd403f1b..f448cee774 100644 --- a/lcl/interfaces/win32/win32wsstdctrls.pp +++ b/lcl/interfaces/win32/win32wsstdctrls.pp @@ -309,11 +309,24 @@ begin end; class procedure TWin32WSScrollBar.SetParams(const AScrollBar: TCustomScrollBar); +var + ScrollInfo: TScrollInfo; + AMax: Integer; begin with AScrollBar do begin - SendMessage(Handle, SBM_SETRANGE, Min, Max); - SendMessage(Handle, SBM_SETPOS, Position, LPARAM(true)); + AMax := Max + PageSize - 1; + if AMax < Min then AMax := Min; + if AMax < Max then AMax := Max; + + ScrollInfo.cbSize := SizeOf(TScrollInfo); + ScrollInfo.fMask := SIF_POS or SIF_Range or SIF_PAGE; + ScrollInfo.nMin := Min; + ScrollInfo.nMax := AMax; + ScrollInfo.nPage := PageSize; + ScrollInfo.nPos := Position; + + SendMessage(Handle, SBM_SETSCROLLINFO, WParam(True), LParam(@ScrollInfo)); case Kind of sbHorizontal: SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) or SBS_HORZ); diff --git a/lcl/interfaces/wince/wincewinapi.inc b/lcl/interfaces/wince/wincewinapi.inc index 5774cf3979..c781545b0b 100644 --- a/lcl/interfaces/wince/wincewinapi.inc +++ b/lcl/interfaces/wince/wincewinapi.inc @@ -2220,6 +2220,8 @@ Begin //With ScrollInfo Do // Assert(False, Format('Trace:> [TWinCEWidgetSet.SetScrollInfo] Mask:0x%x, Min:%d, Max:%d, Page:%d, Pos:%d', [FMask, NMin, NMax, NPage, NPos])); ScrollInfo.cbSize:=sizeof(ScrollInfo); + if (ScrollInfo.fMask and SIF_Range > 0) then + ScrollInfo.nMax := Max(ScrollInfo.nMin, ScrollInfo.nMax - 1); Result := Windows.SetScrollInfo(Handle, SBStyle, @ScrollInfo, BRedraw); With ScrollInfo Do Assert(False, Format('Trace:> [TWinCEWidgetSet.SetScrollInfo] --> %d', [Result])); diff --git a/lcl/interfaces/wince/wincewsstdctrls.pp b/lcl/interfaces/wince/wincewsstdctrls.pp index 375712b988..6235451aff 100644 --- a/lcl/interfaces/wince/wincewsstdctrls.pp +++ b/lcl/interfaces/wince/wincewsstdctrls.pp @@ -308,11 +308,24 @@ begin end; class procedure TWinCEWSScrollBar.SetParams(const AScrollBar: TCustomScrollBar); +var + ScrollInfo: TScrollInfo; + AMax: Integer; begin with AScrollBar do begin - SendMessage(Handle, SBM_SETRANGE, Min, Max); - SendMessage(Handle, SBM_SETPOS, Position, LPARAM(true)); + AMax := Max + PageSize - 1; + if AMax < Min then AMax := Min; + if AMax < Max then AMax := Max; + + ScrollInfo.cbSize := SizeOf(TScrollInfo); + ScrollInfo.fMask := SIF_POS or SIF_Range or SIF_PAGE; + ScrollInfo.nMin := Min; + ScrollInfo.nMax := AMax; + ScrollInfo.nPage := PageSize; + ScrollInfo.nPos := Position; + + SendMessage(Handle, SBM_SETSCROLLINFO, WParam(True), LParam(@ScrollInfo)); case Kind of sbHorizontal: SetWindowLong(Handle, GWL_STYLE, GetWindowLong(Handle, GWL_STYLE) or SBS_HORZ); diff --git a/lcl/stdctrls.pp b/lcl/stdctrls.pp index 8537cb0bfd..e6f690ba76 100644 --- a/lcl/stdctrls.pp +++ b/lcl/stdctrls.pp @@ -90,7 +90,7 @@ type procedure Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer); dynamic; public constructor Create(AOwner: TComponent); override; - procedure SetParams(APosition, AMin, AMax: Integer); + procedure SetParams(APosition, AMin, AMax, APageSize: Integer); public property Kind: TScrollBarKind read FKind write SetKind default sbHorizontal; property LargeChange: TScrollBarInc read FLargeChange write FLargeChange default 1;