Thread: WM_PAINT call confusion

  1. #1
    Registered User eth0's Avatar
    Join Date
    Dec 2003
    Posts
    164

    WM_PAINT call confusion

    My understanding is as follows:

    When a window needs painting, the procedure calls WM_PAINT. If there is no handler for this message, the message is passed to DefWindowProc which takes care of the default painting of the window.

    Code:
    LRESULT CALLBACK
    WndProc(HWND hwnd,
            UINT msg,
            WPARAM wParam,
            LPARAM lParam)
    {
        switch(msg)
        {
            ...
    
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    When a handler is present, it intercepts the message and executes the code within the handler. Then, instead of calling DefWindowProc, the window procedure then returns 0

    Code:
    LRESULT CALLBACK
    WndProc(HWND hwnd,
            UINT msg,
            WPARAM wParam,
            LPARAM lParam)
    {
        switch(msg)
        {
            case WM_PAINT:
            {
                HDC hdc;
                PAINTSTRUCT ps;
    
                hdc = BeginPaint(hwnd, &ps);
                ...
                EndPaint(hwnd, &ps);
            }
            break;
    
            default:
                return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
    }
    So my question is, if WM_PAINT is not being handed to DefWindowProc, when and how is the window actually drawn?
    Open source isn't a matter of life or death......
    .......its much more important than that!!


    SuSE Linux - GCC 3.4.2
    XP Pro - Visual Studio 2005 TS, MinGW 3.4.2

  2. #2
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    Um... I would say that when you call BeginPaint, Windows fills out the PAINTSTRUCT with meaty chunks of goodness, such as a DC for you to use and a RECT that describes the area to be redrawn (which Windows also validates or marks "clean" before handing to you). If the area is complex (i.e. not a rectangle) you'll receive more than one WM_PAINT to cover the difference.

    So, you do your drawing after that and finish up with an EndPaint (which frees some resources used). WM_PAINT messages are considered with fairly low priority in Windows however, so in some (specific) cases you may want to pump the message yourself rather than letting USER32's dispatch mechanism deal with it.

  3. #3
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    Quote Originally Posted by eth0
    My understanding is as follows:
    ...So my question is, if WM_PAINT is not being handed to DefWindowProc, when and how is the window actually drawn?
    It appears that you are drawing it with the HDC you are given.

    Quote Originally Posted by SMurf
    ...If the area is complex (i.e. not a rectangle) you'll receive more than one WM_PAINT to cover the difference.
    I believe this is incorrect. I think WM_PAINT messages are combined as they add up in the message queue. This generates complex regions for the paint DC and does not need to generate several rectangle ones.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  4. #4
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    confirmed...
    ...In addition, multiple WM_PAINT messages for the same window are combined into a single WM_PAINT message, consolidating all invalid parts of the client area into a single area. Combining WM_PAINT messages reduces the number of times a window must redraw the contents of its client area.
    http://msdn.microsoft.com/library/de...sagequeues.asp
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  5. #5
    Registered /usr
    Join Date
    Aug 2001
    Location
    Newport, South Wales, UK
    Posts
    1,273
    Yeah, but since the rc member of the PAINTSTRUCT is almost always used to paint with, this mean's that you'll be using the smallest RECT that bounds the complex area. You can get the actual region if you want, but that can only be used with certain functions (FillRgn for example).

  6. #6
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    I was only debating the "multiple WM_PAINT" part. No offense intended
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    135
    Quote Originally Posted by SMurf
    Yeah, but since the rc member of the PAINTSTRUCT is almost always used to paint with, this mean's that you'll be using the smallest RECT that bounds the complex area. You can get the actual region if you want, but that can only be used with certain functions (FillRgn for example).
    Weather he uses the rcPaint member or the actual arbitrary region doesn't really matter because, windows will prevent you from painting outside the invalid region anyway.

    To to OP: The window will only *not* be painted if you Handle the WM_PAINT message and sometimes also the WM_ERASEBKGND message and not do *any* painting at all or, erasing. Otherwise, the window will use the default implementation to paint and validate itself.

    But to put it simply; the paining is done in the WM_PAINT handler if you intercept, or, handle it and do some painting.

  8. #8
    Registered User
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by xeddiex
    Weather he uses the rcPaint member or the actual arbitrary region doesn't really matter because, windows will prevent you from painting outside the invalid region anyway.

    To to OP: The window will only *not* be painted if you Handle the WM_PAINT message and sometimes also the WM_ERASEBKGND message and not do *any* painting at all or, erasing. Otherwise, the window will use the default implementation to paint and validate itself.

    But to put it simply; the paining is done in the WM_PAINT handler if you intercept, or, handle it and do some painting.
    I've subclassed a static and it seems that the window is not painting or erasing as you stated. If windows get moved over it the image of those windows will be moved onto the static. Do you know the solution to this?

    Example: http://programming-designs.com/error.gif

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get RSSI value, send to sensor, sensor receive package, repackage it?
    By techissue2008 in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-04-2009, 10:13 AM
  2. Error C2664 - Trying to call an external Dll
    By jamez05 in forum C++ Programming
    Replies: 3
    Last Post: 08-08-2006, 06:07 AM
  3. Iterative Tree Traversal using a stack
    By BigDaddyDrew in forum C++ Programming
    Replies: 7
    Last Post: 03-10-2003, 05:44 PM
  4. C++ confusion
    By charlie in forum C++ Programming
    Replies: 5
    Last Post: 09-13-2001, 05:46 AM
  5. call by reference and a call by value
    By IceCold in forum C Programming
    Replies: 4
    Last Post: 09-08-2001, 05:06 PM