拖拉条

#pragma once #include "..//..//DCBuffer.h" #include "..//..//COM_IMAGE.h" #define WM_BITMAPSLIDER_MOVING WM_USER + 9425 #define WM_BITMAPSLIDER_MOVED WM_USER + 9426 class CImgSliderDEx: public CStatic { // Construction public: CImgSliderDEx(); virtual ~CImgSliderDEx(); // Implementation public: BOOL Init(CString strChannelPath, CString strChannelActivePath, CString strPath, CString strActivePath); void GetRange( int &nMin, int &nMax ) { nMin = m_nMin; nMax = m_nMax; }; void SetRange( int nMin, int nMax, BOOL bRedraw=FALSE ); int GetPos() { return m_nPos; }; void SetPos( int nPos ); int SetPageSize( int nSize ); void Enable( BOOL bEnable = TRUE ); void SetVerticalSlider(){m_bVertical = TRUE;} protected: void DrawFocusRect( BOOL bDraw = TRUE, BOOL bRedraw = FALSE ); void ResetBG( ) {m_nThumbBgX = -1;} BOOL SetBitmapChannel(CString strPath, CString strActivePath = L""); BOOL SetImgThumb(CString strPath, CString strActivePath = L""); void DrawImg( CDC* pDC, int xStart, int yStart, int wWidth, int wHeight, COM_IMAGE* pImg, int xSource, int ySource); int Pixel2Pos( int nPixel ); int Pos2Pixel( int nPos ); void SetMargin( int nLeft, int nTop, int nRight, int nBottom ); CRect m_rect; int m_nWidth, m_nHeight; int m_nChannelWidth, m_nChannelHeight; int m_nActiveWidth, m_nActiveHeight; int m_nThumbWidth, m_nThumbHeight; int m_nMax, m_nMin, m_nPos, m_nPage; int m_nMarginLeft, m_nMarginRight, m_nMarginTop, m_nMarginBottom; int m_nThumbBgX, m_nThumbBgY; int m_nMouseOffset; BOOL m_bVertical; BOOL m_bChannelActive, m_bThumbActive; BOOL m_bThumb, m_bChannel; BOOL m_bLButtonDown, m_bFocus, m_bFocusRect, m_bDrawFocusRect; BOOL m_bEnable; COM_IMAGE m_imgChannel, m_imgChannelActive; COM_IMAGE m_imgThumb, m_imgActive; //{{AFX_MSG(CImgSliderDEx) afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnLButtonUp(UINT nFlags, CPoint point); afx_msg UINT OnGetDlgCode(); afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg void OnKillFocus(CWnd* pNewWnd); afx_msg void OnSetFocus(CWnd* pOldWnd); afx_msg void OnDestroy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };

 

/

 

// BitmapSlider.cpp : implementation file
//

#include "stdafx.h"
#include "ImgSliderDEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

 

CImgSliderDEx::CImgSliderDEx()
{
 m_nPos = m_nMin = 0;
 m_nMax = 100;
 m_nPage = 20;
 m_nMarginLeft = m_nMarginRight = m_nMarginTop = m_nMarginBottom = 0;
 m_nThumbWidth = m_nThumbHeight = 0;
 m_bChannel = m_bVertical = m_bThumb = m_bLButtonDown = FALSE;
 m_bFocusRect = m_bFocus = FALSE;
 m_bDrawFocusRect = TRUE;
 m_bEnable = TRUE;
 m_nThumbBgX = m_nThumbBgY = -1;
}

CImgSliderDEx::~CImgSliderDEx()
{
}


BEGIN_MESSAGE_MAP(CImgSliderDEx, CStatic)
 //{{AFX_MSG_MAP(CImgSliderDEx)
 ON_WM_ERASEBKGND()
 ON_WM_PAINT()
 ON_WM_LBUTTONDOWN()
 ON_WM_MOUSEMOVE()
 ON_WM_LBUTTONUP()
 ON_WM_GETDLGCODE()
 ON_WM_KEYDOWN()
 ON_WM_KILLFOCUS()
 ON_WM_SETFOCUS()
 ON_WM_CREATE()
 ON_WM_DESTROY()
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CImgSliderDEx message handlers

BOOL CImgSliderDEx::Init(CString strChannelPath, CString strChannelActivePath, CString strPath, CString strActivePath)
{
 if( SetBitmapChannel(strChannelPath,strChannelActivePath)
  && SetImgThumb(strPath,strActivePath))
  return TRUE;
 return FALSE;
}

BOOL CImgSliderDEx::OnEraseBkgnd(CDC* pDC)

 // Do not erase background for the transparency effect
 return TRUE;
}

// Draw channel and thumb
//
void CImgSliderDEx::OnPaint()
{
 CPaintDC dcOrigin(this);
 CDCBuffer dc(&dcOrigin, &m_rect);

 // Delete focus rectangle for transparent channel
 if( m_bFocusRect && !m_bChannel )
 {
  dc.DrawFocusRect( m_rect );
  m_bFocusRect = FALSE;
 }

 // Draw channel
 if( m_bChannel )
 {
  if( m_bChannelActive && m_bEnable )
  {
   int iDestRatePos = Pos2Pixel(m_nPos);
   int iSourceRatePos = 0;
   if( m_bVertical )
   {
    iSourceRatePos = iDestRatePos*m_nChannelHeight/m_nHeight;
    m_imgChannel.drawImage(&dc,
     CRect(0, iDestRatePos, m_nWidth, m_nHeight),
     CRect(0, 0, m_nChannelWidth, m_nChannelHeight-iSourceRatePos));

    iSourceRatePos = iDestRatePos*m_nActiveHeight/m_nHeight;
    m_imgChannelActive.drawImage(&dc,
     CRect(0, 0, m_nWidth, iDestRatePos),
     CRect(0, m_nActiveHeight-iSourceRatePos, m_nActiveWidth, m_nActiveHeight));
   }
   else
   {
    iSourceRatePos = iDestRatePos*m_nChannelWidth/m_nWidth;
    m_imgChannel.drawImage(&dc,
     CRect(iDestRatePos, 0, m_nWidth, m_nHeight),
     CRect(iSourceRatePos, 0, m_nChannelWidth, m_nChannelHeight));

    iSourceRatePos = iDestRatePos*m_nActiveWidth/m_nWidth;
    m_imgChannelActive.drawImage(&dc,
     CRect(0, 0, iDestRatePos, m_nHeight),
     CRect(0,0, iSourceRatePos, m_nActiveHeight));
   }

  }
  else
  {
   m_imgChannel.drawImage(&dc,CRect(0, 0, m_nWidth, m_nHeight),CRect(0, 0, m_nWidth, m_nHeight));
  }
 }

 // Draw thumb
 CRect rtDest(0,0,0,0);
 CRect rtSource(0,0,m_nThumbWidth,m_nThumbHeight);
 if( m_bVertical)
 {
  rtDest.left = m_nMarginLeft;
  rtDest.top = Pos2Pixel(m_nPos) - m_nThumbHeight/2;
  rtDest.right = m_nMarginLeft+m_nThumbWidth;
  rtDest.bottom = Pos2Pixel(m_nPos) - m_nThumbHeight/2+m_nThumbHeight;
 }
 else
 {
  rtDest.left = Pos2Pixel(m_nPos) - m_nThumbWidth/2;
  rtDest.top = m_nMarginTop;
  rtDest.right = Pos2Pixel(m_nPos) - m_nThumbWidth/2+m_nThumbWidth;
  rtDest.bottom = m_nMarginTop+m_nThumbHeight;
 }
 if( m_bThumb && m_bEnable )
 {
  if( m_bThumbActive && m_bLButtonDown )
  {
   m_imgActive.drawImage(&dc,rtDest,rtSource);
  }
  else
  {
   m_imgThumb.drawImage(&dc,rtDest,rtSource);
  }
 }

 // Draw focus rectangle
 if( m_bDrawFocusRect && m_bFocus && m_bEnable )
 {
  dc.DrawFocusRect( m_rect );
  m_bFocusRect = TRUE;
 }
}

