Flickering...?
-
// // This is, what I have actually written into my dialog's OnPaint()-function: // CClientDC dc(this); CPen WhitePen; CPen BlackPen; CBrush BlackBrush; WhitePen.CreatePen(PS_SOLID, 1, RGB(255,255,255)); BlackPen.CreatePen(PS_SOLID, 1, RGB(0,0,0)); BlackBrush.CreateSolidBrush(RGB(0,0,0)); CPen* pOriginalPen = dc.SelectObject(&BlackPen); dc.Rectangle(24, 10, 80, 30); dc.SelectObject(&BlackBrush); dc.Rectangle(24, 10, 80, 30); // // Instead of the last two lines I've also tried it with: // dc.FillSolidRectangle(24, 10, 80, 30 RGB(0,0,0)); // // How can I get rid of this flickering of the black rectangle in my dialog??? :confused: // // // Thanks in adv. // // // Manfred // --- Programming is knowing...
-
// // This is, what I have actually written into my dialog's OnPaint()-function: // CClientDC dc(this); CPen WhitePen; CPen BlackPen; CBrush BlackBrush; WhitePen.CreatePen(PS_SOLID, 1, RGB(255,255,255)); BlackPen.CreatePen(PS_SOLID, 1, RGB(0,0,0)); BlackBrush.CreateSolidBrush(RGB(0,0,0)); CPen* pOriginalPen = dc.SelectObject(&BlackPen); dc.Rectangle(24, 10, 80, 30); dc.SelectObject(&BlackBrush); dc.Rectangle(24, 10, 80, 30); // // Instead of the last two lines I've also tried it with: // dc.FillSolidRectangle(24, 10, 80, 30 RGB(0,0,0)); // // How can I get rid of this flickering of the black rectangle in my dialog??? :confused: // // // Thanks in adv. // // // Manfred // --- Programming is knowing...
override the dialog's OnEraseBackground (use classWizard). just return TRUE. this will prevent the dialog's background color from being drawn -c ------------------------------ Smaller Animals Software, Inc. http://www.smalleranimals.com
-
// // This is, what I have actually written into my dialog's OnPaint()-function: // CClientDC dc(this); CPen WhitePen; CPen BlackPen; CBrush BlackBrush; WhitePen.CreatePen(PS_SOLID, 1, RGB(255,255,255)); BlackPen.CreatePen(PS_SOLID, 1, RGB(0,0,0)); BlackBrush.CreateSolidBrush(RGB(0,0,0)); CPen* pOriginalPen = dc.SelectObject(&BlackPen); dc.Rectangle(24, 10, 80, 30); dc.SelectObject(&BlackBrush); dc.Rectangle(24, 10, 80, 30); // // Instead of the last two lines I've also tried it with: // dc.FillSolidRectangle(24, 10, 80, 30 RGB(0,0,0)); // // How can I get rid of this flickering of the black rectangle in my dialog??? :confused: // // // Thanks in adv. // // // Manfred // --- Programming is knowing...
A few problems with your code: First, you should be using CPaintDC in an OnPaint message. This is done automatically by the framework. Second, You are creating pens and brushes, then selecting them into the DC, but not deselecting them which means that when the CPen is destroyed, it will not delete the pen you created (because it's selected in the DC) and will cause a resource leak.
-
// // This is, what I have actually written into my dialog's OnPaint()-function: // CClientDC dc(this); CPen WhitePen; CPen BlackPen; CBrush BlackBrush; WhitePen.CreatePen(PS_SOLID, 1, RGB(255,255,255)); BlackPen.CreatePen(PS_SOLID, 1, RGB(0,0,0)); BlackBrush.CreateSolidBrush(RGB(0,0,0)); CPen* pOriginalPen = dc.SelectObject(&BlackPen); dc.Rectangle(24, 10, 80, 30); dc.SelectObject(&BlackBrush); dc.Rectangle(24, 10, 80, 30); // // Instead of the last two lines I've also tried it with: // dc.FillSolidRectangle(24, 10, 80, 30 RGB(0,0,0)); // // How can I get rid of this flickering of the black rectangle in my dialog??? :confused: // // // Thanks in adv. // // // Manfred // --- Programming is knowing...
The advice you were given re: leaks is spot on, but to stop flickering, you need to double buffer. This means create a new bitmap and DC, draw into it and then copy the whole lot onto your dialog in one Blt at the end. Also, don't call CPaintDC until you're about to do the Blt and you won't need to undermine OnEraseBackground, which can have some nasty side effects. What will happen is this: CDC myDC; // Create DC, select bitmap and draw what you want on your dialog CPaintDC dc(this); // Background has been erased if necessary // Now BitBlt from your other DC, so that the effect is immediate and you get no flicker Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
-
A few problems with your code: First, you should be using CPaintDC in an OnPaint message. This is done automatically by the framework. Second, You are creating pens and brushes, then selecting them into the DC, but not deselecting them which means that when the CPen is destroyed, it will not delete the pen you created (because it's selected in the DC) and will cause a resource leak.
To your first: Why should I use CPaintDC instead of CClientCD ? I'm having a dialog-based application and only want to paint a Piano-keyboard onto the screen. This I will do once when entering the Dialog. At runtime I will change the colors of single keys so no need for redrawing the whole keyboard - only single keys... To your second: I guess with 'deselecting' you mean 'deleting' my pens and brushes. Because deselecting happens everytime I select a new Object with the SelectObject() function. So do I get it right now ??? 1 - Every DC has at least one original PEN, BRUSH, FONT, BITMAP and RGN. 2 - When creating a new e.g. PEN/BRUSH I have to store the original PEN/BRUSH with CPen* pOriginalPen = dc.SelectObject(&NewPen); CBrush* pOriginalBrush = dc.SelectObject(&NewBrush); 3 - and give it back to the DC at the end of the function. dc.SelectObject(pOriginalPen); dc.SelectObject(pOriginalBrush); 4 - Every pen, region, font, bitmap or brush created with e.g. BlackPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); WhitePen.CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); BlackBrush.CreateSolidBrush(RGB(0, 0, 0); WhiteBrush.CreateSolidBrush(RGB(255, 255, 255); 5 - must explicitely be deleted with (respectively AFTER having given my OriginalObjects back to the DC) BlackPen.DeleteObject(); WhitePen.DeleteObject(); BlackBrush.DeleteObject(); WhiteBrush.DeleteObject(); 6 - This means the objects are not deleted automatically at the end of the function. I wonder why this DC related things are relatively difficult in comparison with other parts of the MFC. I went through all the DC-related SDK and MSDN stuff and through several books but this is realy not explained rather clearly in any place. Hope that someone can get me out of this only-one part I do not realy get in my brain. Thanks Manfred --- Programming is knowing... (should be ;-))
-
The advice you were given re: leaks is spot on, but to stop flickering, you need to double buffer. This means create a new bitmap and DC, draw into it and then copy the whole lot onto your dialog in one Blt at the end. Also, don't call CPaintDC until you're about to do the Blt and you won't need to undermine OnEraseBackground, which can have some nasty side effects. What will happen is this: CDC myDC; // Create DC, select bitmap and draw what you want on your dialog CPaintDC dc(this); // Background has been erased if necessary // Now BitBlt from your other DC, so that the effect is immediate and you get no flicker Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
OKI For now I selected the CRgn as my object of desire because 1 - I want to paint a Piano-Keyboard onto the screen in my Dialog 2 - When comparing OnLButtonDown(nFlags, point) with PtInRegion(point) I can easily find and repaint single keys. 3 - Regions don't flicker - not in BLUE, not in BLACK not in any color Is there any disadvantage of using Regions ? Thanks for your help Manfred --- Programming is knowing...
-
To your first: Why should I use CPaintDC instead of CClientCD ? I'm having a dialog-based application and only want to paint a Piano-keyboard onto the screen. This I will do once when entering the Dialog. At runtime I will change the colors of single keys so no need for redrawing the whole keyboard - only single keys... To your second: I guess with 'deselecting' you mean 'deleting' my pens and brushes. Because deselecting happens everytime I select a new Object with the SelectObject() function. So do I get it right now ??? 1 - Every DC has at least one original PEN, BRUSH, FONT, BITMAP and RGN. 2 - When creating a new e.g. PEN/BRUSH I have to store the original PEN/BRUSH with CPen* pOriginalPen = dc.SelectObject(&NewPen); CBrush* pOriginalBrush = dc.SelectObject(&NewBrush); 3 - and give it back to the DC at the end of the function. dc.SelectObject(pOriginalPen); dc.SelectObject(pOriginalBrush); 4 - Every pen, region, font, bitmap or brush created with e.g. BlackPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); WhitePen.CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); BlackBrush.CreateSolidBrush(RGB(0, 0, 0); WhiteBrush.CreateSolidBrush(RGB(255, 255, 255); 5 - must explicitely be deleted with (respectively AFTER having given my OriginalObjects back to the DC) BlackPen.DeleteObject(); WhitePen.DeleteObject(); BlackBrush.DeleteObject(); WhiteBrush.DeleteObject(); 6 - This means the objects are not deleted automatically at the end of the function. I wonder why this DC related things are relatively difficult in comparison with other parts of the MFC. I went through all the DC-related SDK and MSDN stuff and through several books but this is realy not explained rather clearly in any place. Hope that someone can get me out of this only-one part I do not realy get in my brain. Thanks Manfred --- Programming is knowing... (should be ;-))
1/ You should use CPaintDC because CCLientDC is for getting a DC outside CPaintDC. I know you should never call CPaintDC outside OnPaint, but I admit you'll have to look elsewhere for a definitive answer as to why the reverse is true. 2/ Correct. Also true for bitmaps, but if you only select one bitmap into a DC, you'll never notice. 3/ Also correct. 4&5/ No. They are classes and have destructors. The CDC destructor cannot destory a pen it does not have, but if the DC is deleted in it's originla state, the destructors will do the rest. 6/ The GDI stuff is a thin wrapper on Win32 functions, and so it has not changed much. Although try writing this stuff in Win32 where you DO have to delete everything and it gets a bit harder. Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
-
OKI For now I selected the CRgn as my object of desire because 1 - I want to paint a Piano-Keyboard onto the screen in my Dialog 2 - When comparing OnLButtonDown(nFlags, point) with PtInRegion(point) I can easily find and repaint single keys. 3 - Regions don't flicker - not in BLUE, not in BLACK not in any color Is there any disadvantage of using Regions ? Thanks for your help Manfred --- Programming is knowing...
I've never used regions, but in reading about them, I'm not sure that this is what they are for. However, as I say, I am hardly qualified to comment as I have not used them. IF they work, then great, unless someone else can shed more light on any disadvantages, but certainly I'd suggest the double buffering method is the way one usually eliminates flicker, and a method you will end up with as the only viable alternative at some stage if your drawing to the screen becomes progressively more complex. I am assuming you're not building a region off screen and then drawing it in one go - if you are, then you've done what I suggested in any case. Good luck with it. Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
-
I've never used regions, but in reading about them, I'm not sure that this is what they are for. However, as I say, I am hardly qualified to comment as I have not used them. IF they work, then great, unless someone else can shed more light on any disadvantages, but certainly I'd suggest the double buffering method is the way one usually eliminates flicker, and a method you will end up with as the only viable alternative at some stage if your drawing to the screen becomes progressively more complex. I am assuming you're not building a region off screen and then drawing it in one go - if you are, then you've done what I suggested in any case. Good luck with it. Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
Quick answer... I've defined every key of my piano-keyboard as a region. That means 88 keys(regions). 52 white keys and 36 black keys. - CRgn-Array as a Member of my Dialog CRgn KeyRegion[88]; - In the constructor of my dialog I create them all KeyRegion[KeyNumber].CreateRectRgn(); - so I guess the array gets automatically deleted when destroying the dialog - should not be leaking... - In my function OnPaintKeyboard() I paint all my 88 keys CClientDC dc(this); CBrush BlackBrush; BlackBrush.CreateSolidBrush(RGB(0,0,0)); CBrush WhiteBrush; WhiteBrush.CreateSolidBrush(RGB(255,255,255)); - With... dc.PaintRgn(&KeyRegion[KeyNumber]); - I can paint my region in the color of the previous selected Brush-Object e.g. dc.SelectObject(&BlackBrush); That looks good to me... - And to you ??? I have a second function OnPaintKey() that paints a single key only - not the whole keyboard. 1 - One Question is wherefrom should I call my OnPaintKeyboard() function so that the whole keyboard gets painted when the dialog gets visible on screen? 2 - Second Question is wherefrom should I call my OnPaintKeyboard() function so that the whole keyboard gets correctly redrawn when necessary?(Overlaping windows or Moving and removing out of the visible screen...) 3 - Third Question: Where can I use my OnPaintKey() function (for a single key!!!) so that not every key has to be redrawn when only the color of one key changes ? Manfred --- Programming is knowing...
-
Quick answer... I've defined every key of my piano-keyboard as a region. That means 88 keys(regions). 52 white keys and 36 black keys. - CRgn-Array as a Member of my Dialog CRgn KeyRegion[88]; - In the constructor of my dialog I create them all KeyRegion[KeyNumber].CreateRectRgn(); - so I guess the array gets automatically deleted when destroying the dialog - should not be leaking... - In my function OnPaintKeyboard() I paint all my 88 keys CClientDC dc(this); CBrush BlackBrush; BlackBrush.CreateSolidBrush(RGB(0,0,0)); CBrush WhiteBrush; WhiteBrush.CreateSolidBrush(RGB(255,255,255)); - With... dc.PaintRgn(&KeyRegion[KeyNumber]); - I can paint my region in the color of the previous selected Brush-Object e.g. dc.SelectObject(&BlackBrush); That looks good to me... - And to you ??? I have a second function OnPaintKey() that paints a single key only - not the whole keyboard. 1 - One Question is wherefrom should I call my OnPaintKeyboard() function so that the whole keyboard gets painted when the dialog gets visible on screen? 2 - Second Question is wherefrom should I call my OnPaintKeyboard() function so that the whole keyboard gets correctly redrawn when necessary?(Overlaping windows or Moving and removing out of the visible screen...) 3 - Third Question: Where can I use my OnPaintKey() function (for a single key!!!) so that not every key has to be redrawn when only the color of one key changes ? Manfred --- Programming is knowing...
IN terms of initial drawing, you can use ONInitDialog, but the whole system revolves around OnPaint, so that's really where you should do all your drawing. Invalidate() will cause OnPaint to be called, and it is called when the window is shown. INvalidateRect() allows you to get only a portion of the screen redrawn - it also calls OnPaint. If the bool passed to either is true then OnEraseBackground is called first. So you should call from OnPaint and force single key redraw by invalidating a region instead of the dialog. Christian The content of this post is not necessarily the opinion of my yadda yadda yadda. To understand recursion, we must first understand recursion.
-
To your first: Why should I use CPaintDC instead of CClientCD ? I'm having a dialog-based application and only want to paint a Piano-keyboard onto the screen. This I will do once when entering the Dialog. At runtime I will change the colors of single keys so no need for redrawing the whole keyboard - only single keys... To your second: I guess with 'deselecting' you mean 'deleting' my pens and brushes. Because deselecting happens everytime I select a new Object with the SelectObject() function. So do I get it right now ??? 1 - Every DC has at least one original PEN, BRUSH, FONT, BITMAP and RGN. 2 - When creating a new e.g. PEN/BRUSH I have to store the original PEN/BRUSH with CPen* pOriginalPen = dc.SelectObject(&NewPen); CBrush* pOriginalBrush = dc.SelectObject(&NewBrush); 3 - and give it back to the DC at the end of the function. dc.SelectObject(pOriginalPen); dc.SelectObject(pOriginalBrush); 4 - Every pen, region, font, bitmap or brush created with e.g. BlackPen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); WhitePen.CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); BlackBrush.CreateSolidBrush(RGB(0, 0, 0); WhiteBrush.CreateSolidBrush(RGB(255, 255, 255); 5 - must explicitely be deleted with (respectively AFTER having given my OriginalObjects back to the DC) BlackPen.DeleteObject(); WhitePen.DeleteObject(); BlackBrush.DeleteObject(); WhiteBrush.DeleteObject(); 6 - This means the objects are not deleted automatically at the end of the function. I wonder why this DC related things are relatively difficult in comparison with other parts of the MFC. I went through all the DC-related SDK and MSDN stuff and through several books but this is realy not explained rather clearly in any place. Hope that someone can get me out of this only-one part I do not realy get in my brain. Thanks Manfred --- Programming is knowing... (should be ;-))
You must use CPaintDC in OnPaint because CPaintDC calls BeginPaint() and EndPaint() to validate the window regions when a WM_PAINT message is sent. Look up CPaintDC and read the documentation. When you select a pen or brush into the DC but do not unselect it (by selecting the original resource), then when the CPen or CBrush goes out of scope, the destructor attempts to delete the brush or pen, but cannot because it's selected in the DC. That means the delete fails and the resource is never deleted. You don't have to explicitly delete the brushes or pens, since this is done automatically by the destructor of the CPen or CBrush object, so long as the brush or pen is not currently selected in a DC.