鼠标滚轮与滚动条

鼠标滚轮与滚动条

1.创建一个带滚动条的窗口
//
CMainWnd::CMainWnd()
{
	Create(NULL, _T("Accel App"),WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL);
}

2.OnSize 函数里面初始化滚动条
void CMainWnd::OnSize(UINT nType, int cx, int cy)
{
	CFrameWnd::OnSize(nType, cx, cy);
	CClientDC dc(this);
	TEXTMETRIC tm;
	dc.GetTextMetrics(&tm);
	m_ncxChar = tm.tmHeight + tm.tmExternalLeading;
	
	int m_nVScrollMax = 0; //舒适化滚动条最大值为0
	m_nVPageSize = m_nVScrollPos=0; //初始化类成员
	
	//设置垂直滚动条参数

	m_nVPageSize = cy;
	m_nVScrollMax = 100*m_ncxChar;//线条总长度1600,滚动位置最大1600-1
	//滚动范围必须在线条超出窗口的范围内
	m_nVScrollPos = min(m_nVScrollPos, m_nVScrollMax - 1 - m_nVPageSize);
	
	SCROLLINFO si;
	si.fMask = SIF_ALL;
	si.nMin = 0;
	si.nMax = m_nVScrollMax;
	si.nPos = m_nVScrollPos;
	si.nPage = m_nVPageSize;

	SetScrollInfo(SB_VERT, &si, TRUE);
}
3.响应滚动 OnVScroll
void CMainWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	int nDelta;
	switch (nSBCode)
	{
	case SB_LINEDOWN:
		nDelta = +10;
		break;
	case SB_LINEUP:
		nDelta = -10;
		break;
	case SB_PAGEDOWN:
		nDelta = +m_nVPageSize;
		break;
	case SB_PAGEUP:
		nDelta = -m_nVPageSize;
		break;
	case SB_THUMBTRACK:
		nDelta = (int)nPos - m_nVScrollPos;
		break;

	default:
		return;
	}
	//设置改变后的滚动他位置
	int nScrollPos = m_nVScrollPos + nDelta;
	//最大位移量
	int nMaxPos = 100 * m_ncxChar - m_nVPageSize;
	
	if (nScrollPos<0)//当滚动条位置为0,且点击up时,nScrollPos<0
	{
		nDelta = -m_nVScrollPos;
	}
	else if (nScrollPos >nMaxPos)//当m_nVScrollPos在终端时,点down,nScrollPos >nMaxPos
	{
		//nDelta =100 * m_ncxChar  - m_nVPageSize;
		nDelta = nMaxPos - m_nVScrollPos;
	}
	if (nDelta!=0)
	{
		m_nVScrollPos += nDelta;
		SetScrollPos(SB_VERT, m_nVScrollPos, TRUE);
		ScrollWindow(0, -nDelta);
	}
}
4.加入鼠标滚轮
   
       DECLARE_MESSAGE_MAP()
   
       //鼠标滚动消息
   	afx_msg BOOL OnMouseWheel(UINT, short, CPoint);
       afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

/
//cpp里面加入 ON_WM_MOUSEWHEEL()

       BEGIN_MESSAGE_MAP(CMainWnd,CFrameWnd)
       ON_WM_MOUSEWHEEL()
       ON_WM_VSCROLL()
       ON_WM_SIZE()
       ON_WM_PAINT()
       END_MESSAGE_MAP()
5.处理鼠标滚动消息
BOOL CMainWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
{
	BOOL bUp = TRUE;
    //zDelta <0 向下滚动
	int nDelta = zDelta;

	if (zDelta<0)
	{
		bUp = FALSE;
		nDelta = -zDelta;
	}
	UINT nWheelScrollLines;
	::SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &nWheelScrollLines, 0);
	
	if (nWheelScrollLines ==WHEEL_PAGESCROLL)
	{
		SendMessage(WM_VSCROLL, MAKEWPARAM(bUp ? SB_PAGEUP : SB_PAGEDOWN, 0), 0);
	}
	else
	{
		int nLines = (nDelta * nWheelScrollLines)/WHEEL_DELTA;
		while (nLines--)
		{
			SendMessage(WM_VSCROLL, MAKEWPARAM(bUp ? SB_LINEUP : SB_LINEDOWN, 0), 0);
		}

	}
	return TRUE;
}
/*
如果将来使用的鼠标滚轮的间隔尺寸不到120单位,那么用zDelta除以WHEELDELTA
就确保了应用程序不会滚动太快。WHEEL_ PAGESCROLL是一个特殊值,它告诉应用程序
就确保了应用程序不会滚动太快。WHEEL_ PAGESCROLL是一个特殊值,它告诉应用程序
WHEELL PAGESCROLL的定义在Winuser.h 中。
*/

6.最后设置视点随着滚动条滚动
void CMainWnd::OnPaint()
{
	CPaintDC dc(this);
    //设置视点随着滚动条滚动
	dc.SetWindowOrg(0, m_nVScrollPos);

	for (int i=0;i<100;i++)
	{
		LPWSTR a=NULL;
		//wsprintf(a,L"%d", i);
		//CString str("Hello");
	//	str.Append(i);
		TCHAR str[30];
		wsprintf(str, L"The %d Line", i);
		dc.TextOutW(100, i* m_ncxChar, str);
	}
	dc.SetBkMode(TRANSPARENT);
}

你可能感兴趣的:(MFC,C/C++)