From: Luigino on

> Actually, that is not "rotating", that is "sliding". So all you need to do is maintain an
> origin value and redraw from the origin.

well yeah.... just I was thinking about "rotating" 'cause the effect
is similar...visually it is rotating to left though... ;-)

> For optimization, you can use ScrollWindow to scroll the existing material to the left,
> which will create a gap on the right, and the OnDraw will only actually write to the gap,
> thus reducing apparent flicker.

Hmmmmm.....you're right.... in fact if I draw everthing, grid and all
values of lines from an array of values, surely it would be more heavy
with a bad bad flicker I suppose...I think I'll have to remember
somewhere last point to draw next line from...
But, a question: does this ScrollWindow(...) also scroll some left
part in a hided area so if I resize window I can show that hided area
of values?... just like the task manager...

Luigi
From: Scott McPhillips [MVP] on
"Luigino" <npuleio(a)rocketmail.com> wrote in message
news:3ee9e75e-9a89-47a6-8aa9-2ced7caa9620(a)a37g2000prf.googlegroups.com...
> Hmmmmm.....you're right.... in fact if I draw everthing, grid and all
> values of lines from an array of values, surely it would be more heavy
> with a bad bad flicker I suppose...I think I'll have to remember
> somewhere last point to draw next line from...
> But, a question: does this ScrollWindow(...) also scroll some left
> part in a hided area so if I resize window I can show that hided area
> of values?... just like the task manager...
>
> Luigi

No, ScrollWindow just copies the visible pixels from old to new rectangle.
The pixels that are scrolled offscreen are gone. So to do what Task Manager
does you will need to save the old data, and redraw the entire picture when
the window size is changed.

--
Scott McPhillips [VC++ MVP]

From: Joseph M. Newcomer on
What I did was save an "optimized" set of drawing commands (in particular, the PolyLine
data). When I scrolled the window, it merely established what point at which I drew the
PolyLine data from. The ScrollWindow is just a graphical optimization. Note that the
PolyLine data was already pre-scaled to the window coordinates (I used MM_ANISOTROPIC) so
it was cheap to maintain, and I kept only a finite amount of scrollback. If the user went
back further than the "cache", I had to read data in from the file and recompute the range
(I always started some large delta-T before the left edge of the drawing).

So it is up to you to maintain and redraw the image at all times. For example, in my
OnDraw, I *always* did a PolyLine from T[left] for whatever the length was. But if I had
done a ScrollWindow, the first, say, three inches of the display (left-to-right) was
overdrawn, but also clipped, so GDI optimized it by not bothering to draw it at all, and
started the drawing in the invalidated region. But I never worried about the invalidated
region; I drew the whole thing. So ScrollWindow is just an optimization. If you
commented the ScrollWindow out, the whole thing should sitll work, but it just would
flicker more.
joe

On Mon, 26 Oct 2009 13:19:45 -0400, "Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp>
wrote:

>"Luigino" <npuleio(a)rocketmail.com> wrote in message
>news:3ee9e75e-9a89-47a6-8aa9-2ced7caa9620(a)a37g2000prf.googlegroups.com...
>> Hmmmmm.....you're right.... in fact if I draw everthing, grid and all
>> values of lines from an array of values, surely it would be more heavy
>> with a bad bad flicker I suppose...I think I'll have to remember
>> somewhere last point to draw next line from...
>> But, a question: does this ScrollWindow(...) also scroll some left
>> part in a hided area so if I resize window I can show that hided area
>> of values?... just like the task manager...
>>
>> Luigi
>
>No, ScrollWindow just copies the visible pixels from old to new rectangle.
>The pixels that are scrolled offscreen are gone. So to do what Task Manager
>does you will need to save the old data, and redraw the entire picture when
>the window size is changed.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Luigino on
HI Joe,

I studied a bit on this thing about ScrollWindow, PolyLine and the
flicker thing....and I got this point:
lemme guess using ScrollView means preventing flickering, even if I
use CMemDC which as documented it should reduce flickering effect,
when I am redesign the entire client area; indeed it should be enough
to redesign a single object in the client area without using
ScrollWindow since it's a little object with a very limited flicker
which would be like invisible to the eye... right?...

In fact with this code I implemented:

void MyDLL::OnTimer(UINT TimerVal)
{
BOOL timerstate;
// ****** stopping timer ******
timerstate = TRUE;
if (!KillTimer(iTimerVal))
{
// message
MessageBox(_T("Unable to stop timer!"), _T
("IDT_TIMER_0"), MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
timerstate = FALSE;
}
// ****** processing event ******
gridOffset++;
if (gridOffset > 12.5)
gridOffset = 0;

Invalidate();

// ****** restart timer *******
if (timerstate)
{
iTimerVal = SetTimer(IDT_TIMER_0, 1000, 0);
}

// call base class handler
CWnd::OnTimer(TimerVal);
}

void MyDLL::OnDraw(CDC* pDC)
{
CMemDC mDC(pDC);

//EraseBkgnd(mDC);

CRect rect;
GetClientRect(rect);

// For now, background black fixed
mDC->FillRect(rect, CBrush::FromHandle((HBRUSH)GetStockObject
(BLACK_BRUSH)));

// ********** Background ***********

// Grid
if (bActivateGrid)
{
CPen qLinePen(PS_SOLID, 1, RGB(0,139,0));
mDC->SelectObject(&qLinePen);

// Grid - Horizontal lines
mDC->MoveTo(1, 0);
mDC->LineTo(rect.Width(), 0);
int height = rect.Height();
int maxlines = height / 12.5;
for (int i=1;i<=maxlines;i++){
int y_axis = i * 12.5;
if (y_axis <= rect.Height()) {
mDC->MoveTo(1, y_axis);
mDC->LineTo(rect.Width(), y_axis);
}
}

// Grid - Vertical lines
mDC->MoveTo(0, 0);
mDC->LineTo(0, rect.Height());
int width = rect.Width();
maxlines = width / 12.5;
for (int i=1;i<=maxlines;i++){
int x_axis = (i * 12.5) - gridOffset;
if (x_axis <= rect.Width()) {
mDC->MoveTo(x_axis, 1);
mDC->LineTo(x_axis, rect.Height());
}
}
}
}

here actually I'm redrawing the entire client area so it produces a
flicker even if I am using CMemDC because on this drawing I can
understand I'm doing lots of operations in a single draw...
Indeed, if I got it good as you are explaining, using ScrollWindow
would be like a single operation for almost entire part of client area
which would be very fast and then draw only next values in that little
remaining part at right edge.
The only thing I'm thinking at now is when I'm resizing which I think
it wouldn't really flicker redrawing the entire window client is about
to know what value from I have to draw left to right since in a
complete redraw due to resizing would draw from left to right....
Am I right?... What do you suggest in this case?....

Ciao!
Luigi

From: Joseph M. Newcomer on
See below...
On Tue, 27 Oct 2009 08:25:23 -0700 (PDT), Luigino <npuleio(a)rocketmail.com> wrote:

>HI Joe,
>
>I studied a bit on this thing about ScrollWindow, PolyLine and the
>flicker thing....and I got this point:
>lemme guess using ScrollView means preventing flickering, even if I
>use CMemDC which as documented it should reduce flickering effect,
>when I am redesign the entire client area; indeed it should be enough
>to redesign a single object in the client area without using
>ScrollWindow since it's a little object with a very limited flicker
>which would be like invisible to the eye... right?...
****
If you are using the two-stage CMemDC approach, you don't need to worry about
ScrollWindow; it is an optimization that doesn't require maintiaining a separate bitmap
while giving the effect of having one.
****
>
>In fact with this code I implemented:
>
>void MyDLL::OnTimer(UINT TimerVal)
>{
> BOOL timerstate;
> // ****** stopping timer ******
> timerstate = TRUE;
> if (!KillTimer(iTimerVal))
> {
> // message
> MessageBox(_T("Unable to stop timer!"), _T
>("IDT_TIMER_0"), MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL);
> timerstate = FALSE;
> }
> // ****** processing event ******
> gridOffset++;
> if (gridOffset > 12.5)
> gridOffset = 0;
>
> Invalidate();
>
> // ****** restart timer *******
> if (timerstate)
> {
> iTimerVal = SetTimer(IDT_TIMER_0, 1000, 0);
> }
>
> // call base class handler
****
I don't understand why you are stopping and starting the timer. YOu don't need to, and it
doesn't solve any known problem to do so. The code is also clumsy; you could have easily
have written
timerstate = KillTimer(TimerVal);
(I don't know what iTimerVal is) since that does everything you are doing, except that
nothing you are doing makes sense.

void MyDLL:OnTimer(UINT TimerVal)
{
if(TimerVal == IDT_TIMER)
{
gridOffset++;
if(gridOffset > 12.5)
gridOffset = 0.0;
Invalidate();
}
CWnd::OnTimer(TimerVal);
}

See how much simpler it is?

I'm presuming gridOffset is a double.
****
> CWnd::OnTimer(TimerVal);
>}
>
>void MyDLL::OnDraw(CDC* pDC)
>{
> CMemDC mDC(pDC);
>
> //EraseBkgnd(mDC);
>
> CRect rect;
> GetClientRect(rect);
>
> // For now, background black fixed
> mDC->FillRect(rect, CBrush::FromHandle((HBRUSH)GetStockObject
>(BLACK_BRUSH)));
>
> // ********** Background ***********
>
> // Grid
> if (bActivateGrid)
> {
> CPen qLinePen(PS_SOLID, 1, RGB(0,139,0));
> mDC->SelectObject(&qLinePen);
>
> // Grid - Horizontal lines
> mDC->MoveTo(1, 0);
> mDC->LineTo(rect.Width(), 0);
> int height = rect.Height();
> int maxlines = height / 12.5;
> for (int i=1;i<=maxlines;i++){
> int y_axis = i * 12.5;
> if (y_axis <= rect.Height()) {
> mDC->MoveTo(1, y_axis);
> mDC->LineTo(rect.Width(), y_axis);
> }
> }
>
> // Grid - Vertical lines
> mDC->MoveTo(0, 0);
> mDC->LineTo(0, rect.Height());
> int width = rect.Width();
> maxlines = width / 12.5;
> for (int i=1;i<=maxlines;i++){
> int x_axis = (i * 12.5) - gridOffset;
> if (x_axis <= rect.Width()) {
> mDC->MoveTo(x_axis, 1);
> mDC->LineTo(x_axis, rect.Height());
> }
> }
****
Fine, but I don't see where you do the BitBlt from mDC to PDC. So it doesn't actually do
anything.

Note that for raw performance, you would want to run through and convert the coordinates
to an array of CPoints and do a PolyLine or PolyPolyLine; it will be much faster.

Note that
int x_axis = (i * 12.5) - gridOffset;
should not compile without a warning. You should be compiling at /W4 for error checking.
int x_axis = (int) ( (double)i * 12.5) - gridOffset);
and you might consider adding 0.5 to get rounding.


****
> }
>}
>
>here actually I'm redrawing the entire client area so it produces a
>flicker even if I am using CMemDC because on this drawing I can
>understand I'm doing lots of operations in a single draw...
*****
TYpically, I consolidate the drawing into a separate handler, so I do

#ifdef _DEBUG_GRAPHICS
DoDrawing(*pDC);
#else
...create memDC
DoDrawing(mDC);
BitBlt(...);
#endif

and I do

#ifdef _DEBUG_GRAPHICS
#define GDI_FLUSH() GdiFlush()
#else
#define GDI_FLUSH()
#endif

Then you can single-step your graphics drawing if you define _DEBUG_GRAPHICS and see
things drawn one item at a time. Flicker is awful, but you can debug the graphics. Toss
GDI_FLUSH() calls after each drawing action.
****
>Indeed, if I got it good as you are explaining, using ScrollWindow
>would be like a single operation for almost entire part of client area
>which would be very fast and then draw only next values in that little
>remaining part at right edge.
****
The goal of ScrollWindow is to eliminate the double-buffer hack, particularly if you need
a massive bitmap for back (1920x1200x24bit = ~7MB)
****
>The only thing I'm thinking at now is when I'm resizing which I think
>it wouldn't really flicker redrawing the entire window client is about
>to know what value from I have to draw left to right since in a
>complete redraw due to resizing would draw from left to right....
>Am I right?... What do you suggest in this case?....
****
If you handle WM_ENTERSIZEMOVE and disable drawing (just set a flag and don't draw) and
WM_EXITSIZEMOVE clears the flag, does an Invalidate() and UpdateWindow(), then you don't
get the annoying "resize flicker" effect.

Due to a serious failure to understand reality, these messages don't have handlers you can
generate from VS; you have to hand-edit ON_MESSAGE handlers.
joe
****
>
>Ciao!
>Luigi
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm