Repeating the scroll
Doncho Angelov -- alian@plovdiv.techno-link.com
Sunday, February 02, 1997
Environment: VC++ 4.0, Win 95
Hello everybody !
I have the following problem:
I'm implementing drag operation in my CScrollView. It's simple dragging =
of graphical object from one place to another. But as you know the =
ScrollView has size, which is (sometimes) much bigger than the window's =
client area. So I want after I go outside the client area during =
dragging with the mouse, the CScrollView to scroll automatically while =
I'm 'away' from the client area and to finish scrolling at the end or =
when I return to the client area. I've checked some materials to find =
'ready' code, but I couldn't find even an idea. The only one idea which =
came into my mind was to initialize timer who's going to check and to =
send scrolling messages while the cursor is outside the client area, but =
this is a little 'confusing'.
Any better ideas ?
Thanks in advance !
Doncho
Simon Salter -- Simon@chersoft.co.uk
Wednesday, February 05, 1997
Good scrolling is, imho, quite hard to do and also fairly rare. Here are
some ideas which build on what I suspect you are already thinking about.
When you are dragging the object you will have set capture to the view.
In OnMouseMove() you can test to see if you are outside or inside the
client rect and use this to start/stop scrolling of the view. You might
like to actually test a rect slightly smaller than the client area so
that scrolling starts when you get close to the edge.
To implement the scrolling you will first need to work out what
direction to scroll in (by looking where the mouse is in relation to the
client area). Controlling the scroll can be tricky. My preference is
that you do it in some controlled fashion which means when someone runs
your app on a super wizz cpu the scrolling does not rush past at an
unreasonable rate. (The MSDEV edit windows do this if you drag sideways
- it can sometimes need some deft mouse handling). So I'd use a timer to
set up a regular scrolling interval and start it from OnMouseMove(). I
might also calculate how far from the client area the cursor is and
increase the rate of scrolling proportionately. The OnTimer() would have
to calculate how much scrolling to do for one 'tick' and either do the
scroll or, if the mouse was back on the client area, kill the timer.
>-----Original Message-----
>From: Doncho Angelov [SMTP:alian@plovdiv.techno-link.com]
>Sent: Fri, 02 February 1996 23:22
>To: 'MFC-L'
>Subject: Repeating the scroll
>
>Environment: VC++ 4.0, Win 95
>
>Hello everybody !
>
>I have the following problem:
> I'm implementing drag operation in my CScrollView. It's simple dragging =
>of graphical object from one place to another. But as you know the =
>ScrollView has size, which is (sometimes) much bigger than the window's =
>client area. So I want after I go outside the client area during =
>dragging with the mouse, the CScrollView to scroll automatically while =
>I'm 'away' from the client area and to finish scrolling at the end or =
>when I return to the client area. I've checked some materials to find =
>'ready' code, but I couldn't find even an idea. The only one idea which =
>came into my mind was to initialize timer who's going to check and to =
>send scrolling messages while the cursor is outside the client area, but =
>this is a little 'confusing'.
> Any better ideas ?
>
>Thanks in advance !
>
>Doncho
John Young -- jyoung@gol.com
Thursday, February 06, 1997
Hi Doncho,
At 11:21 pm 2/2/96 +-200, Doncho Angelov wrote:
>Environment: VC++ 4.0, Win 95
>
>Hello everybody !
>
>I have the following problem:
> I'm implementing drag operation in my CScrollView. It's simple dragging =
>of graphical object from one place to another. But as you know the =
>ScrollView has size, which is (sometimes) much bigger than the window's =
>client area. So I want after I go outside the client area during =
>dragging with the mouse, the CScrollView to scroll automatically while =
>I'm 'away' from the client area and to finish scrolling at the end or =
>when I return to the client area. I've checked some materials to find =
>'ready' code, but I couldn't find even an idea. The only one idea which =
>came into my mind was to initialize timer who's going to check and to =
>send scrolling messages while the cursor is outside the client area, but =
>this is a little 'confusing'.
> Any better ideas ?
I did this recently. What I did was to capture the mouse in the view's
OnLButtonDown() handler, detect when the mouse is dragged out of the
client area in the OnMouse() handler and start a timer. In the
OnTimer() handler, simply calculate the new scroll and call
ScrollToPosition(). When the mouse button is released, then release
the capture and kill the timer.
The timer value can be varied so that the scrolling slows down when the
mouse nears the client area, and speeds up when it is further away.
Here's the heart of the code I use...
void CPredView::OnLButtonDown(UINT nFlags, CPoint point)
{
theMouse.Capture (this);
CScrollView::OnLButtonDown (nFlags, point);
}
void CPredView::OnMouseMove (UINT nFlags, CPoint point)
{
if ( nFlags & MK_LBUTTON )
{
CRect rectClient;
GetClientRect (&rectClient);
if ( point.y >= rectClient.top &&
point.y <= rectClient.bottom )
{
m_bMouseScrolling = FALSE;
KillTimer (TIMER_MOUSESCROLL);
}
else
{
// Mouse is outside the client area, so scroll
if ( !m_bMouseScrolling )
{
m_bMouseScrolling = TRUE;
SetTimer (TIMER_MOUSESCROLL, 50, NULL);
}
}
}
CScrollView::OnMouseMove(nFlags, point);
}
void CPredView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bMouseScrolling = FALSE;
KillTimer (TIMER_MOUSESCROLL);
theMouse.Release();
CScrollView::OnLButtonUp(nFlags, point);
}
void CPredView::OnTimer (UINT nIDEvent)
{
if ( nIDEvent == TIMER_MOUSESCROLL )
{
CPoint pt = theMouse;
ScreenToClient (&pt);
OnMouseScroll (pt);
}
CScrollView::OnTimer(nIDEvent);
}
void CPredView::OnMouseScroll (CPoint ptMouse)
{
// Mouse is outside the client window.
CPoint ptScroll = GetScrollPosition();
if ( IsBelowClient (ptMouse) )
{
// Scroll up by some amount
ptScroll += ?
ScrollToPosition (ptScroll);
// Adjust speed
if ( ptMouse.y > rectClient.bottom + m_nSpeedThreshold )
SetTimer (TIMER_MOUSESCROLL, 10, NULL); // Fast
else SetTimer (TIMER_MOUSESCROLL, 300, NULL); // Slow
}
else if ( IsAboveClient (ptMouse) )
{
// Scroll down
ptScroll -= ?
ScrollToPosition (ptScroll);
// Adjust speed
if ( ptMouse.y < rectClient.top - m_nSpeedThreshold )
SetTimer (TIMER_MOUSESCROLL, 10, NULL); // Fast
else SetTimer (TIMER_MOUSESCROLL, 300, NULL); // Slow
}
}
HTH
-John
John Young, Yaesu Musen Co., Ltd., Japan.
If only computers did what you wanted, not what you tell them.
Become an MFC-L member
| Вернуться в корень Архива
|