How do I force a window to scroll?

G

Guest

I want to force a window to scroll and am finding this to be an impossibly difficult task. First I tried using the API functions ScrollWindow and ScrollWindowEx but they do not work. The portion that is being exposed in the scroll is not painting properly even though I've passed it the flags to tell it to invalidate and erase the new area's background. Then when I force the window to redraw by covering the window with another app the window is redrawn in its original position.

I was then led down the path of calling SetScrollPosition on my window but this doesn't work either. The contents of the window are not redrawn and it's difficult to convert the number of actual pixels I want to scroll by into the generally larger min/max range of the scrollbar. Even after I add code to cause the scroll the scrollbar works great but the contents of the window do not move. Then eventually I get to the point where tapping the scrollbar arrows itself will cause the window to jump dramatically to another point.

From what I can tell there's absolutely no communication between a window and its internally-created scrollbar and that causes these API calls to fail. So I then tried to do both a SetScrollPos and a ScrollWindow and I didn't have anymore luck.

Since the act of manually scrolling a window is not documented in the MSDN or even mentioned in the newsgroups I'm starting to think that my desired behavior is not something applications are not supposed to handle on their own. If this is true how do I cause a window automatically when the user drags content to the upper or lower portion of the window like so many other apps do?

Thanks
 
J

Jeff Partch [MVP]

Steve said:
I want to force a window to scroll and am finding this to be an impossibly
difficult task. First I tried using the API functions ScrollWindow and
ScrollWindowEx but they do not work. The portion that is being exposed in
the scroll is not painting properly even though I've passed it the flags to
tell it to invalidate and erase the new area's background. Then when I
force the window to redraw by covering the window with another app the
window is redrawn in its original position.
I was then led down the path of calling SetScrollPosition on my window but
this doesn't work either. The contents of the window are not redrawn and
it's difficult to convert the number of actual pixels I want to scroll by
into the generally larger min/max range of the scrollbar. Even after I add
code to cause the scroll the scrollbar works great but the contents of the
window do not move. Then eventually I get to the point where tapping the
scrollbar arrows itself will cause the window to jump dramatically to
another point.
From what I can tell there's absolutely no communication between a window
and its internally-created scrollbar and that causes these API calls to
fail. So I then tried to do both a SetScrollPos and a ScrollWindow and I
didn't have anymore luck.
Since the act of manually scrolling a window is not documented in the MSDN
or even mentioned in the newsgroups I'm starting to think that my desired
behavior is not something applications are not supposed to handle on their
own. If this is true how do I cause a window automatically when the user
drags content to the upper or lower portion of the window like so many other
apps do?

Have you tried to SendMessage it a series of WM_VSCROLL?
 
G

Guest

Not at the time I wrote that first message, but I eventually tried that and had success and I wanted to share my solution on this newsgroup. :

Sending a scroll message was one of my first thoughts, but I decided against it because I made the stupid assumption that when a WM_VSCROLL is fired by the scrollbar the scrollbar itself had already done what it needed to do and sent that message to itself to handle the client area of the window. I thought that if I handled it I would, at best, get the proper client area but the scrollbar would be in the wrong spot. Thankfully I was wrong and that solution worked perfectly and reliably

For those who are interested this is what I did, at the point where I knew that I wanted to scroll the window I added
::SendMessage(theWindowToScroll->m_hWnd, WM_VSCROLL, SB_LINEUP, 0);
(and there's a corresponding SB_LINEDOWN to go down too

My function that performs this task is part of the IDropTarget::DragOver() which is fired over and over as your mouse moves (and even hovers) over a window so I added a Sleep(50) to slow down this process otherwise the window can scroll so fast it isn't useful. It might be best to skip, say, every other ::SendMessage call than to perform a sleep but I'm going to see how it goes before I make a change like that
 
Y

Yan-Hong Huang[MSFT]

Hello Stephen,

Thanks for sharing it in the community. I believe it could help other
developers much. :)

More on it, all of the supported scoll types are:

SB_BOTTOM
Scroll to lower right.
SB_ENDSCROLL
End scroll.
SB_LINEDOWN
Scroll one line down.
SB_LINEUP
Scroll one line up.
SB_PAGEDOWN
Scroll one page down.
SB_PAGEUP
Scroll one page up.
SB_THUMBPOSITION
Scroll to absolute position. The current position is specified by the
high-order word.
SB_TOP
Scroll to upper left.

which is defined in Winuser.h.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top