CDC dc;
VERIFY( dc.Attach( lpDrawItemStruct->hDC ) ); // save the device context.
const int iDcSave = dc.SaveDC(); // get the rect of column.
CRect rc( lpDrawItemStruct->rcItem ); // set the clipping region to limit drawing within the column.
CRgn rgn;
VERIFY( rgn.CreateRectRgnIndirect( &rc ) );
(void)dc.SelectObject( &rgn ); // draw the background,
CBrush brush(GetSysColor(COLOR_3DFACE));
dc.FillRgn(&rgn,&brush);
VERIFY( rgn.DeleteObject() ); // get the column text and format.
TCHAR szText[ 256 ];
HD_ITEM hdi; hdi.mask = HDI_TEXT | HDI_FORMAT;
hdi.pszText = szText;
hdi.cchTextMax = 255; VERIFY( GetItem( lpDrawItemStruct->itemID, &hdi ) ); // determine the format for drawing the column label.
UINT uFormat = DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER | DT_END_ELLIPSIS ; if( hdi.fmt & HDF_CENTER)
uFormat |= DT_CENTER;
else if( hdi.fmt & HDF_RIGHT)
uFormat |= DT_RIGHT;
else
uFormat |= DT_LEFT; // adjust the rect if the mouse button is pressed on it.
if( lpDrawItemStruct->itemState == ODS_SELECTED )
{
rc.left++;
rc.top += 2;
rc.right++;
} CRect rcIcon( lpDrawItemStruct->rcItem );
const int iOffset = ( rcIcon.bottom - rcIcon.top ) / 4; // adjust the rect further if the sort arrow is to be displayed.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
rc.right -= 3 * iOffset; rc.left += iOffset;
rc.right -= iOffset; // draw the column label.
if( rc.left < rc.right )
(void)dc.DrawText( szText, -1, rc, uFormat ); // draw the sort arrow.
if( lpDrawItemStruct->itemID == (UINT)m_iSortColumn )
{
// set up the pens to use for drawing the arrow.
CPen penLight( PS_SOLID, 1, GetSysColor( COLOR_3DHILIGHT ) );
CPen penShadow( PS_SOLID, 1, GetSysColor( COLOR_3DSHADOW ) );
CPen* pOldPen = dc.SelectObject( &penLight ); if( m_bSortAscending )
{
// draw the triangle of arrow;
dc.MoveTo( rcIcon.right - 2 * iOffset, iOffset);
dc.LineTo( rcIcon.right - iOffset, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 3 * iOffset - 2, rcIcon.bottom - iOffset - 1 ); POINT arrUp[] = { {rcIcon.right - 2 * iOffset, iOffset},
{rcIcon.right - iOffset,rcIcon.bottom - iOffset - 1},
{rcIcon.right - 3 * iOffset - 2,rcIcon.bottom - iOffset - 1}};

VERIFY(rgn.CreatePolygonRgn(arrUp,3,WINDING));
CBrush brushUp(m_ArrowColorUp);
dc.SelectObject(&rgn);
dc.FillRgn(&rgn,&brushUp);
VERIFY(rgn.DeleteObject()); dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 3 * iOffset - 1, rcIcon.bottom - iOffset - 1 );
dc.LineTo( rcIcon.right - 2 * iOffset, iOffset - 1);

//fill the triangle with referenced color;  }
else
{
// draw the arrow pointing downwards.
dc.MoveTo( rcIcon.right - iOffset - 1, iOffset );
dc.LineTo( rcIcon.right - 2 * iOffset - 1, rcIcon.bottom - iOffset );
dc.SelectObject( &penShadow );
dc.MoveTo( rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset );
dc.LineTo(rcIcon.right - 3 * iOffset - 1, iOffset  );
dc.LineTo( rcIcon.right - iOffset - 1, iOffset );
POINT arrDown[]={{rcIcon.right - 2 * iOffset - 2, rcIcon.bottom - iOffset},
{rcIcon.right - 3 * iOffset - 1, iOffset},
{rcIcon.right - iOffset - 1, iOffset}
}; VERIFY(rgn.CreatePolygonRgn(arrDown,3,WINDING));
CBrush brushDown(m_ArrowColorDown);
dc.SelectObject(&rgn);
dc.FillRgn(&rgn,&brushDown);
VERIFY(rgn.DeleteObject());

} // restore the pen.
dc.SelectObject( pOldPen );
} // restore the previous device context.
VERIFY( dc.RestoreDC( iDcSave ) ); // detach the device context before returning.
(void)dc.Detach();