Solved

Why SB_THUMBTRACK does not work in a list control?

Posted on 1998-02-25
8
1,722 Views
Last Modified: 2013-11-20
Hi:

I need to have an external scrollbar control for some other controls, in part for list box and list control ("external" means that I create a scrollbar and redirect its WM_*SCROLL messages to other controls). I have made a test: placed a list box, a list control and a vertical  scrollbar in a dialog, added 100 items to the both lists and set up the scrollbar info. Then in CMyDialog::OnVScroll I write:

void CMyDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
      // TODO: Add your message handler code here and/or call default
      
      if( pScrollBar == 0 ) {
            CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
            return;
      }

      listBox.SendMessage( WM_VSCROLL, MAKEWPARAM( nSBCode, nPos ),
                                    (LPARAM)0 );
      listCtrl.SendMessage( WM_VSCROLL, MAKEWPARAM( nSBCode, nPos ),
                                    (LPARAM)0 );
}

Everything works fine on both controls when I click on the scrollbar's arrows (line up/down) and below/over the thumb (page up/down), but when  I drag the thumb SB_THUMBTRACK/SBTHUMBPOSITION) only the list box is scrolled, the list control has no reaction. But when I drag its own scrollbar it works fine.

Does anybody know what the problem is? How can I make the list control to "hear" these SB_THUMBTRACK/SBTHUMBPOSITION messages?

Regards,
Asker.













0
Comment
Question by:asker
  • 4
  • 3
8 Comments
 
LVL 7

Expert Comment

by:galkin
ID: 1316542
List control doesn't have child scroll bar. You can check it by Spy utility. It is rather drawing but not actual window. So it doesn't handle scrollbar messages. Use ScrollWindowEx to scroll list control.
0
 

Author Comment

by:asker
ID: 1316543
To Galkin:

If a window is created with WS_VSCROLL/WS_HSCROLL it does not have a scroll bar control (it is only a drawing), but a window does receive WM_VSCROLL/WM_HSCROLL when you click it and you should handle them if you need to provide scrolling (read help on these messages).

By sending WM_VSCROLL message to the list control I simulate a situation when its own scrollbar gets accessed. When I am doing such with a list box or other controls (tree, for example. All of them do not have a scroll bar - use Spy++) - it works. It works with a list control - on line up/down, page up/down only. The question is - why sending SB_THUMBTRACK does not work with a list control while it works with the others?
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1316544
Forcing fake WM_xSCROLL to any control or window is pure evil. You should, instead:

1) Find the correct programatic way to scroll the control. For a listbox control, you can use the LB_SETTOPINDEX message (or the CListBox::SetTopIndex() method in MFC). For a list view control, you should use the LVM_SCROLL (or the CListCtrl::Scroll() method in MFC) to scroll. Almost all controls have similar mechanisms.

2) Find the handle to the scrollbars on the control and call SetScrollInfo() on the scrollbar. In the SCROLLINFO structure, set the nPos member to be what you want. You might have to do a GetScrollInfo() first to get the other structure members.

.B ekiM

0
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

Author Comment

by:asker
ID: 1316545
To Mikeblas:

>Forcing fake WM_xSCROLL to any control or window is pure evil.

Why? WM_xSCROLL messages are exactly what the control or window receives when the user works with a scroll bar. Each window handles those messages in a specific way, so instead implementing that processing once more (by myselsf), wouldn't it be better to send the WM_XScroll?

Scrollbar messages are just "interface" to the GUI element "scrollbar", which notifies its parent with them.
0
 
LVL 11

Accepted Solution

by:
mikeblas earned 250 total points
ID: 1316546
The WM_xSCROLL messages are what the window receives when the user scrolls, sure. But the semantics are very much different.

When the user scrolls, the control will have already updated the scrollbar info. When the control calls GetScrollInfo() in response to a WM_xSCROLL message, the info retruned will reflect the updated position and state of the scrollbar.

On the other hand, when you blindly send or post a WM_xSCROLL message, the information returned by GetScrollInfo() _hasn't_ been update. You're lying about the state change.

When you force a fake WM_xSCROLL message, you've not updated the scroll message.

