Table of contents
-
-
- 01. Scroll bar class
-
- 1.1, SCROLLINFO structure
- 1.2. Set the position of the slider
- 1.3. Set the maximum and minimum values
- 1.4. Obtain the parameters of the scroll bar, including the minimum and maximum values of the scroll bar position, the page size, and the position of the scroll button
- 1.5. Set the parameters of the scroll bar (same as above)
- 1.6. Obtain the maximum position of the scroll block
- 02. Base class design
-
01. Scroll bar class
The scroll bar is an object of the CScrollBar class. It is a very important control in Windows applications. It is usually attached to the dialog box to help observe data or determine the position. It can also be used as a tool for data input. There are two types of scroll bars, horizontal and vertical.
The previous article also talked about the programming method of the vertical scroll bar, but it is based on the content of the content copy on the Internet. Here, after my own research, a base class is encapsulated, so that it is convenient to use this method directly by inheriting the base class through subclasses in the future. Before understanding some methods, first understand a structure:SCROLLINFO
1.1, SCROLLINFO structure
typedef struct tagSCROLLINFO {
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, *LPSCROLLINFO;
Member description:
cbSize: The length in bytes of the SCROLLINFO structure, which must be filled in when setting and querying parameters.
fMask: Specifies which members in the structure are valid. There are 5 options for this value, and multiple options can be combined with "OR". The value is in
It must be filled in when setting and querying parameters.
SIF_ALL: The entire structure is valid
SIF_DISABLENOSCROLL: This value is only used when setting parameters, and the members of this structure are selected according to the needs of control parameter settings.
SIF_PAGE: valid for nPage members SIF_POS
: valid for nPos members SIF_RANGE : valid for nMin
and nMax members The position of the scroll box when dragging, this parameter can only be queried, not set.
Introduce several functions: SetScrollPos
, SetScrollRange
, SetScrollInfo
, GetScrollInfo
,GetScrollLimit
1.2. Set the position of the slider
int SetScrollPos( int nPos , BOOL bRedraw = TRUE );
Parameter description:
①: nPos indicates the position of the slider.
②: Redraw the scroll bar when bRedraw is TRUE.
1.3. Set the maximum and minimum values
void SetScrollRange(int nMinPos , int nMaxPos , BOOL bRedraw = TRUE);
Parameter description:
①: nMinPos indicates the minimum value
②: nMinPos indicates the maximum value.
③: Redraw the scroll bar when bRedraw is TRUE.
1.4. Obtain the parameters of the scroll bar, including the minimum and maximum values of the scroll bar position, the page size, and the position of the scroll button
BOOL GetScrolllnfo(int nBar, LPSCROLLINFO lpScrollInfo, UINT nMask = SIF_ALL);
Parameter description:
①: nBar: Specify the type of the scroll bar parameter to be retrieved
②: lpScrollInfo: Point to the SCROLLINFO structure
③: nMask: Specify which members of the structure to use, and those not specified will not be used
1.5. Set the parameters of the scroll bar (same as above)
BOOL SetScrollInfo(int nBar, LPSCORLLINFO lpScrollInfo, BOOL bRedraw = TRUE);
Parameter description:
①: nBar: Specifies the type of the scroll bar parameter to be retrieved
②: lpScrollInfo: Points to the SCROLLINFO structure
③: bRedraw: Whether to redraw the scroll bar, if it is TRUE, it means redraw
1.6. Obtain the maximum position of the scroll block
int GetScrollLimit(int nBar);
Parameter description:
①: nBar: Specifies the type of the scroll bar parameter to be obtained
02. Base class design
After we understand some of the functions and the relevant knowledge of the SCROLLINFO structure, you will not be confused when you look at my base class encapsulation, so go directly to the code!
Instructions:
CScrollDialog dialog box: the window base class that supports scroll bars
Usage: Based on this class, the dialog box is derived, and the message handlers for the four events of OnHScroll, OnVScroll, OnSize, and OnShowWindow are added to the derived class
2.1、ScrollDialog.h
#pragma once
class CScrollDialog : public CDialog
{
DECLARE_DYNAMIC(CScrollDialog)
public:
CScrollDialog(UINT nIDTemplate, CWnd* pParent = NULL); //构造函数
virtual ~CScrollDialog();
void UpDateWindows(); //更新窗口大小
private:
int m_nInitWidth; //初始化宽度
int m_nInitHeight; //初始化高度
int m_nCurWidth; //当前宽度
int m_nCurHeight; //当前高度
int m_nOldPosX;
int m_nOldPosY;
BOOL m_bSized;
protected:
virtual void DoDataExchange(CDataExchange* pDX); //DDX/DDV 支持
/* DECLARE_MESSAGE_MAP */
public:
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
};
2.2、ScrollDialog.cpp
#include "stdafx.h"
#include "ScrollDialog.h"
IMPLEMENT_DYNAMIC(CScrollDialog, CDialog)
CScrollDialog::CScrollDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
: CDialog(nIDTemplate, pParent)
{
m_nInitWidth = 0;
m_nInitHeight = 0;
m_nCurWidth = 0;
m_nCurHeight= 0;
m_nOldPosX = 0;
m_nOldPosY = 0;
m_bSized = FALSE;
}
CScrollDialog::~CScrollDialog()
{
}
void CScrollDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
void CScrollDialog::OnScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int minpos = 0;
int maxpos = 0;
GetScrollRange(SB_HORZ, &minpos, &maxpos);
maxpos = GetScrollLimit(SB_HORZ);
//得到当前水平滚动条的位置
int curpos = GetScrollPos(SB_HORZ);
//确定新的滚动条位置
switch (nSBCode)
{
case SB_LEFT:
curpos = minpos;
break;
case SB_RIGHT:
curpos = maxpos;
break;
case SB_ENDSCROLL:
break;
case SB_LINELEFT:
if(curpos > minpos)
curpos--;
break;
case SB_LINERIGHT:
if(curpos < maxpos)
curpos++;
break;
case SB_PAGELEFT:
{
//获得页长度
SCROLLINFO info;
GetScrollInfo(SB_HORZ, &info, SIF_ALL);
if(curpos > minpos)
curpos = max(minpos, curpos - (int)info.nPage); //减去滑块的长度再做判断
}
break;
case SB_PAGERIGHT:
{
SCROLLINFO info;
GetScrollInfo(SB_HORZ, &info, SIF_ALL);
if(curpos < maxpos)
curpos = min(maxpos, curpos + (int)info.nPage);
}
break;
case SB_THUMBPOSITION: //滚动到绝对位置(nPos为该位置)
curpos = nPos; //拖动操作结束时的滚动框的位置
break;
case SB_THUMBTRACK: //将滚动框拖动到指定位置nPos
curpos = nPos;
break;
}
//设置新的位置
SetScrollPos(SB_HORZ, curpos);
SCrollWindow(m_nOldPosX - curpos, 0);
m_nOldPosX = curpos;
UpdateWindow();
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CScrollDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int minpos = 0;
int maxpos = 0;
GetScrollRange(SB_VERT, &minpos, &maxpos);
maxpos = GetScrollLimit(SB_VERT);
int curpos = GetScrollPos(SB_VERT);
switch (nSBCode)
{
case SB_TOP:
curpos = minpos;
break;
case SB_BOTTOM:
curpos = maxpos;
break;
case SB_ENDSCROLL:
break;
case SB_LINEUP
if(curpos > minpos)
curpos--;
break;
case SB_LINEDOWN:
if(curpos < maxpos)
curpos++;
break;
case SB_PAGEUP:
{
SCROLLINFO info;
GetScrollInfo(SB_VERT, &info, SIF_ALL);
if(curpos > minpos)
curpos = max(minpos, curpos - (int)info.nPage);
}
break;
case SB_PAGEDOWN:
{
SCROLLINFO info;
GetScrollInfo(SB_VERT, &info, SIF_ALL);
if(curpos > minpos)
curpos = max(minpos, curpos + (int)info.nPage);
}
break;
case SB_THUMBPOSITION: //滚动到绝对位置(nPos为该位置)
curpos = nPos; //拖动操作结束时的滚动框的位置
break;
case SB_THUMBTRACK: //将滚动框拖动到指定位置nPos
curpos = nPos;
break;
}
//设置新的位置
SetScrollPos(SB_VERT, curpos);
SCrollWindow(0,m_nOldPosY - curpos);
m_nOldPosY = curpos;
UpdateWindow();
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CScrollDialog::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType,cx,cy);
if(!m_bSized)
{
//获取窗口初始大小(一般为创建时资源文件中定义的尺寸)
m_nInitWidth = cx;
m_nInitHeight = cy;
m_bSized = TRUE;
}
//更新当前窗口大小
m_nCurWidth = cx;
m_nCurHeight = cy;
UpdateWindow();
}
void CScrollDialog::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow,nStatus);
if(bShow)
{
//显示窗口时动态显示滚动条并设置滚动条范围或者隐藏滚动条
UpDataWindow();
}
}
void CScrollDialog::UpDateWindow()
{
SCROLLINFO si = {
0 };
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
GetScrollInfo(SB_HORZ, &si);
si.nMin = 0;
si.nMax = m_nInitWidth;
if(si.nPos > si.nMax)
{
si.nPos = si.nMax;
}
si.nPage = m_nCurWidth;
if(si.nPage >= (UINT)si.nMax)
{
//刚好一页,不要滚动条
ShowScrollBar(SB_HORZ, SW_HIDE);
}
else {
ShowScrollBar(SB_HORZ, SW_SHOW);
SetScrollInfo(SB_HORZ, &si);
ScrollWindow(m_nOldPosX - si.nPos, 0);
m_nOldPosX = si.nPos;
}
GetScrollInfo(SB_VERT, &si);
si.nMin = 0;
si.nMax = m_nInitHeight;
if(si.nPos > si.nMax)
{
si.nPos = si.nMax;
}
si.nPage = m_NCurHeight;
if(sinPage >= (UINT)si.nMax)
{
//刚好一页,隐藏滚动条
ShowScrollBar(SB_VERT, SW_HIDE);
}
else {
ShowScrollBar(SB_VERT, SW_SHOW);
SetScrollInfo(SB_VERT, &si);
ScrollWindow(0, m_nOldPosY - si.nPos);
m_nOldPosY = si.nPos;
}
UpdateWindow(); //更新窗口显示
}
This is the end of the base class encapsulation of the scroll bar. If you have any problems during use, please discuss and make progress together.
Copyright Notice: Please indicate the source of the reprint, original article, thank you!