CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 4 of 4 FirstFirst 1234
Results 46 to 58 of 58
  1. #46
    Join Date
    Mar 2001
    Posts
    2,529

    Re: [win32] - avoid flicker and do a correct redraw

    Hmmm sometimes passing FALSE instead of true to InvalidateRect() can stop the blinking if memory serves...
    ahoodin
    To keep the plot moving, that's why.

  2. #47
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: [win32] - avoid flicker and do a correct redraw

    From MSDN:
    bErase [in]
    Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.
    Victor Nijegorodov

  3. #48
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: [win32] - avoid flicker and do a correct redraw

    yes, but that may or may not cause correct painting... painting the background may be a necessary process. Failure to erase the background can cause "old stuff" to remain on screen and not go away.



    Flicker happens because a pixel (or typically a group of pixels) is in one color, gets *temporarily* overwritten by some other color during an intermediary step. Then gets painted back in it's original color.

    Since the screen updating is not usually (i can be on some videocards) synchronised with the screen refresh cycle, there are moments where you will see the "temporary" colored pixel, and that is what causes the disturbing flicker.

    As I have said before (3x now), the best way to solve this kind of flicker is to prevent the intermediary stages from even making it to the screen. Which is achieved with making a memory DC, doing all intermediate painting onto the memory DC, then blit the resulting bitmap at once to screen. WS_EX_COMPOSITED has Windows attempt to do this on it's own, but it can't really fix flicker because the video can't know what are the intermediate stages and what aren't.


    There are other screen artefacts that are sometimes called "flicker" but are actually entirely different beasts with different causes and solutions.

  4. #49
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    Quote Originally Posted by OReubens View Post
    yes, but that may or may not cause correct painting... painting the background may be a necessary process. Failure to erase the background can cause "old stuff" to remain on screen and not go away.



    Flicker happens because a pixel (or typically a group of pixels) is in one color, gets *temporarily* overwritten by some other color during an intermediary step. Then gets painted back in it's original color.

    Since the screen updating is not usually (i can be on some videocards) synchronised with the screen refresh cycle, there are moments where you will see the "temporary" colored pixel, and that is what causes the disturbing flicker.

    As I have said before (3x now), the best way to solve this kind of flicker is to prevent the intermediary stages from even making it to the screen. Which is achieved with making a memory DC, doing all intermediate painting onto the memory DC, then blit the resulting bitmap at once to screen. WS_EX_COMPOSITED has Windows attempt to do this on it's own, but it can't really fix flicker because the video can't know what are the intermediate stages and what aren't.


    There are other screen artefacts that are sometimes called "flicker" but are actually entirely different beasts with different causes and solutions.
    by some reason i can't put the WS_EX_COMPOSITED working
    but see these: the Invalidate() TRUE or FALSE(for clean the background or not) redraw the entire window inclued the child controls make them flickering. heres my WM_PAINT:
    Code:
    case WM_ERASEBKGND:
                    {
                        return TRUE;
                    }
                    break;
    
                    case WM_PAINT:
                    {
                        PAINTSTRUCT  ps;
                        BeginPaint(inst->hwnd, &ps);
    
                        //draw a background on inst->imgForm
                        inst->imgForm.Brush(inst->clrBackColor);
                        pen test;
                        inst->imgForm.Pen(test);
                        inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //call the Paint lambda
                        if (inst->Paint!=NULL)
                            inst->Paint((HDC)inst->imgForm);
    
                        //change the HDC backcolor\brush
                        FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
    
                        //TransparentBlt() for avoid overloading the pixel
                        TransparentBlt(ps.hdc, inst->pntScrollDC.x,inst->pntScrollDC.y , inst->imgForm.width(), inst->imgForm.height(), inst->imgForm,0 ,0, inst->imgForm.width(), inst->imgForm.height(), GetPixel(inst->imgForm,0,0));
    
                        EndPaint(inst->hwnd, &ps);
                        return 0;
                    }
                    break;
    Code:
    void Refresh()
            {
                RECT a={0,0,imgForm.width(),imgForm.height()};
                InvalidateRect(hwnd, &a, FALSE);
            }
    i call the Refresh() using a timer animation. i get several flickers. i'm sorry, but i don't understand how avoid them

  5. #50
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [win32] - avoid flicker and do a correct redraw

    Quote Originally Posted by Cambalinho View Post
    heres my WM_PAINT:
    Your paint handler must do only a single operation with physical DC (ps.hdc): XxxBlt between your physical DC and memory DC. All the other operations must be done only in memory DC. This is what OReubens constantly tells you, and you seem never hear him.
    Last edited by Igor Vartanov; August 21st, 2015 at 02:46 AM.
    Best regards,
    Igor

  6. #51
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    Quote Originally Posted by Igor Vartanov View Post
    Your paint handler must do only a single operation with physical DC (ps.hdc): XxxBlt between your physical DC and memory DC. All the other operations must be done only in memory DC. This is what OReubens constantly tells you, and you seem never hear him.
    Igor sorry if i make you think on that way. i hear everyone. i'm trying to understand more.
    finally i understand why the WS_EX_COMPOSITED was not working.... for avoid a flicker i must do:

    1 -avoid averrride pixels;
    2 - use WS_EX_COMPOSITED and WS_CLIPCHILDREN on parent window, and WS_CLIPSIBLINGS on child window. if, when execute the program, we see a black color, so we invalidate it;
    3 - InvalidateRect() refresh the window, but must be FALSE for not repaint the background and we do it on WM_PAINT;
    4 - we avoid the CS_VREDRAW and CS_HREDRAW on style WNDCLASS member;
    5 - the WM_ERASEBKGND(some child controls use another message) returns TRUE;
    6 - we use Double-Buffering on WM_PAINT for, on end, we draw it only once. advice do the variables outside of WM_PAINT for save time and CPU and not, always recreate them.

    now i have very less flickers.
    Last edited by Cambalinho; August 21st, 2015 at 05:00 AM.

  7. #52
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    i fix another flicker. but see these code:
    Code:
    case WM_ERASEBKGND:
                    {
                        return TRUE;
                    }
                    break;
    
                    case WM_PAINT:
                    {
                        PAINTSTRUCT  ps;
                        BeginPaint(inst->hwnd, &ps);
    
                        //draw a background on inst->imgForm
                        inst->imgForm.Brush(inst->clrBackColor);
                        pen test;
                        inst->imgForm.Pen(test);
                        inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //call the Paint lambda
                        if (inst->Paint!=NULL)
                            inst->Paint((HDC)inst->imgForm);
                        BitBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, SRCCOPY);
    
                        RECT rctWindowUnPainted={inst->pntScrollDC.x+ inst->imgForm.width(),inst->pntScrollDC.y+inst->imgForm.height(),inst->imgForm.width(), inst->imgForm.height() };
    
                        FillRect(ps.hdc,&rctWindowUnPainted,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
    
                        EndPaint(inst->hwnd, &ps);
                        return 0;
                    }
                    break;
    my question is: why the redraw isn't clean?(see the image)
    Name:  refresh problem.jpg
