Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the real size ("logical area") of a TScrollBox

Tags:

delphi

I need to find the entire size (also called "logical area") of a TScrollBox - as opposite to visible area that you get via Width and Height property (or ClientWidth ClientHeight).

I want to create some controls inside that TScrollBox. One of them (called TViewer) needs to be as high as the TScrollBox itself. The thing is that during creation, the TScrollBox is scrolled down to show last created control. So, using Top=1 will not work because my control will have top=1 which is not the top of the logical area.


Delphi 7

like image 703
Server Overflow Avatar asked Dec 16 '10 22:12

Server Overflow


4 Answers

  1. Drop a component, like a TLabel, on the TScrollBox.
  2. Set the component's Left and Top properties to 0.
  3. Set the component's Visible property to False.

Now you always have the origin. The "logical height" is now:

myScrollBox.Height + (myOriginControl.Top * -1);
like image 58
Marcus Adams Avatar answered Nov 16 '22 13:11

Marcus Adams


Maybe ScrollBox.HorzScrollBar.Range and ScrollBox.VertScrollBar.Range + the corresponding .Positions are what you need.

like image 29
Uli Gerhardt Avatar answered Nov 16 '22 12:11

Uli Gerhardt


Look at Scrollbars:

ScrollBox1.VertScrollBar.Range
ScrollBox1.HorzScrollBar.Range

It can be less than height and width if the scrollbox logical area is not bigger than phisical area (scrollbars not visible in that case)

Or use this to get the max of both:

var
  AHeight, AWidth: Integer;
begin
  AHeight := Max(ScrollBox1.VertScrollBar.Range, ScrollBox1.Height);
  AWidth := Max(ScrollBox1.HorzScrollBar.Range, ScrollBox1.Width);
  ShowMessageFmt('%d,%d', [AHeight, AWidth]);
end;

Edit From @Altar comments, I can add the logical height and/or width is not the problem. If you want to add any control which occupies all the height of the scrollbar, use the AHeight from the above calculation, but set the Top to the negative of VertScrollBar.Position, something like this:

procedure TForm2.Button3Click(Sender: TObject);
var
  AHeight, AWidth: Integer;
  Btn: TButton;
begin
  AHeight := Max(ScrollBox1.VertScrollBar.Range, Height);
  AWidth := Max(ScrollBox1.HorzScrollBar.Range, Width);
  Btn := TButton.Create(Self);
  Btn.Parent := ScrollBox1;
  Btn.Left := 15;
  Btn.Top := -ScrollBox1.VertScrollBar.Position;
  Btn.Height := AHeight;
end;
like image 2
jachguate Avatar answered Nov 16 '22 12:11

jachguate


Im not sure i understand exactly what you want to do, but to get the complete area defined as "scrollable" you would have to write ScrollBox.HorScrollBar.Range + ScrollBox.Clientwidth (and the same thing for the vertical section). The scrollbox always deducts the visible "page" size from the total. So if you define a height of 1000 pixels, with 100 pixels showing - it will have a scrolling range of 900. You have to add the clientheight to get the rest.

Also, to get the correct "top" position you will have to read Canvas.Cliprect.Top, since a scrolling window does not change the top position of sub-controls. Windows handles this for you and only tells you what to re-draw once the scrollbars are initialized.

Since you want to create a control that is just as high as the complete scrollable area, i presume you are creating an editor of sorts?

If so you would probably get better results taking a look at SynEdit and extract the base-class that adds scrollbars to a normal TCustomControl (it's quite easy). That way you can control both the painting and the layout of your controls.

Here is one I wrote for Lazarus and FreePascal a while back. If you add messages to the uses clause and prefix the message handlers with WM rather than TLM it will compile under Delphi.

(code to long, had to use external link): http://delphimax.wordpress.com/2010/09/20/platform-independent-image-component-for-lazarus/

like image 1
Jon Lennart Aasenden Avatar answered Nov 16 '22 14:11

Jon Lennart Aasenden