0

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.

Younth
  • 65
  • 6
  • I'm sorry I can't build the project and reproduce the problem with your description, could you please show [a minimal, reproducible sample](https://stackoverflow.com/help/minimal-reproducible-example) without private information? – Zeus Mar 26 '21 at 01:55
  • @SongZhu-MSFT come on, you again. here is a link [link](https://github.com/YouSyd/TreeGrid_Test/blob/2a82b6c549d8bc1c2470758f69d2b99f60d7a9fd/TreeGrid.cpp#L545), you chinese right? I make some description on the git. Hope to make some discussion somewhere more convinet. – Younth Mar 26 '21 at 04:52
  • I built the project based on your code, but when the window was resized, there was no flicker. But some drawings are not erased, and if I return 0 in `WM_ERASEBKGND`, everything is normal. Could you describe your problem in detail? – Zeus Mar 26 '21 at 06:45
  • I don't want to use the default erase backgound method. It has a problem, when you wrapped a lot layer, I mean the treeview contorl has parent window A, A has parent window B and so on. If you use the default erase backgroud procedure(return zero), flicker turned out. – Younth Mar 26 '21 at 08:03
  • Maybe you can add some screenshots or gifs to describe the current phenomenon and the effect you expect. – Zeus Mar 26 '21 at 08:18
  • the git brunch has a Gif, I'm courious about if you know chinese or not ? – Younth Mar 26 '21 at 08:21
  • I can reproduce the problem in the GIF, but returning 0 can help with erasure. What problem does this cause for you? – Zeus Mar 26 '21 at 08:52
  • No , The test code I give to you is jus one layer. Go git and check the new Gif I uploaded , you will find the flicker. Are you abroad ? I mean if both of us can speak the some native language , but here with English, seems very wired. By the way , I mean if I need Bing translate to understand what you say and pretend to make you know what I say . That really sucks. – Younth Mar 26 '21 at 09:17
  • You can try adding `SWP_NOREDRAW` in `SetWindowsPos`. And you can refer to: [Flickering on window when resizing from left side](https://stackoverflow.com/questions/20958574/flickering-on-window-when-resizing-from-left-side) and [Static controls slightly flicker when main window is resized](https://stackoverflow.com/questions/20362622/static-controls-slightly-flicker-when-main-window-is-resized). – Zeus Mar 26 '21 at 09:50
  • Thank you for your advise. As far as I have tried , it seems no improvement yet. – Younth Mar 26 '21 at 10:14
  • Somehow it turned out Stackoverflow only do gathering problems but no clear actions to deal with how to solve or answer for this kind of samlier questions . Luckily I'm not that urgent , and I'm not the only one got blocked. – Younth Mar 26 '21 at 10:40

1 Answers1

0

The window style WS_CLIPCHILDREN can work. The container window should apply this style to avoid the double refresh of the control area. In this way you can keep the WM_ERASEBKGND, and no flicker.

Younth
  • 65
  • 6