CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 4 1234 LastLast
Results 1 to 15 of 58
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    [RESOLVED] [win32] - avoid flicker and do a correct redraw

    for resize or readraw the control i do:
    Code:
    SetWindowPos(hwnd, 0, 0, 0, 0, 0,
                SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|
                SWP_DRAWFRAME | SWP_FRAMECHANGED|SWP_NOCOPYBITS);
    but theses flags: SWP_DRAWFRAME and SWP_FRAMECHANGED give me the flicker.
    if i have the control transparent and don't use these code, the control isn't redraw, when i change the text
    so how can redraw the control without flicker? or 'clean' correctly the control, before give it the next text?

  2. #2
    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
    for resize or readraw the control
    To redraw a control you need InvalidateRect.

    Besides, resizing hardly gets along with zero values and SWP_NOSIZE flag. There's definitely must be something about the resizing that I don't know or understand.

    As for the flicker, you need to read more about WM_ERASEBKGND
    Best regards,
    Igor

  3. #3
    Join Date
    Apr 2009
    Posts
    1,355

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

    Quote Originally Posted by Igor Vartanov View Post
    To redraw a control you need InvalidateRect.

    Besides, resizing hardly gets along with zero values and SWP_NOSIZE flag. There's definitely must be something about the resizing that I don't know or understand.

    As for the flicker, you need to read more about WM_ERASEBKGND
    "The DefWindowProc function erases the background by using the class background brush specified by the hbrBackground member of the WNDCLASS structure. If hbrBackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.

    An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; this indicates that no further erasing is required. If the application returns zero, the window will remain marked for erasing. (Typically, this indicates that the fErase member of the PAINTSTRUCT structure will be TRUE.) "

    sorry... can you explain better?

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

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

    What part looks unclear to you? You need to get to a habit of reading MSDN on every single entity you meet in the text you are to understand. This literally means that to understand this fragment you need to have a background about DefWindowProc, WNDCLASS structure and related, PAINTSTRUCT and related, etc.

    So please don't wait until somebody digests everything for you. You have to learn to survive on your own having only a few hints from the community about possible directions.
    Best regards,
    Igor

  5. #5
    Join Date
    Apr 2009
    Posts
    1,355

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

    Quote Originally Posted by Igor Vartanov View Post
    What part looks unclear to you? You need to get to a habit of reading MSDN on every single entity you meet in the text you are to understand. This literally means that to understand this fragment you need to have a background about DefWindowProc, WNDCLASS structure and related, PAINTSTRUCT and related, etc.

    So please don't wait until somebody digests everything for you. You have to learn to survive on your own having only a few hints from the community about possible directions.
    "An application should return nonzero if it erases the background; otherwise, it should return zero."
    so:
    Code:
    case WM_ERASEBKGND:
            return true;//or even '1'... but must be diferent than '0' or don't clean it.
    what make me confuse is: if we are talking about controls, why the MSDN speaks about WM_PAINT message?
    (the WM_PAINT is for rebuild, for example, a new control and show images and work with HDC)

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

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

    WM_PAINT is sent to any window, including controls, which area became invalid.

    It might be invalid due to various reasons. For example, parent window was moved the way that the control or some part of it was displaced off the screen, and moved back to screen again. This way the window, or invalid part of it needs to be re-painted, and that's why WM_PAINT is sent.

    Or in case the window internally changes its state, e.g. the text it renders on screen, to be re-painted it declares itself invalid by calling InvalidateRect. This will again result in sending WM_PAINT to the window to be re-painted with the updated content.
    Best regards,
    Igor

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

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

    Quote Originally Posted by Igor Vartanov View Post
    WM_PAINT is sent to any window, including controls, which area became invalid.

    It might be invalid due to various reasons. For example, parent window was moved the way that the control or some part of it was displaced off the screen, and moved back to screen again. This way the window, or invalid part of it needs to be re-painted, and that's why WM_PAINT is sent.

    Or in case the window internally changes its state, e.g. the text it renders on screen, to be re-painted it declares itself invalid by calling InvalidateRect. This will again result in sending WM_PAINT to the window to be re-painted with the updated content.
    thanks for all

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

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

    Quote Originally Posted by Igor Vartanov View Post
    WM_PAINT is sent to any window
    Need to pick a nit here...

    WM_PAINT is never SENT to a window by Windows. (and you should never send it yourself either)

    The messagequeue has a flag that indicates that any part of the windows associated with said messagequeue have become invalidated and thus needs repainting.
    When you get messages from the queue, and the queue is empty) and the invalid flag is set, then GetMessage will return a WM_PAINT.

    This is why multiple invalidates only result in 1 WM_PAINT...
    ...and why WM_PAINT messages seem to be "pushed back" in the messagequeue and other messages get prioritized). If you invalidate a window and then send/post a message, you will first get the sent/posted message, then a WM_PAINT.

    There are other messages that equally don't actually get queued in the message queue but rather set a flag with the flag generating a returned message.
    Such as WM_TIMER, this works similarly, because if you don't get messages for X time (bad idea, but hey...), you won't suddenly get a flood of WM_TIMER messages you haven't been processing during that time).
    It's different to WM_PAINT in that a message is generated when you do GetMessage() and the timer flag is set rather than when the queue is empty. THere's several flags, but the point at which they generate a message is different.
    Last edited by OReubens; February 7th, 2014 at 08:16 AM.

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

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

    Quote Originally Posted by OReubens View Post
    WM_PAINT is never SENT to a window by Windows.
    WM_PAINT message

    The WM_PAINT message is sent when the system or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.
    The reality is a little bit trickier.
    Best regards,
    Igor

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

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

    1 - for do transparent i do(for all drawed controls):
    Code:
    case WM_ERASEBKGND:
                {
                    return (LRESULT)TRUE;
                }
                break;
    2 - for avoid flicker i add the WS_CLIPCHILDREN style on parent.

    3 - for readraw, i use:
    Code:
    RECT d;
                    GetClientRect(hwnd,&d);
                    InvalidateRect(hwnd,&d,TRUE);
    why the child control isn't clear, before call the WM_PAINT message?

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

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

    because you didn't clear it in the WM_ERASEBKGND :-)
    that's what that message is there for.

  12. #12
    Join Date
    Apr 2009
    Posts
    1,355

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

    Quote Originally Posted by OReubens View Post
    because you didn't clear it in the WM_ERASEBKGND :-)
    that's what that message is there for.
    i'm confused..i thot that i was doing it
    from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
    so what i'm doing wrong?

  13. #13
    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
    i'm confused..i thot that i was doing it
    from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
    so what i'm doing wrong?
    You just return TRUE, but erase nothing. As the result, neither you nor Windows takes care of the background.
    Last edited by Igor Vartanov; March 30th, 2015 at 04:38 AM.
    Best regards,
    Igor

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

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

    from MSDN: "An application should return nonzero if it erases the background; otherwise, it should return zero."
    so what i'm doing wrong?
    You are returning a nonzero value for WM_ERASEBKGND (ie indicating that the background has been erased) without actually erasing the background! If you need background processing different to that provided by DefWindowProc() then this needs to be done in WM_ERASEBKGND.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  15. #15
    Join Date
    Apr 2009
    Posts
    1,355

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

    Quote Originally Posted by 2kaud View Post
    You are returning a nonzero value for WM_ERASEBKGND (ie indicating that the background has been erased) without actually erasing the background! If you need background processing different to that provided by DefWindowProc() then this needs to be done in WM_ERASEBKGND.
    i'm doing it:
    Code:
    case WM_ERASEBKGND: 
                {
                    if(inst->blnTransparent==true)
                    {
                        SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND,(LONG_PTR)GetStockObject(NULL_BRUSH));
                    }
                    else
                    {
                        SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND,(LONG_PTR)CreateSolidBrush(inst->clrBackColor));
                    }
                    DefWindowProc(hwnd, msg, wParam, lParam);
                }
                break;
    but i'm doing 1 error. why isn't transparent?

Page 1 of 4 1234 LastLast

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