// Sets the range (minimum and maximum positions) for the slider.
//
// Parameters:
//  [IN] nMin
//    Minimum position for the slider.
//  [IN] nMax
//    Maximum position for the slider.
//  [IN] bRedraw
//    TRUE to redraw after the range is set.
//    FALSE to only change the range.
//
void CImgSliderDEx::SetRange(int nMin, int nMax, BOOL bRedraw)
{
 m_nMax = nMax;
 m_nMin = nMin;
 if( bRedraw )
  Invalidate();
}

// Sets the current position of the slider.
//
// Parameters:
//  [IN] nPos
//    Specifies the new slider position.
//
void CImgSliderDEx::SetPos(int nPos)
{
 m_nPos = nPos;

 // Boundary check
 if( m_nPos > m_nMax )
  m_nPos = m_nMax;
 if( m_nPos < m_nMin )
  m_nPos = m_nMin;

 Invalidate();
}

// Sets the size of the page for a control.
//
// Parameters:
//  [IN] nSize
//    The new page size of the control.
//
// Return value:
//  The previous page size.
//
int CImgSliderDEx::SetPageSize(int nSize)
{
 int nRet = m_nPage;

 m_nPage = nSize;

 return nRet;
}

// Sets the left, top, right, and bottom margins for a control
//
void CImgSliderDEx::SetMargin(int nLeft, int nTop, int nRight, int nBottom )
{
 m_nMarginTop = nTop;
 m_nMarginLeft = nLeft;
 m_nMarginRight = nRight; 
 m_nMarginBottom = nBottom;
}

// Enables or disables control.
//
//  [IN] bEnable
//    TRUE to enable control.
//    FALSE to disable control.
//
void CImgSliderDEx::Enable(BOOL bEnable)
{
 m_bEnable = bEnable;

 // If control is disabled during dragging
 if( !m_bEnable && m_bLButtonDown )
 {
  m_bLButtonDown = FALSE;
  ReleaseCapture();
 }

 Invalidate();
}

// Specify whether draw focus rectangle or not.
//
//  [IN] bDraw
//    TRUE to draw focus rectangle.
//    FALSE to hide focus rectangle.
//
//  [IN] bRedraw
//    TRUE to redraw status is changed.
//    FALSE to only change the status.
//
void CImgSliderDEx::DrawFocusRect(BOOL bDraw, BOOL bRedraw)
{
 m_bDrawFocusRect = bDraw;

 if( bRedraw )
  Invalidate();
}

// Load bitmaps for a channel
//
// Parameters:
//  [IN] nChannelID
//    ID number of the bitmap resource of the channel.
//  [IN] nActiveID
//    ID number of the bitmap resource of the active channel.
//  [IN] bTransparent
//    TRUE to apply transparency effect.
//    FALSE to display normal bitmap.
//  [IN] clrpTransColor
//    RGB color to treat as transparent.
//  [IN] iTransPixelX
//    Logical x-coordinate of a point.
//    It's color will be treated as transparent.
//  [IN] iTransPixelY
//    Logical y-coordinate of a point.
//    It's color will be treated as transparent.
//
// Return value:
//  TRUE
//   Function succeedes.
//  FALSE
//   Function failes to load bitmaps.
//
BOOL CImgSliderDEx::SetBitmapChannel(CString strPath, CString strActivePath)
{
 // load a bitmap
 m_imgChannel.loadFile(strPath);
 m_nChannelWidth = m_imgChannel.Width();
 m_nChannelHeight = m_imgChannel.Hight();
 if( L"" != strActivePath )
 {
  m_imgChannelActive.loadFile(strActivePath);
  m_nActiveWidth = m_imgChannelActive.Width();
  m_nActiveHeight = m_imgChannelActive.Hight();
  m_bChannelActive = TRUE;
 }
 else
  m_bChannelActive = FALSE;

 GetClientRect( &m_rect );
 m_nWidth = m_rect.Width();
 m_nHeight = m_rect.Height();
 m_bChannel = TRUE;

 return TRUE;
}

BOOL CImgSliderDEx::SetImgThumb(CString strPath, CString strActivePath)
{
 // load a bitmap
 m_imgThumb.loadFile(strPath);
 // Load a bitmap for active state.
 if( L"" != strActivePath )
 {
  m_imgActive.loadFile(strActivePath);
  m_bThumbActive = TRUE;
 }
 else
  m_bThumbActive = FALSE;

 // Get size of the bitmap
 m_nThumbWidth = m_imgThumb.Width();
 m_nThumbHeight = m_imgThumb.Hight();
 m_bThumb = TRUE;

 return TRUE;
}
// OnLButtonDown
//
// Dragging is started
//
void CImgSliderDEx::OnLButtonDown(UINT nFlags, CPoint point)
{
 if( !m_bEnable )
  return;

 SetCapture();
 SetFocus();

 m_bLButtonDown = TRUE;

 // If mouse button is clicked on the thumb,
 // capture the coordinates of mouse pointer and center of thumb
 // and calculate distance between them.
 if( m_bVertical )
 {
  if( abs( point.y - Pos2Pixel( m_nPos ) ) <= m_nThumbHeight / 2 )
   m_nMouseOffset = point.y - Pos2Pixel( m_nPos );
  else
   m_nMouseOffset = 0;

 } else {

  if( abs( point.x - Pos2Pixel( m_nPos ) ) <= m_nThumbWidth / 2 )
   m_nMouseOffset = point.x - Pos2Pixel( m_nPos );
  else
   m_nMouseOffset = 0;
 }

 OnMouseMove( nFlags, point );
 Invalidate();

 CStatic::OnLButtonDown(nFlags, point);
}

// OnMouseMove
//
// During dragging
//
void CImgSliderDEx::OnMouseMove(UINT nFlags, CPoint point)
{
 if( !m_bLButtonDown || !m_bEnable )
  return;

 int nPixel;

 // Boundary check
 if( m_bVertical )
 {
  nPixel = point.y - m_nMouseOffset;

  if( nPixel > m_nHeight - m_nMarginBottom - m_nThumbHeight/2 )
   nPixel = m_nHeight - m_nMarginBottom - m_nThumbHeight/2;

  if( nPixel < m_nMarginTop + m_nThumbHeight/2 )
   nPixel = m_nMarginTop + m_nThumbHeight/2;

 } else {

  nPixel = point.x - m_nMouseOffset;

  if( nPixel < m_nMarginLeft + m_nThumbWidth/2 )
   nPixel = m_nMarginLeft + m_nThumbWidth/2;

  if( nPixel > m_nWidth - m_nMarginRight - m_nThumbWidth/2 )
   nPixel = m_nWidth - m_nMarginRight - m_nThumbWidth/2;
 }

 // Apply change
 if( Pos2Pixel(m_nPos) != nPixel ) {

  SetPos( Pixel2Pos( nPixel ) );

  ::PostMessage(
   GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVING,
   GetDlgCtrlID(), m_nPos );
 }

 CStatic::OnMouseMove(nFlags, point);
}

// OnLButtonUp
//
// Dragging is finished
//
void CImgSliderDEx::OnLButtonUp(UINT nFlags, CPoint point)
{
 if( !m_bEnable )
  return;

 ReleaseCapture();
 m_bLButtonDown = FALSE;

 Invalidate();

 ::PostMessage(
  GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED,
  GetDlgCtrlID(), point.x  );//m_nPos

 CStatic::OnLButtonUp(nFlags, point);
}

