Well, there kinda sorta is (an intrinsic scrollbar). Ackshooly, I know that there is, because I got it to work earlier. Though I don't know how or why.
Ackshooly, this is getting verrry interesting. After reading Greenhorn's reply, I started experimenting with the window proc of the control, specifically the sequence of message processing. Since he mentioned
WM_SIZE as a place to call SetScrollInfo() from, I tried various sequences involving WM_SIZE.
Let me tell you,
WM_SIZE is a goddamn can of worms. It's quite mysterious to me what is actually going on with that message. Yeah, I know what
MSDN has to say about it: it is "
sent to a window after its size has changed".
There are a number of values sent depending on what kind of resizing is supposed to have occurred. When I captured this message, I found only two of them were being sent to my control:
SIZE_RESTORED (0) and
SIZE_MINIMIZED (1). I don't understand the latter, since so far as I know the control was never minimized (unless it started out life in this state).
SIZE_RESTORED basically means "neither maximized nor minimized", therefore "normal" (I'm guessing).
In any case, I'm not sure I even need to mess around with
WM_SIZE, since my controls are intended to be fixed-size and not resizeable. There are other ways of getting the actual control size (like
GetClientRect(), or through the
CREATESTRUCT passed with
WM_CREATE). So maybe I don't even need to bother with this message?
I read a
discussion of this online where a programmer basically said that it's almost impossible to tell when the "real"
WM_SIZE comes along, and that he had given up on this and put
SetScrollInfo() in his
WM_PAINT handler instead.
Oh, I almost forgot to mention the other can-o'worms aspect:
setting the scroll info can then generate even more WM_SIZE messages, because if the scrollbar appears or disappears the size of the client rectangle changes, which can lead to a cascade of recursive (or at least nested) messages. So this makes it seem like
WM_SIZE would be the last place you'd want to put
SetScrollInfo().
Anyhow, I experimented with the placement of a
WM_SIZE handler, with wildly divergent results. I've attached 3 small executables that show what happens. What's strange is that even if the
WM_SIZE handler goes straight to default processing (via DefWindowProc() ), the results are very different depending on
when this message is handled.
In one case (first program, mcLB_SBtest1), where I look for
WM_SIZE first thing (and use
DefWindowProc() to handle it), I get a blank control
but I get a non-operational but perfectly visible scroll bar! Weird, huh? The second program, mcLB_SBtest2, shows the control normally (and operational) but shows a "ghost" scrollbar. In this case, the scrollbar isn't visible, but you can tell it's (sort of) there by clicking and dragging in the area where it should be, at the bottom of the control; I forward all the
WM_HSCROLL messages to the parent window which displays them in the status window at the bottom. Only 2 values of this message ever come through:
SB_ENDSCROLL and
SB_THUMBTRACK. (The position value of the latter never changes from 0 even if you "drag" the scrollbar thumb, which of course you cannot see.) This is probably because the scrollbar isn't properly set, even though I call
SetScrollbarInfo() with values that
should make it both visible and active. I suspect that the trick here, if it is even possible to make this work, is to call that function at the right time ...
Try out these testbed programs to see what happens. Explanations are displayed.
So I'm really scratching my head now. Any ideas?