how to dynamically delete sub-control created in run-time
-
first of all, i shall thanks all of you guys. In my project, i created some STATIC & EDIT controls in a CDialog and set these control's parent to a group box(also a STATIC control). it works well for create, but it can't be delete dynamically. For example, i create 5 EDIT control then delete it(there are no sub-controls in group box this time), and i create 2 EDIT control again, oops! there are 5 EDIT control showing in the group box. So, i guess this caused by the group box haven't refreshed in time. and then i sendmessage to group box to force it to refresh. unfortunately it doesn't works. here is my code:
void CPLCDlg::DynamicCreateEdit(UINT nNums)
{
const int YSpace = 15;
const int EHeight = 20;
const UINT EDITID = 72000;
if (nNums <= 0)
return;
CButton* pGroup = (CButton*)GetDlgItem(IDC_STATIC_GROUP);
if (NULL != pGroup)
{
if (NULL != m_pDynEdit && m_siNumsOfDynEdit > 0)
{
for (short i = 0; i < m_siNumsOfDynEdit; i++)
{
if (NULL != m_pDynEdit[i].GetSafeHwnd())
{
m_pDynEdit[i].ShowWindow(SW_HIDE);
m_pDynEdit[i].DestroyWindow();
}
delete m_pDynEdit[i];
}
delete[] m_pDynEdit;
m_pDynEdit = NULL;
::SendMessage(pGroup->GetSafeHwnd(), WM_ERASEBKGND, 0, 0);
}
pGroup->Invalidate(FALSE);
pGroup->RedrawWindow();
pGroup->UpdateWindow();
CRect rcPos;
CString str;
rcPos.SetRectEmpty();
m_pDynEdit = new CEdit[nNums]();
for (short i = 0; i < nNums; i++)
{
rcPos.left = 10;
rcPos.top = 20 + (EHeight + YSpace) * i;
rcPos.right = rcPos.left + 30;
rcPos.bottom = rcPos.top + EHeight;
str.Empty();
str.Format(_T("%d"), i + 1);
if (m_pDynEdit[i].CreateEx(WS_EX_STATICEDGE, _T("EDIT"), (LPCTSTR)str, ES_CENTER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcPos, pGroup, EDITID + i))
{
//m_pDynEdit[i].SetWindowText(_T("0"));
}} m\_siNumsOfDynEdit = nNums; }
}
-
first of all, i shall thanks all of you guys. In my project, i created some STATIC & EDIT controls in a CDialog and set these control's parent to a group box(also a STATIC control). it works well for create, but it can't be delete dynamically. For example, i create 5 EDIT control then delete it(there are no sub-controls in group box this time), and i create 2 EDIT control again, oops! there are 5 EDIT control showing in the group box. So, i guess this caused by the group box haven't refreshed in time. and then i sendmessage to group box to force it to refresh. unfortunately it doesn't works. here is my code:
void CPLCDlg::DynamicCreateEdit(UINT nNums)
{
const int YSpace = 15;
const int EHeight = 20;
const UINT EDITID = 72000;
if (nNums <= 0)
return;
CButton* pGroup = (CButton*)GetDlgItem(IDC_STATIC_GROUP);
if (NULL != pGroup)
{
if (NULL != m_pDynEdit && m_siNumsOfDynEdit > 0)
{
for (short i = 0; i < m_siNumsOfDynEdit; i++)
{
if (NULL != m_pDynEdit[i].GetSafeHwnd())
{
m_pDynEdit[i].ShowWindow(SW_HIDE);
m_pDynEdit[i].DestroyWindow();
}
delete m_pDynEdit[i];
}
delete[] m_pDynEdit;
m_pDynEdit = NULL;
::SendMessage(pGroup->GetSafeHwnd(), WM_ERASEBKGND, 0, 0);
}
pGroup->Invalidate(FALSE);
pGroup->RedrawWindow();
pGroup->UpdateWindow();
CRect rcPos;
CString str;
rcPos.SetRectEmpty();
m_pDynEdit = new CEdit[nNums]();
for (short i = 0; i < nNums; i++)
{
rcPos.left = 10;
rcPos.top = 20 + (EHeight + YSpace) * i;
rcPos.right = rcPos.left + 30;
rcPos.bottom = rcPos.top + EHeight;
str.Empty();
str.Format(_T("%d"), i + 1);
if (m_pDynEdit[i].CreateEx(WS_EX_STATICEDGE, _T("EDIT"), (LPCTSTR)str, ES_CENTER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcPos, pGroup, EDITID + i))
{
//m_pDynEdit[i].SetWindowText(_T("0"));
}} m\_siNumsOfDynEdit = nNums; }
}
Just recreate the dialog? Place it over the old and delete the old, if it's noticeable. (25 cent solution)
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
first of all, i shall thanks all of you guys. In my project, i created some STATIC & EDIT controls in a CDialog and set these control's parent to a group box(also a STATIC control). it works well for create, but it can't be delete dynamically. For example, i create 5 EDIT control then delete it(there are no sub-controls in group box this time), and i create 2 EDIT control again, oops! there are 5 EDIT control showing in the group box. So, i guess this caused by the group box haven't refreshed in time. and then i sendmessage to group box to force it to refresh. unfortunately it doesn't works. here is my code:
void CPLCDlg::DynamicCreateEdit(UINT nNums)
{
const int YSpace = 15;
const int EHeight = 20;
const UINT EDITID = 72000;
if (nNums <= 0)
return;
CButton* pGroup = (CButton*)GetDlgItem(IDC_STATIC_GROUP);
if (NULL != pGroup)
{
if (NULL != m_pDynEdit && m_siNumsOfDynEdit > 0)
{
for (short i = 0; i < m_siNumsOfDynEdit; i++)
{
if (NULL != m_pDynEdit[i].GetSafeHwnd())
{
m_pDynEdit[i].ShowWindow(SW_HIDE);
m_pDynEdit[i].DestroyWindow();
}
delete m_pDynEdit[i];
}
delete[] m_pDynEdit;
m_pDynEdit = NULL;
::SendMessage(pGroup->GetSafeHwnd(), WM_ERASEBKGND, 0, 0);
}
pGroup->Invalidate(FALSE);
pGroup->RedrawWindow();
pGroup->UpdateWindow();
CRect rcPos;
CString str;
rcPos.SetRectEmpty();
m_pDynEdit = new CEdit[nNums]();
for (short i = 0; i < nNums; i++)
{
rcPos.left = 10;
rcPos.top = 20 + (EHeight + YSpace) * i;
rcPos.right = rcPos.left + 30;
rcPos.bottom = rcPos.top + EHeight;
str.Empty();
str.Format(_T("%d"), i + 1);
if (m_pDynEdit[i].CreateEx(WS_EX_STATICEDGE, _T("EDIT"), (LPCTSTR)str, ES_CENTER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcPos, pGroup, EDITID + i))
{
//m_pDynEdit[i].SetWindowText(_T("0"));
}} m\_siNumsOfDynEdit = nNums; }
}
Rather than destroy and recreate just hide and then show again them! Do destroy/delete only by destroying the dialog itself!
-
first of all, i shall thanks all of you guys. In my project, i created some STATIC & EDIT controls in a CDialog and set these control's parent to a group box(also a STATIC control). it works well for create, but it can't be delete dynamically. For example, i create 5 EDIT control then delete it(there are no sub-controls in group box this time), and i create 2 EDIT control again, oops! there are 5 EDIT control showing in the group box. So, i guess this caused by the group box haven't refreshed in time. and then i sendmessage to group box to force it to refresh. unfortunately it doesn't works. here is my code:
void CPLCDlg::DynamicCreateEdit(UINT nNums)
{
const int YSpace = 15;
const int EHeight = 20;
const UINT EDITID = 72000;
if (nNums <= 0)
return;
CButton* pGroup = (CButton*)GetDlgItem(IDC_STATIC_GROUP);
if (NULL != pGroup)
{
if (NULL != m_pDynEdit && m_siNumsOfDynEdit > 0)
{
for (short i = 0; i < m_siNumsOfDynEdit; i++)
{
if (NULL != m_pDynEdit[i].GetSafeHwnd())
{
m_pDynEdit[i].ShowWindow(SW_HIDE);
m_pDynEdit[i].DestroyWindow();
}
delete m_pDynEdit[i];
}
delete[] m_pDynEdit;
m_pDynEdit = NULL;
::SendMessage(pGroup->GetSafeHwnd(), WM_ERASEBKGND, 0, 0);
}
pGroup->Invalidate(FALSE);
pGroup->RedrawWindow();
pGroup->UpdateWindow();
CRect rcPos;
CString str;
rcPos.SetRectEmpty();
m_pDynEdit = new CEdit[nNums]();
for (short i = 0; i < nNums; i++)
{
rcPos.left = 10;
rcPos.top = 20 + (EHeight + YSpace) * i;
rcPos.right = rcPos.left + 30;
rcPos.bottom = rcPos.top + EHeight;
str.Empty();
str.Format(_T("%d"), i + 1);
if (m_pDynEdit[i].CreateEx(WS_EX_STATICEDGE, _T("EDIT"), (LPCTSTR)str, ES_CENTER | WS_VISIBLE | WS_CHILD | WS_TABSTOP, rcPos, pGroup, EDITID + i))
{
//m_pDynEdit[i].SetWindowText(_T("0"));
}} m\_siNumsOfDynEdit = nNums; }
}
Looks like you send a
WM_ERASEBKGND
message to the parent group window (pGroup) and then redraw it. But parent windows will clip the child windows[^]. This is why you still see the windows you deleted. In other words when you invalidate/redraw pGroup it skips over the rectangles where your m_pDynEdit child windows were being drawn. You can use the ExcludeClipRect function[^] to remove the clipped rectangles from the clipping region. Also, you can use the RectVisible function[^] to check for clipping. I'm on a TV, I apologize in advance for any typos.