Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I created a derived class of CListCtrl, but I have a problem..when I click on a row the row doesn't become blue..and I don't understand why..my derived class:

<pre>
#include "stdafx.h"
#include "Domino6.h"
#include "MyListCtrl.h"
#include "MyHeader.h"


// MyListCtrl

IMPLEMENT_DYNAMIC(MyListCtrl, CListCtrl)

MyListCtrl::MyListCtrl()
{
	//m_bList = false;
}

MyListCtrl::~MyListCtrl()
{
}


BEGIN_MESSAGE_MAP(MyListCtrl, CListCtrl)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
END_MESSAGE_MAP()


void MyListCtrl::PreSubclassWindow()
{
	// TODO: Add your specialized code here and/or call the base class
	CHeaderCtrl* pHeader = NULL;
	pHeader = GetHeaderCtrl();
	int nWidth;


	if (m_bList == false)
		nWidth = GetColumnWidth(1);

	else
		nWidth = GetColumnWidth(0);
	
	if (pHeader != NULL)
	{
		//int nWidth = GetColumnWidth(1);
		
		//m_HeaderCtrl.m_nCol = m_nCol;
		VERIFY(m_HeaderCtrl.SubclassWindow(pHeader->m_hWnd)); // m_HeaderCtrl is the new wrapper object
	}
	CListCtrl::PreSubclassWindow();
}
// MyListCtrl message handlers


void MyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
	NMLVCUSTOMDRAW *pCD = (NMLVCUSTOMDRAW*)pNMHDR;
	// By default set the return value to do the default behavior.
	*pResult = CDRF_DODEFAULT;

	LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
	// TODO: Add your control notification handler code here
	*pResult = CDRF_DODEFAULT;

	int n_width = 0;

	if(m_bList == false)

	n_width = GetColumnWidth(1);

	else

	n_width = GetColumnWidth(0);


	int NumberOfColumns = m_HeaderCtrl.GetItemCount();

	m_HeaderCtrl.m_nwidth_  = GetColumnWidth(0);
	m_HeaderCtrl.m_nwidth1_ = GetColumnWidth(1);
	m_HeaderCtrl.m_nwidth1 = GetColumnWidth(2);
	m_HeaderCtrl.m_nwidth2 = GetColumnWidth(3);
	m_HeaderCtrl.m_nwidth3 = GetColumnWidth(4);
	m_HeaderCtrl.m_nwidth4 = GetColumnWidth(5);
	m_HeaderCtrl.m_nwidth5 = GetColumnWidth(6);

	//obtain row and column of item
	m_nRow = pCD->nmcd.dwItemSpec;
	m_nCol = pCD->iSubItem;

	//Remove standard highlighting of selected (sub)item.
	pCD->nmcd.uItemState = CDIS_DEFAULT;

	switch (pCD->nmcd.dwDrawStage)
	{
	case  CDDS_PREPAINT:  // First stage (for the whole control)
	{
		*pResult = CDRF_NOTIFYITEMDRAW;
	}
	break;

	case CDDS_ITEMPREPAINT:
	{
		*pResult = CDRF_NOTIFYSUBITEMDRAW;
	}
	break;

	case  CDDS_ITEMPREPAINT | CDDS_SUBITEM: // Stage three 
	{
		if (m_bList == true)
		{
			{
				CDC* pDC = CDC::FromHandle(pNMCD->hdc);

				CBrush brushBlue(RGB(255, 192, 203));// inner color blue.
				CBrush* pOldBrush = pDC->SelectObject(&brushBlue);

				// create and select a thick, black pen
				CPen penBlack;
				penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));// red color with width 3
				CPen* pOldPen = pDC->SelectObject(&penBlack);

				for (int ij = 0; ij < 50; ij++)
				{
					CRect rect1(0, 24 + (17 * (ij)), n_width, 42 + (17 * (ij)));  //CRect(a,b,c,d) come b metto il valore d del rettangolo precedente, invece d = b+18; 
					pDC->Rectangle(rect1);

					if (ij < m_arrStr.GetSize())
					pDC->DrawText(m_arrStr[ij], CRect(rect1), DT_BOTTOM);
				}

				pDC->SelectObject(pOldBrush);
				pDC->SelectObject(pOldPen);
			}
			*pResult = CDRF_NOTIFYPOSTPAINT;
		}
		break;
	case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: // Stage four (called for each subitem of the focused item)
	{

	}
	break;

	default:// it wasn't a notification that was interesting to us.
	{
		*pResult = CDRF_DODEFAULT;
	}
	break;
	}
  }
}


What I have tried:

I saw that if I use an other list that isn't derived I don't have this problem..can you help me?
Posted
Updated 3-Jan-24 23:49pm
v2

If you are painting a single item yourself then (according to my sample code) you need to also return CDRF_NEWFONT when processing CDDS_ITEMPREPAINT | CDDS_SUBITEM. This is also shown in the Microsoft example at Using Custom Draw - Win32 apps | Microsoft Learn[^].
 
Share this answer
 
Comments
Member 14594285 4-Jan-24 6:24am    
I saw example..but it isn't complete..so I don't have to use void? what type?
Richard MacCutchan 4-Jan-24 6:31am    
Sorry, I don't understand what you mean.
Member 14594285 4-Jan-24 8:37am    
in this case I use:

void MyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW *pCD = (NMLVCUSTOMDRAW*)pNMHDR;

}

so instead of void, what must I use? and in this?
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
Richard MacCutchan 4-Jan-24 9:07am    
No, you return the status values in pResult, as you are already doing. But you need to ensure you return the correct notifications for the framework to process the control according to your settings, as I specified in my original post above.
Member 14594285 4-Jan-24 9:19am    
I wrote:
void MyListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMLVCUSTOMDRAW *pCD = (NMLVCUSTOMDRAW*)pNMHDR;
// By default set the return value to do the default behavior.
*pResult = CDRF_DODEFAULT;

LPNMCUSTOMDRAW pNMCD = reinterpret_cast<lpnmcustomdraw>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = CDRF_DODEFAULT;

int n_width = 0;

if(m_bList == false)

n_width = GetColumnWidth(1);

else

n_width = GetColumnWidth(0);


int NumberOfColumns = m_HeaderCtrl.GetItemCount();

m_HeaderCtrl.m_nwidth_ = GetColumnWidth(0);
m_HeaderCtrl.m_nwidth1_ = GetColumnWidth(1);
m_HeaderCtrl.m_nwidth1 = GetColumnWidth(2);
m_HeaderCtrl.m_nwidth2 = GetColumnWidth(3);
m_HeaderCtrl.m_nwidth3 = GetColumnWidth(4);
m_HeaderCtrl.m_nwidth4 = GetColumnWidth(5);
m_HeaderCtrl.m_nwidth5 = GetColumnWidth(6);

//obtain row and column of item
m_nRow = pCD->nmcd.dwItemSpec;
m_nCol = pCD->iSubItem;

//Remove standard highlighting of selected (sub)item.
pCD->nmcd.uItemState = CDIS_DEFAULT;

switch (pCD->nmcd.dwDrawStage)
{
case CDDS_PREPAINT: // First stage (for the whole control)
{
*pResult = CDRF_NOTIFYITEMDRAW;
}
break;

case CDDS_ITEMPREPAINT:
{
//*pResult = CDRF_NOTIFYSUBITEMDRAW;
*pResult = CDRF_NEWFONT;
}
break;

case CDDS_ITEMPREPAINT | CDDS_SUBITEM: // Stage three
{
if (m_bList == true)
{
{
CDC* pDC = CDC::FromHandle(pNMCD->hdc);

CBrush brushBlue(RGB(255, 192, 203));// inner color blue.
CBrush* pOldBrush = pDC->SelectObject(&brushBlue);

// create and select a thick, black pen
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));// red color with width 3
CPen* pOldPen = pDC->SelectObject(&penBlack);

for (int ij = 0; ij < 50; ij++)
{
CRect rect1(0, 24 + (17 * (ij)), n_width, 42 + (17 * (ij))); //CRect(a,b,c,d) come b metto il valore d del rettangolo precedente, invece d = b+18;
pDC->Rectangle(rect1);

if (ij < m_arrStr.GetSize())
pDC->DrawText(m_arrStr[ij], CRect(rect1), DT_BOTTOM);
}

pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
//*pResult = CDRF_NOTIFYPOSTPAINT;
*pResult = CDRF_NEWFONT;
}
*pResult = CDRF_NEWFONT;
break;
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM: // Stage four (called for each subitem of the focused item)
{

}
break;

default:// it wasn't a notification that was interesting to us.
{
//*pResult = CDRF_DODEFAULT;
*pResult = CDRF_NEWFONT;
}
break;
}
}
//return CDRF_NEWFONT;
}

but the row isn't bllue when I click, with this code I don't solve
A lot of interesting details with drawing in Listcontrols is descripted in the outstanding article Neat Stuff to Do in List Controls Using Custom Draw.
So you may find not only some solution, but also some further inspiration.
 
Share this answer
 
Comments
Richard MacCutchan 4-Jan-24 10:23am    
Which I already provided in my last reply.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900