CSliderCtrl 重写

//d4.sina.com.cn/pfpghc2/201701/12/99103c2257c64b74b2274c34d07b6a06.png

CSliderCtrl 重写


 原文 http://blog.sina.com.cn/s/blog_4cf67a310101axiq.html


CProSliderCtrl.h

#pragma once

#define WM_FREEZE WM_USER+0xF003
// CProSliderCtrl

class CProSliderCtrl : public CSliderCtrl
{
 DECLARE_DYNAMIC(CProSliderCtrl)
public: // Progress Control functions
 // Gets the current lower and upper limits, orrange, of the progress bar control.
 void _GetRange(int& nLower,int& nUpper);
 // Sets the upper and lower limits of theprogress bar control's range and redraws the bar to reflect the newranges.
 void _SetRange(short nLower, short nUpper);
 // Sets the upper and lower limits of theprogress bar control's range and redraws the bar to reflect the newranges.
 void _SetRange32(int nLower, int nUpper);
 // Sets the background color for the progressbar.
 COLORREF _SetBkColor(COLORREF clrNew);
 // Sets the thumb color
 COLORREF _SetThumbColor(COLORREF clrNew);
 // Sets the channel color
 COLORREF _SetChColor(COLORREF clrNew);
 // Gets the current position of the progressbar.
 int _GetPos(void);
 // Advances the current position of a progressbar control by a specified increment and redraws the bar to reflectthe new position.
 int _OffsetPos(int nPos);
 // Sets the current position for a progress barcontrol and redraws the bar to reflect the new position.
 int _SetPos(int nPos);
 // Specifies the step increment for a progressbar control.
 int _SetStep(int nStep);
 // Advances the current position for a progressbar control by the step increment and redraws the bar to reflectthe new position.
 int _StepIt(void);
 // De/Freezes the slider and returns the prev.state
 BOOL Freeze(void);
 // Enables/Disables borders
 HRESULT _EnableBorders(BOOL bEnable=TRUE);
 BOOL _IsEnabled(void);
public:
 CProSliderCtrl();
 virtual ~CProSliderCtrl();
protected:
 DECLARE_MESSAGE_MAP()
 // General Purpose Draw Function
 void Draw(LPNMCUSTOMDRAW pNMCD);
 void RecursiveRect(CDC *pDC, CRect rc, COLORREFnClr, BOOL First=FALSE);
 void RecursiveChannel(CDC *pDC, CRect rc,COLORREF nClr,
  BOOL First=FALSE, BOOLVertical=FALSE,BYTE StepSize=20);
protected: // Progress Control variables
 // Progress bar background color
 COLORREF m_ProBkColor;
 // Progress bar color;
 COLORREF m_ProgressBarColor;
 // Progress bar ranges
 PBRANGE m_ProRange; 
 // Progress bar position
 int m_ProgressPos;
 // Step increment for Progress control
 int m_ProgressStep;
 // Direction, V/H
 DWORD m_Direction;
 // Thumb Color when mouse is over
 COLORREF m_ThClOver;
 // Thumb Color when mouse is out
 COLORREF m_ThClOut;
 // Thumb Color when mouse is pressed
 COLORREF m_ThClPre;
 // Thumb Default Color
 COLORREF m_ThClDef;
 // Borders
 BOOL m_bBorders;
 // Slider Freezed?
 BOOL m_bFreezed;
 // Temproray color storages
 COLORREF tmp1,tmp2;
 BOOL m_bBlink;
public:
 afx_msg void OnNMCustomdraw(NMHDR *pNMHDR,LRESULT *pResult);
protected:
 // Draws the slider thumb
 HRESULT DrawSliderThumb(LPNMCUSTOMDRAWpNMCD);
 HRESULT DrawSliderBorder(LPNMCUSTOMDRAWpNMCD);
 HRESULT DrawSliderChannel(LPNMCUSTOMDRAWpNMCD);
 void SetThumbColor(COLORREF nClr);
public:
 afx_msg void OnMouseMove(UINT nFlags, CPointpoint);
 afx_msg void OnTimer(UINT nIDEvent);
 afx_msg void OnLButtonDown(UINT nFlags, CPointpoint);
};

 

CProSliderCtrl.cpp

#include "stdafx.h"
//#include "ProSlider.h"
#include "ProSliderCtrl.h"

IMPLEMENT_DYNAMIC(CProSliderCtrl, CSliderCtrl)
CProSliderCtrl::CProSliderCtrl()
: m_ProBkColor(RGB(51,51,51)),
m_ThClOver(RGB(255,102,0)),
m_ThClOut(RGB(0,204,0)),
m_ThClPre(RGB(153,102,204)),
m_ProgressBarColor(RGB(102,102,204)),
m_ThClDef(m_ThClOut),
m_ProgressStep(10),
m_bBorders(TRUE)
{
 m_bFreezed = FALSE;
 m_bBlink = FALSE;
}

CProSliderCtrl::~CProSliderCtrl()
{

}


BEGIN_MESSAGE_MAP(CProSliderCtrl, CSliderCtrl)
 ON_NOTIFY_REFLECT(NM_CUSTOMDRAW,OnNMCustomdraw)
 ON_WM_MOUSEMOVE()
 ON_WM_TIMER()
 ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

 

// CProSliderCtrl message handlers

// Custom control drawing operations
void CProSliderCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT*pResult)
{
 LPNMCUSTOMDRAW pNMCD =reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
 switch(pNMCD->dwDrawStage)
 {
 case CDDS_POSTERASE: // Afterthe erasing cycle is complete.
  *pResult =CDRF_SKIPDEFAULT;
  break;
 case CDDS_POSTPAINT: // Afterthe painting cycle is complete.
  *pResult =CDRF_DODEFAULT;
  break;
 caseCDDS_PREERASE:  // Before theerasing cycle begins.
  *pResult =CDRF_SKIPDEFAULT;
  break;
 caseCDDS_PREPAINT:  // Before thepainting cycle begins.
  *pResult =CDRF_NOTIFYITEMDRAW;
  break;
 case CDDS_ITEMPREPAINT: //Before an item is drawn.
  switch(pNMCD->dwItemSpec)
  {
  // Identifies the channel thatthe slider control's thumb marker slides along.
  caseTBCD_CHANNEL: 
   if(m_bBorders)DrawSliderBorder(pNMCD);
   DrawSliderChannel(pNMCD);
   *pResult =CDRF_SKIPDEFAULT;
   break;
  // Identifies the incrementtick marks that appear along the edge of the slider control.
  caseTBCD_TICS: 
   *pResult =CDRF_DODEFAULT;
   break;
  // Identifies the slidercontrol's thumb marker. This is the portion of
  // the control that the usermoves.
  case TBCD_THUMB:
   if(DrawSliderThumb(pNMCD)==S_OK)
    *pResult= CDRF_SKIPDEFAULT;
   else
    *pResult= CDRF_DODEFAULT;
   break;
  default:
   *pResult =CDRF_DODEFAULT;
   break;
  }
  break;
 default:
  *pResult =CDRF_DODEFAULT;
  break;
 }
}

// Gets the lower and upper limits of the range of the progressbar control.
void CProSliderCtrl::_GetRange(int& nLower,int& nUpper)
{
 nLower = m_ProRange.iLow;
 nUpper = m_ProRange.iHigh;
 return;
}
// Sets the minimum and maximum ranges for a progress bar
// control and redraws the bar to reflect the new ranges.
void CProSliderCtrl::_SetRange(short nLower, short nUpper)
{
 m_ProRange.iLow = nLower;
 m_ProRange.iHigh = nUpper;
 return;
}
//Sets the minimum and maximum ranges for a progress bar controland
// redraws the bar to reflect the new ranges.
void CProSliderCtrl::_SetRange32(int nLower, int nUpper)
{
 m_ProRange.iLow = nLower;
 m_ProRange.iHigh = nUpper;
 return;
}
// Sets the background color for the progress bar. (bordercolor)
COLORREF CProSliderCtrl::_SetBkColor(COLORREF clrNew)
{
    COLORREFm_tmp = m_ProBkColor;
 m_ProBkColor = clrNew;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return m_tmp;
}
// Sets the thumb color for the slider control.
COLORREF CProSliderCtrl::_SetThumbColor(COLORREF clrNew)
{
    COLORREFm_tmp = m_ThClDef;
 m_ThClDef = clrNew;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return m_tmp;
}

// Sets the progress bar color.
COLORREF CProSliderCtrl::_SetChColor(COLORREF clrNew)
{
    COLORREFm_tmp = m_ProgressBarColor;
 m_ProgressBarColor = clrNew;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return m_tmp;
}

// Gets the current position of the progress bar.
int CProSliderCtrl::_GetPos(void)
{
 return (m_ProgressPos);
}
// Advances the current position of a progress bar control by aspecified
// increment and redraws the bar to reflect the new position.
int CProSliderCtrl::_OffsetPos(int nPos)
{
 int curr = m_ProgressPos;
 m_ProgressPos+= nPos;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return(curr);
}
// Sets the current position for a progress bar control and redrawsthe bar
// to reflect the new position.
int CProSliderCtrl::_SetPos(int nPos)
{
    int curr =m_ProgressPos;
 m_ProgressPos = nPos;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return(curr);
}
// Specifies the step increment for a progress bar control.
int CProSliderCtrl::_SetStep(int nStep)
{
 int curr = m_ProgressStep;
 m_ProgressStep = nStep;
 return curr;
}

