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. Simple GDI program

Simple GDI program

Scheduled Pinned Locked Moved C / C++ / MFC
graphicsadobequestionannouncement
8 Posts 4 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.
  • D Offline
    D Offline
    Dustin Henry
    wrote on last edited by
    #1

    I am trying to write a simple GDI program that displays a countdown timer(MM:SS:hh). I am just using the WM_PAINT message to display the updated time and calling InvalidateRect() in my main loop. This however causes the screen to flash as I am clearing the screen before I redraw the text.

    FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
    DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);
    

    Any suggestions on how I can stop the text from flashing while still being able to update at hundreths of a second? Thanks, Dustin

    A M 2 Replies Last reply
    0
    • D Dustin Henry

      I am trying to write a simple GDI program that displays a countdown timer(MM:SS:hh). I am just using the WM_PAINT message to display the updated time and calling InvalidateRect() in my main loop. This however causes the screen to flash as I am clearing the screen before I redraw the text.

      FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
      DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);
      

      Any suggestions on how I can stop the text from flashing while still being able to update at hundreths of a second? Thanks, Dustin

      A Offline
      A Offline
      Arman S
      wrote on last edited by
      #2

      InvalidateRect with the last [bErase] parameter FALSE. This will prevent from flickering. If you will have a problem with the messed drawings (caused by previous drawings) you could use non-transparent mode or somth else like drawing a new background before the actual text is drawn [which I could see is done by your FillRect call].

      -- ===== Arman

      D 1 Reply Last reply
      0
      • D Dustin Henry

        I am trying to write a simple GDI program that displays a countdown timer(MM:SS:hh). I am just using the WM_PAINT message to display the updated time and calling InvalidateRect() in my main loop. This however causes the screen to flash as I am clearing the screen before I redraw the text.

        FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
        DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);
        

        Any suggestions on how I can stop the text from flashing while still being able to update at hundreths of a second? Thanks, Dustin

        M Offline
        M Offline
        Mark Salsbery
        wrote on last edited by
        #3

        Instead of drawing the background and drawing the text in two steps, try doing it in one:

        //FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
        ::SetTextColor(hdc, RGB(0xFF,0xFF,0xFF));
        ::SetBkColor(hdc, RGB(0x00,0x00,0x00));
        ::DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);

        You'll also want to follow Arman's advice so the background doesn't get repainted every update. Also, WM_PAINT isn't the only place you can draw on the window from. You can draw the text from anywhere you want. WM_PAINT messages are low priority so if you need better performance do the DrawText from elsewhere. If it's from a different thread, you need to sync acess to the HDC as always. *edit* (Thanks Michael Dunn) You'll still need to redraw the window contents in response to WM_PAINT and/or WM_ERASEBKGND so the window is refreshed when it needs updating (e.g when another window is dragged across it and/or off it). *end edit* Mark -- modified at 14:21 Monday 14th May, 2007

        "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

        D M 2 Replies Last reply
        0
        • M Mark Salsbery

          Instead of drawing the background and drawing the text in two steps, try doing it in one:

          //FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
          ::SetTextColor(hdc, RGB(0xFF,0xFF,0xFF));
          ::SetBkColor(hdc, RGB(0x00,0x00,0x00));
          ::DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);

          You'll also want to follow Arman's advice so the background doesn't get repainted every update. Also, WM_PAINT isn't the only place you can draw on the window from. You can draw the text from anywhere you want. WM_PAINT messages are low priority so if you need better performance do the DrawText from elsewhere. If it's from a different thread, you need to sync acess to the HDC as always. *edit* (Thanks Michael Dunn) You'll still need to redraw the window contents in response to WM_PAINT and/or WM_ERASEBKGND so the window is refreshed when it needs updating (e.g when another window is dragged across it and/or off it). *end edit* Mark -- modified at 14:21 Monday 14th May, 2007

          "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

          D Offline
          D Offline
          Dustin Henry
          wrote on last edited by
          #4

          Thanks for the halp Mark, that worked perfectly. I've become so dependent on DirectX I've forgotten how to use GDI properly.:) Dustin

          1 Reply Last reply
          0
          • A Arman S

            InvalidateRect with the last [bErase] parameter FALSE. This will prevent from flickering. If you will have a problem with the messed drawings (caused by previous drawings) you could use non-transparent mode or somth else like drawing a new background before the actual text is drawn [which I could see is done by your FillRect call].

            -- ===== Arman

            D Offline
            D Offline
            Dustin Henry
            wrote on last edited by
            #5

            I had actually been using InvalidatRect with bErase set to false. The problem was that I was using transparent mode as you stated, and not seting the background of the text like Mark suggested. Thanks for the help, Dustin :)

            A 1 Reply Last reply
            0
            • D Dustin Henry

              I had actually been using InvalidatRect with bErase set to false. The problem was that I was using transparent mode as you stated, and not seting the background of the text like Mark suggested. Thanks for the help, Dustin :)

              A Offline
              A Offline
              Arman S
              wrote on last edited by
              #6

              Now you are doing right. The problem was that I was using transparent mode as you stated Well, I said use 'non-transparent' :)

              -- ===== Arman

              1 Reply Last reply
              0
              • M Mark Salsbery

                Instead of drawing the background and drawing the text in two steps, try doing it in one:

                //FillRect(hdc, &rPos, (HBRUSH)GetStockObject(BLACK_BRUSH));
                ::SetTextColor(hdc, RGB(0xFF,0xFF,0xFF));
                ::SetBkColor(hdc, RGB(0x00,0x00,0x00));
                ::DrawText(hdc, stTime, stTime.GetLength(), &rPos, DT_CENTER | DT_WORDBREAK);

                You'll also want to follow Arman's advice so the background doesn't get repainted every update. Also, WM_PAINT isn't the only place you can draw on the window from. You can draw the text from anywhere you want. WM_PAINT messages are low priority so if you need better performance do the DrawText from elsewhere. If it's from a different thread, you need to sync acess to the HDC as always. *edit* (Thanks Michael Dunn) You'll still need to redraw the window contents in response to WM_PAINT and/or WM_ERASEBKGND so the window is refreshed when it needs updating (e.g when another window is dragged across it and/or off it). *end edit* Mark -- modified at 14:21 Monday 14th May, 2007

                "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                M Offline
                M Offline
                Michael Dunn
                wrote on last edited by
                #7

                Mark Salsbery wrote:

                Also, WM_PAINT isn't the only place you can draw on the window from. You can draw the text from anywhere you want.

                This is true, but if you do any drawing outside of WM_ERASEBKGND and WM_PAINT, you'll need to manually redo the drawing if the window becomes uncovered. (This is what causes people to ask "I draw something in WM_INITDIALOG but it goes away if I move another window over mine.") If you do all drawing in response to those two messages, you won't need to do that bookkeeping.

                --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ Dunder-Mifflin, this is Pam.

                M 1 Reply Last reply
                0
                • M Michael Dunn

                  Mark Salsbery wrote:

                  Also, WM_PAINT isn't the only place you can draw on the window from. You can draw the text from anywhere you want.

                  This is true, but if you do any drawing outside of WM_ERASEBKGND and WM_PAINT, you'll need to manually redo the drawing if the window becomes uncovered. (This is what causes people to ask "I draw something in WM_INITDIALOG but it goes away if I move another window over mine.") If you do all drawing in response to those two messages, you won't need to do that bookkeeping.

                  --Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ Dunder-Mifflin, this is Pam.

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #8

                  Yes. I should have included that in my response. Thanks Mike! Mark

                  "Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder

                  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