I have another weird problem (with LargeChange and SmallChange), they are defined as TScrollBarInc (in StrCtrls TScrollBar definition) and that is defined as 1..32767 (in Forms TScrollBarInc = 1..32767;
) instead of Integer, while Min, Max and Position are defined as Integer (on StdCtrls TScrollBar definition), also on SetParams the parameters are Integer, not 1..32767.
This is (in my oppinion) clearly a BUG on the class definition of TScrollBarInc.
Let me put an example:
Edit1.Text:='100000000'; // Ten millions
MyScrollBar.Min:=0;
MyScrollBar.Max:=100000000; // One hundred millions
MyScrollBar.Position:=1000000; // One million
MyScrollBar.LargeChange:=StrToInt(Edit1.Text);
// When in Edit1.Text is "100000000" (ten millions), this puts in
// LargeChange a negative value (-27008, not ten millions)
// and there is no error at compile not at execution time.
MyScrollBar.SmallChange:=Round(StrToInt(Edit1.Text)/10);
// When in Edit1.Text is "100000000" (ten millions), this puts in
// SmallChange a positive value (16960, not one million(
// and there is no error at compile not at execution time.
Caption:=IntToStr(ScrollBar1.LargeChange)+' & '+IntToStr(ScrollBar1.SmallChange);
// This is to see the values (it shows '16960 & -27008').
It is needed a FIX, a Type Override for that two parameters of the class (LargeChange & SmallChange), so override its type to Integer (same type as Min, Max & Position) ... also the IDE help say that LargeChange and SmallChange are in Min & Max range, but it is imposible to assign 0 and/or any value greater than 32767.
How can this 'type override' be done? EDIT: Now i know, here is the code to add just before TForm1 = class(TForm)
, i mean just after interfase uses, before any class declaration:
type
TScrollBar=class(StdCtrls.TScrollBar)
private
// Just override the type to the correct type
// same type as Min, Max & Position
FSmallChange:Integer;
FLargeChange:Integer;
protected
// The scrool of LargeChange and SmallChange must be done by us
procedure Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer); override;
public
published
// Just override the type to the correct type
// same type as Min, Max & Position
property LargeChange: Integer read FLargeChange write FLargeChange default 1;
property SmallChange: Integer read FSmallChange write FSmallChange default 1;
end;
Now it is only needed to capture OnScroll and do the scroll by own code, not letting the main buggy class code do the job... since internal SmallChange & LargeChangeare hidden and will allways have value 1.
procedure TScrollBar.Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer);
begin
// The +1 and -1 is to undo internal scroll that occurs
// so the desired scroll is not altered by one
// remember we had hide internal LargeChange & SmallChange
// and they will remain with value 1 forever
case ScrollCode
of scPageUp
:begin
ScrollPos:=ScrollPos-FLargeChange+1;
end;
scPageDown
:begin
ScrollPos:=ScrollPos+FLargeChange-1;
end;
scLineUp
:begin
ScrollPos:=ScrollPos-FSmallChange+1;
end;
scLineDown
:begin
ScrollPos:=ScrollPos+FSmallChange-1;
end;
end;
end;
P.D.: Just in case someone could ask, TurboDelphi 2006 ... also TTntScrollBar is affected by the same missmatch type definitions.
Min
orMax
is a property that does some bound checking.SetPageSize
,SetParams
to avoid setting individual properties one by one.