Prev: Changing the Backcolor of Tab Control in MFC ,Winxp
Next: Multiple closed networks and UDP. Please help me.
From: Luigino on 26 Oct 2009 13:05 > 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 26 Oct 2009 13:19 "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 26 Oct 2009 22:27 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 27 Oct 2009 11:25 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 28 Oct 2009 23:50 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
First
|
Prev
|
Pages: 1 2 3 4 5 6 Prev: Changing the Backcolor of Tab Control in MFC ,Winxp Next: Multiple closed networks and UDP. Please help me. |