效果:
鼠标热点(黄色):
代码下载:点击打开链接
1、首先说一下,当我们拖动滑块控件时,滑块控件的响应函数:1)当滑块是横向滑块时,为滑块父窗口的WM_HSCROLL消息添加响应函数;2)当滑块是竖向滑块时,为滑块父窗口的WM_VSCROLL消息添加响应函数。
2、自绘原理:创建一个CSliderCtrl的派生类:CMySliderCtrl;建立一个派生类类型的控件变量:CMySliderCtrl m_Slider;。
3、自绘操作是在派生类中进行,涉及到的主要函数有:
public:
BOOL m_bTrack;
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
// MySliderCtrl.cpp : 实现文件
//
#include "stdafx.h"
#include "CSliderCtrl自绘.h"
#include "MySliderCtrl.h"
// CMySliderCtrl
IMPLEMENT_DYNAMIC(CMySliderCtrl, CSliderCtrl)
CMySliderCtrl::CMySliderCtrl()
{
m_bTrack = FALSE;
}
CMySliderCtrl::~CMySliderCtrl()
{
}
BEGIN_MESSAGE_MAP(CMySliderCtrl, CSliderCtrl)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_HSCROLL()
END_MESSAGE_MAP()
// CMySliderCtrl 消息处理程序
void CMySliderCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect rcTotal,rcThumb,rcEdge;
GetClientRect(&rcTotal);
GetThumbRect(&rcThumb);
rcEdge = rcThumb;
rcEdge.InflateRect(8,2);//绘制滑块外边矩形
//以滑块为研究对象
int nLength = rcTotal.Width()-rcEdge.Width();//滑块可以移动的最大范围
//将单击的位置转换为滑块上的刻度:
int nPos,nMin,nMax;
GetRange(nMin,nMax);
nPos = point.x* (nMax - nMin)/nLength - 8 *(nMax - nMin)/nLength;
TRACE("nMax=%d,nMin=%d,nLength=%d,point.x=%d,nPos=%d\r\n",nMax,nMin,nLength,point.x,nPos);
SetPos(nPos);
m_bTrack = TRUE;
Invalidate(FALSE);
CSliderCtrl::OnLButtonDown(nFlags, point);
}
void CMySliderCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
CRect rcThumb;
GetThumbRect(&rcThumb);//获得滑块的矩形大小
m_bTrack = rcThumb.PtInRect(point);
Invalidate(FALSE);
CSliderCtrl::OnLButtonUp(nFlags, point);
}
void CMySliderCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
CRect rcThumb;
GetThumbRect(&rcThumb);//获得滑块的矩形大小
BOOL bTrack;
if (nFlags & MK_LBUTTON)
{
bTrack = TRUE;
}else{
if (rcThumb.PtInRect(point))
{
bTrack = TRUE;
}else{
bTrack = FALSE;
}
}
if (m_bTrack != bTrack)
{
m_bTrack = bTrack;
}
//TRACE("trach=%d\r\n",m_bTrack);
Invalidate(FALSE);
CSliderCtrl::OnMouseMove(nFlags, point);
}
void CMySliderCtrl::OnPaint()
{
CPaintDC dc(this);
CRect rcTotal;
GetClientRect(&rcTotal);
int nCurPos = 0,nMin = 0,nMax = 0;
nCurPos = GetPos();
GetRange(nMin,nMax);
//绘制滑过的区域
CRect rcDraw = rcTotal;
rcDraw.right = nCurPos * rcTotal.Width()/(nMax - nMin);
dc.FillSolidRect(&rcDraw,RGB(148,250,148));
//绘制剩下没滑过的区域
rcDraw.left = rcDraw.right;
rcDraw.right = rcTotal.right;
dc.FillSolidRect(&rcDraw,RGB(132,174,148));
CRect rcThumb,rcEdge;
GetThumbRect(&rcThumb);//得到滑块的位置
CBrush br;
if(m_bTrack) br.CreateSolidBrush(RGB(247,166,8));//热点颜色
else br.CreateSolidBrush(RGB(82,215,33));//非热点颜色
dc.SelectObject(&br);
CPen pen(PS_SOLID,1,RGB(0,128,0));
dc.SelectObject(&pen);
rcEdge = rcThumb;
rcEdge.InflateRect(8,2);//绘制滑块外边矩形
dc.RoundRect(&rcEdge,CPoint(10,10));
dc.FillSolidRect(&rcThumb,RGB(200,100,100));//绘制滑块
}
BOOL CMySliderCtrl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;//停止刷新背景,防止闪烁
//return CSliderCtrl::OnEraseBkgnd(pDC);
}