MFC对话框处理滚动条



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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值