📄 roundsliderctrl.cpp
字号:
m_bDragChanged = true;
PostMessageToParent(TB_THUMBTRACK);
RedrawWindow();
}
}
else
{
CSliderCtrl::OnMouseMove(nFlags, point);
}
}
// 说 明:松开鼠标左键的处理函数
// 关于该函数更加详细的说明,请参见MSDN
//
void CRoundSliderCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_bDragging)
{
m_bDragging = false;
::ReleaseCapture();
if(SetKnob(point))
{
PostMessageToParent(TB_THUMBTRACK);
m_bDragChanged = true;
}
if(m_bDragChanged)
{
PostMessageToParent(TB_THUMBPOSITION);
m_bDragChanged = false;
}
RedrawWindow();
}
else
{
CSliderCtrl::OnLButtonUp(nFlags, point);
}
}
// 说 明: 鼠标消息处理
// 关于该函数更加详细的说明,请参见MSDN
//
BOOL CRoundSliderCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
BOOL bResult = TRUE;
ScreenToClient(&pt);
if(ChildWindowFromPoint(pt) == this)
{
bResult = CSliderCtrl::OnMouseWheel(nFlags, zDelta, pt);
RedrawWindow();
}
return bResult;
}
// 返回值:如果指针位置可以改变,返回非零置;否则为零
// 参 数:
// pt 当前的鼠标位置
// 说 明:计算当前鼠标位置相对应的滑块位置,并设置它
//
bool CRoundSliderCtrl::SetKnob(const CPoint& pt)
{
const int nMin = GetRangeMin();
const int nMax = GetRangeMax()+1;
CSize szDelta = pt - m_ptCenter;
if(m_bInverted) szDelta.cx *= -1;
double dNewPos = 0.0;
if(szDelta.cx != 0)
{
dNewPos = 90.0 - atan(-(double)szDelta.cy / (double)szDelta.cx) * 180.0 / pi;
}
if(((szDelta.cx == 0) && (szDelta.cy >= 0)) || (szDelta.cx < 0))
{
dNewPos += 180.0;
}
dNewPos -= m_nZero;
while(dNewPos < 0.0) dNewPos += 360.0;
while(dNewPos >= 360.0) dNewPos -= 360.0;
const int nNewPos = nMin + (int)(dNewPos*(nMax-nMin)/360.0);
const bool bChanged = (nNewPos != GetPos());
if(bChanged)
{
int nMax, nMin;
GetRange( nMin, nMax );
if( nNewPos <= nMax )
{
//根据鼠标的点击,在这里进行微调
int nOldPos = GetPos();
if( nNewPos > nOldPos )
SetPos( nOldPos + 1 );
else
SetPos( nOldPos - 1 );
}
else
{
//坐标点大于应设置点时的微调
int nOldPos = GetPos();
int nMiddle = (int)( nMax * 0.3 );
int nNowPos = nOldPos;
if( ( nNewPos - nMax ) > ( nMiddle / 2 ) )
nNowPos--;
else
nNowPos++;
nNowPos = nNowPos > nMax ? nMax : nNowPos;
SetPos( nNowPos );
}
}
return bChanged;
}
// 说 明:键盘按下时的处理过程
// 关于该函数更加详细的说明,请参见MSDN
//
void CRoundSliderCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
const int nMin = GetRangeMin();
const int nMax = GetRangeMax()+1;
switch(nChar)
{
case VK_LEFT:
case VK_UP:
{
int nNewPos = GetPos()-GetLineSize();
while(nNewPos < nMin) nNewPos += (nMax - nMin);
SetPos(nNewPos);
RedrawWindow();
PostMessageToParent(TB_LINEUP);
}
break;
case VK_RIGHT:
case VK_DOWN:
{
int nNewPos = GetPos()+GetLineSize();
while(nNewPos >= nMax) nNewPos -= (nMax - nMin);
SetPos(nNewPos);
RedrawWindow();
PostMessageToParent(TB_LINEDOWN);
}
break;
case VK_PRIOR:
{
int nNewPos = GetPos()-GetPageSize();
while(nNewPos < nMin) nNewPos += (nMax - nMin);
SetPos(nNewPos);
RedrawWindow();
PostMessageToParent(TB_PAGEUP);
}
break;
case VK_NEXT:
{
int nNewPos = GetPos()+GetPageSize();
while(nNewPos >= nMax) nNewPos -= (nMax - nMin);
SetPos(nNewPos);
RedrawWindow();
PostMessageToParent(TB_PAGEDOWN);
}
break;
case VK_HOME:
case VK_END:
// Do nothing (ignore keystroke)
break;
default:
CSliderCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}
}
// 说 明:字符键按下时的处理过程
// 关于该函数更加详细的说明,请参见MSDN
//
void CRoundSliderCtrl::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_LEFT:
case VK_UP:
case VK_RIGHT:
case VK_DOWN:
case VK_PRIOR:
case VK_NEXT:
PostMessageToParent(TB_ENDTRACK);
break;
case VK_HOME:
case VK_END:
// Do nothing
break;
default:
CSliderCtrl::OnKeyUp(nChar, nRepCnt, nFlags);
}
}
// 说 明:消息的处理过程,向客户区发送滑块滚动后的消息已经参数
//
void CRoundSliderCtrl::PostMessageToParent(const int nTBCode) const
{
CWnd* pWnd = GetParent();
if(pWnd) pWnd->PostMessage(WM_HSCROLL, (WPARAM)((GetPos() << 16) | nTBCode), (LPARAM)GetSafeHwnd());
}
// 说 明:重新恢复并且创建字体
//
void CRoundSliderCtrl::ReconstructFont()
{
m_font.DeleteObject();
const BOOL bCreated = m_font.CreateFontIndirect(&m_lf);
ASSERT(bCreated);
}
// 说 明:需要设置鼠标指针时调用
//
BOOL CRoundSliderCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
::SetCursor( m_hcCross );
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////
///////////////////// 公共接口函数 //////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// 参 数:
// nMin 滑块范围的最小值
// nMax 滑块范围的最大值
// bRedraw 指示是否立即重绘控件
// 说 明:调用该函数设置整个控件的可调整范围,更详细的资料请参见
// MSDN 中关于 CSliderCtrl::SetRange 的说明
//
void CRoundSliderCtrl::SetRange( int nMin, int nMax, BOOL bRedraw )
{
m_nMax = nMax;
m_nMin = nMin;
//计算应该的滑块范围大小
nMax = (int)( nMax + ( nMax * 0.3 ) );
CSliderCtrl::SetRange( nMin, nMax, bRedraw );
}
// 参 数:
// nMin 获得的控件范围最小值
// nMax 获得的控件范围最大值
// 说 明: 调用函数来得到当前滑块控件的可调节 最大/最小 值
//
void CRoundSliderCtrl::GetRange( int &nMin, int &nMax )
{
nMin = m_nMin;
nMax = m_nMax;
}
// 参 数:
// strNewText CString 对象类型的字符串
// 说 明: 调用该函数来为圆形控件内设置字符。在允许控件显示字符时,
// 如果不调用此函数,那么系统将默认在控件内部显示滑块当前的位置值
//
void CRoundSliderCtrl::SetText(const CString& strNewText)
{
m_strText = strNewText;
}
// 返回值:返回当前控件内显示字体的内容
// 说 明:调用此函数来得到当前控件内的字符串
//
CString CRoundSliderCtrl::GetText() const
{
return m_strText;
}
// 参 数:
// nNewKnobRadius 涉及指针大小的整型变量,该值最小不能小于5
// 说 明:设置指针的大小
//
void CRoundSliderCtrl::SetKnobRadius(const int nNewKnobRadius)
{
ASSERT(nNewKnobRadius > 4);
m_nKnobRadius = nNewKnobRadius;
}
// 返回值: 返回当前的指针大小
// 说 明: 得到指针的大小
//
int CRoundSliderCtrl::GetKnobRadius() const
{
return m_nKnobRadius;
}
// 参 数:
// bDragByKnobOnly 如果此值为真,那么只有当鼠标指针在此控件
// 指针之上拖动时,控件指针才进行拖动
// 说 明:指示是否应该仅让指针根着鼠标走
//
void CRoundSliderCtrl::SetDragByKnobOnly(const bool bDragByKnobOnly)
{
m_bDragByKnobOnly = bDragByKnobOnly;
}
// 返回值:如果为真,那么只有当鼠标指针在此控件
// 指针之上拖动时,控件指针才进行拖动
// 说 明:确定是否应该仅让指针根着鼠标走
//
bool CRoundSliderCtrl::GetDragByKnobOnly() const
{
return m_bDragByKnobOnly;
}
// 参 数:nZero 控件初始化的角度值,该值应该是不小于0和大于360
// 说 明:指定开始时指针默认的角度
//
void CRoundSliderCtrl::SetZero(const int nZero)
{
ASSERT(nZero >= 0 && nZero < 360);
m_nZero = nZero;
}
// 返回值:0 - 360 的控件初始角度值
// 说 明:得到开始时指针默认的角度
//
int CRoundSliderCtrl::GetZero() const
{
return m_nZero;
}
//准备废弃
void CRoundSliderCtrl::SetInverted(const bool bNewInverted)
{
m_bInverted = bNewInverted;
}
//准备废弃
bool CRoundSliderCtrl::GetInverted() const
{
return m_bInverted;
}
// 参 数:
// crBkgnd 滑块控件背景颜色值,可以是RGB 三色中的任何一种
// 说 明:调用此函数来设置滑块控件的背景颜色;注意:该函数只能
// 在未调用 SetBitmap 时起作用。
//
void CRoundSliderCtrl::SetDialColor(const COLORREF crBkgnd)
{
if(m_hDialBrush) ::DeleteObject(m_hDialBrush);
m_hDialBrush = ::CreateSolidBrush(crBkgnd);
}
// 参 数:
// crBkgnd 指针在鼠标左键未按下时的颜色
// 说 明:调用此函数可以设置指针在鼠标左键未按下时的颜色,系统默认
// 情况下是将指针颜色置为系统COLOR_3DFACE颜色
//
void CRoundSliderCtrl::SetKnobColor(const COLORREF crBkgnd)
{
if(m_hKnobBrush) ::DeleteObject(m_hKnobBrush);
m_hKnobBrush = ::CreateSolidBrush(crBkgnd);
}
// 参 数:
// crBkgnd 指针在鼠标左键按下激活时的颜色
// 说 明:调用此函数可以设置指针在鼠标左键按下激活或者拖动时的颜色,系统默认
// 情况下是将指针颜色置为系统COLOR_3DFACE颜色
//
void CRoundSliderCtrl::SetActiveKnobColor( const COLORREF crBkgnd )
{
if(m_hActiveKnobBrush) ::DeleteObject(m_hActiveKnobBrush);
m_hActiveKnobBrush = ::CreateSolidBrush( crBkgnd );
}
// 参 数:
// crText RGB颜色值
// 说 明:指定显示在控件中的字符串颜色
//
void CRoundSliderCtrl::SetTextColor(const COLORREF crText)
{
m_crText = crText;
}
// 参 数:
// bSet 布尔值,指示字体是否为黑体
// 说 明:指示控件中的字体是否为黑体
//
void CRoundSliderCtrl::SetFontBold(const bool bSet)
{
m_lf.lfWeight = bSet;
ReconstructFont();
}
// 参 数:
// bSet布尔值,指示字体是否具有下划线
// 说 明:指示控件中的字体是否具有下划线
//
void CRoundSliderCtrl::SetFontUnderline(const bool bSet)
{
m_lf.lfUnderline = bSet;
ReconstructFont();
}
// 参 数:
// bSet布尔值,指示字体是否为斜体
// 说 明:指示控件中的字体是否为斜体
//
void CRoundSliderCtrl::SetFontItalic(const bool bSet)
{
m_lf.lfItalic = bSet;
ReconstructFont();
}
// 参 数:
// nSize 字体的大小的整型变量
// 说 明:设置控件中字体的大小
//
void CRoundSliderCtrl::SetFontSize(const int nSize)
{
m_lf.lfHeight = -nSize;
ReconstructFont();
}
// 参 数:
// strFont 关于字体信息的CSting类型的字符串变量
// 说 明:设置控件中字体的名称
//
void CRoundSliderCtrl::SetFontName(const CString& strFont)
{
strcpy(m_lf.lfFaceName, strFont);
ReconstructFont();
}
// 参 数:
// bShow 指示控件内部是否要显示当前滑动内容的文字
// 说 明:指示控件内部是否要显示当前滑动内容的文字,默认情
// 况下控件内部无显示内容
//
void CRoundSliderCtrl::SetShowText( const BOOL bShow /* = TRUE */)
{
m_bShowText = bShow;
}
// 参 数:
// uNewBitID 位图资源ID
// 说 明:调用此函数可以为控件设置位图背景,图片大小最好跟
// 控件大小一致。
//
void CRoundSliderCtrl::SetBitmap( UINT uNewBitID )
{
m_uiBitID = uNewBitID;
m_bBitmap = TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////
//////////////// PUBLIC END ////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// Overrideables
CString CRoundSliderCtrl::OnFormatText() const
{
CString strFormattedText;
strFormattedText.Format(GetText(), 100-GetPos());
return strFormattedText;
}
#ifdef _DEBUG
void CRoundSliderCtrl::AssertValid() const
{
CSliderCtrl::AssertValid();
ASSERT(m_nZero >= 0 && m_nZero < 360);
ASSERT(m_nKnobRadius > 4);
}
void CRoundSliderCtrl::Dump(CDumpContext& dc) const
{
CSliderCtrl::Dump(dc);
dc << "m_strText = '" << m_strText << "'\n"
<< "m_nKnobRadius = " << m_nKnobRadius << "\n"
<< "m_nZero = " << m_nZero << "\n"
<< "m_bInverted = " << (m_bInverted ? "true" : "false") << "\n";
// Some information is still missing. Add whatever you need :)
}
#endif // _DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -