鼠标左键定位滑块
首先创建一个类继承于CSliderCtrl然后由于要根据鼠标左键定位到相应的位置,则必须要添加消息响应函数OnLButtonDown(),内容见下:
void CMySlider::OnLButtonDown(UINT nFlags, CPoint point)
{
CRect mChannel;
GetChannelRect(&mChannel); // 获得Channel(即那条线)的矩形大小
//获得所设置的范围值(这边应在初始化函数中实现设置范围)
//函数是SetRange()
int mMinRg,mMaxRg;
GetRange(mMinRg, mMaxRg);
//计算鼠标点击后的pos值
int posRate = (point.x - mChannel.left) * 100 / mChannel.Width();
int newPos = (mMaxRg - mMinRg) * posRate / 100;
//设置当前需要滑动的距离
SetPos(newPos);
CSliderCtrl::OnLButtonDown(nFlags, point);
}
自绘制滑块和滑块线(channel)
要自绘制滑块等其他控件,必须响应NM_CUSTOMDRAW消息。
控件的绘制是分为许多个不同的阶段,而且分为不同部分一部分一部分绘制的,我们必须根据需要来控制绘制的代码,函数体中的主要内容:
// 首先nmcd是一个用于绘制的结构体具体参数可查看MSDN
// 当在绘制不同的部分时,会保存不同部分的结构信息
// 因此在程序创建时,此函数会被调用多次
NMCUSTOMDRAW nmcd = *(LPNMCUSTOMDRAW)pNMHDR;
DWORD dwStage = nmcd.dwDrawStage;
DWORD itemSpec = nmcd.dwItemSpec;
switch (dwStage) // 采用switch - case结构来区分各个阶段
{
case CDDS_PREPAINT: // 在程序绘制刚开始时
// 这里如果没有对返回的值pResult赋值
// CDRF_NOTIFYITEMDRAW消息则,图像的自绘制会失败
// 程序将无法收到item的绘制消息
// 而CDRF_NOTIFYPOSTPAINT则是为了绘制channel
// 绘制循环时循环进行的
*pResult = CDRF_NOTIFYITEMDRAW | CDRF_NOTIFYPOSTPAINT;
break;
case CDDS_ITEMPREPAINT:
switch (itemSpec)
{
case TBCD_CHANNEL:
// 如果不想做操作可以赋值CDRF_DODEFAULT
*pResult = CDRF_DODEFAULT | CDRF_NOTIFYPOSTPAINT;
break;
case TBCD_THUMB:
{
CDC* pDC = CDC::FromHandle( nmcd.hdc);
pDC->SelectObject( m_Brush );
pDC->SelectObject( m_Pen );
pDC->Ellipse( &(nmcd.rc) );
pDC->Detach();
}
// 忽略默认的绘制如果没有这句
// 之前的工作就白费了
*pResult = CDRF_SKIPDEFAULT;
break;
}
break;
case CDDS_ITEMPOSTPAINT:
switch (itemSpec)
{
case TBCD_CHANNEL:
CDC* pDC = CDC::FromHandle( nmcd.hdc);
pDC->SelectObject( m_Brush );
pDC->SelectObject( m_Pen );
pDC->Rectangle( &(nmcd.rc) );
pDC->Detach();
*pResult = CDRF_SKIPDEFAULT;
break;
}
break;
default:
break;
}
}