It's naieve to think that messages are just an interface and can be forced and faked at will. The control is still quite free to alter its own state before or after the message is sent.

On the other hand, you're correct in pointing out that the WM_xSCROLL message is a notification of a change: it's invalid to send such a message when no state change occurs. By forcing the message, you're not causing the change--you're saying that a change has already occured.  And it hasn't.

I can tell you that, internally, the list view control (almost) immediately calls GetScrollInfo(). And your since your phony scroll messages arrive to the control without the scroll info changing, the control doesn't budge.  On the other hand, the list _box_ (not list _view_) control uses the messages to update the delta scroll for the window. It doesn't look at the scroll info; just the messages.

That explains the difference in behaviour between the controls, explain why your opinion that the messages are "an interface" is inaccurate, and why forcing fake WM_xSCROLL messages without updating the scrollbar info first is the work of Satan.

Did you even _try_ my suggestion of using LVM_SCROLL, by the way?

.B ekiM

0
 

Author Comment

by:asker
ID: 1316547
To Mikeblas:

>I can tell you that, internally, the list view control (almost) immediately >calls GetScrollInfo(). And your since your phony scroll messages arrive >to the control without the scroll info changing, the control doesn't >budge.  On the other hand, the list _box_ (not list _view_) control uses the >messages to update the delta scroll for the window. It doesn't look at the >scroll info; just the messages.

That is the answer to my question, so I grade your answer. And I can guess why the situation is as such: the reason is 16 to 32 bit transition. WM_*SCROLL messages do not allow using of 32 bit nPos, nTrackPos and so on, so controls and windows have to use GetScrollInfo to get the correct message parameters. It means that SB_THUMBTRACK and SB_THUMBPOSITION messages should be considered as only notifications (in the common case) and their parameters should be ignored (only those returned from GetScrollInfo are valid).

So, if it were still 16 bit environment (without GetScrollInfo), my approach would work.

>Did you even _try_ my suggestion of using LVM_SCROLL, by the way?

No. I need a common solution, not that is control specific. And, please, believe me - I do not work for Satan, the only idol of mine is The User:-)

Thank you for the answer.

Regards,
Asker.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1316548
Forcing fake WM_xSCROLL messages may or may not work in any environment. 16-bit apps might call GetScrollPos() or GetScrollRange() instead of using the information provided with the control. Such an app, too, would fail when confronted with a phony scroll mssage.

.B ekiM

0
 

Author Comment

by:asker
ID: 1316549
>Forcing fake WM_xSCROLL messages may or may not work in any >environment. 16-bit apps might call GetScrollPos() or GetScrollRange() >instead of using the information provided with the control. Such an app, >too, would fail when confronted with a phony scroll mssage.

No! GetScrollRange returns the range values - they are not changing while the thumb is being dragged (as a rule, of course), it does not return even the current position.

About GetScrollPos: here is what the help says about it:

" An application implements such scrolling by processing the WM_HSCROLL or WM_VSCROLL messages that carry the SB_THUMBTRACK notification message, thereby tracking the position of the scroll box, also known as the thumb, while the user moves it. Unfortunately, there is no function to retrieve the thumb’s 32-bit position while the user moves it. GetScrollPos provides static position data only; an application can therefore only obtain 32-bit position data before or after a scroll has taken place. "

It is not true - it is a mistake in the help (it is outdated!), because we know (thanks to you:-) that GetScrollInfo with SIF_TRACKPOS does return the 32 bit thumb position, while the current position of the scrollbar (retrieved with GetScrollPos or GetScrollInfo) DOES NOT CHANGE!

What does it mean? I believe, that earlier the only way to get the tracking position was to handle the parameter of the SB_THUMBTRACK message. That is why I belive that my approach would work in 16 bit environment (calling SetScrollPos with the tracking position and bRedraw = TRUE followed by immediate call to SetScrollPos with the original position and bRedraw = FALSE makes the scrollbar to move its thumb while keeping the current position constant).

Regards,
Asker.
0

Featured Post

ScreenConnect 6.0 Free Trial

Discover new time-saving features in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question