#include "StdAfx.h" #include "UISlider.h" namespace DuiLib { CSliderUI::CSliderUI() : m_uButtonState(0), m_nStep(1),m_bSendMove(false) { m_uTextStyle = DT_SINGLELINE | DT_CENTER; m_szThumb.cx = m_szThumb.cy = 10; } LPCTSTR CSliderUI::GetClass() const { return _T("SliderUI"); } UINT CSliderUI::GetControlFlags() const { if( IsEnabled() ) return UIFLAG_SETCURSOR; else return 0; } LPVOID CSliderUI::GetInterface(LPCTSTR pstrName) { if( _tcscmp(pstrName, DUI_CTR_SLIDER) == 0 ) return static_cast(this); return CProgressUI::GetInterface(pstrName); } void CSliderUI::SetEnabled(bool bEnable) { CControlUI::SetEnabled(bEnable); if( !IsEnabled() ) { m_uButtonState = 0; } } int CSliderUI::GetChangeStep() { return m_nStep; } void CSliderUI::SetChangeStep(int step) { m_nStep = step; } void CSliderUI::SetThumbSize(SIZE szXY) { m_szThumb = szXY; } RECT CSliderUI::GetThumbRect() const { if( m_bHorizontal ) { int left = m_rcItem.left + (m_rcItem.right - m_rcItem.left - m_szThumb.cx) * (m_nValue - m_nMin) / (m_nMax - m_nMin); int top = (m_rcItem.bottom + m_rcItem.top - m_szThumb.cy) / 2; return CDuiRect(left, top, left + m_szThumb.cx, top + m_szThumb.cy); } else { int left = (m_rcItem.right + m_rcItem.left - m_szThumb.cx) / 2; int top = m_rcItem.bottom - m_szThumb.cy - (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy) * (m_nValue - m_nMin) / (m_nMax - m_nMin); return CDuiRect(left, top, left + m_szThumb.cx, top + m_szThumb.cy); } } LPCTSTR CSliderUI::GetThumbImage() const { return m_sThumbImage; } void CSliderUI::SetThumbImage(LPCTSTR pStrImage) { m_sThumbImage = pStrImage; Invalidate(); } LPCTSTR CSliderUI::GetThumbHotImage() const { return m_sThumbHotImage; } void CSliderUI::SetThumbHotImage(LPCTSTR pStrImage) { m_sThumbHotImage = pStrImage; Invalidate(); } LPCTSTR CSliderUI::GetThumbPushedImage() const { return m_sThumbPushedImage; } void CSliderUI::SetThumbPushedImage(LPCTSTR pStrImage) { m_sThumbPushedImage = pStrImage; Invalidate(); } void CSliderUI::SetValue(int nValue) //2014.7.28 redrain 当鼠标正在滑动滑块时不会收到SetValue的影响,比如滑动改变音乐的进度,不会因为外部一直调用SetValue而让我们无法滑动滑块 { if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) return; CProgressUI::SetValue(nValue); } void CSliderUI::DoEvent(TEventUI& event) { if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) { if( m_pParent != NULL ) m_pParent->DoEvent(event); else CProgressUI::DoEvent(event); return; } if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK ) { if( IsEnabled() ) {//2014.7.28 redrain 注释掉原来的代码,加上这些代码后可以让Slider不是在鼠标弹起时才改变滑块的位置 m_uButtonState |= UISTATE_CAPTURED; int nValue; if( m_bHorizontal ) { if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) nValue = m_nMax; else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) nValue = m_nMin; else nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx); } else { if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) nValue = m_nMin; else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) nValue = m_nMax; else nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy); } if(m_nValue !=nValue && nValue>=m_nMin && nValue<=m_nMax) { m_nValue =nValue; Invalidate(); } } return; } // if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_DBLCLICK ) // { // if( IsEnabled() ) { // RECT rcThumb = GetThumbRect(); // if( ::PtInRect(&rcThumb, event.ptMouse) ) { // m_uButtonState |= UISTATE_CAPTURED; // } // } // return; // } if( event.Type == UIEVENT_BUTTONUP ) { int nValue; if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { m_uButtonState &= ~UISTATE_CAPTURED; } if( m_bHorizontal ) { if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) nValue = m_nMax; else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) nValue = m_nMin; else nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx); } else { if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) nValue = m_nMin; else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) nValue = m_nMax; else nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy); } if(/*m_nValue !=nValue && 2014.7.28 redrain 这个注释很关键,是他导致了鼠标拖动滑块无法发出DUI_MSGTYPE_VALUECHANGED消息*/nValue>=m_nMin && nValue<=m_nMax) { m_nValue =nValue; m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED); Invalidate(); } return; } if( event.Type == UIEVENT_CONTEXTMENU ) { return; } if( event.Type == UIEVENT_SCROLLWHEEL ) { switch( LOWORD(event.wParam) ) { case SB_LINEUP: SetValue(GetValue() + GetChangeStep()); m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED); return; case SB_LINEDOWN: SetValue(GetValue() - GetChangeStep()); m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED); return; } } if( event.Type == UIEVENT_MOUSEMOVE ) { if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {//2014.7.28 redrain 重写这个消息判断让Slider发出DUI_MSGTYPE_VALUECHANGED_MOVE消息,让他在滑动过程也发出消息,比如用在改变音量时,一边滑动就可以一边改变音量 if( m_bHorizontal ) { if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) m_nValue = m_nMax; else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) m_nValue = m_nMin; else m_nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx); } else { if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) m_nValue = m_nMin; else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) m_nValue = m_nMax; else m_nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy); } if (m_bSendMove) m_pManager->SendNotify(this, DUI_MSGTYPE_VALUECHANGED_MOVE); Invalidate(); } // Generate the appropriate mouse messages POINT pt = event.ptMouse; RECT rcThumb = GetThumbRect(); if( IsEnabled() && ::PtInRect(&rcThumb, event.ptMouse) ) { m_uButtonState |= UISTATE_HOT; Invalidate(); }else { m_uButtonState &= ~UISTATE_HOT; Invalidate(); } return; } // if( event.Type == UIEVENT_MOUSEMOVE ) // { // if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { // if( m_bHorizontal ) { // if( event.ptMouse.x >= m_rcItem.right - m_szThumb.cx / 2 ) m_nValue = m_nMax; // else if( event.ptMouse.x <= m_rcItem.left + m_szThumb.cx / 2 ) m_nValue = m_nMin; // else m_nValue = m_nMin + (m_nMax - m_nMin) * (event.ptMouse.x - m_rcItem.left - m_szThumb.cx / 2 ) / (m_rcItem.right - m_rcItem.left - m_szThumb.cx); // } // else { // if( event.ptMouse.y >= m_rcItem.bottom - m_szThumb.cy / 2 ) m_nValue = m_nMin; // else if( event.ptMouse.y <= m_rcItem.top + m_szThumb.cy / 2 ) m_nValue = m_nMax; // else m_nValue = m_nMin + (m_nMax - m_nMin) * (m_rcItem.bottom - event.ptMouse.y - m_szThumb.cy / 2 ) / (m_rcItem.bottom - m_rcItem.top - m_szThumb.cy); // } // Invalidate(); // } // return; // } if( event.Type == UIEVENT_SETCURSOR ) { RECT rcThumb = GetThumbRect(); if( IsEnabled()) { ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND))); return; } } // if( event.Type == UIEVENT_SETCURSOR ) // { // RECT rcThumb = GetThumbRect(); // if( IsEnabled() && ::PtInRect(&rcThumb, event.ptMouse) ) { // ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND))); // return; // } // } if( event.Type == UIEVENT_MOUSEENTER ) {//2014.7.28 redrain 只有鼠标在滑块的范围内才变为UISTATE_HOT // if( IsEnabled() ) { // m_uButtonState |= UISTATE_HOT; // Invalidate(); // } // return; } if( event.Type == UIEVENT_MOUSELEAVE ) { if( IsEnabled() ) { m_uButtonState &= ~UISTATE_HOT; Invalidate(); } return; } CControlUI::DoEvent(event); } void CSliderUI::SetCanSendMove(bool bCanSend) //2014.7.28 redrain { m_bSendMove = bCanSend; } bool CSliderUI::GetCanSendMove() const //2014.7.28 redrain { return m_bSendMove; } void CSliderUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) { if( _tcscmp(pstrName, _T("thumbimage")) == 0 ) SetThumbImage(pstrValue); else if( _tcscmp(pstrName, _T("thumbhotimage")) == 0 ) SetThumbHotImage(pstrValue); else if( _tcscmp(pstrName, _T("thumbpushedimage")) == 0 ) SetThumbPushedImage(pstrValue); else if( _tcscmp(pstrName, _T("thumbsize")) == 0 ) { SIZE szXY = {0}; LPTSTR pstr = NULL; szXY.cx = _tcstol(pstrValue, &pstr, 10); ASSERT(pstr); szXY.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr); SetThumbSize(szXY); } else if( _tcscmp(pstrName, _T("step")) == 0 ) { SetChangeStep(_ttoi(pstrValue)); } else if( _tcscmp(pstrName, _T("sendmove")) == 0 ) { SetCanSendMove(_tcscmp(pstrValue, _T("true")) == 0); } else CProgressUI::SetAttribute(pstrName, pstrValue); } void CSliderUI::PaintStatusImage(HDC hDC) { CProgressUI::PaintStatusImage(hDC); RECT rcThumb = GetThumbRect(); rcThumb.left -= m_rcItem.left; rcThumb.top -= m_rcItem.top; rcThumb.right -= m_rcItem.left; rcThumb.bottom -= m_rcItem.top; if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) { if( !m_sThumbPushedImage.IsEmpty() ) { m_sImageModify.Empty(); m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom); if( !DrawImage(hDC, (LPCTSTR)m_sThumbPushedImage, (LPCTSTR)m_sImageModify) ) m_sThumbPushedImage.Empty(); else return; } } else if( (m_uButtonState & UISTATE_HOT) != 0 ) { if( !m_sThumbHotImage.IsEmpty() ) { m_sImageModify.Empty(); m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom); if( !DrawImage(hDC, (LPCTSTR)m_sThumbHotImage, (LPCTSTR)m_sImageModify) ) m_sThumbHotImage.Empty(); else return; } } if( !m_sThumbImage.IsEmpty() ) { m_sImageModify.Empty(); m_sImageModify.SmallFormat(_T("dest='%d,%d,%d,%d'"), rcThumb.left, rcThumb.top, rcThumb.right, rcThumb.bottom); if( !DrawImage(hDC, (LPCTSTR)m_sThumbImage, (LPCTSTR)m_sImageModify) ) m_sThumbImage.Empty(); else return; } } }