您的位置:首页 > 其它

MFC对话框处理滚动条

2018-03-08 11:02 260 查看
MFC对话框处理滚动条
flyfish
原理
nMin
Specifies the minimum scrolling position.
滚动条范围最小值
nMax
Specifies the maximum scrolling position.
滚动条范围最大值
nPage
Specifies the page size. A scroll bar uses this value to determine the appropriate size of the
proportional scroll box.
页尺寸,用来确定比例滚动条的大小
nPos
Specifies the position of the scroll box.
滚动条的位置
以垂直滚动条为例,假设一个窗口高度1080像素,而显示器或者用户看到的只有768像素,那么就可以设置
nMax=1080,nPage=768.
头文件
//成员变量

//在资源视图中看到的对话框的大小
CRect   m_rectOriginal;

// 鼠标拖拽
BOOL    m_bDragging;
CPoint  m_ptDragPoint;

// 滚动条实际位置
int m_nScrollPos;

// 对话框实际高度
int m_nCurrentHeight;

//消息函数
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
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 OnKillFocus(CWnd* pNewWnd);

//重写函数
virtual BOOL OnInitDialog();

//增加函数
void EndDrag();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
实现文件
//消息映射
ON_WM_VSCROLL()
ON_WM_SIZE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_KILLFOCUS()

//实现函数
void CDlgX::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
int nDelta;
int nMaxPos = m_rectOriginal.Height() - m_nCurrentHeight;

switch (nSBCode)
{
case SB_LINEDOWN:
if (m_nScrollPos >= nMaxPos)
return;

nDelta = min(max(nMaxPos / 20, 5), nMaxPos - m_nScrollPos);
break;

case SB_LINEUP:
if (m_nScrollPos <= 0)
return;
nDelta = -min(max(nMaxPos / 20, 5), m_nScrollPos);
break;
case SB_PAGEDOWN:
if (m_nScrollPos >= nMaxPos)
return;
nDelta = min(max(nMaxPos / 10, 5), nMaxPos - m_nScrollPos);
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
nDelta = (int)nPos - m_nScrollPos;
break;

case SB_PAGEUP:
if (m_nScrollPos <= 0)
return;
nDelta = -min(max(nMaxPos / 10, 5), m_nScrollPos);
break;

default:
return;
}
m_nScrollPos += nDelta;
SetScrollPos(SB_VERT, m_nScrollPos, TRUE);
ScrollWindow(0, -nDelta);
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CDlgX::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);

// TODO:  在此处添加消息处理程序代码
m_nCurrentHeight = cy;

SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = m_rectOriginal.Height();
si.nPage = cy;
si.nPos = 0;
SetScrollInfo(SB_VERT, &si, TRUE);
}

BOOL CDlgX::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
int nMaxPos = m_rectOriginal.Height() - m_nCurrentHeight;

if (zDelta < 0)
{
if (m_nScrollPos < nMaxPos)
{
zDelta = min(max(nMaxPos / 20, 5), nMaxPos - m_nScrollPos);

m_nScrollPos += zDelta;
SetScrollPos(SB_VERT, m_nScrollPos, TRUE);
ScrollWindow(0, -zDelta);
}
}
else
{
if (m_nScrollPos > 0)
{
zDelta = -min(max(nMaxPos / 20, 5), m_nScrollPos);

m_nScrollPos += zDelta;
SetScrollPos(SB_VERT, m_nScrollPos, TRUE);
ScrollWindow(0, -zDelta);
}
}
return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}

void CDlgX::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
m_bDragging = TRUE;
SetCapture();

m_ptDragPoint = point;
CDialogEx::OnLButtonDown(nFlags, point);
}

void CDlgX::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
EndDrag();
CDialogEx::OnLButtonUp(nFlags, point);
}

void CDlgX::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
if (m_bDragging)
{
int nDelta = m_ptDragPoint.y - point.y;
m_ptDragPoint = point;

int nNewPos = m_nScrollPos + nDelta;

if (nNewPos<0)
nNewPos = 0;
else if (nNewPos>m_rectOriginal.Height() - m_nCurrentHeight)
nNewPos = m_rectOriginal.Height() - m_nCurrentHeight;

nDelta = nNewPos - m_nScrollPos;
m_nScrollPos = nNewPos;

SetScrollPos(SB_VERT, m_nScrollPos, TRUE);
ScrollWindow(0, -nDelta);
}
CDialogEx::OnMouseMove(nFlags, point);
}

void CDlgX::OnKillFocus(CWnd* pNewWnd)
{
CDialogEx::OnKillFocus(pNewWnd);

// TODO:  在此处添加消息处理程序代码
EndDrag();
}

BOOL CDlgX::OnInitDialog()
{
CDialogEx::OnInitDialog();

// TODO:  在此添加额外的初始化

//存储对话框初始大小
GetWindowRect(m_rectOriginal);

//初始滚动条位置
m_nScrollPos = 0;

return TRUE;  // return TRUE unless you set the focus to a control
// 异常:  OCX 属性页应返回 FALSE
}
void CDlgX::EndDrag()
{
m_bDragging = FALSE;
ReleaseCapture();
//SetCursor(m_hCursor1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
**

另一种方法 使用CScrollBar类的方法

**
对话框中添加一个垂直滚动条 vertical scroll bar
为其绑定一个控件变量 m_vScroll
增加消息WM_MOUSEWHEEL ,WM_VSCROLL
头文件
增加
CScrollBar m_vScroll;
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
int m_nScrollUnitHeight = 20;//一条记录的高度
int m_nUnitCount = 10;//记录总数
CRect m_rectScroll;//滚动条的rect
int m_nScrollPos;//滚动条位置
1
2
3
实现文件
绑定变量的时候向导会自动增加数据交换
void CMFCDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SCROLLBAR1, m_vScroll);
}
增加消息的时候 向导会自动增加消息映射的代码
BEGIN_MESSAGE_MAP(CMFCDlg, CDialogEx)
ON_WM_VSCROLL()
ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()
对话框初始化增加
CRect rect;
GetClientRect(rect);
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);;
si.nMin = 0;
si.nMax = m_nScrollUnitHeight*m_nUnitCount;
si.nPage = m_nScrollUnitHeight;
si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;

m_vScroll.SetScrollInfo(&si, TRUE);

m_vScroll.GetWindowRect(m_rectScroll);//滚动条所在的位置
ScreenToClient(m_rectScroll);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
其他实现函数
void CMFCDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
SCROLLINFO si;
si.cbSize = sizeof(si);
m_vScroll.GetScrollInfo(&si, SIF_POS | SIF_PAGE | SIF_RANGE);
m_nScrollPos = si.nPos;
switch (nSBCode)
{
case SB_LINEDOWN:  m_nScrollPos += 10;
if (m_nScrollPos > (si.nMax - si.nMin - si.nPage))
{
m_nScrollPos = si.nMax - si.nMin - si.nPage;

}
break;

case SB_LINEUP:    m_nScrollPos -= 10;
if (m_nScrollPos < si.nMin)
{
m_nScrollPos = 0;
}
break;
case SB_PAGEDOWN:  m_nScrollPos += si.nPage;
if (m_nScrollPos > (si.nMax - si.nMin - si.nPage))
{
m_nScrollPos = si.nMax - si.nMin - si.nPage;

}
break;
case SB_PAGEUP:  m_nScrollPos -= si.nPage;
if (m_nScrollPos < si.nMin)
{
m_nScrollPos = 0;
}
break;
case  SB_THUMBTRACK: m_nScrollPos = nPos; break;

}

ScrollWindow(0, -(m_nScrollPos - si.nPos), NULL, NULL);
m_vScroll.MoveWindow(m_rectScroll, TRUE);

si.fMask = SIF_POS;
si.nPos = m_nScrollPos;
m_vScroll.SetScrollInfo(&si, TRUE);
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}

BOOL CMFCDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
if (zDelta == -120)
{

m_nScrollPos += 10;
OnVScroll(SB_PAGEDOWN, m_nScrollPos, &m_vScroll);
}
else if (zDelta == 120)
{
m_nScrollPos -= 10;
OnVScroll(SB_PAGEUP, m_nScrollPos, &m_vScroll);

}

m_vScroll.MoveWindow(m_rectScroll, TRUE);
return CDialogEx::OnMouseWheel(nFlags, zDelta, pt);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mfc 滚动条