3

If you open Notepad, add ten lines and resize the editor to only show nine, the thumb track (the draggable block on a scroll bar) is almost the full length of the vertical scroll bar. If you add a couple of thousand rows, the thumb track is only a few pixels high.

I'd like to duplicate this bahaviour in a TCustomControl descendant where I implemented a horizontal scroll bar. So I added WS_HSCROLL to my window style (in CreateParams) and implemented a handler for WM_HSCROLL. Along the way, I use SetScrollRange and SetScrollPos to manage the range and the position of the thumb track - but the little bugger remains a near-perfect square.

What am I missing?

Cobus Kruger
  • 8,338
  • 3
  • 61
  • 106
  • Cobus, an example of your code would be very useful for you to get help. – RRUZ Sep 11 '09 at 01:34
  • @RRUZ: No, absolutely no need. If you want to see how not to do it, look no further than the VCL grid control. If you want to see how to do it, look at VirtualTree, SynEdit or any other such control that works correctly. Source code for them is available. – mghie Sep 11 '09 at 05:08
  • hi, this is more of a related question: how are you adding scrolling to the control itself, is there a TScrollbar that is member of your TCustomControl descendent class? – wmercer Feb 19 '12 at 22:16

2 Answers2

7

You can use the PageSize property to influence the thumb size.

Example:

ScrollBar1.Min      := 0;
ScrollBar1.Max      := 100;
ScrollBar1.Position := 70;
ScrollBar1.PageSize := 50;

Will look like:

Page Size

Community
  • 1
  • 1
Wouter van Nifterick
  • 23,603
  • 7
  • 78
  • 122
4

The documentation recommends using SetScrollInfo rather than SetScrollRange and SetScrollPos.

As Wouter's answer points out, you also need to set the page size. The position and range tell the OS where the center of the thumb belongs, but the page size tells it how much of the range is visible, and that's what determines the size of the thumb. You have to use SetScrollInfo for that; as a bonus, it lets you set the position, range, and page size all at once.


TCustomControl differs from TWinControl in just one way: It has a canvas. TScrollingWinControl differs in just one way, too: It has scroll bars. Adding a canvas to a TScrollingWinControl descendant should be much easier than adding scroll bars to a TCustomControl descendant — it's less code to copy and paste from the VCL source code. Change your control's base class and then see where you are.

Even if that's not an option, you'd still do well to look at how TScrollingWinControl and TControlScrollBar work together.

Community
  • 1
  • 1
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • +1, but I'm not sure that inheriting from `TScrollingWinControl` is less work in the long run. At least on Win9X it also severely limits the available scroll range (16 bit coordinates). Even on the NT line it would limit number of lines to 2^31 `div` (line height) in pixels. I would rather use `SetScrollInfo()` and calculate everything in code. – mghie Sep 11 '09 at 05:13
  • I don't agree with the TScrollingWinControl part of your answer either, partly because my scrolling needs to be rather complex. But I used SetScrollInfo and it works a treat, thanks. – Cobus Kruger Sep 14 '09 at 10:14