1.消息映射宏: MESSAGE_HANDLER(WM_VSCROLL, OnVscroll) MESSAGE_HANDLER(WM_SIZE, OnSize) MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) 2.在OnInitDialog里获取窗口的实际大小,以及初始化滚动条位置: ::GetWindowRect(m_hWnd, &m_wndRect); ScreenToClient(&m_wndRect); m_nScrollPos = 0; 3.响应消息: LRESULT OnVscroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) { int curPos = HIWORD(wParam); int nDelta = 0; int nScrollStep = (m_nScrollRange) / 9; m_nScrollPos = ::GetScrollPos(m_hWnd, SB_VERT); switch (LOWORD(wParam)) { case SB_LINEDOWN: if (m_nScrollPos >= m_nScrollRange) { return 0; } nDelta = min(nScrollStep, m_nScrollRange - m_nScrollPos); break; case SB_LINEUP: if (m_nScrollPos <= 0) { return 0; } nDelta = -min(nScrollStep, m_nScrollPos); break; case SB_PAGEDOWN: if (m_nScrollPos >= m_nScrollRange) { return 0; } nDelta = min(m_nScrollRange, m_nScrollRange - m_nScrollPos); break; case SB_PAGEUP: if (m_nScrollPos <= 0) { return 0; } nDelta = -min(m_nScrollRange, m_nScrollPos); break; case SB_THUMBPOSITION: case SB_THUMBTRACK: nDelta = curPos - m_nScrollPos; break; default: break; } m_nScrollPos += nDelta; ::SetScrollPos(m_hWnd, SB_VERT, m_nScrollPos, TRUE); ::ScrollWindow(m_hWnd, 0, -nDelta, NULL, m_wndRect); ::UpdateWindow(m_hWnd); return 0; } LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) { SCROLLINFO si; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_ALL; si.nMin = 0; si.nMax = m_wndRect.Height(); //窗口的实际高度 si.nPage = HIWORD(lParam); //窗口的显示高度 si.nPos = 0; SetScrollInfo(SB_VERT, &si, TRUE); m_nScrollRange = si.nMax - si.nPage; //滚动范围 return 0; } LRESULT OnMouseWheel(UINT , WPARAM wParam, LPARAM , BOOL& ) { MouseWheelHandle(HIWORD(wParam)); return 0; } void MouseWheelHandle(short nDir) { if (nDir > 0) { ::SendMessage(m_hWnd, WM_VSCROLL, SB_LINEUP, 0); } else if (nDir < 0) { ::SendMessage(m_hWnd, WM_VSCROLL, SB_LINEDOWN, 0); } }