// Advances the current position for a progress bar controlby
// the step increment and redraws the bar to reflect the newposition.
int CProSliderCtrl::_StepIt(void)

 int curr = m_ProgressPos;
 int min,max;
 GetRange(min,max);
 m_ProgressPos+m_ProgressStep>=max?m_ProgressPos+=m_ProgressStep-max:m_ProgressPos+=m_ProgressStep;
 CSliderCtrl::SetRange(min,max,TRUE);
 return(curr);
}

// Draws the slider window border, internal use only, cannot beaccessible
HRESULT CProSliderCtrl::DrawSliderBorder(LPNMCUSTOMDRAWpNMCD)
{
 RECT border;
 GetClientRect(&border);
 CDC *pDC =CDC::FromHandle(pNMCD->hdc);
 RecursiveChannel(pDC,border,m_ProBkColor,TRUE,FALSE,5);
 return S_OK;
}

// Draws the Progress bar, internal use only, cannot beaccessible
HRESULT CProSliderCtrl::DrawSliderChannel(LPNMCUSTOMDRAWpNMCD)
{
 CRect crect;
 double rr;
 CDC *pDC =CDC::FromHandle(pNMCD->hdc);
 crect.CopyRect(&pNMCD->rc);
 BOOL Vert=FALSE;
 if(crect.Height()>crect.Width())Vert=TRUE;
 switch(Vert)
 {
 case TRUE:
  crect.InflateRect(5, 0, 5,0);
  DrawEdge(pNMCD->hdc,&crect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  crect.InflateRect(1, 0, 1,0);
  if(m_ProRange.iHigh!=0)
  {
   rr=(crect.Height()*m_ProgressPos)/m_ProRange.iHigh;
   crect.bottom=(LONG)rr+9;
  } else crect.bottom=9;
  crect.top = 9;
  RecursiveChannel(pDC,crect,m_ProgressBarColor,TRUE,TRUE);
  break;
 case FALSE:
  crect.InflateRect(0, 5, 0,5);
  DrawEdge(pNMCD->hdc,&crect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  crect.InflateRect(0, 1, 0,1);
       if(m_ProRange.iHigh!=0)
  {
   rr=(crect.Width()*m_ProgressPos)/m_ProRange.iHigh;
   crect.right=(LONG)rr+9;
  } else crect.right=9;
  crect.left = 9;
  RecursiveChannel(pDC,crect,m_ProgressBarColor,TRUE);
  break;
 }
 return S_OK;
}

// Recursive channel drawer used to generate pastel colors
__inline void CProSliderCtrl::RecursiveChannel(CDC *pDC,
             CRect rc, COLORREF nClr,
             BOOL First,
             BOOL Vertical,
             BYTE StepSize)
{
 CBrush Brush;
 Brush.CreateSolidBrush(nClr);
 HGDIOBJ old =pDC->SelectObject(Brush);
 CPen Pen;
 Pen.CreatePen(PS_SOLID,1,nClr);
 CPen* pOldPen =pDC->SelectObject(&Pen); 
 pDC->RoundRect(rc,CPoint(2,2));
 First?rc.DeflateRect(1,1):Vertical?rc.DeflateRect(1,0):rc.DeflateRect(0,1);
 BYTE r,g,b;
 r = GetRValue(nClr);
 g = GetGValue(nClr);
 b = GetBValue(nClr);
 StepSize+r>=255?r=255:r=StepSize+r; //r+=Stepsize gives warning C4244
 StepSize+g>=255?g=255:g=StepSize+g;
 StepSize+b>=255?b=255:b=StepSize+b;
 if(!rc.IsRectEmpty())RecursiveRect(pDC,rc,RGB(r,g,b));
 pDC->SelectObject(old);
 pDC->SelectObject(pOldPen);
 ::DeleteObject(Brush);
 ::DeleteObject(Pen);
}

// Recursive slider thumb drawer used to generate pastelcolors
HRESULT CProSliderCtrl::DrawSliderThumb(LPNMCUSTOMDRAW pNMCD)
{
 if(pNMCD->uItemState& CDIS_SELECTED)
  this->m_ThClDef= this->m_ThClPre;
 Draw(pNMCD);
 return S_OK;
}

// internal use only
__inline void CProSliderCtrl::Draw(LPNMCUSTOMDRAW pNMCD)
{
 CDC *pDC =CDC::FromHandle(pNMCD->hdc);
 RecursiveRect(pDC,&pNMCD->rc,m_ThClDef,TRUE);
 return;
}

// Used by the Draw function.
__inline void CProSliderCtrl::RecursiveRect(CDC *pDC, CRect rc,COLORREF nClr, BOOL First)
{
 CBrush Brush;
 Brush.CreateSolidBrush(nClr);
 HGDIOBJ old =pDC->SelectObject(Brush);
 CPen Pen;
 Pen.CreatePen(PS_SOLID,1,nClr);
 CPen* pOldPen =pDC->SelectObject(&Pen); 
 pDC->RoundRect(rc,CPoint(2,2));
 First?rc.DeflateRect(1,1):this->GetStyle()&TBS_VERT?rc.DeflateRect(1,0):rc.DeflateRect(0,1);
 BYTE r,g,b;
 r = GetRValue(nClr);
 g = GetGValue(nClr);
 b = GetBValue(nClr);
 if(r<=245) r+=10;
 if(g<=245) g+=10;
 if(b<=245) b+=10;
 if(!rc.IsRectEmpty())RecursiveRect(pDC,rc,RGB(r,g,b));
 pDC->SelectObject(old);
 pDC->SelectObject(pOldPen);
 ::DeleteObject(Brush);
 ::DeleteObject(Pen);
}

// Catches the mouse movements and sets the Thumb colors
void CProSliderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
 CRect tRect;
 GetThumbRect(&tRect);
 tRect.InflateRect(2,-2,2,-2);
 if(tRect.PtInRect(point))
 {
  SetThumbColor(m_ThClOver);
 }else
 {
  SetThumbColor(m_ThClOut);
 }
 CSliderCtrl::OnMouseMove(nFlags, point);
}

// Sets the thumb color and redraws the thumb
void CProSliderCtrl::SetThumbColor(COLORREF nClr)
{
 this->m_ThClDef = nClr;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
}

// Enables/Disables window borders
HRESULT CProSliderCtrl::_EnableBorders(BOOL bEnable)
{
 m_bBorders = bEnable;
 int min,max;
 GetRange(min,max);
 CSliderCtrl::SetRange(min,max,TRUE);
 return S_OK;
}

// Test if the borders are enabled or not
BOOL CProSliderCtrl::_IsEnabled(void)
{
 return m_bBorders;
}

// Used to freeze the slider bar, i.e. not controlable when bythe user
// and thumb and the border starts blinking
BOOL CProSliderCtrl::Freeze(void)

 BOOL Prev= m_bFreezed;
 if(!Prev) // Freeze now
 {
  tmp1 = m_ThClDef;
  tmp2 = m_ProBkColor;
  SetTimer(WM_FREEZE,1000,NULL);
  m_bFreezed = TRUE;

 }else
 {
  KillTimer(WM_FREEZE);
  m_bFreezed = FALSE;
  m_ThClDef = tmp1;
  m_ProBkColor = tmp2;
  int min,max;
  GetRange(min,max);
  CSliderCtrl::SetRange(min,max,TRUE);
 }
 return Prev;
}

// used for freezing operation
void CProSliderCtrl::OnTimer(UINT nIDEvent)
{
 int min,max;
 if(m_bBlink)
  {
   m_ThClDef =RGB(102,102,204);
   m_bBlink =FALSE;
   m_ProBkColor= RGB(102,102,204);
   GetRange(min,max);
   CSliderCtrl::SetRange(min,max,TRUE);
   
  } else
  {
   m_ThClDef =RGB(204,204,204);
   m_ProBkColor= RGB(204,204,204);
   GetRange(min,max);
   CSliderCtrl::SetRange(min,max,TRUE);   
   m_bBlink =TRUE;   
  }
 CSliderCtrl::OnTimer(nIDEvent);
}


void CProSliderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
 if(m_bFreezed) return; else
 CSliderCtrl::OnLButtonDown(nFlags, point);
}

 

调用//

//CDemo2Dlg.h

CProSliderCtrl m_SliderCtrl;

 

//CDemo2Dlg.cpp

DDX_Control(pDX, IDC_SLIDER1, m_SliderCtrl);

 

BOOL CDemo2Dlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT*pResult)
{
 // TODO:在此添加专用代码和/或调用基类
 NMHDR *pParam =reinterpret_cast<NMHDR*>(lParam);
 if(pParam->hwndFrom ==m_SliderCtrl.m_hWnd)
 {
  TCHAR strNum[256];
  sprintf(strNum,"%d%%",m_SliderCtrl.GetPos(););
  SetDlgItemText(IDC_EDIT1,strNum);
 }

 return CDialog::OnNotify(wParam, lParam,pResult);
}

幻灯播放
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值