CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Feb 2003
    Location
    Deutschland, Unterfranken
    Posts
    6

    CListCtrl field colour

    Hello,
    How can I change the colour (foreground or background) of one single field in a CListCtrl?
    Thank you for answers.

  2. #2
    Join Date
    Aug 1999
    Location
    Germany
    Posts
    2,338
    Only by drawing every item for yourself. Set the LVS_OWNERDRAWFIXED-style and override DrawItem.

  3. #3
    Join Date
    Oct 1999
    Location
    Broomfield, CO
    Posts
    3,382
    You do NOT need to use owner draw for what you want to do. Use Custom Draw. See the Custom Draw Reference in the Platform SDK docs for specifics.

    You create a class that is derived form CListCtrl, handle the NM_CUSTOMDRAW message in that class, and declare your list control member variable to be of that class.

    For example, here is a class that uses custom draw to paint a numeric value in red foreground if the value is negative and if it is in a certain column of the list control.

    The member variable of the dialog that uses this list control would be declared like CHedgeFeeListCtrl m_listctrlFees;

    header file
    Code:
    #if !defined(AFX_HEDGEFEELISTCTRL_H__636791CC_008B_403D_A30B_91B92D91597D__INCLUDED_)
    #define AFX_HEDGEFEELISTCTRL_H__636791CC_008B_403D_A30B_91B92D91597D__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    class CHedgeFeeListCtrl : public CListCtrl
    {
    // Construction
    public:
    	CHedgeFeeListCtrl();
    
    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CHedgeFeeListCtrl)
    	//}}AFX_VIRTUAL
    
    // Implementation
    public:
    	virtual ~CHedgeFeeListCtrl();
    
    	// Generated message map functions
    protected:
    	//{{AFX_MSG(CHedgeFeeListCtrl)
    		// NOTE - the ClassWizard will add and remove member functions here.
    	//}}AFX_MSG
    	afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
    	
    	DECLARE_MESSAGE_MAP()
    };
    
    /////////////////////////////////////////////////////////////////////////////
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(AFX_HEDGEFEELISTCTRL_H__636791CC_008B_403D_A30B_91B92D91597D__INCLUDED_)
    Implementation file:

    Code:
    #include "stdafx.h"
    #include "billmain.h"
    #include "HedgeFeeListCtrl.h"
    #include "APLHedgeListDlg.h"
    #include "..\Common\HedgeFeeListInfo.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    CHedgeFeeListCtrl::CHedgeFeeListCtrl()
    {
    }
    
    CHedgeFeeListCtrl::~CHedgeFeeListCtrl()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CHedgeFeeListCtrl, CListCtrl)
    	//{{AFX_MSG_MAP(CHedgeFeeListCtrl)
    	//}}AFX_MSG_MAP
    	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
    END_MESSAGE_MAP()
    
    ///////////////////////////////////////
    /*
      Purpose:  Change fonts, etc. for drawing list control items and subitems
        Input:  None
    */
    ///////////////////
    
    void CHedgeFeeListCtrl::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
    {
    	// for this notification, the structure is actually a
    	// NMLVCUSTOMDRAW that tells you what's going on with the custom
    	// draw action. So, we'll need to cast the generic pNMHDR pointer.
    	NMLVCUSTOMDRAW* pCD = (NMLVCUSTOMDRAW*)pNMHDR;
    	int row = pCD->nmcd.dwItemSpec;
    	if(row < 0 || row > GetItemCount() - 1)
    	{
    		if(pCD->nmcd.dwDrawStage == CDDS_PREPAINT)
    		{
    			*pResult = CDRF_NOTIFYSUBITEMDRAW;
    		}
    		else
    		{
    			*pResult = CDRF_DODEFAULT;
    		}
    		return;
    	}
    
    	int pos = (int)GetItemData(row);
    	CHedgeFeeListInfo hfli = CAPLHedgeListDlg::m_vHedgeInfo[pos];
    	bool bNegative = false;
    	if(hfli.m_Amount.int64 < 0)
    	{
    		bNegative = true;
    	}
    
    	switch(pCD->nmcd.dwDrawStage)
    	{
    	case CDDS_PREPAINT:
    		*pResult = CDRF_NOTIFYSUBITEMDRAW;          // ask for subitem notifications.
    		break;
    
    	case CDDS_ITEMPREPAINT:
    		*pResult = CDRF_NOTIFYSUBITEMDRAW;
    		break;
    	case CDDS_ITEMPREPAINT|CDDS_SUBITEM:
    		{
    			if(pCD->iSubItem == 9)
    			{
    				pCD->clrText = BILLING_BLACK;
    				*pResult = CDRF_NEWFONT;
    			}
    			else if(pCD->iSubItem == 8 && bNegative)
    			{
    				pCD->clrText = BILLING_RED;
    				*pResult = CDRF_NEWFONT;
    			}
    			else
    			{
    				*pResult = CDRF_DODEFAULT;
    			}
    			break;
    		}
    	default:// it wasn't a notification that was interesting to us.
    		*pResult = CDRF_DODEFAULT;
    	}
    }

  4. #4
    Join Date
    Aug 2001
    Posts
    42
    I want to move the part of the logic which decides whether we need to draw it in Red ForeGround or not from void CHedgeFeeListCtrl::OnCustomDraw() method to the CAPLHedgeListDlg itself. I guess this can be done by handling the NM_CUSTOMDRAW notification in the CAPLHedgeListDlg itself. But I need to do something in the CHedgeFeeListCtrl::OnCustomDraw() method first, then in the CAPLHedgeListDlg::OnCustomDraw() method I need to do some more thing. How to achieve this?
    Last edited by r_kalidass; January 22nd, 2004 at 09:22 AM.

  5. #5
    Join Date
    Oct 1999
    Location
    Broomfield, CO
    Posts
    3,382
    I guess this can be done by handling the NM_CUSTOMDRAW notification in the CAPLHedgeListDlg itself.
    No, it cannot, unless you do some fancy message rerouting. Windows sends the draw command to the list control, not to the owner of the list control, and it is sent for every item in every row of the list control.

    You are probably better off puting info that determines how to draw an item in the item's data (using SetItemData). That's the usual way, and it is straight-forward. In many list controls for which I use custom draw, SetItemData is passed a pointer to a structure that contains whatever I need, if a simple data type is insufficient.

  6. #6
    Join Date
    Aug 2003
    Posts
    938
    this is jsut an idea but try selchage...adn basicly overdite it , amke another funciotn that dose the same nad then make that be set in onINitDialog on some line and changed the color of the selchage....i donno but it might work if ,,,,,,

  7. #7
    Join Date
    Aug 2001
    Posts
    42
    Thanks for the reply. I solved this by using the message reflection. I added ON_NOTIFY_REFLECT_EX() in the list ctrl and ON_NOTIFY in the dialog. In the listctrl handler after doing the required stuff I return FALSE to notify the parent i.e dialog.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured