void CCustomDrawSliderCtrl::OnReflectedCustomDraw(NMHDR* pNMHDR, LRESULT* pResult) { // for additional info, read beginning MSDN "Customizing a Control's Appearance Using Custom Draw" at // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/custdraw/custdraw.asp // slider controls (which are actually called "trackbar" controls) are specifically discussed at // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/trackbar/notifications/nm_customdraw_trackbar.asp
case CDDS_PREERASE: // Before the erase cycle begins case CDDS_POSTERASE: // After the erase cycle is complete case CDDS_ITEMPREERASE: // Before an item is erased case CDDS_ITEMPOSTERASE: // After an item has been erased
// these are not handled now, but you might like to do so in the future
*pResult = CDRF_DODEFAULT; break;
case CDDS_ITEMPREPAINT: // Before an item is drawn
// this is where we perform our item-specific custom drawing switch ( itemSpec ) { case TBCD_CHANNEL: *pResult = CDRF_DODEFAULT| CDRF_NOTIFYPOSTPAINT; break; case TBCD_TICS: *pResult = CDRF_DODEFAULT; break;
int xx, yy, dx, dy, cx, cy; xx = nmcd.rc.left; yy = nmcd.rc.top; dx = 2; dy = 2; cx = nmcd.rc.right - xx - 1; cy = nmcd.rc.bottom - yy - 1; POINT pts[8] = { {xx+dx, yy}, {xx, yy+dy}, {xx, yy+cy-dy}, {xx+dx, yy+cy}, {xx+cx-dx, yy+cy}, {xx+cx, yy+cy-dy}, {xx+cx, yy+dy}, {xx+cx-dx, yy} }; pDC->Polygon( pts, 8 ); pDC->RestoreDC( iSaveDC ); pDC->Detach(); } *pResult = CDRF_SKIPDEFAULT; // don't let control draw itself, or it will un-do our work break;
default: ASSERT( FALSE ); // all of a slider's items have been listed, so we shouldn't get here };
break; case CDDS_ITEMPOSTPAINT: // After an item has been drawn switch ( itemSpec ) { case TBCD_CHANNEL: // channel that the trackbar control's thumb er slides along // For the item-post-paint of the channel, we basically like what the control has drawn, // which is a four-line high rectangle whose colors (in order) are white, mid-gray, black, // and dark-gray. // However, to emphasize the control's color, we will replace the middle two lines // (i.e., the mid-gray and black lines) with hilite and shadow colors of the control // using CDC::Draw3DRect. { CDC* pDC = CDC::FromHandle( nmcd.hdc ); RECT rrc = {nmcd.rc.left+1, nmcd.rc.top+1, nmcd.rc.right-1, nmcd.rc.bottom-1}; pDC->Draw3dRect( &rrc, m_crMidShadow, m_crHilite ); pDC->Detach(); } *pResult = CDRF_SKIPDEFAULT; break; case TBCD_TICS: // the increment tick s that appear along the edge of the trackbar control // currently, there is no special post-item-paint drawing of the tics *pResult = CDRF_DODEFAULT; break;
case TBCD_THUMB: // trackbar control's thumb er. This is the portion of the control that the user moves // currently, there is no special post-item-paint drawing for the thumb
*pResult = CDRF_DODEFAULT ; // don't let control draw itself, or it will un-do our work break;
default: ASSERT( FALSE ); // all of a slider's items have been listed, so we shouldn't get here }; break; case CDDS_POSTPAINT: // After the paint cycle is complete // this is the post-paint for the entire control, and it's possible to add to whatever is // now visible on the control // To emphasize the directivity of the control, we simply draw in two colored dots at the // extreme edges of the control {
{
// for additional info, read beginning MSDN "Customizing a Control's Appearance Using Custom Draw" at
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/custdraw/custdraw.asp
// slider controls (which are actually called "trackbar" controls) are specifically discussed at
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/trackbar/notifications/nm_customdraw_trackbar.asp
NMCUSTOMDRAW nmcd = *(LPNMCUSTOMDRAW)pNMHDR;
UINT drawStage = nmcd.dwDrawStage;
UINT itemSpec = nmcd.dwItemSpec;
switch ( drawStage )
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT ;
break;
case CDDS_PREERASE: // Before the erase cycle begins
case CDDS_POSTERASE: // After the erase cycle is complete
case CDDS_ITEMPREERASE: // Before an item is erased
case CDDS_ITEMPOSTERASE: // After an item has been erased
// these are not handled now, but you might like to do so in the future
*pResult = CDRF_DODEFAULT;
break;
case CDDS_ITEMPREPAINT: // Before an item is drawn
// this is where we perform our item-specific custom drawing
switch ( itemSpec )
{
case TBCD_CHANNEL: *pResult = CDRF_DODEFAULT| CDRF_NOTIFYPOSTPAINT;
break; case TBCD_TICS: *pResult = CDRF_DODEFAULT;
break;
case TBCD_THUMB:
{
CDC* pDC = CDC::FromHandle( nmcd.hdc );
int iSaveDC = pDC->SaveDC();
CBrush* pB = &m_normalBrush;
CPen pen( PS_SOLID, 1, m_crShadow );
// if thumb is selected/focussed, switch brushes
if ( nmcd.uItemState && CDIS_FOCUS )
{
pB = &m_focusBrush;
pDC->SetBrushOrg( nmcd.rc.right%8, nmcd.rc.top%8 );
pDC->SetBkColor( m_crPrimary );
pDC->SetTextColor( m_crHilite );
}
pDC->SelectObject( pB );
pDC->SelectObject( &pen ); pDC->Ellipse( &(nmcd.rc) );
int xx, yy, dx, dy, cx, cy;
xx = nmcd.rc.left;
yy = nmcd.rc.top;
dx = 2;
dy = 2;
cx = nmcd.rc.right - xx - 1;
cy = nmcd.rc.bottom - yy - 1;
POINT pts[8] = { {xx+dx, yy}, {xx, yy+dy}, {xx, yy+cy-dy}, {xx+dx, yy+cy},
{xx+cx-dx, yy+cy}, {xx+cx, yy+cy-dy}, {xx+cx, yy+dy}, {xx+cx-dx, yy} }; pDC->Polygon( pts, 8 ); pDC->RestoreDC( iSaveDC );
pDC->Detach();
}
*pResult = CDRF_SKIPDEFAULT; // don't let control draw itself, or it will un-do our work
break;
default:
ASSERT( FALSE ); // all of a slider's items have been listed, so we shouldn't get here
};
break; case CDDS_ITEMPOSTPAINT: // After an item has been drawn switch ( itemSpec )
{
case TBCD_CHANNEL: // channel that the trackbar control's thumb er slides along
// For the item-post-paint of the channel, we basically like what the control has drawn,
// which is a four-line high rectangle whose colors (in order) are white, mid-gray, black,
// and dark-gray.
// However, to emphasize the control's color, we will replace the middle two lines
// (i.e., the mid-gray and black lines) with hilite and shadow colors of the control
// using CDC::Draw3DRect.
{
CDC* pDC = CDC::FromHandle( nmcd.hdc ); RECT rrc = {nmcd.rc.left+1, nmcd.rc.top+1, nmcd.rc.right-1, nmcd.rc.bottom-1};
pDC->Draw3dRect( &rrc, m_crMidShadow, m_crHilite );
pDC->Detach();
}
*pResult = CDRF_SKIPDEFAULT;
break; case TBCD_TICS: // the increment tick s that appear along the edge of the trackbar control
// currently, there is no special post-item-paint drawing of the tics *pResult = CDRF_DODEFAULT;
break;
case TBCD_THUMB: // trackbar control's thumb er. This is the portion of the control that the user moves
// currently, there is no special post-item-paint drawing for the thumb
*pResult = CDRF_DODEFAULT ; // don't let control draw itself, or it will un-do our work
break;
default:
ASSERT( FALSE ); // all of a slider's items have been listed, so we shouldn't get here
}; break; case CDDS_POSTPAINT: // After the paint cycle is complete
// this is the post-paint for the entire control, and it's possible to add to whatever is
// now visible on the control
// To emphasize the directivity of the control, we simply draw in two colored dots at the
// extreme edges of the control
{
CDC* pDC = CDC::FromHandle( nmcd.hdc ); CBrush bWhite( RGB(255, 255, 255) ); // white brush
CBrush bDark( m_crDarkerShadow ); // dark but still colored brush
CPen p(PS_SOLID, 1, m_crPrimary); CRect rClient;
GetClientRect( &rClient );
DWORD dwStyle = GetStyle();
int cx = 8;
CRect rrcFirst;( 1, 1, cx, cx );
CRect rrcLast; // TBS_RIGHT, TBS_BOTTOM and TBS_HORZ are all defined as 0x0000, so avoid testing on them if ( dwStyle & TBS_VERT )
{
if ( dwStyle & TBS_LEFT )
{
rrcFirst = CRect( rClient.right-cx, 1, rClient.right-1, cx );
rrcLast = CRect( rClient.right-cx, rClient.bottom-cx, rClient.right-1, rClient.bottom-1 );
}
else
{
rrcFirst = CRect( 1, 1, cx, cx );
rrcLast = CRect( 1, rClient.bottom-cx, cx, rClient.bottom-1 );
}
}
else
{
if ( dwStyle & TBS_TOP )
{
rrcFirst = CRect( 1, rClient.bottom-cx, cx, rClient.bottom-1 );
rrcLast = CRect( rClient.right-cx, rClient.bottom-cx, rClient.right-1, rClient.bottom-1 );
}
else
{
rrcFirst = CRect( 1, 1, cx, cx );
rrcLast = CRect( rClient.right-cx, 1, rClient.right-1, cx );
}
}
int iSave = pDC->SaveDC();
pDC->SelectObject( &bWhite );
pDC->SelectObject( &p );
pDC->Ellipse( &rrcFirst );
pDC->SelectObject( &bDark );
pDC->Ellipse( &rrcLast );
pDC->RestoreDC( iSave ); pDC->Detach();
} *pResult = CDRF_SKIPDEFAULT;
break;
default:
ASSERT( FALSE ); // all drawing stages are listed, so we shouldn't get here
};
}