Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. WM_ERASEBKGND

WM_ERASEBKGND

Scheduled Pinned Locked Moved C / C++ / MFC
jsonperformancehelptutorialquestion
14 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    Hosam Aly Mahmoud
    wrote on last edited by
    #1

    I am making a small Win32 API application. I wanted to have a coloured background. When I tried to handle WM_ERASEBKGND, I got too much flicker. I tried to make a memory dc and use it, but that did not improve the flicker. Is it something I do wrong? Could you please show me how to handle WM_ERASEBKGND without flicker? Note: I noticed that the flicker was gone when I created a brush and made myWndClass.hbrBackground point to it. But the problem is that I may want to draw in WM_ERASEBKGND, not just have a single brush.

    Hosam Aly Mahmoud

    R 1 Reply Last reply
    0
    • H Hosam Aly Mahmoud

      I am making a small Win32 API application. I wanted to have a coloured background. When I tried to handle WM_ERASEBKGND, I got too much flicker. I tried to make a memory dc and use it, but that did not improve the flicker. Is it something I do wrong? Could you please show me how to handle WM_ERASEBKGND without flicker? Note: I noticed that the flicker was gone when I created a brush and made myWndClass.hbrBackground point to it. But the problem is that I may want to draw in WM_ERASEBKGND, not just have a single brush.

      Hosam Aly Mahmoud

      R Offline
      R Offline
      Ryan Binns
      wrote on last edited by
      #2

      Do everything in response to WM_PAINT and use a memory DC. Handle WM_ERASEBKGND and do nothing there. Hope this helps,

      Ryan

      "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

      H 1 Reply Last reply
      0
      • R Ryan Binns

        Do everything in response to WM_PAINT and use a memory DC. Handle WM_ERASEBKGND and do nothing there. Hope this helps,

        Ryan

        "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

        H Offline
        H Offline
        Hosam Aly Mahmoud
        wrote on last edited by
        #3

        Thank you for your reply. I thought that WM_PAINT would only allow me to draw a certain region of the window, not all of it. Also, the docs said that to make a background (for example a picture) you should handle WM_ERASEBKGND. Am I wrong?

        Hosam Aly Mahmoud

        R 1 Reply Last reply
        0
        • H Hosam Aly Mahmoud

          Thank you for your reply. I thought that WM_PAINT would only allow me to draw a certain region of the window, not all of it. Also, the docs said that to make a background (for example a picture) you should handle WM_ERASEBKGND. Am I wrong?

          Hosam Aly Mahmoud

          R Offline
          R Offline
          Ryan Binns
          wrote on last edited by
          #4

          Hosam Aly Mahmoud wrote: I thought that WM_PAINT would only allow me to draw a certain region of the window, not all of it. The device context given as a parameter to a WM_PAINT message is set up to only draw to the regions of the window which have been invalidated. By definition, any region that is not invalidated, does not need painting, so you shouldn't have a problem. Hosam Aly Mahmoud wrote: Also, the docs said that to make a background (for example a picture) you should handle WM_ERASEBKGND. Am I wrong? WM_ERASEBKGND is sent whenever InvalidateRect() or InvalidateRgn() are called with fErase=TRUE. If the fErase flag is FALSE, then WM_ERASEBKGND is not sent. It is quite ok to draw the background in WM_PAINT however. In fact, to get true flicker-free drawing, it is the only way.

          Ryan

          "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

          H 1 Reply Last reply
          0
          • R Ryan Binns

            Hosam Aly Mahmoud wrote: I thought that WM_PAINT would only allow me to draw a certain region of the window, not all of it. The device context given as a parameter to a WM_PAINT message is set up to only draw to the regions of the window which have been invalidated. By definition, any region that is not invalidated, does not need painting, so you shouldn't have a problem. Hosam Aly Mahmoud wrote: Also, the docs said that to make a background (for example a picture) you should handle WM_ERASEBKGND. Am I wrong? WM_ERASEBKGND is sent whenever InvalidateRect() or InvalidateRgn() are called with fErase=TRUE. If the fErase flag is FALSE, then WM_ERASEBKGND is not sent. It is quite ok to draw the background in WM_PAINT however. In fact, to get true flicker-free drawing, it is the only way.

            Ryan

            "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

            H Offline
            H Offline
            Hosam Aly Mahmoud
            wrote on last edited by
            #5

            Many thanks for your reply. I am using Win32 API, so I get the HDC using BeginPaint(). I tried to draw in WM_PAINT, but I get a white background although I have myWndClass.hbrBackground = NULL. Here is my code:

            case WM_PAINT:
            {
            static PAINTSTRUCT ps;
            static dc = BeginPaint(hWnd, &ps);

            static HDC memDC = CreateCompatibleDC(dc);
            static HBITMAP memBitmap = CreateCompatibleBitmap(dc, MainWindowRect.right, MainWindowRect.bottom);
            SelectObject(memDC, memBitmap);
            
            FloodFill ( memDC, 20, 20, RGB(255,0,0) );	// red background
            
            static HBRUSH oldBrush = (HBRUSH) SelectObject(memDC, myBrush);
            Rectangle(memDC, myRect.left, myRect.top, myRect.right, myRect.bottom );
            SelectObject(memDC, oldBrush);
            
            BitBlt(dc, 0, 0, MainWindowRect.right, MainWindowRect.bottom,
            			memDC, 0, 0, SRCCOPY);
            // in WM\_SIZE I wrote: GetClientRect(&MainWindowRect);
            EndPaint(hWnd, &ps);
            return 0;
            

            }

            case WM_ERASEBKGND:
            return 0; // processed already in WM_PAINT.

            Hosam Aly Mahmoud

            R 2 Replies Last reply
            0
            • H Hosam Aly Mahmoud

              Many thanks for your reply. I am using Win32 API, so I get the HDC using BeginPaint(). I tried to draw in WM_PAINT, but I get a white background although I have myWndClass.hbrBackground = NULL. Here is my code:

              case WM_PAINT:
              {
              static PAINTSTRUCT ps;
              static dc = BeginPaint(hWnd, &ps);

              static HDC memDC = CreateCompatibleDC(dc);
              static HBITMAP memBitmap = CreateCompatibleBitmap(dc, MainWindowRect.right, MainWindowRect.bottom);
              SelectObject(memDC, memBitmap);
              
              FloodFill ( memDC, 20, 20, RGB(255,0,0) );	// red background
              
              static HBRUSH oldBrush = (HBRUSH) SelectObject(memDC, myBrush);
              Rectangle(memDC, myRect.left, myRect.top, myRect.right, myRect.bottom );
              SelectObject(memDC, oldBrush);
              
              BitBlt(dc, 0, 0, MainWindowRect.right, MainWindowRect.bottom,
              			memDC, 0, 0, SRCCOPY);
              // in WM\_SIZE I wrote: GetClientRect(&MainWindowRect);
              EndPaint(hWnd, &ps);
              return 0;
              

              }

              case WM_ERASEBKGND:
              return 0; // processed already in WM_PAINT.

              Hosam Aly Mahmoud

              R Offline
              R Offline
              Ryan Binns
              wrote on last edited by
              #6

              Remove the static keyword from all of your variable declarations and try again.

              Ryan

              "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

              H 1 Reply Last reply
              0
              • R Ryan Binns

                Remove the static keyword from all of your variable declarations and try again.

                Ryan

                "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                H Offline
                H Offline
                Hosam Aly Mahmoud
                wrote on last edited by
                #7

                I did it but no difference. :((

                Hosam Aly Mahmoud

                1 Reply Last reply
                0
                • H Hosam Aly Mahmoud

                  Many thanks for your reply. I am using Win32 API, so I get the HDC using BeginPaint(). I tried to draw in WM_PAINT, but I get a white background although I have myWndClass.hbrBackground = NULL. Here is my code:

                  case WM_PAINT:
                  {
                  static PAINTSTRUCT ps;
                  static dc = BeginPaint(hWnd, &ps);

                  static HDC memDC = CreateCompatibleDC(dc);
                  static HBITMAP memBitmap = CreateCompatibleBitmap(dc, MainWindowRect.right, MainWindowRect.bottom);
                  SelectObject(memDC, memBitmap);
                  
                  FloodFill ( memDC, 20, 20, RGB(255,0,0) );	// red background
                  
                  static HBRUSH oldBrush = (HBRUSH) SelectObject(memDC, myBrush);
                  Rectangle(memDC, myRect.left, myRect.top, myRect.right, myRect.bottom );
                  SelectObject(memDC, oldBrush);
                  
                  BitBlt(dc, 0, 0, MainWindowRect.right, MainWindowRect.bottom,
                  			memDC, 0, 0, SRCCOPY);
                  // in WM\_SIZE I wrote: GetClientRect(&MainWindowRect);
                  EndPaint(hWnd, &ps);
                  return 0;
                  

                  }

                  case WM_ERASEBKGND:
                  return 0; // processed already in WM_PAINT.

                  Hosam Aly Mahmoud

                  R Offline
                  R Offline
                  Ryan Binns
                  wrote on last edited by
                  #8

                  Hosam Aly Mahmoud wrote: FloodFill ( memDC, 20, 20, RGB(255,0,0) ); // red background :rolleyes: I should have seen this before... The colour you pass to FloodFill() is not the colour of the fill. It's the colour of the border. FloodFill() fills the area with the currently selected brush. To fill a rectangle with a given colour, either create a solid brush (CreateSolidBrush()) and use Rectangle(), or use the ExtTextOut() function to draw opaque text without actually drawing text:

                  SetBkColor(memDC, RGB(255,0,0)); // Red background
                  RECT rect;
                  // TODO: Setup the rectangle here
                  ExtTextOut(memDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);

                  Hope this helps,

                  Ryan

                  "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                  H 1 Reply Last reply
                  0
                  • R Ryan Binns

                    Hosam Aly Mahmoud wrote: FloodFill ( memDC, 20, 20, RGB(255,0,0) ); // red background :rolleyes: I should have seen this before... The colour you pass to FloodFill() is not the colour of the fill. It's the colour of the border. FloodFill() fills the area with the currently selected brush. To fill a rectangle with a given colour, either create a solid brush (CreateSolidBrush()) and use Rectangle(), or use the ExtTextOut() function to draw opaque text without actually drawing text:

                    SetBkColor(memDC, RGB(255,0,0)); // Red background
                    RECT rect;
                    // TODO: Setup the rectangle here
                    ExtTextOut(memDC, 0, 0, ETO_OPAQUE, rect, NULL, 0, NULL);

                    Hope this helps,

                    Ryan

                    "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                    H Offline
                    H Offline
                    Hosam Aly Mahmoud
                    wrote on last edited by
                    #9

                    Thank you very much! That really helped! :-D Now I am wondering, if I want to make the background an image, should I do it in response to WM_PAINT too? Why is WM_ERASEBKGND available then? Why did they put it if I should draw in WM_PAINT? :(( Thank you very much for your patience! :rose:

                    Hosam Aly Mahmoud

                    R 1 Reply Last reply
                    0
                    • H Hosam Aly Mahmoud

                      Thank you very much! That really helped! :-D Now I am wondering, if I want to make the background an image, should I do it in response to WM_PAINT too? Why is WM_ERASEBKGND available then? Why did they put it if I should draw in WM_PAINT? :(( Thank you very much for your patience! :rose:

                      Hosam Aly Mahmoud

                      R Offline
                      R Offline
                      Ryan Binns
                      wrote on last edited by
                      #10

                      Hosam Aly Mahmoud wrote: Now I am wondering, if I want to make the background an image, should I do it in response to WM_PAINT too? Yes. That will work fine :) Hosam Aly Mahmoud wrote: Why is WM_ERASEBKGND available then? Why did they put it if I should draw in WM_PAINT? There is nothing wrong with using WM_ERASEBKGND for drawing the background. It's simply not possible to do flicker-free drawing using it. I'm not certain why it's there - it's probably been there since Windows 1.0

                      Ryan

                      "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                      J H 2 Replies Last reply
                      0
                      • R Ryan Binns

                        Hosam Aly Mahmoud wrote: Now I am wondering, if I want to make the background an image, should I do it in response to WM_PAINT too? Yes. That will work fine :) Hosam Aly Mahmoud wrote: Why is WM_ERASEBKGND available then? Why did they put it if I should draw in WM_PAINT? There is nothing wrong with using WM_ERASEBKGND for drawing the background. It's simply not possible to do flicker-free drawing using it. I'm not certain why it's there - it's probably been there since Windows 1.0

                        Ryan

                        "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                        J Offline
                        J Offline
                        J Dunlap
                        wrote on last edited by
                        #11

                        Ryan Binns wrote: I'm not certain why it's there Well, if you "eat" the WM_ERASEBKGND message, return 1, and forward it to the parent window, you can get transparent effects, because you're telling the parent to erase an area, rather than erasing it yourself with the default brush, which is the normal behavior. This is a neat trick that is played by the Common Controls Toolbar so that it can have a transparent background. It also calls WM_ERASEBACKGND on the parent window whenever it draws anything outside of a WM_PAINT message, so that the background is always erased to the parent's background.

                        "Blessed are the peacemakers, for they shall be called sons of God." - Jesus
                        "You must be the change you wish to see in the world." - Mahatma Gandhi

                        R H 2 Replies Last reply
                        0
                        • J J Dunlap

                          Ryan Binns wrote: I'm not certain why it's there Well, if you "eat" the WM_ERASEBKGND message, return 1, and forward it to the parent window, you can get transparent effects, because you're telling the parent to erase an area, rather than erasing it yourself with the default brush, which is the normal behavior. This is a neat trick that is played by the Common Controls Toolbar so that it can have a transparent background. It also calls WM_ERASEBACKGND on the parent window whenever it draws anything outside of a WM_PAINT message, so that the background is always erased to the parent's background.

                          "Blessed are the peacemakers, for they shall be called sons of God." - Jesus
                          "You must be the change you wish to see in the world." - Mahatma Gandhi

                          R Offline
                          R Offline
                          Ryan Binns
                          wrote on last edited by
                          #12

                          :cool: I'll have to remember that :)

                          Ryan

                          "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                          1 Reply Last reply
                          0
                          • R Ryan Binns

                            Hosam Aly Mahmoud wrote: Now I am wondering, if I want to make the background an image, should I do it in response to WM_PAINT too? Yes. That will work fine :) Hosam Aly Mahmoud wrote: Why is WM_ERASEBKGND available then? Why did they put it if I should draw in WM_PAINT? There is nothing wrong with using WM_ERASEBKGND for drawing the background. It's simply not possible to do flicker-free drawing using it. I'm not certain why it's there - it's probably been there since Windows 1.0

                            Ryan

                            "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

                            H Offline
                            H Offline
                            Hosam Aly Mahmoud
                            wrote on last edited by
                            #13

                            Thank you for your replies, your help and all your patience! :rose:

                            Hosam Aly Mahmoud

                            1 Reply Last reply
                            0
                            • J J Dunlap

                              Ryan Binns wrote: I'm not certain why it's there Well, if you "eat" the WM_ERASEBKGND message, return 1, and forward it to the parent window, you can get transparent effects, because you're telling the parent to erase an area, rather than erasing it yourself with the default brush, which is the normal behavior. This is a neat trick that is played by the Common Controls Toolbar so that it can have a transparent background. It also calls WM_ERASEBACKGND on the parent window whenever it draws anything outside of a WM_PAINT message, so that the background is always erased to the parent's background.

                              "Blessed are the peacemakers, for they shall be called sons of God." - Jesus
                              "You must be the change you wish to see in the world." - Mahatma Gandhi

                              H Offline
                              H Offline
                              Hosam Aly Mahmoud
                              wrote on last edited by
                              #14

                              Thank you for the information!

                              Hosam Aly Mahmoud

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups