Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. ListCtrl Custom Draw

ListCtrl Custom Draw

Scheduled Pinned Locked Moved C / C++ / MFC
csharpc++tutorialquestion
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    ROK_RShadow
    wrote on last edited by
    #1

    I have been reading Michael Dunn's article about Custom Draw and the List Control to figure out how to change the background and text color to change on a selected item. I have tried the code below in both the pre and post paint stages. Also in both stages I have tryed returning both CDRF_DODEFAULT and CDRF_SKIPDEFAULT, either nothing happens.. or no selection highlight is drawn. Anybody have any ideas? I'm lost with Custom Draw.. I don't understand why I can change the text/bk color for every item.. but if I test for a selected item, and then try and change the text/bk color.. nadda.. nothing .. zip..

    void CPlayListWindow::OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult )
    {
    	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
    
    
    	// tell windows to draw the control its self
    	// unless we change it
    	*pResult = 0;
    
    	// Now we need to check the draw stage
    	// if the stage is at the pre paint stage
    	// we need to tell windows that we want
    	// messages for every item
    	if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
    		*pResult = CDRF_NOTIFYITEMDRAW;
    	
    
    	else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
    	{
    		// This is the prepaint stage for each 
    		// individual item.
    		*pResult = CDRF_NOTIFYPOSTPAINT;
    	}
    	else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
    	{
    	
    		// first we are going to check to see if the
    		// item is selected. If it is we are going
    		// to tell it the background color
    		// is transparent (black) and the text color is blue
    		LVITEM rItem;
            int    nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );
    
    		ZeroMemory ( &rItem, sizeof(LVITEM) );
            rItem.mask  = LVIF_IMAGE | LVIF_STATE;
            rItem.iItem = nItem;
            rItem.stateMask = LVIS_SELECTED;
    		GetListCtrl().GetItem(&rItem);
    		
    		if(rItem.state == LVIS_SELECTED)
    		{
    			// now lets change the items color
    			pLVCD->clrTextBk = RGB(0,0,255);
    			pLVCD->clrText = RGB(0,0,255);
    
    
    			// Tell windows to draw it for us now
    			//*pResult = CDRF_DODEFAULT
    			*pResult = CDRF_SKIPDEFAULT;
    		}
    	
    	}
    
    }
    

    C# a poor attempt at bringing C++ to the VB masses

    R 1 Reply Last reply
    0
    • R ROK_RShadow

      I have been reading Michael Dunn's article about Custom Draw and the List Control to figure out how to change the background and text color to change on a selected item. I have tried the code below in both the pre and post paint stages. Also in both stages I have tryed returning both CDRF_DODEFAULT and CDRF_SKIPDEFAULT, either nothing happens.. or no selection highlight is drawn. Anybody have any ideas? I'm lost with Custom Draw.. I don't understand why I can change the text/bk color for every item.. but if I test for a selected item, and then try and change the text/bk color.. nadda.. nothing .. zip..

      void CPlayListWindow::OnCustomDrawList ( NMHDR* pNMHDR, LRESULT* pResult )
      {
      	NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
      
      
      	// tell windows to draw the control its self
      	// unless we change it
      	*pResult = 0;
      
      	// Now we need to check the draw stage
      	// if the stage is at the pre paint stage
      	// we need to tell windows that we want
      	// messages for every item
      	if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)
      		*pResult = CDRF_NOTIFYITEMDRAW;
      	
      
      	else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
      	{
      		// This is the prepaint stage for each 
      		// individual item.
      		*pResult = CDRF_NOTIFYPOSTPAINT;
      	}
      	else if(CDDS_ITEMPOSTPAINT == pLVCD->nmcd.dwDrawStage)
      	{
      	
      		// first we are going to check to see if the
      		// item is selected. If it is we are going
      		// to tell it the background color
      		// is transparent (black) and the text color is blue
      		LVITEM rItem;
              int    nItem = static_cast<int>( pLVCD->nmcd.dwItemSpec );
      
      		ZeroMemory ( &rItem, sizeof(LVITEM) );
              rItem.mask  = LVIF_IMAGE | LVIF_STATE;
              rItem.iItem = nItem;
              rItem.stateMask = LVIS_SELECTED;
      		GetListCtrl().GetItem(&rItem);
      		
      		if(rItem.state == LVIS_SELECTED)
      		{
      			// now lets change the items color
      			pLVCD->clrTextBk = RGB(0,0,255);
      			pLVCD->clrText = RGB(0,0,255);
      
      
      			// Tell windows to draw it for us now
      			//*pResult = CDRF_DODEFAULT
      			*pResult = CDRF_SKIPDEFAULT;
      		}
      	
      	}
      
      }
      

      C# a poor attempt at bringing C++ to the VB masses

      R Offline
      R Offline
      Roger Allen
      wrote on last edited by
      #2

      I have been working from the same article just yesterday. Hers a copy of mu OnCustom draw...

      void CCommunicationView::OnCustomDrawLog(NMHDR* pNMHDR, LRESULT* pResult)
      {
      NMLVCUSTOMDRAW *pLVCD = reinterpret_cast(pNMHDR);

      \*pResult = CDRF\_DODEFAULT;			// assume normal windows drawn control
      
      if (CDDS\_PREPAINT == pLVCD->nmcd.dwDrawStage)
      {
      	\*pResult = CDRF\_NOTIFYITEMDRAW;
      }
      else if (CDDS\_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
      {
      	// this is the prepaint stage, we need each sub-item pre-paint
      	\*pResult = CDRF\_NOTIFYSUBITEMDRAW;
      }
      else if ((CDDS\_ITEMPREPAINT | CDDS\_SUBITEM) == pLVCD->nmcd.dwDrawStage)
      {
      	// now render the image if it has one
      	int		item = pLVCD->nmcd.dwItemSpec;
      	LVITEM rItem;
          ZeroMemory(&rItem, sizeof(LVITEM));
          rItem.mask = LVIF\_IMAGE | LVIF\_STATE;
          rItem.iItem = item;
          rItem.stateMask = LVIS\_SELECTED;
          m\_Log.GetItem(&rItem );
      	// we render the text ourselves in the right colour and take tabs into account
      	int		value = m\_Log.GetItemData(item);
      	CDC\*	pDC = CDC::FromHandle ( pLVCD->nmcd.hdc );
      	CRect	rcText;
      	CRect	rcIcon;
      	CString	text;
      	
      	m\_Log.GetItemRect(item, &rcIcon, LVIR\_ICON);
      	m\_Log.GetItemRect(item, &rcText, LVIR\_BOUNDS);
      	rcText.left += rcIcon.Width();
      
      	text = m\_Log.GetItemText(item, 0);
      	if (rItem.state & LVIS\_SELECTED)
      	{
      		pDC->SetTextColor(GetSysColor(COLOR\_HIGHLIGHTTEXT));
      		CBrush	brush(GetSysColor(COLOR\_HIGHLIGHT));
      		pDC->FillRect(rcText, &brush);
      	}
      	else
      	{
      		pDC->SetTextColor(value);
      		CBrush	brush(GetSysColor(COLOR\_HIGHLIGHTTEXT));
      		pDC->FillRect(rcText, &brush);
      	}
      	pDC->DrawText(text, rcText, DT\_END\_ELLIPSIS | DT\_EXPANDTABS | DT\_SINGLELINE | DT\_VCENTER);
      	pLVCD->clrText = value;
      	m\_ilLog.Draw(pDC, rItem.iImage, rcIcon.TopLeft(), ILD\_TRANSPARENT);
      	\*pResult = CDRF\_SKIPDEFAULT;
      }
      

      }

      Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003

      R 1 Reply Last reply
      0
      • R Roger Allen

        I have been working from the same article just yesterday. Hers a copy of mu OnCustom draw...

        void CCommunicationView::OnCustomDrawLog(NMHDR* pNMHDR, LRESULT* pResult)
        {
        NMLVCUSTOMDRAW *pLVCD = reinterpret_cast(pNMHDR);

        \*pResult = CDRF\_DODEFAULT;			// assume normal windows drawn control
        
        if (CDDS\_PREPAINT == pLVCD->nmcd.dwDrawStage)
        {
        	\*pResult = CDRF\_NOTIFYITEMDRAW;
        }
        else if (CDDS\_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)
        {
        	// this is the prepaint stage, we need each sub-item pre-paint
        	\*pResult = CDRF\_NOTIFYSUBITEMDRAW;
        }
        else if ((CDDS\_ITEMPREPAINT | CDDS\_SUBITEM) == pLVCD->nmcd.dwDrawStage)
        {
        	// now render the image if it has one
        	int		item = pLVCD->nmcd.dwItemSpec;
        	LVITEM rItem;
            ZeroMemory(&rItem, sizeof(LVITEM));
            rItem.mask = LVIF\_IMAGE | LVIF\_STATE;
            rItem.iItem = item;
            rItem.stateMask = LVIS\_SELECTED;
            m\_Log.GetItem(&rItem );
        	// we render the text ourselves in the right colour and take tabs into account
        	int		value = m\_Log.GetItemData(item);
        	CDC\*	pDC = CDC::FromHandle ( pLVCD->nmcd.hdc );
        	CRect	rcText;
        	CRect	rcIcon;
        	CString	text;
        	
        	m\_Log.GetItemRect(item, &rcIcon, LVIR\_ICON);
        	m\_Log.GetItemRect(item, &rcText, LVIR\_BOUNDS);
        	rcText.left += rcIcon.Width();
        
        	text = m\_Log.GetItemText(item, 0);
        	if (rItem.state & LVIS\_SELECTED)
        	{
        		pDC->SetTextColor(GetSysColor(COLOR\_HIGHLIGHTTEXT));
        		CBrush	brush(GetSysColor(COLOR\_HIGHLIGHT));
        		pDC->FillRect(rcText, &brush);
        	}
        	else
        	{
        		pDC->SetTextColor(value);
        		CBrush	brush(GetSysColor(COLOR\_HIGHLIGHTTEXT));
        		pDC->FillRect(rcText, &brush);
        	}
        	pDC->DrawText(text, rcText, DT\_END\_ELLIPSIS | DT\_EXPANDTABS | DT\_SINGLELINE | DT\_VCENTER);
        	pLVCD->clrText = value;
        	m\_ilLog.Draw(pDC, rItem.iImage, rcIcon.TopLeft(), ILD\_TRANSPARENT);
        	\*pResult = CDRF\_SKIPDEFAULT;
        }
        

        }

        Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003

        R Offline
        R Offline
        ROK_RShadow
        wrote on last edited by
        #3

        Thanks for the quick reply. I got it working.. but I am still confused. I don't understand why I have to draw it out in the pre paint stage. Post paint I might be able to understand.. but I don't understand why I can loop through message for each Item, and change there colors using nmcd.clr...() but I can't check if the item is selected and use mncd to change color????? C# a poor attempt at bringing C++ to the VB masses

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups