CBitmapSlider扩展
来源:互联网 发布:js中的date对象 编辑:程序博客网 时间:2024/05/21 17:51
http://www.codeproject.com/Articles/4850/CBitmapSlider
试用了很多slider 发现这个还是最稳定 最给力的
相对于作者给出的代码 做了如下修改:
1:添加滚轮事件
2:添加EnableWindow的函数:EnableEx
代码如下:
#ifndef _MEMDC_H_#define _MEMDC_H_//////////////////////////////////////////////////// CMemDC_flicker_free - memory DC//// Author: Keith Rule// Email: keithr@europa.com// Copyright 1996-2002, Keith Rule//// You may freely use or modify this code provided this// Copyright is included in all derived versions.//// History - 10/3/97 Fixed scrolling bug.// Added print support. - KR//// 11/3/99 Fixed most common complaint. Added// background color fill. - KR//// 11/3/99 Added support for mapping modes other than// MM_TEXT as suggested by Lee Sang Hun. - KR//// 02/11/02 Added support for CScrollView as supplied// by Gary Kirkham. - KR//// This class implements a memory Device Context which allows// flicker free drawing.////// I made a few changes to support transparency effect //// Line 44 : Added bBg parameter.// Line 83 ~ 87 : If bBg is TRUE, copy background.//class CMemDC_flicker_free : public CDC {private: CBitmap m_bitmap; // Offscreen bitmap CBitmap* m_oldBitmap; // bitmap originally found in CMemDC_flicker_free CDC* m_pDC; // Saves CDC passed in constructor CRect m_rect; // Rectangle of drawing area. BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.public: CMemDC_flicker_free(CDC* pDC, const CRect* pRect = NULL, BOOL bBg = FALSE) : CDC() { ASSERT(pDC != NULL); // Some initialization m_pDC = pDC; m_oldBitmap = NULL; m_bMemDC = !pDC->IsPrinting(); // Get the rectangle to draw if (pRect == NULL) { pDC->GetClipBox(&m_rect); } else { m_rect = *pRect; } if (m_bMemDC) { // Create a Memory DC CreateCompatibleDC(pDC); pDC->LPtoDP(&m_rect); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); m_oldBitmap = SelectObject(&m_bitmap); SetMapMode(pDC->GetMapMode()); SetWindowExt(pDC->GetWindowExt()); SetViewportExt(pDC->GetViewportExt()); pDC->DPtoLP(&m_rect); SetWindowOrg(m_rect.left, m_rect.top); } else { // Make a copy of the relevent parts of the current DC for printing m_bPrinting = pDC->m_bPrinting; m_hDC = pDC->m_hDC; m_hAttribDC = pDC->m_hAttribDC; } // Fill background if( bBg ) BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), m_pDC, m_rect.left, m_rect.top, SRCCOPY); else FillSolidRect(m_rect, pDC->GetBkColor()); } ~CMemDC_flicker_free() { if (m_bMemDC) { // Copy the offscreen bitmap onto the screen. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, m_rect.left, m_rect.top, SRCCOPY); //Swap back the original bitmap. SelectObject(m_oldBitmap); } else { // All we need to do is replace the DC with an illegal value, // this keeps us from accidently deleting the handles associated with // the CDC that was passed to the constructor. m_hDC = m_hAttribDC = NULL; } } // Allow usage as a pointer CMemDC_flicker_free* operator->() { return this; } // Allow usage as a pointer operator CMemDC_flicker_free*() { return this; }};#endif
#if !defined(AFX_BITMAPSLIDER_H__BED36788_B60C_4C9E_AC56_FE430B93A0FD__INCLUDED_)#define AFX_BITMAPSLIDER_H__BED36788_B60C_4C9E_AC56_FE430B93A0FD__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// BitmapSlider.h : header file/////////////////////////////////////////////////////////////////////////////////// CBitmapSlider v1.5//// It's free for everywhere - 16/September/2003 - Joon-ho Ryu///////////////////////////////////////////////////////////////////////////////#include "memdc.h" // "Flicker Free Drawing In MFC" by Keith Rule#define WM_BITMAPSLIDER_MOVING WM_USER + 9425#define WM_BITMAPSLIDER_MOVED WM_USER + 9426class CBitmapSlider : public CStatic{// Constructionpublic: CBitmapSlider();// Attributespublic:// Operationspublic:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CBitmapSlider) //}}AFX_VIRTUAL// Implementationpublic: void GetRange( int &nMin, int &nMax ) { nMin = m_nMin; nMax = m_nMax; }; int GetRangeMax() { return m_nMax; }; int GetRangeMin() { return m_nMin; }; int GetPos() { return m_nPos; }; void SetRange( int nMin, int nMax, BOOL bRedraw=FALSE ); void SetRangeMin(int nMin, BOOL bRedraw = FALSE); void SetRangeMax( int nMax, BOOL bRedraw = FALSE ); void SetPos( int nPos ); int SetPageSize( int nSize ); BOOL SetBitmapChannel( UINT nChannelID, UINT nActiveID=NULL, BOOL bTransparent=FALSE, COLORREF clrpTransColor=0xFF000000, int iTransPixelX=0, int iTransPixelY=0 ); BOOL SetBitmapThumb( UINT nThumbID, UINT nActiveID=NULL, BOOL bTransparent=FALSE, COLORREF clrpTransColor=0xFF000000, int iTransPixelX=0, int iTransPixelY=0 ); void SetMargin( int nLeft, int nTop, int nRight, int nBottom ); void SetMarginTop( int nMargin ) { m_nMarginTop = nMargin; }; void SetMarginLeft( int nMargin ) { m_nMarginLeft = nMargin; }; void SetMarginRight( int nMargin ) { m_nMarginRight = nMargin; }; void SetMarginBottom( int nMargin ) { m_nMarginBottom = nMargin; }; void SetVertical( BOOL bVertical=TRUE ) { m_bVertical = bVertical; }; void Enable(BOOL bEnable = TRUE); void EnableEx(BOOL bEnable = TRUE); void DrawFocusRect( BOOL bDraw = TRUE, BOOL bRedraw = FALSE ); virtual ~CBitmapSlider(); // Generated message map functionsprotected: void RestoreBackground( CDC *pDC, int nXDst, int nYDst, int nWidth, int nHeight, CBitmap *pBmSrc); void CopyBackground( CDC *pDC, int nXSrc, int nYSrc, int nWidth, int nHeight, CBitmap *pBmDst ); void DrawBitmap( CDC* pDC, int xStart, int yStart, int wWidth, int wHeight, CDC* pTmpDC, int xSource, int ySource, CBitmap *bmMask = NULL, BOOL bTransparent = FALSE ); void DrawTransparentBitmap( CDC* pDC, int xStart, int yStart, int wWidth, int wHeight, CDC* pTmpDC, int xSource, int ySource, CBitmap *bmMask ); void PrepareMask( CBitmap* pBmpSource, CBitmap* pBmpMask, COLORREF clrpTransColor=0xFF000000, int iTransPixelX=0, int iTransPixelY=0 ); int Pixel2Pos( int nPixel ); int Pos2Pixel( int nPos ); int m_nMax, m_nMin, m_nPos, m_nPage; CRect m_rect; int m_nWidth, m_nHeight; int m_nThumbWidth, m_nThumbHeight; 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_bTransparentChannel, m_bTransparentThumb, m_bThumb, m_bChannel; BOOL m_bLButtonDown, m_bFocus, m_bFocusRect, m_bDrawFocusRect; BOOL m_bEnable; BOOL m_bEnableEx; CBitmap m_bmChannel, m_bmChannelMask, m_bmChannelActive, m_bmChannelActiveMask; CBitmap m_bmThumb, m_bmThumbMask, m_bmThumbActive, m_bmThumbActiveMask, m_bmThumbBg; //{{AFX_MSG(CBitmapSlider) 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 BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); 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()private: // This is CStatic method void SetBitmap( HBITMAP /*hBitmap*/ ) {};};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_BITMAPSLIDER_H__BED36788_B60C_4C9E_AC56_FE430B93A0FD__INCLUDED_)
// BitmapSlider.cpp : implementation file//#include "stdafx.h"#include "BitmapSlider.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////////// CBitmapSlider v1.5//// It's free for everywhere - 16/September/2003 - Joon-ho Ryu///////////////////////////////////////////////////////////////////////////////CBitmapSlider::CBitmapSlider(){ 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_bEnableEx = TRUE; m_nThumbBgX = m_nThumbBgY = -1;}CBitmapSlider::~CBitmapSlider(){}BEGIN_MESSAGE_MAP(CBitmapSlider, CStatic) //{{AFX_MSG_MAP(CBitmapSlider) ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_MOUSEMOVE() ON_WM_MOUSEWHEEL() 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()/////////////////////////////////////////////////////////////////////////////// CBitmapSlider message handlersBOOL CBitmapSlider::OnEraseBkgnd(CDC* /*pDC*/) { // Do not erase background for the transparency effect return TRUE;}// Draw channel and thumb//void CBitmapSlider::OnPaint() { CPaintDC dcOrigin(this); // "Flicker Free Drawing In MFC" by Keith Rule CMemDC_flicker_free dc( &dcOrigin, &m_rect, m_bTransparentChannel ); CDC dcMem; dcMem.CreateCompatibleDC( &dc ); CBitmap *pbmTmp; // Delete focus rectangle for transparent channel if( m_bFocusRect && ( m_bTransparentChannel || !m_bChannel ) ) { dc.DrawFocusRect( m_rect ); m_bFocusRect = FALSE; } // Draw channel if( m_bChannel ) { pbmTmp = dcMem.SelectObject( &m_bmChannel ); // There is a bitmap for active channel if( m_bChannelActive && m_bEnable ) { // Vertical slider if( m_bVertical ) { // Lower part DrawBitmap( &dc, 0, Pos2Pixel(m_nPos), m_nWidth, m_nHeight - Pos2Pixel(m_nPos), &dcMem, 0, Pos2Pixel(m_nPos), &m_bmChannelActiveMask, m_bTransparentChannel ); dcMem.SelectObject( &m_bmChannelActive ); // Upper part DrawBitmap( &dc, 0, 0, m_nWidth, Pos2Pixel(m_nPos), &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel ); // Horizontal slider } else { // Right side DrawBitmap( &dc, Pos2Pixel(m_nPos), 0, m_nWidth - Pos2Pixel(m_nPos), m_nHeight, &dcMem, Pos2Pixel(m_nPos), 0, &m_bmChannelActiveMask, m_bTransparentChannel ); dcMem.SelectObject( &m_bmChannelActive ); // Left side DrawBitmap( &dc, 0, 0, Pos2Pixel(m_nPos), m_nHeight, &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel ); } // Only one bitmap for channel } else { DrawBitmap( &dc, 0, 0, m_nWidth, m_nHeight, &dcMem, 0, 0, &m_bmChannelMask, m_bTransparentChannel ); } dcMem.SelectObject( pbmTmp ); } // If there is a bitmap to restore background image of a thumb if( m_nThumbBgX != -1 ) { RestoreBackground( &dc, m_nThumbBgX, m_nThumbBgY, m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg ); m_nThumbBgX = -1; } // Draw thumb if( m_bThumb && m_bEnable ) { if( m_bThumbActive && m_bLButtonDown ) pbmTmp = dcMem.SelectObject( &m_bmThumbActive ); // Active thumb else pbmTmp = dcMem.SelectObject( &m_bmThumb ); // Normal thumb // Vertical slider if( m_bVertical ) { // Background image is need to be restored if( m_bTransparentChannel || !m_bChannel ) { m_nThumbBgX = m_nMarginLeft; m_nThumbBgY = Pos2Pixel(m_nPos) - m_nThumbHeight/2; CopyBackground( &dc, m_nThumbBgX, m_nThumbBgY, m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg ); } DrawBitmap( &dc, m_nMarginLeft, Pos2Pixel(m_nPos) - m_nThumbHeight/2, m_nThumbWidth, m_nThumbHeight, &dcMem, 0, 0, &m_bmThumbMask, m_bTransparentThumb ); // Horizontal slider } else { // Background image is need to be restored if( m_bTransparentChannel || !m_bChannel ) { m_nThumbBgX = Pos2Pixel(m_nPos) - m_nThumbWidth/2; m_nThumbBgY = m_nMarginTop; CopyBackground( &dc, m_nThumbBgX, m_nThumbBgY, m_nThumbWidth, m_nThumbHeight, &m_bmThumbBg ); } DrawBitmap( &dc, Pos2Pixel(m_nPos) - m_nThumbWidth/2, m_nMarginTop, m_nThumbWidth, m_nThumbHeight, &dcMem, 0, 0, &m_bmThumbMask, m_bTransparentThumb ); } // if horizontal dcMem.SelectObject( pbmTmp ); } // if draw thumb // Draw focus rectangle if( m_bDrawFocusRect && m_bFocus && m_bEnable ) { dc.DrawFocusRect( m_rect ); m_bFocusRect = TRUE; } dcMem.DeleteDC();}// Sets the maximum range for the slider.//// Parameters:// [IN] nMax// Maximum position for the slider.// [IN] bRedraw// TRUE to redraw after the range is set.// FALSE to only change maximum position.//void CBitmapSlider::SetRangeMax(int nMax, BOOL bRedraw){ m_nMax = nMax; if( bRedraw ) Invalidate();}// Sets the minimum range for the slider.//// Parameters:// [IN] nMin// Minimum position for the slider.// [IN] bRedraw// TRUE to redraw after the range is set.// FALSE to only change minimum position.//void CBitmapSlider::SetRangeMin(int nMin, BOOL bRedraw){ m_nMin = nMin; if( bRedraw ) Invalidate();}// 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 CBitmapSlider::SetRange(int nMin, int nMax, BOOL bRedraw){ SetRangeMin( nMin, FALSE ); SetRangeMax( nMax, bRedraw );}// Sets the current position of the slider.//// Parameters:// [IN] nPos// Specifies the new slider position.//void CBitmapSlider::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 CBitmapSlider::SetPageSize(int nSize){ int nRet = m_nPage; m_nPage = nSize; return nRet;}// Sets the left, top, right, and bottom margins for a control//void CBitmapSlider::SetMargin(int nLeft, int nTop, int nRight, int nBottom ){ SetMarginLeft( nLeft ); SetMarginTop( nTop ); SetMarginRight( nRight ); SetMarginBottom( nBottom );}// Enables or disables control.//// [IN] bEnable// TRUE to enable control.// FALSE to disable control.//void CBitmapSlider::Enable(BOOL bEnable){ m_bEnable = bEnable; // If control is disabled during dragging if( !m_bEnable && m_bLButtonDown ) { m_bLButtonDown = FALSE; ReleaseCapture(); } Invalidate();}void CBitmapSlider::EnableEx(BOOL bEnable /* = TRUE */){ EnableWindow(bEnable); m_bEnableEx = bEnable; SetPos(m_nPos);}// 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 CBitmapSlider::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 CBitmapSlider::SetBitmapChannel( UINT nChannelID, UINT nActiveID , BOOL bTransparent, COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY ){ // This control will not have any bitmap for channel if( !nChannelID ) { m_bChannel = FALSE; m_bmChannel.DeleteObject(); m_bmChannelMask.DeleteObject(); m_bmChannelActive.DeleteObject(); m_bmChannelActiveMask.DeleteObject(); return TRUE; } // load a bitmap m_bmChannel.DeleteObject(); if( !m_bmChannel.LoadBitmap( nChannelID ) ) return FALSE; // Prepare mask for transparency effect. if( bTransparent ) { PrepareMask( &m_bmChannel, &m_bmChannelMask, clrpTransColor, iTransPixelX, iTransPixelY ); } // Load a bitmap for active state. if( nActiveID ) { m_bmChannelActive.DeleteObject(); if( !m_bmChannelActive.LoadBitmap( nActiveID ) ) { m_bmChannel.DeleteObject(); if( bTransparent ) m_bmChannelMask.DeleteObject(); return FALSE; } if( bTransparent ) { PrepareMask( &m_bmChannelActive, &m_bmChannelActiveMask, clrpTransColor, iTransPixelX, iTransPixelY ); } m_bChannelActive = TRUE; // There is no bitmap for active state. } else m_bChannelActive = FALSE; // Get size of bitmap. BITMAP bitmap; m_bmChannel.GetBitmap( &bitmap ); m_nWidth = bitmap.bmWidth; m_nHeight = bitmap.bmHeight; // Compare size if( m_bChannelActive ) { BITMAP bitmap; m_bmChannelActive.GetBitmap( &bitmap ); ASSERT( m_nWidth == bitmap.bmWidth && m_nHeight == bitmap.bmHeight ); } // Change size of control as same as the bitmap. SetWindowPos(NULL, 0, 0, m_nWidth, m_nHeight, SWP_NOZORDER | SWP_NOMOVE); GetClientRect( &m_rect ); m_bTransparentChannel = bTransparent; m_bChannel = TRUE; return TRUE;}// Load bitmaps for a thumb//// Parameters:// [IN] nThumbID// ID number of the bitmap resource of the thumb// [IN] nActiveID// ID number of the bitmap resource of the active thumb// [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 CBitmapSlider::SetBitmapThumb( UINT nThumbID, UINT nActiveID, BOOL bTransparent, COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY ){ // This control will not have bitmap if( !nThumbID ) { m_bThumb = FALSE; m_bmThumb.DeleteObject(); m_bmThumbMask.DeleteObject(); m_bmThumbActive.DeleteObject(); m_bmThumbActiveMask.DeleteObject(); m_bmThumbBg.DeleteObject(); return TRUE; } // load a bitmap m_bmThumb.DeleteObject(); if( !m_bmThumb.LoadBitmap( nThumbID ) ) return FALSE; // Prepare mask for transparency effect. if( bTransparent ) { PrepareMask( &m_bmThumb, &m_bmThumbMask, clrpTransColor, iTransPixelX, iTransPixelY ); } // Load a bitmap for active state. if( nActiveID ) { m_bmThumbActive.DeleteObject(); if( !m_bmThumbActive.LoadBitmap( nActiveID ) ) { m_bmThumb.DeleteObject(); if( bTransparent ) m_bmThumbMask.DeleteObject(); return FALSE; } if( bTransparent ) { PrepareMask( &m_bmThumbActive, &m_bmThumbActiveMask, clrpTransColor, iTransPixelX, iTransPixelY ); } m_bThumbActive = TRUE; // There is no bitmap for active state. } else m_bThumbActive = FALSE; // Get size of the bitmap BITMAP bitmap; m_bmThumb.GetBitmap( &bitmap ); m_nThumbWidth = bitmap.bmWidth; m_nThumbHeight = bitmap.bmHeight; // Get size of the control if there was no bitmap for channel. if( !m_bChannel ) { GetClientRect( &m_rect ); m_nHeight = m_rect.Height(); m_nWidth = m_rect.Width(); } ASSERT( m_nThumbWidth <= m_nWidth && m_nThumbHeight <= m_nHeight ); // Compare size if( m_bThumbActive ) { BITMAP bitmap; m_bmThumbActive.GetBitmap( &bitmap ); ASSERT( m_nThumbWidth == bitmap.bmWidth && m_nThumbHeight == bitmap.bmHeight ); } // Set attributes m_bTransparentThumb = bTransparent; m_bThumb = TRUE; return TRUE;}// OnLButtonDown//// Dragging is started//void CBitmapSlider::OnLButtonDown(UINT nFlags, CPoint point) { if (!m_bEnable || !m_bEnableEx) 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 CBitmapSlider::OnMouseMove(UINT nFlags, CPoint point) { if (!m_bLButtonDown || !m_bEnable || !m_bEnableEx) 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);}BOOL CBitmapSlider::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt){ m_nPos += (zDelta < 0 ? 1 : -1); SetPos(m_nPos); ::PostMessage( GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED, GetDlgCtrlID(), m_nPos); return CStatic::OnMouseWheel(nFlags, zDelta, pt);}// OnLButtonUp//// Dragging is finished//void CBitmapSlider::OnLButtonUp(UINT nFlags, CPoint point) { if (!m_bEnable || !m_bEnableEx) return; ReleaseCapture(); m_bLButtonDown = FALSE; Invalidate(); ::PostMessage( GetParent()->GetSafeHwnd(), WM_BITMAPSLIDER_MOVED, GetDlgCtrlID(), m_nPos ); CStatic::OnLButtonUp(nFlags, point);}// Calculate point of thumb from position value//int CBitmapSlider::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 CBitmapSlider::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 ) ); }}// Copy background image to bitmap//void CBitmapSlider::CopyBackground( CDC *pDC, int nXSrc, int nYSrc, int nWidth, int nHeight, CBitmap *pBmDst){ pBmDst->DeleteObject(); pBmDst->CreateCompatibleBitmap( pDC, nWidth, nHeight ); CDC memDC; memDC.CreateCompatibleDC( pDC ); CBitmap *pBmTmp = memDC.SelectObject( pBmDst ); memDC.BitBlt( 0, 0, nWidth, nHeight, pDC, nXSrc, nYSrc, SRCCOPY ); memDC.SelectObject( pBmTmp ); memDC.DeleteDC();}// Restore background image from bitmap//void CBitmapSlider::RestoreBackground( CDC *pDC, int nXDst, int nYDst, int nWidth, int nHeight, CBitmap *pBmSrc){ CDC memDC; memDC.CreateCompatibleDC( pDC ); CBitmap *pBmTmp = memDC.SelectObject( pBmSrc ); pDC->BitBlt( nXDst, nYDst, nWidth, nHeight, &memDC, 0, 0, SRCCOPY ); memDC.SelectObject( pBmTmp ); memDC.DeleteDC();}// DrawBitmap//// It's for code readability//void CBitmapSlider::DrawBitmap( CDC *pDC, int xStart, int yStart, int wWidth, int wHeight, CDC *pTmpDC, int xSource, int ySource, CBitmap *bmMask, BOOL bTransparent ){ if( bTransparent ) { DrawTransparentBitmap( pDC, xStart, yStart, wWidth, wHeight, pTmpDC, xSource, ySource, bmMask ); } else { pDC->BitBlt( xStart, yStart, wWidth, wHeight, pTmpDC, xSource, ySource, SRCCOPY ); }}// PrepareMask//// "Drawing Transparent Bitmap with ease with on the fly masks in MFC"// By Raja Segar//// I changed default clrpTransColor value from NULL(black) to 0xFF000000(not RGB color)//void CBitmapSlider::PrepareMask( CBitmap *pBmpSource, CBitmap *pBmpMask, COLORREF clrpTransColor, int iTransPixelX, int iTransPixelY){ BITMAP bm; // Get the dimensions of the source bitmap pBmpSource->GetObject(sizeof(BITMAP), &bm); // Create the mask bitmap pBmpMask->DeleteObject(); pBmpMask->CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL); // We will need two DCs to work with. One to hold the Image // (the source), and one to hold the mask (destination). // When blitting onto a monochrome bitmap from a color, pixels // in the source color bitmap that are equal to the background // color are blitted as white. All the remaining pixels are // blitted as black. CDC hdcSrc, hdcDst; hdcSrc.CreateCompatibleDC(NULL); hdcDst.CreateCompatibleDC(NULL); // Load the bitmaps into memory DC CBitmap* hbmSrcT = (CBitmap*) hdcSrc.SelectObject(pBmpSource); CBitmap* hbmDstT = (CBitmap*) hdcDst.SelectObject(pBmpMask); // Dynamically get the transparent color COLORREF clrTrans; if (clrpTransColor == 0xFF000000) { // User did not specify trans color so get it from bmp clrTrans = hdcSrc.GetPixel(iTransPixelX, iTransPixelY); } else { clrTrans = clrpTransColor; } // Change the background to trans color COLORREF clrSaveBk = hdcSrc.SetBkColor(clrTrans); // This call sets up the mask bitmap. hdcDst.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcSrc,0,0,SRCCOPY); // Now, we need to paint onto the original image, making // sure that the "transparent" area is set to black. What // we do is AND the monochrome image onto the color Image // first. When blitting from mono to color, the monochrome // pixel is first transformed as follows: // if 1 (black) it is mapped to the color set by SetTextColor(). // if 0 (white) is is mapped to the color set by SetBkColor(). // Only then is the raster operation performed. COLORREF clrSaveDstText = hdcSrc.SetTextColor(RGB(255,255,255)); hdcSrc.SetBkColor(RGB(0,0,0)); hdcSrc.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &hdcDst,0,0,SRCAND); // Clean up by deselecting any objects, and delete the // DC's. hdcDst.SetTextColor(clrSaveDstText); hdcSrc.SetBkColor(clrSaveBk); hdcSrc.SelectObject(hbmSrcT); hdcDst.SelectObject(hbmDstT); hdcSrc.DeleteDC(); hdcDst.DeleteDC();}// DrawTransparentBitmap//// "Drawing Transparent Bitmap with ease with on the fly masks in MFC"// By Raja Segar//void CBitmapSlider::DrawTransparentBitmap( CDC *pDC, int xStart, int yStart, int wWidth, int wHeight, CDC *pTmpDC, int xSource, int ySource, CBitmap *bmMask ){ // We are going to paint the two DDB's in sequence to the destination. // 1st the monochrome bitmap will be blitted using an AND operation to // cut a hole in the destination. The color image will then be ORed // with the destination, filling it into the hole, but leaving the // surrounding area untouched. CDC hdcMem; hdcMem.CreateCompatibleDC(NULL); CBitmap* hbmT = hdcMem.SelectObject(bmMask); pDC->BitBlt( xStart, yStart, wWidth, wHeight, &hdcMem, xSource, ySource, SRCAND); // Also note the use of SRCPAINT rather than SRCCOPY. pDC->BitBlt(xStart, yStart, wWidth, wHeight, pTmpDC, xSource, ySource,SRCPAINT); // Now, clean up. hdcMem.SelectObject(hbmT); hdcMem.DeleteDC();}// To get keyboard input//UINT CBitmapSlider::OnGetDlgCode() { if( GetKeyState(VK_TAB) >= 0 ) { return DLGC_WANTALLKEYS; } return CStatic::OnGetDlgCode();}// Handling keyboard input//void CBitmapSlider::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if (!m_bEnable || !m_bEnableEx) 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 CBitmapSlider::OnKillFocus(CWnd* pNewWnd) { CStatic::OnKillFocus(pNewWnd); m_bFocus = FALSE; Invalidate();}// This control gains its focus//void CBitmapSlider::OnSetFocus(CWnd* pOldWnd) { CStatic::OnSetFocus(pOldWnd); m_bFocus = TRUE; Invalidate();}// Release resources//void CBitmapSlider::OnDestroy() { CStatic::OnDestroy(); m_bmThumb.DeleteObject(); m_bmThumbMask.DeleteObject(); m_bmThumbActive.DeleteObject(); m_bmThumbActiveMask.DeleteObject(); m_bmThumbBg.DeleteObject(); m_bmChannel.DeleteObject(); m_bmChannelMask.DeleteObject(); m_bmChannelActive.DeleteObject(); m_bmChannelActiveMask.DeleteObject();}
有点一点需要注意:
如果窗口是滑动显示 ,需要做一些特殊处理:
::AnimateWindow(wnd_.GetSafeHwnd(), 500, AW_ACTIVATE | AW_HOR_POSITIVE);
在滑动之后 调用一下
slider_.ShowWindow(SW_HIDE);slider_.ShowWindow(SW_SHOW);
0 0
- CBitmapSlider扩展
- CButtonST,CBitmapSlider使用技巧
- 扩展
- 扩展
- 扩展
- 扩展
- 扩展
- 扩展欧几里得及其扩展
- 扩展CRT&&扩展lucas
- 扩展JAAS
- XML扩展
- 扩展Struts
- 扩展Struts
- ListView扩展
- luasql扩展
- 符号扩展
- 扩展功能
- 扩展 PHP
- SQL Server 2005 查看数据库表的大小 按照表大小排列
- USB开发—自上而下(三)
- 【手势交互】2. 分类
- jquery easyui datagrid 设置设置在选中
- Butter Knife简单使用教程
- CBitmapSlider扩展
- c++ map的使用 出现次数最多的数
- Tablayout(Android) 的几个重要属性
- java Class.getResource和ClassLoader.getResource的区别分析
- JAVA 读取XML实例
- leetoj Partition List
- Jquery Easyui datagrid如何在动态获取当前选中行的值
- PhysicsBody物理世界
- Spring MVC入门