日本2017最新r级:自绘滚动条
来源:百度文库 编辑:偶看新闻 时间:2024/05/08 00:36:10
我自己做的自定义滚动条,练练手。 自定义一个CCustomScroll类,从CWnd中派生 头文件(h)源码class CCustomScroll : public CWnd
{
// Construction
public:
CCustomScroll();
UINT m_ThumbWidth; //滚动块和箭头宽度
UINT m_ThumbHeight; //滚动块和箭头高度
CWnd* m_pParent; //父窗口
CRect m_ClientRect; //窗口客户区域 CRect m_ThumbRect; //滚动块区域 BOOL m_ButtonDown; //鼠标是否单击滚动块
CPoint m_Startpt; //鼠标按下时的起点
BOOL m_IsLeft; //滚动块是否超过左箭头
BOOL m_IsLeftArrow; //是否单击左滚动条按钮
BOOL m_IsRightArrow;//是否单击右滚动条按钮
BOOL m_IsLeftRange; //是否单击了左滚动区域
BOOL m_IsRightRange;//是否单击了右滚动区域 UINT m_MinRange; //最小滚动范围
UINT m_MaxRange; //最大滚动范围
UINT m_CurPos; //当前的位置(逻辑单位)
double m_Rate; //物理像素与逻辑单位的比率 UINT m_LeftArrow; //左箭头位图ID
UINT m_RightArrow; //右箭头位图ID
UINT m_ChanelBK; //背景位图ID
UINT m_ThumbBK; //滚动块位图ID// Attributes
public:// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCustomScroll)
//}}AFX_VIRTUAL// Implementation
public:
void SetScrollRange(int minRange,int maxRange);
void DrawHorScroll();
void DrawControl();
virtual ~CCustomScroll(); // Generated message map functions
protected:
//{{AFX_MSG(CCustomScroll)
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG DECLARE_MESSAGE_MAP()
}; 执行文件(cpp)源 为了防止画面闪烁用了双缓冲绘图技术(就是在内存设备上下文里画图,然后用StretchBlt往屏幕设备上下文上贴图防止画面闪烁图技术),具体定义可以上网去查,这里不做太多说明。我再次写了一个CMemDC 类。 class CMemDC : public CDC
{
private:
CBitmap* m_bmp;
CBitmap* m_oldbmp;
CDC* m_pDC;
CRect m_Rect;
public:
CMemDC(CDC* pDC, const CRect& rect) : CDC()
{
CreateCompatibleDC(pDC);
m_bmp = new CBitmap;
m_bmp->CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
m_oldbmp = SelectObject(m_bmp);
m_pDC = pDC;
m_Rect = rect;
}
~CMemDC()
{
m_pDC->BitBlt(m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height(),
this, m_Rect.left, m_Rect.top, SRCCOPY);
SelectObject(m_oldbmp);
if (m_bmp != NULL)
delete m_bmp;
}
}; CCustomScroll::CCustomScroll()
{
m_ButtonDown = FALSE;//鼠标是否单击滚动块
m_IsLeft = FALSE;//滚动块是否超过左箭头
m_MinRange = 0;
m_MaxRange = 200;
m_CurPos = 0;
m_IsLeftArrow = FALSE;
m_IsRightArrow = FALSE;
m_IsLeftRange = FALSE;
m_IsRightRange = FALSE;
}CCustomScroll::~CCustomScroll()
{
}
BEGIN_MESSAGE_MAP(CCustomScroll, CStatic)
//{{AFX_MSG_MAP(CCustomScroll)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
响应WM_PAINT消息,自制滚动条的函数就在这里了void CCustomScroll::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawControl();
// Do not call CStatic::OnPaint() for painting messages
} void CCustomScroll::DrawControl()
{
DrawHorScroll(); //画水平滚动条// DrawVerScroll(); 这里可以画垂直滚动条,原理一样,就不在此写了
}void CCustomScroll::DrawHorScroll()
{ //其实就是在内存设备上下文里画图,然后用StretchBlt往屏幕设备上下文上贴图
CClientDC dc(this); CMemDC memdc(&dc,m_ClientRect);
CDC bmpdc;
bmpdc.CreateCompatibleDC(&dc); //当前匹配的CDC CBitmap bmp;
bmp.LoadBitmap(m_LeftArrow);//左箭头的图片
CBitmap* pOldbmp = bmpdc.SelectObject(&bmp); // 计算左箭头的位置
CRect LeftArrowRect (m_ClientRect.left,m_ClientRect.top,m_ClientRect.left+m_ThumbWidth,m_ClientRect.bottom);
memdc.StretchBlt(m_ClientRect.left,m_ClientRect.top,m_ThumbWidth,m_ThumbHeight,&bmpdc,0,0,m_ThumbWidth,m_ThumbHeight,SRCCOPY); if (pOldbmp)
bmpdc.SelectObject(pOldbmp);
if (bmp.GetSafeHandle())
bmp.DeleteObject(); pOldbmp = NULL;
//通道的开始位置和宽度
int nChanelStart = m_ClientRect.left+m_ThumbWidth;
int nChanelWidth = m_ClientRect.Width()- 2*m_ThumbWidth;
//绘制通道
bmp.LoadBitmap(m_ChanelBK); pOldbmp = bmpdc.SelectObject(&bmp); memdc.StretchBlt(nChanelStart,m_ClientRect.top,nChanelWidth,m_ClientRect.Height(),&bmpdc,0,0,1,10,SRCCOPY);
if (pOldbmp)
bmpdc.SelectObject(pOldbmp);
if (bmp.GetSafeHandle())
bmp.DeleteObject(); //绘制右箭头
bmp.LoadBitmap(m_RightArrow);
pOldbmp = bmpdc.SelectObject(&bmp); int nRArrowStart = m_ThumbWidth+nChanelWidth;
memdc.StretchBlt(nRArrowStart,m_ClientRect.top,m_ThumbWidth,m_ClientRect.Height(),&bmpdc,0,0,m_ThumbWidth,m_ThumbHeight,SRCCOPY);
//绘制滚动块
if (bmp.GetSafeHandle())
bmp.DeleteObject(); bmp.LoadBitmap(m_ThumbBK);
pOldbmp = bmpdc.SelectObject(&bmp);
memdc.StretchBlt(m_ThumbRect.left,m_ThumbRect.top,m_ThumbRect.Width()+1,m_ThumbRect.Height(),&bmpdc,0,0,m_ThumbRect.Width(),m_ThumbRect.Height(),SRCCOPY);} 下面这个函数是处理鼠标按下事件的,如果按下的是向上或者向下按钮,并且按住不放,那么Thumb必须连续移动,但是MFC是不处理按下不放的事件的,所以这里得设置一个定制器。还有个问题就是如果鼠标拖动Thumb,在拖动过程中鼠标移出了CScrollBarEx区域,MFC也不会处理鼠标移动事件的,要用SetCapture();来捕捉消息。注意要在鼠标谈起的时候释放捕捉ReleaseCapture() void CCustomScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
m_Startpt = point; //确定滚动区域
CRect rcScroll = m_ClientRect; rcScroll.left += m_ThumbWidth;
rcScroll.right-= m_ThumbWidth; SetCapture(); DWORD wparam;
if (m_ThumbRect.PtInRect(point))//判断是否点在滑动块上
{
m_ButtonDown = TRUE;
} else if (rcScroll.PtInRect(point)) //单击滚动区域 { CPoint centerPt = m_ThumbRect.CenterPoint();
int offset = point.x-centerPt.x;
if ((int)point.x m_IsLeftRange = TRUE;
if ((int)point.x>m_ThumbRect.right)//是否点击到右滚动区域
m_IsRightRange= TRUE; m_ThumbRect.OffsetRect(offset,0);滑动块移动 if (m_ThumbRect.left<(int)m_ThumbWidth) //判断当前滚动量是否超出了左滚动范围 { int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = m_MinRange; wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ; ::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawControl();
return; } else if (m_ThumbRect.right > right>(int)(m_ClientRect.Width()-m_ThumbWidth))//是否超出了右滚动范围 { int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = m_MinRange; wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ; ::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawControl();
return; } else { int range = m_ThumbRect.left-m_ThumbWidth;
m_CurPos = m_Rate*(range); if (m_IsLeftRange)
{
wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ;
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
}
else if (m_IsRightRange)
{
wparam = MAKELONG(SB_PAGERIGHT,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
}
DrawControl(); return; } } else //单击箭头按钮
{ if (point.x<=(int)m_ThumbWidth) //单击左箭头
{
if (m_CurPos>m_MinRange)
wparam = MAKELONG(SB_LINELEFT ,1);
else
wparam = MAKELONG(SB_LINELEFT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos>m_MinRange)
m_CurPos-=1;
m_IsLeftArrow = TRUE;
}
else //单击右箭头
{
if (m_CurPos>=m_MaxRange)
wparam = MAKELONG(SB_LINERIGHT ,0);
else
wparam = MAKELONG(SB_LINERIGHT ,1);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos m_CurPos+=1;
m_IsRightArrow = TRUE; }
int factpos = m_CurPos/m_Rate;
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth +factpos;
m_ThumbRect.right = m_ThumbRect.left+width; DrawControl();
SetTimer(1,100,NULL);
}
CWnd::OnLButtonDown(nFlags, point); } //定时器可以使一直按着左右键来控制滑动块变成可能void CCustomScroll::OnTimer(UINT nIDEvent)
{
DWORD wparam;
if (m_IsLeftArrow)
{
if (m_CurPos>m_MinRange)
wparam = MAKELONG(SB_LINELEFT ,1);
else
wparam = MAKELONG(SB_LINELEFT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos>m_MinRange)
m_CurPos-=1;
}
else if (m_IsRightArrow)
{
if (m_CurPos< m_MaxRange)
wparam = MAKELONG(SB_LINERIGHT,1);
else
wparam = MAKELONG(SB_LINERIGHT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos m_CurPos+=1;
}
int factpos = m_CurPos/m_Rate;
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth +factpos;
m_ThumbRect.right = m_ThumbRect.left+width;
DrawControl(); CWnd::OnTimer(nIDEvent);
} void CCustomScroll::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_ButtonDown)
{
int offset = point.x-m_Startpt.x;
m_Startpt = point;
DWORD wparam;
if (offset<=0) //向左拖动滚动块
{
if (m_ThumbRect.left<=(int)m_ThumbWidth)
return;
else if (abs(offset)>(int)(m_ThumbRect.left-m_ThumbWidth)) //判断当前滚动量是否超出了滚动范围
{
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = 0;
wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
DrawControl();
return;
}
}
else if (offset>0) //向右拖动滚动块
{
if (m_ThumbRect.right>=m_ClientRect.Width()-m_ThumbWidth) //超出右箭头
{
return;
}
else if ( offset> m_ClientRect.Width()-m_ThumbWidth-m_ThumbRect.right) //判断是否超出了滚动范围
{
int width = m_ThumbRect.Width();
m_ThumbRect.right = m_ClientRect.Width()-m_ThumbWidth;
m_ThumbRect.left = m_ThumbRect.right -width;
m_CurPos = m_MaxRange;
wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
DrawControl();
return;
}
}
m_ThumbRect.OffsetRect(offset,0);
int range = m_ThumbRect.left-m_ThumbWidth;
m_CurPos = m_Rate*(range); wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawHorScroll();
}
CWnd::OnMouseMove(nFlags, point);
}
void CCustomScroll::OnLButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
m_ButtonDown = FALSE;
m_IsLeftRange = FALSE;
m_IsRightRange = FALSE; if (m_IsLeftArrow)
{
m_IsLeftArrow = FALSE;
KillTimer(1);
}
if (m_IsRightArrow)
{
m_IsRightArrow = FALSE;
KillTimer(1);
} CWnd::OnLButtonUp(nFlags, point);
}
写到这里,自定义的CCustomScroll类基本写好了。我在VC2003下试了,没有问题,可以使用。
{
// Construction
public:
CCustomScroll();
UINT m_ThumbWidth; //滚动块和箭头宽度
UINT m_ThumbHeight; //滚动块和箭头高度
CWnd* m_pParent; //父窗口
CRect m_ClientRect; //窗口客户区域 CRect m_ThumbRect; //滚动块区域 BOOL m_ButtonDown; //鼠标是否单击滚动块
CPoint m_Startpt; //鼠标按下时的起点
BOOL m_IsLeft; //滚动块是否超过左箭头
BOOL m_IsLeftArrow; //是否单击左滚动条按钮
BOOL m_IsRightArrow;//是否单击右滚动条按钮
BOOL m_IsLeftRange; //是否单击了左滚动区域
BOOL m_IsRightRange;//是否单击了右滚动区域 UINT m_MinRange; //最小滚动范围
UINT m_MaxRange; //最大滚动范围
UINT m_CurPos; //当前的位置(逻辑单位)
double m_Rate; //物理像素与逻辑单位的比率 UINT m_LeftArrow; //左箭头位图ID
UINT m_RightArrow; //右箭头位图ID
UINT m_ChanelBK; //背景位图ID
UINT m_ThumbBK; //滚动块位图ID// Attributes
public:// Operations
public:// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCustomScroll)
//}}AFX_VIRTUAL// Implementation
public:
void SetScrollRange(int minRange,int maxRange);
void DrawHorScroll();
void DrawControl();
virtual ~CCustomScroll(); // Generated message map functions
protected:
//{{AFX_MSG(CCustomScroll)
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG DECLARE_MESSAGE_MAP()
}; 执行文件(cpp)源 为了防止画面闪烁用了双缓冲绘图技术(就是在内存设备上下文里画图,然后用StretchBlt往屏幕设备上下文上贴图防止画面闪烁图技术),具体定义可以上网去查,这里不做太多说明。我再次写了一个CMemDC 类。 class CMemDC : public CDC
{
private:
CBitmap* m_bmp;
CBitmap* m_oldbmp;
CDC* m_pDC;
CRect m_Rect;
public:
CMemDC(CDC* pDC, const CRect& rect) : CDC()
{
CreateCompatibleDC(pDC);
m_bmp = new CBitmap;
m_bmp->CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
m_oldbmp = SelectObject(m_bmp);
m_pDC = pDC;
m_Rect = rect;
}
~CMemDC()
{
m_pDC->BitBlt(m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height(),
this, m_Rect.left, m_Rect.top, SRCCOPY);
SelectObject(m_oldbmp);
if (m_bmp != NULL)
delete m_bmp;
}
}; CCustomScroll::CCustomScroll()
{
m_ButtonDown = FALSE;//鼠标是否单击滚动块
m_IsLeft = FALSE;//滚动块是否超过左箭头
m_MinRange = 0;
m_MaxRange = 200;
m_CurPos = 0;
m_IsLeftArrow = FALSE;
m_IsRightArrow = FALSE;
m_IsLeftRange = FALSE;
m_IsRightRange = FALSE;
}CCustomScroll::~CCustomScroll()
{
}
BEGIN_MESSAGE_MAP(CCustomScroll, CStatic)
//{{AFX_MSG_MAP(CCustomScroll)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
响应WM_PAINT消息,自制滚动条的函数就在这里了void CCustomScroll::OnPaint()
{
CPaintDC dc(this); // device context for painting
DrawControl();
// Do not call CStatic::OnPaint() for painting messages
} void CCustomScroll::DrawControl()
{
DrawHorScroll(); //画水平滚动条// DrawVerScroll(); 这里可以画垂直滚动条,原理一样,就不在此写了
}void CCustomScroll::DrawHorScroll()
{ //其实就是在内存设备上下文里画图,然后用StretchBlt往屏幕设备上下文上贴图
CClientDC dc(this); CMemDC memdc(&dc,m_ClientRect);
CDC bmpdc;
bmpdc.CreateCompatibleDC(&dc); //当前匹配的CDC CBitmap bmp;
bmp.LoadBitmap(m_LeftArrow);//左箭头的图片
CBitmap* pOldbmp = bmpdc.SelectObject(&bmp); // 计算左箭头的位置
CRect LeftArrowRect (m_ClientRect.left,m_ClientRect.top,m_ClientRect.left+m_ThumbWidth,m_ClientRect.bottom);
memdc.StretchBlt(m_ClientRect.left,m_ClientRect.top,m_ThumbWidth,m_ThumbHeight,&bmpdc,0,0,m_ThumbWidth,m_ThumbHeight,SRCCOPY); if (pOldbmp)
bmpdc.SelectObject(pOldbmp);
if (bmp.GetSafeHandle())
bmp.DeleteObject(); pOldbmp = NULL;
//通道的开始位置和宽度
int nChanelStart = m_ClientRect.left+m_ThumbWidth;
int nChanelWidth = m_ClientRect.Width()- 2*m_ThumbWidth;
//绘制通道
bmp.LoadBitmap(m_ChanelBK); pOldbmp = bmpdc.SelectObject(&bmp); memdc.StretchBlt(nChanelStart,m_ClientRect.top,nChanelWidth,m_ClientRect.Height(),&bmpdc,0,0,1,10,SRCCOPY);
if (pOldbmp)
bmpdc.SelectObject(pOldbmp);
if (bmp.GetSafeHandle())
bmp.DeleteObject(); //绘制右箭头
bmp.LoadBitmap(m_RightArrow);
pOldbmp = bmpdc.SelectObject(&bmp); int nRArrowStart = m_ThumbWidth+nChanelWidth;
memdc.StretchBlt(nRArrowStart,m_ClientRect.top,m_ThumbWidth,m_ClientRect.Height(),&bmpdc,0,0,m_ThumbWidth,m_ThumbHeight,SRCCOPY);
//绘制滚动块
if (bmp.GetSafeHandle())
bmp.DeleteObject(); bmp.LoadBitmap(m_ThumbBK);
pOldbmp = bmpdc.SelectObject(&bmp);
memdc.StretchBlt(m_ThumbRect.left,m_ThumbRect.top,m_ThumbRect.Width()+1,m_ThumbRect.Height(),&bmpdc,0,0,m_ThumbRect.Width(),m_ThumbRect.Height(),SRCCOPY);} 下面这个函数是处理鼠标按下事件的,如果按下的是向上或者向下按钮,并且按住不放,那么Thumb必须连续移动,但是MFC是不处理按下不放的事件的,所以这里得设置一个定制器。还有个问题就是如果鼠标拖动Thumb,在拖动过程中鼠标移出了CScrollBarEx区域,MFC也不会处理鼠标移动事件的,要用SetCapture();来捕捉消息。注意要在鼠标谈起的时候释放捕捉ReleaseCapture() void CCustomScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
m_Startpt = point; //确定滚动区域
CRect rcScroll = m_ClientRect; rcScroll.left += m_ThumbWidth;
rcScroll.right-= m_ThumbWidth; SetCapture(); DWORD wparam;
if (m_ThumbRect.PtInRect(point))//判断是否点在滑动块上
{
m_ButtonDown = TRUE;
} else if (rcScroll.PtInRect(point)) //单击滚动区域 { CPoint centerPt = m_ThumbRect.CenterPoint();
int offset = point.x-centerPt.x;
if ((int)point.x
if ((int)point.x>m_ThumbRect.right)//是否点击到右滚动区域
m_IsRightRange= TRUE; m_ThumbRect.OffsetRect(offset,0);滑动块移动 if (m_ThumbRect.left<(int)m_ThumbWidth) //判断当前滚动量是否超出了左滚动范围 { int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = m_MinRange; wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ; ::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawControl();
return; } else if (m_ThumbRect.right > right>(int)(m_ClientRect.Width()-m_ThumbWidth))//是否超出了右滚动范围 { int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = m_MinRange; wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ; ::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawControl();
return; } else { int range = m_ThumbRect.left-m_ThumbWidth;
m_CurPos = m_Rate*(range); if (m_IsLeftRange)
{
wparam = MAKELONG(SB_PAGELEFT,m_CurPos) ;
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
}
else if (m_IsRightRange)
{
wparam = MAKELONG(SB_PAGERIGHT,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
}
DrawControl(); return; } } else //单击箭头按钮
{ if (point.x<=(int)m_ThumbWidth) //单击左箭头
{
if (m_CurPos>m_MinRange)
wparam = MAKELONG(SB_LINELEFT ,1);
else
wparam = MAKELONG(SB_LINELEFT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos>m_MinRange)
m_CurPos-=1;
m_IsLeftArrow = TRUE;
}
else //单击右箭头
{
if (m_CurPos>=m_MaxRange)
wparam = MAKELONG(SB_LINERIGHT ,0);
else
wparam = MAKELONG(SB_LINERIGHT ,1);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos
m_IsRightArrow = TRUE; }
int factpos = m_CurPos/m_Rate;
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth +factpos;
m_ThumbRect.right = m_ThumbRect.left+width; DrawControl();
SetTimer(1,100,NULL);
}
CWnd::OnLButtonDown(nFlags, point); } //定时器可以使一直按着左右键来控制滑动块变成可能void CCustomScroll::OnTimer(UINT nIDEvent)
{
DWORD wparam;
if (m_IsLeftArrow)
{
if (m_CurPos>m_MinRange)
wparam = MAKELONG(SB_LINELEFT ,1);
else
wparam = MAKELONG(SB_LINELEFT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos>m_MinRange)
m_CurPos-=1;
}
else if (m_IsRightArrow)
{
if (m_CurPos< m_MaxRange)
wparam = MAKELONG(SB_LINERIGHT,1);
else
wparam = MAKELONG(SB_LINERIGHT ,0);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
if (m_CurPos
}
int factpos = m_CurPos/m_Rate;
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth +factpos;
m_ThumbRect.right = m_ThumbRect.left+width;
DrawControl(); CWnd::OnTimer(nIDEvent);
} void CCustomScroll::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_ButtonDown)
{
int offset = point.x-m_Startpt.x;
m_Startpt = point;
DWORD wparam;
if (offset<=0) //向左拖动滚动块
{
if (m_ThumbRect.left<=(int)m_ThumbWidth)
return;
else if (abs(offset)>(int)(m_ThumbRect.left-m_ThumbWidth)) //判断当前滚动量是否超出了滚动范围
{
int width = m_ThumbRect.Width();
m_ThumbRect.left = m_ThumbWidth;
m_ThumbRect.right = m_ThumbRect.left+width;
m_CurPos = 0;
wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
DrawControl();
return;
}
}
else if (offset>0) //向右拖动滚动块
{
if (m_ThumbRect.right>=m_ClientRect.Width()-m_ThumbWidth) //超出右箭头
{
return;
}
else if ( offset> m_ClientRect.Width()-m_ThumbWidth-m_ThumbRect.right) //判断是否超出了滚动范围
{
int width = m_ThumbRect.Width();
m_ThumbRect.right = m_ClientRect.Width()-m_ThumbWidth;
m_ThumbRect.left = m_ThumbRect.right -width;
m_CurPos = m_MaxRange;
wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd);
DrawControl();
return;
}
}
m_ThumbRect.OffsetRect(offset,0);
int range = m_ThumbRect.left-m_ThumbWidth;
m_CurPos = m_Rate*(range); wparam = MAKELONG(SB_THUMBPOSITION,m_CurPos);
::SendMessage(GetParent()->m_hWnd,WM_HSCROLL,wparam,(LPARAM)m_hWnd); DrawHorScroll();
}
CWnd::OnMouseMove(nFlags, point);
}
void CCustomScroll::OnLButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
m_ButtonDown = FALSE;
m_IsLeftRange = FALSE;
m_IsRightRange = FALSE; if (m_IsLeftArrow)
{
m_IsLeftArrow = FALSE;
KillTimer(1);
}
if (m_IsRightArrow)
{
m_IsRightArrow = FALSE;
KillTimer(1);
} CWnd::OnLButtonUp(nFlags, point);
}
写到这里,自定义的CCustomScroll类基本写好了。我在VC2003下试了,没有问题,可以使用。