views:

328

answers:

2

I have a C++ MFC app with a dialog where I want to change the type of the control dynamically based on the selection in a combo box. The dialog resource starts off with a plain old edit control which I then call SubclassDlgItem on to change to a custom control type.

So far so good. Now, when the user changes the selection in a different Combobox on the screen, I want to change this control to a different custom type. So, I destroy the existing control by calling delete on the pointer to the custom class for that control. I then call ::CreateEx to re-create my edit control and call SubclassDlgItem again to create the new custom control.

My problem is that this flickers quite a bit, and I think I'm getting the edit control created with ::CreateEx on top of my custom control. Any ideas on how to get rid of the flicker, especially if the user is quickly changing the contents of the controlling combo box?

+2  A: 

You can create a set of all possible controls in the same area of the parent window and show only the relevant one and hide all the others. When the user causes the control change you hide the active control and show the new relevant. This should look smoother.

sharptooth
+1  A: 

A colleague of mine suggested calling CWnd::LockWindowUpdate() before I do the switch. So, it boils down to something like this:

CRect r;
DWORD dwStyle = WS_CHILD|WS_TABSTOP|WS_VISIBLE;
m_pParent->GetDlgItem(m_nID)->GetWindowRect(&r);
m_pParent->ScreenToClient(r);
m_pParent->LockWindowUpdate();
m_pParent->InvalidateRect(r);
delete m_pCust;   // Delete the old custom control
m_pCust = NULL;
::CreateWindowEx(0, "EDIT", "", dwStyle, r.left, r.top, r.Width(), r.Height(), m_pParent->m_hWnd, (HMENU)m_nID, AfxGetInstanceHandle(), NULL);
m_pCust = new CustomCtrl();
pCust->SubclassDlgItem(m_nID, m_pParent);
m_pParent->UnlockWindowUpdate()

There is a little more involed because of what my custom control does. I ended up calling m_pParent->InvalidateRect(r) to get my control to draw correctly at the end.

Also, it turns out that the overlap of the ::CreateEx edit control was because I was calling UnsubclassDlgItem before deleting the old custom control

Tyler