skinscroll.cpp
来自「《Visual C++视频技术方案宝典》配套光盘」· C++ 代码 · 共 320 行
CPP
320 行
// SkinScroll.cpp : implementation file
//
#include "stdafx.h"
#include "CustomScroll.h"
#include "SkinScroll.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSkinScroll
CSkinScroll::CSkinScroll()
{
memset(&m_ScrollInfo,0,sizeof(SCROLLINFO));
m_ScrollInfo.nTrackPos = -1;
m_Pos = 0;
m_Pressed = FALSE;
m_DragPos = 0;
m_ClickState = caNone;
}
CSkinScroll::~CSkinScroll()
{
}
BEGIN_MESSAGE_MAP(CSkinScroll, CScrollBar)
//{{AFX_MSG_MAP(CSkinScroll)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSkinScroll message handlers
void CSkinScroll::OnPaint()
{
CPaintDC dc(this); // device context for painting
CBitmap bmp;
BOOL type = IsVert();
//绘制左箭头
if (type) //水平滚动条
bmp.LoadBitmap(IDB_UPARROW);
else
bmp.LoadBitmap(IDB_LEFTARROW);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject(bmp);
BITMAP bInfo;
bmp.GetBitmap(&bInfo);
int x = bInfo.bmWidth;
int y = bInfo.bmHeight;
CRect rc;
GetClientRect(rc);
if (type)
m_HLeftArrow.CopyRect(CRect(0,0,x,y));
else
m_HLeftArrow.CopyRect(CRect(-1,0,x,y));
dc.BitBlt(m_HLeftArrow.left,m_HLeftArrow.top,m_HLeftArrow.Width(),m_HLeftArrow.Height(),&memDC,0,0,SRCCOPY);
bmp.DeleteObject();
//绘制右箭头
if (type)
bmp.LoadBitmap(IDB_DOWNARROW);
else
bmp.LoadBitmap(IDB_RIGHTARROW);
memDC.SelectObject(bmp);
if (type)
m_HRightArrow.CopyRect(CRect(0,rc.Height()-16,x,rc.Height()));
else
m_HRightArrow.CopyRect(CRect(rc.right-16,0,rc.right-16+x,y));
dc.StretchBlt(m_HRightArrow.left,m_HRightArrow.top,m_HRightArrow.Width(),m_HRightArrow.Height(),&memDC,0,0,x,y,SRCCOPY);
bmp.DeleteObject();
//绘制通道
if (type)
bmp.LoadBitmap(IDB_VCHANEL);
else
bmp.LoadBitmap(IDB_CHANEL);
memDC.SelectObject(bmp);
bmp.GetBitmap(&bInfo);
x = bInfo.bmWidth;
y = bInfo.bmHeight;
if (type)
dc.StretchBlt(-1,16,x,rc.Height()-16*2,&memDC,0,0,x,y,SRCCOPY);
else
dc.StretchBlt(16,0,rc.right-32,y,&memDC,0,0,x,y,SRCCOPY);
bmp.DeleteObject();
if (type)
bmp.LoadBitmap(IDB_VTHUMB);
else
bmp.LoadBitmap(IDB_HTHUMB);
bmp.GetBitmap(&bInfo);
memDC.SelectObject(&bmp);
x = bInfo.bmWidth;
y = bInfo.bmHeight;
//获取滚动块去除箭头的宽度或高度
int width = 0;
if (type)
width = rc.Height()-16*2;
else
width = rc.Width()-16*2;
//滚动块宽度
m_ThumbWidth = m_ScrollInfo.nPage*width/(m_ScrollInfo.nMax-m_ScrollInfo.nMin+1);
int pos = m_Pos*(width)/(m_ScrollInfo.nMax-m_ScrollInfo.nMin+1)+16;
if (type)
m_ThumbRC.CopyRect(CRect(0,pos,16,pos+m_ThumbWidth));
else
m_ThumbRC.CopyRect(CRect(pos,0,pos+m_ThumbWidth,16));
if (m_ScrollInfo.nPage<=m_ScrollInfo.nMax-m_ScrollInfo.nMin)
dc.StretchBlt(m_ThumbRC.left,m_ThumbRC.top,m_ThumbRC.Width(),m_ThumbRC.Height(),&memDC,0,0,x,y,SRCCOPY);
bmp.DeleteObject();
memDC.DeleteDC();
}
void CSkinScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
SetCapture();
m_Point = point;
if (m_ThumbRC.PtInRect(m_Point))
m_Pressed = TRUE;
else
m_Pressed = FALSE;
m_DragPos = m_ScrollInfo.nPos;
m_ClickState = caNone;
BOOL type = IsVert();
//单击滚动条箭头时设置滚动块位置
if (m_HLeftArrow.PtInRect(point))
{
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_LINEUP,0),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_LINELEFT,0),(LPARAM)m_hWnd);
m_ClickState = caLeft;
SetTimer(1,100,NULL);
}
else if (m_HRightArrow.PtInRect(point))
{
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_LINEDOWN,0),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_LINERIGHT,0),(LPARAM)m_hWnd);
m_ClickState = caRight;
SetTimer(1,100,NULL);
}
else if (m_Pressed == FALSE) //单击滚动区域时设置滚动块的位置
{
if (type)
{
if (m_ThumbRC.top>point.y) //单击滚动块左边的区域
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_PAGEUP,0),(LPARAM)m_hWnd);
else if ((m_ThumbRC.top<point.y)) //单击滚动块右边的区域
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_PAGEDOWN,0),(LPARAM)m_hWnd);
}
else
{
if (m_ThumbRC.left>point.x) //单击滚动块左边的区域
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_PAGELEFT,0),(LPARAM)m_hWnd);
else if ((m_ThumbRC.left<point.x)) //单击滚动块右边的区域
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_PAGERIGHT,0),(LPARAM)m_hWnd);
}
}
}
void CSkinScroll::OnLButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
m_ClickState = caNone;
KillTimer(1);
BOOL type = IsVert();
if (m_Pressed)
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_THUMBPOSITION,m_Pos),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_THUMBPOSITION,m_Pos),(LPARAM)m_hWnd);
m_Pressed = FALSE;
}
void CSkinScroll::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_Pressed ) //处于拖动状态
{
BOOL type = IsVert();
CRect rc;
GetClientRect(rc);
int width;//去除滚动条2个按钮的宽度或高度
if (type)
width = rc.Height()-16*2;
else
width = rc.Width()-16*2;
int movepos = 0;
if (type)
movepos = point.y-m_Point.y;
else
movepos = point.x-m_Point.x;
movepos =(int)( (m_ScrollInfo.nMax-m_ScrollInfo.nMin+1-m_ScrollInfo.nPage)/(double)(width-m_ThumbWidth)*(movepos));
movepos+=m_DragPos;
if (movepos< m_ScrollInfo.nMin)
movepos = m_ScrollInfo.nMin;
if (movepos> (m_ScrollInfo.nMax-m_ScrollInfo.nMin+1-m_ScrollInfo.nPage))
movepos = m_ScrollInfo.nMax-m_ScrollInfo.nMin+1-m_ScrollInfo.nPage;
if (movepos>=0)
m_Pos = movepos;
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_THUMBTRACK,m_Pos),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_THUMBTRACK,m_Pos),(LPARAM)m_hWnd);
Invalidate();
}
}
void CSkinScroll::OnSize(UINT nType, int cx, int cy)
{
CScrollBar::OnSize(nType, cx, cy);
OnPaint();
}
void CSkinScroll::OnTimer(UINT nIDEvent)
{
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
BOOL type = IsVert();
if (m_ClickState==caLeft)
{
if (m_Pos > m_ScrollInfo.nMin)
if (m_HLeftArrow.PtInRect(pt))
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_LINEUP,0),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_LINELEFT,0),(LPARAM)m_hWnd);
}
else if (m_ClickState ==caRight)
{
if (m_Pos< m_ScrollInfo.nMax)
if (m_HRightArrow.PtInRect(pt))
if (type)
GetParent()->SendMessage(WM_VSCROLL,MAKELONG(SB_LINEDOWN,0),(LPARAM)m_hWnd);
else
GetParent()->SendMessage(WM_HSCROLL,MAKELONG(SB_LINERIGHT,0),(LPARAM)m_hWnd);
}
}
LRESULT CSkinScroll::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
//阻止滚动条的双击事件
if(message==WM_LBUTTONDBLCLK)
return 1;
if(message==SBM_SETSCROLLINFO)
{
BOOL NeedDraw=wParam;
LPSCROLLINFO pInfo=(LPSCROLLINFO)lParam;
if(pInfo->fMask&SIF_PAGE)
m_ScrollInfo.nPage=pInfo->nPage;
if(pInfo->fMask&SIF_POS)
m_ScrollInfo.nPos=pInfo->nPos;
if(pInfo->fMask&SIF_RANGE)
{
m_ScrollInfo.nMin=pInfo->nMin;
m_ScrollInfo.nMax=pInfo->nMax;
}
if(NeedDraw)
{
m_Pos = m_ScrollInfo.nPos;
Invalidate();
}
return TRUE;
}
if(message==SBM_GETSCROLLINFO)
{
LPSCROLLINFO pInfo=(LPSCROLLINFO)lParam;
int flags=pInfo->fMask;
if(flags&SIF_PAGE)
pInfo->nPage=m_ScrollInfo.nPage;
if(flags&SIF_POS)
pInfo->nPos=m_ScrollInfo.nPos;
if(flags&SIF_TRACKPOS)
pInfo->nTrackPos=m_ScrollInfo.nTrackPos;
if(flags&SIF_RANGE)
{
pInfo->nMin=m_ScrollInfo.nMin;
pInfo->nMax=m_ScrollInfo.nMax;
}
return TRUE;
}
return CScrollBar::WindowProc(message, wParam, lParam);
}
BOOL CSkinScroll::IsVert()
{
return GetStyle()& SBS_VERT;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?