Thread: Treeview Custom Draw

  1. #1
    Registered User
    Join Date
    Feb 2005
    Posts
    8

    Treeview Custom Draw

    I have trouble with getting my custom drawing within a SDK treeview to work.

    The data that is represented in my treeview has icons and colors. Certain items are represented by an icon, others only by their color. In order to get the color to show I "overdraw" each icon where the item should have a color by using FillRect. The size is calculated by the bounding rectangle of the item's text.

    This works perfectly until I move the scrollbar quickly up and down. In the end the colored rectangles are not painted anymore and the whole HDC seems to be messed up (such as context menus of other programs display black parts instead of menu entries).

    What I do (deleted some code lines for simplicity):
    Code:
    llplvcd = (LPNMLVCUSTOMDRAW)lParam;
    
    switch(lplvcd->nmcd.dwDrawStage)
    {
    	case CDDS_PREPAINT:
    		return CDRF_NOTIFYITEMDRAW;
    		break;
    	case CDDS_ITEMPREPAINT:
    		return CDRF_NOTIFYPOSTPAINT;
    		break;
    	case CDDS_ITEMPOSTPAINT:
    		TreeView_GetItemRect(ctrl->hCtrl, (HTREEITEM) lplvcd->nmcd.dwItemSpec, &rect, 1);
    		SetBkColor(lplvcd->nmcd.hdc, RGB(0x00, 0x88, 0xFF));
    		FillRect(lplvcd->nmcd.hdc, &item_rect, CreateSolidBrush(RGB(r, g, b))); //r, g, b calculated from RGB above
    		return 1; // or CDDS_SKIPDEFAULT / _DODEFAULT?
    }
    What I don't know is, what should ITEMPOSTPAINT return? All my google searches returned tons of information on all the other drawstages but none on the ITEMPOSTPAINT. Am I doing something wrong in general? One thing I was suspecting is that the treeview generates so many messages that the messageloop can't keep up.

    The whole program works, if I comment the CDDS_ITEMPOSTPAINT part. So the error has to be there.

    Thanks allot in advance for any help.
    Manuel

  2. #2
    Registered User
    Join Date
    Feb 2005
    Posts
    8
    I think I found out what was causing all the problems:

    First of all I was creating a new SolidBrush every single time I was drawing the FillRect. Though as I had different colors for almost each item I needed that. BUT: I was not deleting this Object.

    Second, I'm receiving the device context in a different way now. Instead of using the one provided within the lParam, I'm getting the dc directly via method call.

    So the code should look more like:
    Code:
    llplvcd = (LPNMLVCUSTOMDRAW)lParam;
    
    switch(lplvcd->nmcd.dwDrawStage)
    {
    	HDC hdc;
    	HBRUSH hbrush;
    
    	case CDDS_PREPAINT:
    		return CDRF_NOTIFYITEMDRAW;
    		break;
    	case CDDS_ITEMPREPAINT:
    		return CDRF_NOTIFYPOSTPAINT;
    		break;
    	case CDDS_ITEMPOSTPAINT:
    		TreeView_GetItemRect(hwnd, (HTREEITEM) lplvcd->nmcd.dwItemSpec, &rect, 1);
    		hdc = GetDC(hwnd);
    		CreateSolidBrush(RGB(r, g, b)); //r, g, b received from somewhere else
    		FillRect(hdc, &item_rect, hbrush); 
    		DeleteObject(hbrush);
    		ReleaseDC(hwnd, hdc);
    		return 0;
    }
    I'm not 100% sure if getting the way I get the DC is the proper way. But as I said above, the biggest problems seemed to be not deleting the brush after I was done painting.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 08-04-2008, 05:34 PM
  2. Which is the better way to draw?
    By g4j31a5 in forum Game Programming
    Replies: 16
    Last Post: 01-22-2007, 11:56 PM
  3. Custom Draw TreeView
    By eXistenZ in forum Windows Programming
    Replies: 3
    Last Post: 08-05-2005, 12:34 PM
  4. draw function HELP!!!
    By sunoflight77 in forum C++ Programming
    Replies: 1
    Last Post: 05-10-2005, 11:28 PM
  5. ray casting
    By lambs4 in forum Game Programming
    Replies: 62
    Last Post: 01-09-2003, 06:57 PM