Drawing while moving the mouse?
Terry Evans -- tevans@ix.netcom.com
Thursday, July 18, 1996
Environment: VC++ 4.1 / Win95
Background of the problem:
I have a CScrollView window which will draw a horizontal, 1 pixel,
line across it when the user clicks, holds down, and moves the left
mouse button up and down within the view. The width of the
view window is always 64 pixels. The height can be anywhere from
200 to about 3000 pixels depending on a scaling factor the user
decides upon. However, I am not drawing anything into the view
except the horizontal line.
I am drawing the horizontal bar in the OnDraw method of the
CScrollView derived class.
The problem:
When the horizontal bar is being moved around on the screen,
sometimes the horizontal bar is being drawn fast enough to be
fine. However, at other times there is about a quarter second
lag before the OnDraw method gets invoked. Therefore, the
horizontal bar appears to be very jerky when it is moving.
Things I have tried:
Invalidating just the part of the client area of the view that
needs to be redrawn in the OnMouseMove method. This didn't speed
it up at all as I expected.
Calling UpdateWindow right after the InvalidateRect in the
OnMouseMove method. This helped some, but the bar is still being
redrawn too slow.
Anyone have ideas on how to make the drag of the horizontal
line appear very smooth?
Thanks for your help!
Terry Evans
tevans@ix.netcom.com
Gene Sewell -- genes@fast.net
Monday, July 22, 1996
[Mini-digest: 3 responses]
Hi,
You didn't specify what else is happening in your app. I'm guessing that
you are doing a bunch of computations, and that the reason for the 1/2 sec
delay is that you sometimes don't let windows in for that long.
Assuming this is true, you need to insert message processing code inside
your compute intensive code. Something like this:
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
{
if (!AfxGetApp()->PreTranslateMessage(&msg))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
AfxGetApp()->OnIdle(0); // updates user interface
If that's your problem, this should help!
Gene
----
Small things make perfection, but perfection is no small thing.
-----From: Dan Liliedahl
At 11:36 PM 7/18/96 -0600, you wrote:
>Environment: VC++ 4.1 / Win95
>
>Background of the problem:
>
> I have a CScrollView window which will draw a horizontal, 1 pixel,
>line across it when the user clicks, holds down, and moves the left
>mouse button up and down within the view. The width of the
>view window is always 64 pixels. The height can be anywhere from
>200 to about 3000 pixels depending on a scaling factor the user
>decides upon. However, I am not drawing anything into the view
>except the horizontal line.
>
> I am drawing the horizontal bar in the OnDraw method of the
>CScrollView derived class.
>
>The problem:
>
> When the horizontal bar is being moved around on the screen,
>sometimes the horizontal bar is being drawn fast enough to be
>fine. However, at other times there is about a quarter second
>lag before the OnDraw method gets invoked. Therefore, the
>horizontal bar appears to be very jerky when it is moving.
>
>Things I have tried:
>
> Invalidating just the part of the client area of the view that
>needs to be redrawn in the OnMouseMove method. This didn't speed
>it up at all as I expected.
>
> Calling UpdateWindow right after the InvalidateRect in the
>OnMouseMove method. This helped some, but the bar is still being
>redrawn too slow.
>
>
> Anyone have ideas on how to make the drag of the horizontal
>line appear very smooth?
>
>Thanks for your help!
>
>Terry Evans
>tevans@ix.netcom.com
>
You need to draw directly to the window in response to the OnMouseDown
event instead of invalidating/updating. When you invalidate/update you
are relying on the system to determine when the best time to paint is.
void OnxxMouseDown(....)
{
if (!m_bTracking)
m_bTracking = TRUE;
}
void OnxxMouseUp(...)
{
if (m_bTracking)
m_bTracking = FALSE;
}
void OnxxmouseMove(...)
{
if (!m_bTracking)
return;
erase_old_bar; // draw on window, NOT invalidate
draw_new_bar;
}
This is obviously not all the logic you will need. Look at the
implementation of the CSplitterView class in MFC for more info.
Dan Liliedahl Phone# (508)937-3700 X632
Adra Systems, Inc. Fax# (508)453-2462
Two Executive Drive EMAIL: dan.liliedahl@adra.com
Chelmsford, MA. 01824
-----From: Marty Fried
I think you'd be better off drawing directly into the view
using device context functions like MoveTo/LineTo, with a CPen.
You can use dc.SetROP2(R2_NOT), and always draw the lines twice,
where the 2nd time restores the screen from the first time. This
is simplest, and gives fast response.
I have code that tracks a header control, drawing a vertical line
as the width is varied. Maybe it will help if you're not familiar
with the methods. It's called from the notification handler for the
header control; you would use whatever routine gets the scroll
notifications.
CClientDC dc(this);
CPen pOldPen
// delete old line
pOldPen = dc.SelectObject(pen);
dc.SetROP2(R2_NOT);
dc.MoveTo(OldX, 0);
dc.LineTo(OldX, m_ViewHeight);
// draw new line
dc.MoveTo(NewX, 0);
dc.LineTo(NewX, m_ViewHeight);
dc.SelectObject(pOldPen);
Hope this helps,
Marty Fried mfried@linex.com
Marin County, California
| Вернуться в корень Архива
|