item size not adjusted after font change in CTreeCtrl

2.2k views Asked by At

I change the font of tree items in CTreeCtrl with the following code:

void CTreeCtrlEx::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMTVCUSTOMDRAW pNMCD = reinterpret_cast<LPNMTVCUSTOMDRAW>(pNMHDR);
    *pResult = 0;

    switch(pNMCD->nmcd.dwDrawStage)
    {
        case CDDS_PREPAINT:
            *pResult = CDRF_NOTIFYITEMDRAW;
            return;
        case CDDS_ITEMPREPAINT:
        {
            CFont * pco_font = GetSomeFont();
            ::SelectObject(pNMCD->nmcd.hdc, pco_font->GetSafeHandle());
            *pResult = CDRF_NEWFONT;
        }
        return;
    }
}

However, the end of the text is being clipped in the items, apparently it is not being
adjusted to the length of the text with the new font.
what would be the remedy?

2

There are 2 answers

1
ingo On

I had the same problem and can confirm that CCM_SETVERSION did not work. In fact the only thing that worked reliably for me was to re-set the text after the paint process was finished. The way I did it was by catching the TVN_ITEMEXPANDING message and by re-setting the text. This would correct the text of all sub-items when a node is expanded. Of course this does not work for bold root nodes.

Here is a sketch of my code:

BEGIN_MESSAGE_MAP(CTreeViewEx, CTreeView)
  ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemExpanding)
END_MESSAGE_MAP()

void CTreeViewEx::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  if(pNMTreeView==NULL) {
    return;
  }
  HTREEITEM hTreeItem = pNMTreeView->itemNew.hItem;
  if(hTreeItem!=NULL) {
    ReevaluteItemTextOfChildren(hTreeItem);
    ...
  }
}

void CTdTreeViewEx::ReevaluteItemTextOfChildren(HTREEITEM hRootNode)
{
  if (hRootNode == NULL) {
    return;
  }
  CTreeCtrl& ctlTree = GetTreeCtrl();
  HTREEITEM hTreeItemCursor = ctlTree.GetNextItem(hRootNode, TVGN_CHILD);
  // Loop over all siblings
  while (hTreeItemCursor != NULL) {
    // Change the text of the current item
    CString csItemText(ctlTree.GetItemText(hTreeItemCursor));
    ctlTree.SetItemText(hTreeItemCursor, csItemText);
    // Get the next brother
    HTREEITEM hNextSibling = ctlTree.GetNextItem(hTreeItemCursor, TVGN_NEXT);
    hTreeItemCursor = hNextSibling;
  }
}
1
Mark Ransom On

From my copy of MSDN, which I can't seem to find online:

Most common controls can be handled in essentially the same way. However, the list-view and tree-view controls have some features that require a somewhat different approach to custom draw.

For Version 5.0, these two controls may display clipped text if you change the font by returning CDRF_NEWFONT. This behavior is necessary for backward compatibility with earlier versions of the common controls. If you want to change the font of a list-view or tree-view control, you will get better results if you send a CCM_SETVERSION message with the wParam value set to 5 before adding any items to the control.

See also the documentation for CCM_SETVERSION.