【发布时间】:2021-03-25 06:55:46
【问题描述】:
我在做什么
问题的倾向可能不清楚。我会做更多的描述。
当您尝试重绘WC_TREEVIEW 控件时,您可能需要注意它的父窗口消息WM_NOTIFY。
可能是这样编码的:
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;
参数NMTREEVIEW 包含更新特定项目区域所需的所有必要信息。
我的第一个问题是结构成员NMTVCUSTOMDRAW::nmcd::dwDrawStage 的含义。
MSDN说了很多,我没有理想。
我的编码是这样的,如果不对请纠正我。谢谢。
//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;
}
我的问题是什么
所有这些都已完成。然后,当您调整支架窗口大小时,您会发现一些变细。
我使树视图控件根据其容器窗口的大小自动调整大小。
现在如果我直接阻止WM_ERASEBKGND返回非零,它会以某种方式减少闪烁。
case WM_ERASEBKGND: return 1;
break;
但是,如果树状视图项目没有占据整个客户区,则未被树状视图项目占据的其余部分将无法正确刷新。 那是我的问题。Treeview 刷新它的背景和项目导致闪烁。我应该怎么做才能解决这个问题?
现在,当我重绘 WC_LISTVIEW 控件时,这对我来说是一个常见问题。它还提供WM_DRAWITEM 来重写项目。
同样的闪烁问题。
【问题讨论】:
-
很抱歉,我无法构建项目并根据您的描述重现问题,您能否在没有私人信息的情况下显示a minimal, reproducible sample?
-
@SongZhu-MSFT 加油,你又来了。这是一个链接link,你是中国人吧?我对git做了一些描述。希望能在更正式的地方进行一些讨论。
-
我根据你的代码建了项目,但是当窗口调整大小时,没有闪烁。但是有些图没有被擦除,如果我在
WM_ERASEBKGND返回0,一切正常。你能详细描述一下你的问题吗? -
我不想使用默认的擦除背景方法。它有一个问题,当你包裹了很多层时,我的意思是树视图控件有父窗口 A,A 有父窗口 B 等等。如果使用默认的擦除背景程序(返回零),就会出现闪烁。
-
也许你可以添加一些截图或gif来描述当前的现象和你期望的效果。