What I am doing
The tilte of question may be not clear. I will make more description.
When you try to redraw a WC_TREEVIEW
contorl, you may need to pay attention to it's parent window message WM_NOTIFY
.
It may coding like this:
case WM_NOTIFY: {
UINT ctrl_id = wParam;
LPNMHDR pnmh = (LPNMHDR)lParam;
HWND ctrl_hwnd = pnmh->hwndFrom;
char class_name[256] = "";
LRESULT result;
GetClassName(ctrl_hwnd,class_name,sizeof(class_name));
if(strstr(class_name,WC_TREEVIEW)) {
LPNMTREEVIEW item = (LPNMTREEVIEW)pnmh;
if(item->hdr.code == NM_CUSTOMDRAW) {
//...Do your item drawing
return result;
}
}
//....
} break;
The parameter NMTREEVIEW
has all the necessary information you need to update the specfic item area.
My Fisrt question is the meaning of structure member NMTVCUSTOMDRAW::nmcd::dwDrawStage
.
MSDN say a lot, I have no ideal.
My coding is like this,if not right please correct me. Thank you.
//My drawing of treeview item.
{
LPNMTVCUSTOMDRAW cust_draw = (LPNMTVCUSTOMDRAW)lParam;
RECT rect;
HDC hdc;
TVHITTESTINFO tv_hit;
TVITEM tv_item;
HTREEITEM item;
char item_text[1024] = "";
int step_level=cust_draw->iLevel;
hdc = cust_draw->nmcd.hdc;
CopyRect(&rect,&(cust_draw->nmcd.rc));
tv_hit.pt = {(rect.left+rect.right)/2,(rect.top+rect.bottom)/2};
if(cust_draw->nmcd.dwDrawStage==CDDS_PREPAINT) {
return CDRF_NOTIFYITEMDRAW;
}
else if(cust_draw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {
item = TreeView_HitTest(hwnd,&tv_hit);
if(item) {
tv_item.mask = TVIF_TEXT|TVIF_STATE|TVIF_CHILDREN;
tv_item.hItem = item;
tv_item.pszText = item_text;
tv_item.cchTextMax = sizeof(item_text);
TreeView_GetItem(hwnd,&tv_item);
MyTreeItemDrawing(hwnd,hdc,rect,step_level,&tv_item);
}
return CDRF_SKIPDEFAULT;
}
return CDRF_SKIPDEFAULT;
}
What is my problem
All those have been done. Then you will find some ficker when you sizing the holder window.
I make the treeview control auto sizing itself according the size of its container window.
Now if I block the WM_ERASEBKGND
return non-zero directly, it will somehow reduce the flicker.
case WM_ERASEBKGND: return 1;
break;
However, if the treeview items do not occupy the whole client zone, the rest part which not been occupied by the treeview items will not refresh correctly. That is my problem.Treeview refresh its background and items caused the flicker. What should I do to solve this problem?
Right now it's a common issue for me when I redrawing the WC_LISTVIEW
control. It also provide WM_DRAWITEM
to rewrite the items.
Same flicker problem.