Views: 1388
Size:  13.3 KB

  8. #53
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: [win32] - avoid flicker and do a correct redraw

    I have no idea what your code does, so I have no answer to your question. If I were you, I would always fill the entire memDC with background color first, and only then painted the essential parts.

    I can see scrolling somehow involved here, so you have to carefully revise your viewport logic.

    Using the WM_PAINT Message

    About Painting and Drawing
    Last edited by Igor Vartanov; August 21st, 2015 at 05:51 AM.
    Best regards,
    Igor

  9. #54
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    Code:
    case WM_PAINT:
                    {
                        PAINTSTRUCT  ps;
                        BeginPaint(inst->hwnd, &ps);
    
                        //draw a background on inst->imgForm
                        inst->imgForm.Brush(inst->clrBackColor);
                        pen test;
                        inst->imgForm.Pen(test);
                        inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //call the Paint lambda
                        if (inst->Paint!=NULL)
                            inst->Paint((HDC)inst->imgForm);
                        FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
                        BitBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, SRCCOPY);
                        EndPaint(inst->hwnd, &ps);
                        return 0;
                    }
    doing these, is redrawing correctly. but do the flickers

  10. #55
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    now see these code:
    Code:
    case WM_ERASEBKGND:
                    {
                        return TRUE;
                    }
                    break;
    
                    case WM_PAINT:
                    {
                        PAINTSTRUCT  ps;
                        BeginPaint(inst->hwnd, &ps);
                        
                        //inst is the form object pointer
                        //imgForm is my image object
                        
                        //draw a background on imgForm
                        inst->imgForm.Brush(inst->clrBackColor);
                        pen test;
                        inst->imgForm.Pen(test);
                        inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //call the Paint lambda
                        if (inst->Paint!=NULL)
                            inst->Paint((HDC)inst->imgForm);
                        
                        //draw the form background
                        FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
                        
                        //draw the imgForm without the background color
                        TransparentBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, inst->imgForm.width(), inst->imgForm.height(), GetPixel(inst->imgForm, 0,0));
                        
                        
                        EndPaint(inst->hwnd, &ps);
                        return 0;
                    }
                    break;
    now, maybe you can understand it.
    - 1st i must draw the form background color on Client Rect;
    - then i draw the image where i need it.... i use transparent for avoid more the flicker. the image can be on or out of Client Rect.

  11. #56
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    finally i came with 1 thot. i did 1 temp image for draw the background with image in scroll way:
    Code:
    case WM_ERASEBKGND:
                    {
                        return TRUE;
                    }
                    break;
    
                    case WM_PAINT:
                    {
                        PAINTSTRUCT  ps;
                        BeginPaint(inst->hwnd, &ps);
    
                        //inst is the form object pointer
                        //imgForm is my image object
                        
                        //creating a temp image for draw the background color and the image on scroll way
                        image imgTemp(inst->imgForm.width(), inst->imgForm.height());
                        //draw the background color on temp image
                        imgTemp.Brush(inst->clrBackColor);
                        pen test;
                        imgTemp.Pen(test);
                        imgTemp.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //draw a background on imgForm
                        inst->imgForm.Brush(inst->clrBackColor);
                        inst->imgForm.Pen(test);
                        inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
    
                        //call the Paint lambda
                        if (inst->Paint!=NULL)
                            inst->Paint((HDC)inst->imgForm);
                        
                        //imgTemp will recive the image on scroll way
                        inst->imgForm.draw(imgTemp,inst->pntScrollDC.x, inst->pntScrollDC.y);
                        
                        //draw the entire image(the temp image) to HDC window
                        BitBlt(ps.hdc,0,0,inst->imgForm.width(), inst->imgForm.height(),imgTemp,0,0, SRCCOPY);
    
                        EndPaint(inst->hwnd, &ps);
                        return 0;
                    }
                    break;
    now works fine and no flicker that i see
    thanks for all to all.
    i hope the thread help more readers with these subject. that's it's complicated at 1st.
    thanks

  12. #57
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: [win32] - avoid flicker and do a correct redraw

    Quote Originally Posted by Cambalinho View Post
    //draw the entire image(the temp image) to HDC window
    BitBlt(ps.hdc,0,0,inst->imgForm.width(), inst->imgForm.height(),imgTemp,0,0, SRCCOPY);


    and this is what I've been saying all along. use a SINGLE paint to screen.

    in the previous ones you still had
    -> paint everything black
    -> paint image on top of black

    put that in a loop and you'll see alternating black and image => flicker

  13. #58
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [win32] - avoid flicker and do a correct redraw

    Quote Originally Posted by OReubens View Post


    and this is what I've been saying all along. use a SINGLE paint to screen.

    in the previous ones you still had
    -> paint everything black
    -> paint image on top of black

    put that in a loop and you'll see alternating black and image => flicker
    don't be mad with me. i was trying.... and we fix it

Page 4 of 4 FirstFirst 1234

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured