<?xml encoding=”UTF-8″>By Balaji Ramamoorthy
If you are using CAdUiListCtrl and wish to customize it more, you can do it by using custom draw. This is same as customizing any other MFC controls and a nice article on customizing a CListCtrl is here :
Neat Stuff to Do in List Controls Using Custom Draw
Following the custom drawing on list control derived from CAdUiListCtrl, here is a code snippet for displaying color values.
<span>// MyListCtrl.h</span><span> </span>
<span>#pragma</span><span> <span>once</span><span> </span></span>
<span>class</span><span> MyListCtrl : <span>public</span><span> CAdUiListCtrl </span></span>
<span>{</span>
DECLARE_DYNAMIC(MyListCtrl)
<span>private</span><span> :</span>
<span>// Helper method</span><span> </span>
CString ColorNameFromIndex(<span>int</span><span> colorIndex);</span>
<span>public</span><span> :</span>
MyListCtrl();
<span>virtual</span><span> ~MyListCtrl();</span>
<span>protected</span><span> :</span>
DECLARE_MESSAGE_MAP()
<span>// Custom draw</span><span> </span>
afx_msg <span>void</span><span> OnCustomDraw </span>
( NMHDR* pNMHDR, LRESULT* pResult );
<span>}</span>;
<span>// MyListCtrl.cpp : implementation file</span><span> </span>
<span>#include</span><span> <span>"stdafx.h"</span><span> </span></span>
<span>#include</span><span> <span>"MyListCtrl.h"</span><span> </span></span>
IMPLEMENT_DYNAMIC(MyListCtrl, CAdUiListCtrl)
MyListCtrl::MyListCtrl()<span>{</span><span>}</span>
MyListCtrl::~MyListCtrl()<span>{</span><span>}</span>
BEGIN_MESSAGE_MAP(MyListCtrl, CAdUiListCtrl)
ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomDraw)
END_MESSAGE_MAP()
<span>// Custom draw </span><span> </span>
afx_msg <span>void</span><span> MyListCtrl::</span>
OnCustomDraw ( NMHDR* pNMHDR, LRESULT* pResult)
<span>{</span>
NMLVCUSTOMDRAW* pLVCD
= <span>reinterpret_cast</span><span> <NMLVCUSTOMDRAW*>(pNMHDR);</span>
<span>// Take the default processing unless we </span><span> </span>
<span>// set this to something else below.</span><span> </span>
*pResult = CDRF_DODEFAULT;
<span>// First thing - check the draw stage. </span><span> </span>
<span>// If's the's prepaint</span><span> </span>
<span>// stage, then tell Windows we want messages </span><span> </span>
<span>// for every item.</span><span> </span>
<span>if</span><span> ( CDDS_PREPAINT </span>
== pLVCD->nmcd.dwDrawStage )
<span>{</span>
*pResult = CDRF_NOTIFYITEMDRAW;
<span>}</span>
<span>else</span><span> <span>if</span><span> ( CDDS_ITEMPREPAINT </span></span>
== pLVCD->nmcd.dwDrawStage )
<span>{</span>
*pResult = CDRF_NOTIFYPOSTPAINT;
<span>}</span>
<span>else</span><span> <span>if</span><span> ( CDDS_ITEMPOSTPAINT </span></span>
== pLVCD->nmcd.dwDrawStage )
<span>{</span>
LVITEM rItem;
<span>int</span><span> nItem = </span>
<span>static_cast</span><span> <<span>int</span><span> >( pLVCD->nmcd.dwItemSpec);</span></span>
CDC* pDC = CDC::FromHandle ( pLVCD->nmcd.hdc);
CRect rcIcon;
<span>// RGB color treating item row as a color index</span><span> </span>
<span>long</span><span> acirgb, r,g,b;</span>
acirgb = acedGetRGB ( nItem );
r = ( acirgb & 0xffL );
g = ( acirgb & 0xff00L ) >> 8;
b = acirgb >> 16;
CBrush brush(RGB(r,g,b));
CRect rcItem;
GetSubItemRect(nItem, 1, rcItem);
<span>int</span><span> w = rcItem.Width();</span>
<span>int</span><span> h = rcItem.Height();</span>
CRect clrBox((<span>int</span><span> )rcItem.left + 0.1 * h, </span>
(<span>int</span><span> )rcItem.top + 0.1 * h, </span>
(<span>int</span><span> )rcItem.left + 0.9 * h, </span>
(<span>int</span><span> )rcItem.top + 0.9 * h);</span>
CBrush* pOldBrush = pDC->SelectObject(&brush);
<span>// create and select a thick, black pen</span><span> </span>
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
CPen* pOldPen = pDC->SelectObject(&penBlack);
pDC->Rectangle(clrBox);
pDC->TextOutW(clrBox.right + 0.1*h,
(<span>int</span><span> )rcItem.top + 0.1 * h, </span>
ColorNameFromIndex(nItem));
<span>// put back the old objects</span><span> </span>
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
*pResult = CDRF_DODEFAULT;
<span>}</span>
<span>}</span>
<span>// Helper method</span><span> </span>
CString MyListCtrl::ColorNameFromIndex
(<span>int</span><span> colorIndex)</span>
<span>{</span>
<span>switch</span><span> (colorIndex)</span>
<span>{</span>
<span>case</span><span> 0:</span>
<span>return</span><span> _T(<span>"Black"</span><span> );</span></span>
<span>case</span><span> 1:</span>
<span>return</span><span> _T(<span>"Red"</span><span> );</span></span>
<span>case</span><span> 2:</span>
<span>return</span><span> _T(<span>"Yellow"</span><span> );</span></span>
<span>case</span><span> 3:</span>
<span>return</span><span> _T(<span>"Green"</span><span> );</span></span>
<span>case</span><span> 4:</span>
<span>return</span><span> _T(<span>"Cyan"</span><span> );</span></span>
<span>default</span><span> :</span>
<span>{</span>
CString str;
str.Format(_T(<span>"%d"</span><span> ), colorIndex);</span>
<span>return</span><span> str;</span>
<span>}</span>
<span>}</span>
<span>}</span>
To use the List control in a dialog, insert an MFC List control and add a member variable for it. Replace the CListCtrl with the custom List control class. Here is a code snippet :
<span>// SampleDlg.h</span><span> </span>
<span>// Member variable for the List control</span><span> </span>
MyListCtrl mMyList;
<span>// SampleDlg.cpp</span><span> </span>
BOOL SampleDlg::OnInitDialog()
<span>{</span>
CDialog::OnInitDialog();
<span>// Insert two columns</span><span> </span>
mMyList.InsertColumn(
0,
_T(<span>"Layer Name"</span><span> ), </span>
LVCFMT_LEFT, 90);
mMyList.InsertColumn(
1,
_T(<span>"Color"</span><span> )</span>
, LVCFMT_LEFT, 90);
<span>// Contents of column-1 will be </span><span> </span>
<span>// customized at runtime</span><span> </span>
<span>// so provided as empty</span><span> </span>
<span>int</span><span> nIndex = </span>
mMyList.InsertItem(0, _T(<span>"Layer 0"</span><span> ));</span>
mMyList.SetItemText(nIndex, 1, _T(<span>" "</span><span> ));</span>
nIndex
= mMyList.InsertItem(1, _T(<span>"Layer 1"</span><span> ));</span>
mMyList.SetItemText(nIndex, 1, _T(<span>" "</span><span> ));</span>
nIndex
= mMyList.InsertItem(2, _T(<span>"Layer 2"</span><span> ));</span>
mMyList.SetItemText(nIndex, 1, _T(<span>" "</span><span> ));</span>
nIndex
= mMyList.InsertItem(3, _T(<span>"Layer 3"</span><span> ));</span>
mMyList.SetItemText(nIndex, 1, _T(<span>" "</span><span> ));</span>
nIndex
= mMyList.InsertItem(4, _T(<span>"Layer 4"</span><span> ));</span>
mMyList.SetItemText(nIndex, 1, _T(<span>" "</span><span> ));</span>
<span>return</span><span> TRUE; </span>
<span>}</span>
Here is the customized list control displaying color values


Leave a Reply