Is there an equivalent to SuspendLayout/ResumeLayout for a MFC Dialog ?
-
The controls still flicker :-( my overall process is:
//Dialog - prevent changes from being redrawn this->SetRedraw(FALSE); //invert parts of static image onthe Dialog, behind the controls pDC = this->GetDC(); targetDC.CreateCompatibleDC(pDC); pOldTargetBmp = targetDC.SelectObject(&m_BmpTarget); targetDC.PatBlt(X,Y,iWidth,iHeight,DSTINVERT); targetDC.SelectObject(pOldTargetBmp); targetDC.DeleteDC(); ReleaseDC(pDC); m_DialogStaticImage.SetBitmap(HBITMAP(m_BmpTarget)); //redraw all controls to put them into foreground m_staticText.RedrawWindow(NULL,NULL,RDW_UPDATENOW); m_editBox.RedrawWindow(NULL,NULL,RDW_FRAME+RDW_INVALIDATE+RDW_UPDATENOW); . . about 15 controls . //Dialog - allow changes to be redrawn this->SetRedraw(TRUE); //no need to erase background since SetBitmap covered everything up this->Invalidate(FALSE); //show updated Dialog this->UpdateWindow();
I was surprised that it would still flicker; I was hoping that all the graphics operations were done in memory, then simply shown when UpdateWindow was called - thus avoiding flicker.abiemann wrote:
I was surprised that it would still flicker; I was hoping that all the graphics operations were done in memory, then simply shown when UpdateWindow was called - thus avoiding flicker.
Nope. Looking more closely at your code, the only way you'll be able to prevent flicker is to do the drawing offscreen yourself, then blt the whole thing to the dialog. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
abiemann wrote:
I was surprised that it would still flicker; I was hoping that all the graphics operations were done in memory, then simply shown when UpdateWindow was called - thus avoiding flicker.
Nope. Looking more closely at your code, the only way you'll be able to prevent flicker is to do the drawing offscreen yourself, then blt the whole thing to the dialog. Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
Indeed, I was hoping that SetRedraw would implement double-buffering easily... but I found a good CP link that I'm studying now: http://www.codeproject.com/gdi/flicker\_free\_intro.asp EDIT: I've compiled the "flicker free" project under VS8 and I see that the "Draw Area" flickers.
-
The controls still flicker :-( my overall process is:
//Dialog - prevent changes from being redrawn this->SetRedraw(FALSE); //invert parts of static image onthe Dialog, behind the controls pDC = this->GetDC(); targetDC.CreateCompatibleDC(pDC); pOldTargetBmp = targetDC.SelectObject(&m_BmpTarget); targetDC.PatBlt(X,Y,iWidth,iHeight,DSTINVERT); targetDC.SelectObject(pOldTargetBmp); targetDC.DeleteDC(); ReleaseDC(pDC); m_DialogStaticImage.SetBitmap(HBITMAP(m_BmpTarget)); //redraw all controls to put them into foreground m_staticText.RedrawWindow(NULL,NULL,RDW_UPDATENOW); m_editBox.RedrawWindow(NULL,NULL,RDW_FRAME+RDW_INVALIDATE+RDW_UPDATENOW); . . about 15 controls . //Dialog - allow changes to be redrawn this->SetRedraw(TRUE); //no need to erase background since SetBitmap covered everything up this->Invalidate(FALSE); //show updated Dialog this->UpdateWindow();
I was surprised that it would still flicker; I was hoping that all the graphics operations were done in memory, then simply shown when UpdateWindow was called - thus avoiding flicker.abiemann wrote:
//no need to erase background since SetBitmap covered everything up this->Invalidate(FALSE);
You have a static control that is used to display a bitmap. Yes? Is it overlapping the other controls such that they are requiring this?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
abiemann wrote:
//no need to erase background since SetBitmap covered everything up this->Invalidate(FALSE);
You have a static control that is used to display a bitmap. Yes? Is it overlapping the other controls such that they are requiring this?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
Yes, I have a static bitmap covering the entire Dialog window. Other controls (Buttons, Edit boxes) are ontop of this bitmap.
So are you rendering this image in the dialog's
OnEraseBkgnd()
method?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
So are you rendering this image in the dialog's
OnEraseBkgnd()
method?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
I love using SuspendLayout and ResumeLayout in .Net to avoid flicker, however, these don't seem to exist for an MFC Dialog. Is there an equivalent to use on my MFC Dialog ?
did you try the WS_CLIP_CHILDREN flag? This alone would reduce a hell of a lot of flicker.
-
did you try the WS_CLIP_CHILDREN flag? This alone would reduce a hell of a lot of flicker.
Good point! For whatever reason, when I see bitmap background code I think skin, transparent controls, etc. For normal controls WS_CLIPCHILDREN will work great! :) Cheers, Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
no I haven't touched the OnEraseBkgnd() or OnPaint methods. The code above is processed whenever the user presses a key or lets go of a key. (I haven't worked much with MFC, so I'm still learning)
abiemann wrote:
no I haven't touched the OnEraseBkgnd()...
Put your bitmap-rendering code in there and note the difference.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
abiemann wrote:
no I haven't touched the OnEraseBkgnd()...
Put your bitmap-rendering code in there and note the difference.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
Hi David, I've made the change and the background bitmap doesn't flicker at all, however, the controls ontop of the bitmap still flicker. This is the change I've made: KeyHandler now triggers OnEraseBkgnd instead of performing PatBlt When the user presses a key, the key's number is stored in a private member variable of the Dialog. To subsequently make it update the background image, the Dialogs' key handler performs :
this->Invalidate(TRUE); this->UpdateWindow();
OnEraseBkgnd now does the PatBlt of the static image behind the controls Next, OnEraseBkgnd(CDC* pDC) is processed. this handler first checks that a key was pressed, if so, it performs the targetDC.PatBlt (I just use the pDC that's passed in) then it returns TRUE. If no key was pressed then I let this handler perform the default CDialog::OnEraseBkgnd(pDC) After this change I noticed that the individual controls no longer need their RedrawWindow() called, however, they still flicker (but the background static image doesn't flicker at all now). I've also removed the SetRedraw() calls -- modified at 19:14 Thursday 6th September, 2007 -
Hi David, I've made the change and the background bitmap doesn't flicker at all, however, the controls ontop of the bitmap still flicker. This is the change I've made: KeyHandler now triggers OnEraseBkgnd instead of performing PatBlt When the user presses a key, the key's number is stored in a private member variable of the Dialog. To subsequently make it update the background image, the Dialogs' key handler performs :
this->Invalidate(TRUE); this->UpdateWindow();
OnEraseBkgnd now does the PatBlt of the static image behind the controls Next, OnEraseBkgnd(CDC* pDC) is processed. this handler first checks that a key was pressed, if so, it performs the targetDC.PatBlt (I just use the pDC that's passed in) then it returns TRUE. If no key was pressed then I let this handler perform the default CDialog::OnEraseBkgnd(pDC) After this change I noticed that the individual controls no longer need their RedrawWindow() called, however, they still flicker (but the background static image doesn't flicker at all now). I've also removed the SetRedraw() calls -- modified at 19:14 Thursday 6th September, 2007Did you try adding the WS_CLIPCHILDREN style to the dialog as suggested by WalderMort? Mark
Mark Salsbery Microsoft MVP - Visual C++ :java:
-
Hi David, I've made the change and the background bitmap doesn't flicker at all, however, the controls ontop of the bitmap still flicker. This is the change I've made: KeyHandler now triggers OnEraseBkgnd instead of performing PatBlt When the user presses a key, the key's number is stored in a private member variable of the Dialog. To subsequently make it update the background image, the Dialogs' key handler performs :
this->Invalidate(TRUE); this->UpdateWindow();
OnEraseBkgnd now does the PatBlt of the static image behind the controls Next, OnEraseBkgnd(CDC* pDC) is processed. this handler first checks that a key was pressed, if so, it performs the targetDC.PatBlt (I just use the pDC that's passed in) then it returns TRUE. If no key was pressed then I let this handler perform the default CDialog::OnEraseBkgnd(pDC) After this change I noticed that the individual controls no longer need their RedrawWindow() called, however, they still flicker (but the background static image doesn't flicker at all now). I've also removed the SetRedraw() calls -- modified at 19:14 Thursday 6th September, 2007In other words, it works but it doesn't work. :confused:
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
did you try the WS_CLIP_CHILDREN flag? This alone would reduce a hell of a lot of flicker.