文本编辑器<三>更好的滚动条

void CMyEditorView::OnSize(UINT nType, int cx, int cy)
{
	CView::OnSize(nType, cx, cy);

	cxClient = cx;
	cyClient = cy;

	si.cbSize = sizeof(si);
         si.fMask      = SIF_RANGE | SIF_PAGE ;
         si.nMin       = 0 ;
         si.nMax       = NUMLINES - 1 ;
         si.nPage      = cyClient / cyChar ;
	SetScrollInfo (SB_VERT,&si,TRUE) ;
}

void CMyEditorView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	//保存原滚动条位置
	si.cbSize = sizeof(si);
	si.fMask = SIF_ALL;
	GetScrollInfo(SB_VERT,&si);
	iVscrollPos = si.nPos;

	//更新滚动条
	switch(nSBCode)
	{
	case SB_THUMBTRACK:
		si.nPos = si.nTrackPos;
		break;
	case SB_PAGEDOWN:
		si.nPos += si.nPage;
		break;
	case SB_PAGEUP:
		si.nPos -= si.nPage;
		break;
	}
	si.fMask = SIF_POS;
	SetScrollInfo( SB_VERT,&si,TRUE );
	GetScrollInfo( SB_VERT,&si );

	//通知更新窗口
	if( si.nPos!=iVscrollPos )
	{
		ScrollWindow( 0,cyChar*(iVscrollPos-si.nPos),NULL,NULL );
		UpdateWindow();
	}
}

void CMyEditorView::OnPaint()
{
	//保存滚动条位置
	si.cbSize = sizeof (si) ;
         si.fMask  = SIF_POS ;
         GetScrollInfo (SB_VERT, &si) ;
	iVscrollPos = si.nPos;

	//确定输出范围
	CPaintDC hdc(this);

	RECT rect;
	GetClientRect(&rect);

	int iPaintBeg = max (0, si.nPos + rect.top / cyChar) ;
	int iPaintEnd = min (NUMLINES-1,si.nPos + rect.bottom / cyChar) ;
	
	//逐行输出
	for ( int i = iPaintBeg ; i <= iPaintEnd ; i++)
         {
		TCHAR                szBuffer [10] ;
        int x = 0 ;
        int y = cyChar * (i - iVscrollPos) ;
    
        TextOut (hdc, x,y,sysmetrics[i].szLabel,lstrlen (sysmetrics[i].szLabel)) ;
        TextOut (hdc, x+22*cxCaps,y,sysmetrics[i].szDesc,lstrlen (sysmetrics[i].szDesc)) ;
    
        SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
        TextOut (hdc, x+22*cxCaps+40*cxChar,y,szBuffer,wsprintf (szBuffer, TEXT ("%5d"),
                                                        GetSystemMetrics (sysmetrics[i].index))) ;
        SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
	}        
}

 

为滚动条添加键盘响应:

void CMyEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	switch(nChar)
	{
		case VK_UP:
            SendMessage ( WM_VSCROLL, SB_LINEUP, 0) ;
            break ;
		case VK_DOWN:
            SendMessage ( WM_VSCROLL, SB_LINEDOWN, 0) ;
            break ;
	}

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}



疑问:

ScrollWindow扮演了什么角色?肯定不是绘图,绘图是在OnPaint里面实现的。类似Invalidate?使用InvalidateRect替代ScrollWindow能够达到同样效果,那为什么不用Invalidate呢?

你可能感兴趣的:(mfc,滚动条)