Discussion:
CTreeCtrl performance issue on Window7
(too old to reply)
jean philippe phan
2010-02-12 12:02:01 UTC
Permalink
Hi
I experienced a CTreeCtrl performance issue only on Window7, not on XP, not
on Vista.
- I insert 5000 items into a CTreeCtrl.
- When i click on a button, i will call SetItem with the integral=2
(TVIF_INTEGRAL) on 1000 first items.
XP takes 1 second to execute this command, W7 takes 8 seconds
Please could some one help me?

Here is my code in MFC modal window:
BOOL CMFCTreeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
// TODO: Add extra initialization here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
for(int i=0; i<5000; ++i)
{
wchar_t ws[125];
wsprintf( ws, L"Tree1: item%ld", i);
pTreeCtrl->InsertItem(ws);
}
}
return TRUE; // return TRUE unless you set the focus to a control
}

void CMFCTreeDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
pTreeCtrl->SetRedraw(FALSE);

HTREEITEM hRoot = pTreeCtrl->GetRootItem();
for(int i=0; i<1000; ++i)
{
hRoot = pTreeCtrl->GetNextItem(hRoot, TVGN_NEXT);
// Set iIntegral
TVITEMEX tvItemEx;
memset(&tvItemEx, 0, sizeof(tvItemEx));
tvItemEx.mask = TVIF_INTEGRAL;
tvItemEx.hItem = hRoot;
tvItemEx.iIntegral = 2;
pTreeCtrl->SetItem((TVITEMW *)&tvItemEx);
}

pTreeCtrl->SetRedraw(TRUE);
pTreeCtrl->Invalidate();
pTreeCtrl->UpdateWindow();
}
//OnOK();
}

void CMFCTreeDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
Glyn
2010-02-25 12:20:01 UTC
Permalink
Post by jean philippe phan
Hi
I experienced a CTreeCtrl performance issue only on Window7, not on XP, not
on Vista.
- I insert 5000 items into a CTreeCtrl.
- When i click on a button, i will call SetItem with the integral=2
(TVIF_INTEGRAL) on 1000 first items.
XP takes 1 second to execute this command, W7 takes 8 seconds
Please could some one help me?
BOOL CMFCTreeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
// TODO: Add extra initialization here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
for(int i=0; i<5000; ++i)
{
wchar_t ws[125];
wsprintf( ws, L"Tree1: item%ld", i);
pTreeCtrl->InsertItem(ws);
}
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCTreeDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
pTreeCtrl->SetRedraw(FALSE);
HTREEITEM hRoot = pTreeCtrl->GetRootItem();
for(int i=0; i<1000; ++i)
{
hRoot = pTreeCtrl->GetNextItem(hRoot, TVGN_NEXT);
// Set iIntegral
TVITEMEX tvItemEx;
memset(&tvItemEx, 0, sizeof(tvItemEx));
tvItemEx.mask = TVIF_INTEGRAL;
tvItemEx.hItem = hRoot;
tvItemEx.iIntegral = 2;
pTreeCtrl->SetItem((TVITEMW *)&tvItemEx);
}
pTreeCtrl->SetRedraw(TRUE);
pTreeCtrl->Invalidate();
pTreeCtrl->UpdateWindow();
}
//OnOK();
}
void CMFCTreeDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
Sorry I don't have a complete solution for you. However I have reproduced
your problem. For some reason under Windows 7 the SetItem function with
TVIF_INTEGRAL takes up to 16ms. Which is very strange indeed.

I suggest that you try to set the iIntegral value at the time that you
originally add the items into the list. Use the TVINSERTSTRUCT which
contains a union of both the TVITEMEX and the TV_ITEMW structures.

Hope this helps

Glyn Richards
jean philippe phan
2010-05-18 16:09:01 UTC
Permalink
Hi Glyn

Thank a lot for your help. The issue will be fixed in OS.
Each time you call SetItem, the CTreeCtrl will call an update.
Regards,
Jean Philippe
Post by Glyn
Post by jean philippe phan
Hi
I experienced a CTreeCtrl performance issue only on Window7, not on XP, not
on Vista.
- I insert 5000 items into a CTreeCtrl.
- When i click on a button, i will call SetItem with the integral=2
(TVIF_INTEGRAL) on 1000 first items.
XP takes 1 second to execute this command, W7 takes 8 seconds
Please could some one help me?
BOOL CMFCTreeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
...
// TODO: Add extra initialization here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
for(int i=0; i<5000; ++i)
{
wchar_t ws[125];
wsprintf( ws, L"Tree1: item%ld", i);
pTreeCtrl->InsertItem(ws);
}
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCTreeDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
CTreeCtrl* pTreeCtrl = (CTreeCtrl*)GetDlgItem(IDC_TREE1);
if (pTreeCtrl != NULL )
{
pTreeCtrl->SetRedraw(FALSE);
HTREEITEM hRoot = pTreeCtrl->GetRootItem();
for(int i=0; i<1000; ++i)
{
hRoot = pTreeCtrl->GetNextItem(hRoot, TVGN_NEXT);
// Set iIntegral
TVITEMEX tvItemEx;
memset(&tvItemEx, 0, sizeof(tvItemEx));
tvItemEx.mask = TVIF_INTEGRAL;
tvItemEx.hItem = hRoot;
tvItemEx.iIntegral = 2;
pTreeCtrl->SetItem((TVITEMW *)&tvItemEx);
}
pTreeCtrl->SetRedraw(TRUE);
pTreeCtrl->Invalidate();
pTreeCtrl->UpdateWindow();
}
//OnOK();
}
void CMFCTreeDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
Sorry I don't have a complete solution for you. However I have reproduced
your problem. For some reason under Windows 7 the SetItem function with
TVIF_INTEGRAL takes up to 16ms. Which is very strange indeed.
I suggest that you try to set the iIntegral value at the time that you
originally add the items into the list. Use the TVINSERTSTRUCT which
contains a union of both the TVITEMEX and the TV_ITEMW structures.
Hope this helps
Glyn Richards
Just Tried this...
If you do...
TVINSERTSTRUCT tviis = {0};
tviis.itemex.mask = TVIF_INTEGRAL | TVIF_TEXT;
tviis.itemex.pszText = ws;
tviis.itemex.iIntegral = 2;
pTreeControl->InsertItem(&tviis);
in your first loop then performance for Windows 7 is restored.
I know it's not a perfect solution, but it looks like this may be an OS issue.
Regards
Glyn Richards
Loading...