// Calculate point of thumb from position value
//
int CImgSliderDEx::Pos2Pixel(int nPos)
{
 if( m_bVertical ) {

  return
   m_nMarginTop + m_nThumbHeight/2 +
   (int)(
   ( m_nHeight - m_nMarginTop - m_nMarginBottom - m_nThumbHeight ) *
   ((double) ( nPos - m_nMin ) / ( m_nMax - m_nMin ) )
   );

 } else {

  return (int)(
   ( m_nWidth - m_nMarginLeft - m_nMarginRight - m_nThumbWidth ) *
   ((double) ( nPos - m_nMin ) / ( m_nMax - m_nMin ) )
   ) + m_nMarginLeft + m_nThumbWidth/2;
 }
}

// Calculate position value from point of mouse
//
int CImgSliderDEx::Pixel2Pos(int nPixel)
{
 if( m_bVertical ) {

  return (int)(
   m_nMin +
   (double)( nPixel - m_nMarginTop - m_nThumbHeight/2) /
   ( m_nHeight - m_nMarginBottom - m_nMarginTop - m_nThumbHeight ) *
   ( m_nMax - m_nMin )
   );

 } else {

  return (int)(
   m_nMin +
   (double)( nPixel - m_nMarginLeft - m_nThumbWidth/2 ) /
   ( m_nWidth - m_nMarginLeft - m_nMarginRight - m_nThumbWidth ) *
   ( m_nMax - m_nMin )
   );
 }
}

void DrawImg(
  CDC* pDC, int xStart, int yStart, int wWidth, int wHeight,
  COM_IMAGE* pImg, int xSource, int ySource)
{
 pImg->drawImage(pDC,CRect(xStart,yStart,xStart+wWidth,yStart+wHeight),
  CRect(xSource,ySource,xSource+wWidth,ySource+wHeight));
}

// To get keyboard input
//
UINT CImgSliderDEx::OnGetDlgCode()
{
 if( GetKeyState(VK_TAB) >= 0 )
 {
  return  DLGC_WANTALLKEYS;
 }
 return CStatic::OnGetDlgCode();
}

// Handling keyboard input
//
void CImgSliderDEx::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
 if( !m_bEnable )
  return;

 switch( nChar )
 {
 // Left & up
 case VK_LEFT :
 case VK_UP :
  SetPos( m_nPos-1 );
  break;

 // Right & down
 case VK_RIGHT :
 case VK_DOWN :
  SetPos( m_nPos+1 );
  break;

 // Home
 case VK_HOME :
  SetPos( m_nMin );
  break;

 // End
 case VK_END :
  SetPos( m_nMax );
  break;

 // Page up
 case VK_PRIOR :
  SetPos( m_nPos - m_nPage );
  break;

 // Page down
 case VK_NEXT :
  SetPos( m_nPos + m_nPage );
  break;

 default :
  CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
  return;
 }
 
 ::PostMessage(
  GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED,
  GetDlgCtrlID(), m_nPos );

 CStatic::OnKeyDown(nChar, nRepCnt, nFlags);
}

// Control looses its focus
//
void CImgSliderDEx::OnKillFocus(CWnd* pNewWnd)
{
 CStatic::OnKillFocus(pNewWnd);

 m_bFocus = FALSE;
 Invalidate();
}

// This control gains its focus
//
void CImgSliderDEx::OnSetFocus(CWnd* pOldWnd)
{
 CStatic::OnSetFocus(pOldWnd);
 m_bFocus = TRUE;
 Invalidate();
}

// Release resources
//
void CImgSliderDEx::OnDestroy()
{
 CStatic::OnDestroy();
 m_imgChannel.Release();
 m_imgChannelActive.Release();
 m_imgThumb.Release();
 m_imgActive.Release();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值