Simple GDI program
-
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
-
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
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
-
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
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
-
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
Thanks for the halp Mark, that worked perfectly. I've become so dependent on DirectX I've forgotten how to use GDI properly.:) Dustin
-
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
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 :)
-
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 :)
-
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
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
andWM_PAINT
, you'll need to manually redo the drawing if the window becomes uncovered. (This is what causes people to ask "I draw something inWM_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.
-
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
andWM_PAINT
, you'll need to manually redo the drawing if the window becomes uncovered. (This is what causes people to ask "I draw something inWM_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.
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