1

I use the code

procedure TMyCanvas.RichEditChange(Sender: TObject);
var
  ScrollInfo: TScrollInfo;
begin

  FillChar(ScrollInfo, SizeOF(ScrollInfo), 0);
  ScrollInfo.cbSize := SizeOf(ScrollInfo);
  ScrollInfo.fMask := SIF_RANGE or SIF_PAGE or SIF_POS;
  if GetScrollInfo(FRichEdit.Handle, SB_VERT, ScrollInfo) then
  begin
    FVertScroll.Max := ScrollInfo.nMax;
    FVertScroll.Min := ScrollInfo.nMin;
    FVertScroll.PageSize := ScrollInfo.nPage;
    FVertScroll.Position := ScrollInfo.nPos;
  end;
  Invalidate;
end;

the problem is that when i add/remove lines it gives me error sometimes when im going to resize the form. it says "scrollbar property out of range"

how can i avoid it?

thanx

4
  • Which line does raise the exception exactly? I'm just guessing that Min or Max is a property that does some bound checking. Commented Jul 13, 2011 at 8:20
  • You could also try SetPageSize, SetParams to avoid setting individual properties one by one. Commented Jul 13, 2011 at 8:47
  • @TOndrej, make that an answer! Commented Jul 13, 2011 at 9:01
  • If you're not getting the error when changing the rich edit's contents, I doubt the code in OnChange handler have got anything to do with it. Commented Jul 13, 2011 at 9:34

3 Answers 3

3

You could try setting the PageSize property, and calling SetParams to avoid setting individual properties one by one.

3
  • +1. The mentioned error only happens when the Min>Max or Max<Min, and that can happen if you set a new Max that's lower then the old Min (the OP's code sets Max first). SetParams gets both values at once, so the error shouldn't happen any more. Commented Jul 13, 2011 at 9:46
  • @Cosmin - Min>Max and Max<Min are the same things, you probably mean Max<PageSize. Commented Jul 13, 2011 at 9:52
  • 1
    @Sertac, if you start with Min = 100 and Max = 200 you can get Min>Max setting Min=300 and you can get Max<Min setting Max=0. While mathematically it's the same thing, I wanted to point out the two ways you can get yourself in that situation. Commented Jul 13, 2011 at 9:57
0

I was getting this error message and found that a change had been made when initialising the scrollbar whereby TScrollbar.Max was being set to 0 when PageSize was 2. Setting PageSize to 0 before Max to 0 fixed the issue.

0

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.