myscrollview.cpp

来自「《精通MFC》源码」· C++ 代码 · 共 263 行

CPP
263
字号
// MyScrollView.cpp : 实现文件
//

#include "stdafx.h"
#include "SAMPLE10_3.h"
#include "MyScrollView.h"


// CMyScrollView

IMPLEMENT_DYNCREATE(CMyScrollView, CView)

CMyScrollView::CMyScrollView()
{
}

CMyScrollView::~CMyScrollView()
{
}

BEGIN_MESSAGE_MAP(CMyScrollView, CView)
		ON_WM_HSCROLL()
		ON_WM_VSCROLL()
		ON_WM_KEYDOWN()
END_MESSAGE_MAP()

void CMyScrollView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	//是滚动条控件吗?
	if (pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg())
		return;    
	//忽略来自其他窗口的滚动条的消息
	if (pScrollBar != GetScrollBarCtrl(SB_HORZ))
		return;
	OnScroll(MAKEWORD(nSBCode, 0xff), nPos);
}

void CMyScrollView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	if (pScrollBar != NULL && pScrollBar->SendChildNotifyLastMsg())
		return;     
	//忽略来自其他控件的滚动条消息
	if (pScrollBar != GetScrollBarCtrl(SB_VERT))
		return;

	OnScroll(MAKEWORD(0xff, nSBCode), nPos);
}

// CMyScrollView 绘图
void CMyScrollView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: 在此添加绘制代码
	//绘制10行,进行测试
	int x,y;
	x = y =0;
	CString s;
	CSize sizeText;
	
	for(int i =0 ;i< 10 ;i++)
	{
		s.Format("第%d行文本",i);
		sizeText = pDC->GetTextExtent(s);
		pDC->TextOut(x,y,s);	
		x+=sizeText.cx ;y+=sizeText.cy ;
	}
}


// CMyScrollView 诊断

#ifdef _DEBUG
void CMyScrollView::AssertValid() const
{
	CView::AssertValid();
}

void CMyScrollView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG



//进行滚动
BOOL CMyScrollView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
{
	// TODO: 在此添加专用代码和/或调用基类
	int x = GetScrollPos(SB_HORZ);
	int xOrig = x;
	//调整滚动条到新的位置
	//x方向:
	//以设备坐标为单位:
	switch (LOBYTE(nScrollCode))
	{
	case SB_TOP:
		x = 0;
		break;
	case SB_BOTTOM:
		x = INT_MAX;
		break;
	case SB_LINEUP:
		x -= 20;
		break;
	case SB_LINEDOWN:
		x += 20;
		break;
	case SB_PAGEUP:
		x -= 50;
		break;		
	case SB_PAGEDOWN:
		x += 50;
		break;
	case SB_THUMBTRACK:
		x = nPos;
		break;
	}

	//y方向:
	int y = GetScrollPos(SB_VERT);
	int yOrig = y;

	switch (HIBYTE(nScrollCode))
	{
	case SB_TOP:
		y = 0;
		break;
	case SB_BOTTOM:
		y = INT_MAX;
		break;
	case SB_LINEUP:
		y -= 20;
		break;
	case SB_LINEDOWN:
		y += 20;
		break;
	case SB_PAGEUP:
		y -= 50;
		break;
	case SB_PAGEDOWN:
		y += 50;
		break;
	case SB_THUMBTRACK:
		y = nPos;
		break;
	}
	//设置滚动条的位置
	BOOL bResult = OnScrollBy(CSize(x - xOrig, y - yOrig), bDoScroll);
	//要重绘
	if (bResult && bDoScroll)
		UpdateWindow();

	return bResult;
}

BOOL CMyScrollView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
{
	int xOrig, x;
	int yOrig, y;

	// 如果范围无效,则不滚动
	CScrollBar* pBar;
	DWORD dwStyle = GetStyle();
	pBar = GetScrollBarCtrl(SB_VERT);
	if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
		(pBar == NULL && !(dwStyle & WS_VSCROLL)))
	{
		// 垂直滚动条不允许		
		sizeScroll.cy = 0;
	}
	pBar = GetScrollBarCtrl(SB_HORZ);
	if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
		(pBar == NULL && !(dwStyle & WS_HSCROLL)))
	{
		// 水平滚动条不允许
		sizeScroll.cx = 0;
	}

	//调整新的x位置
	xOrig = x = GetScrollPos(SB_HORZ);
	int xMax = GetScrollLimit(SB_HORZ);
	x += sizeScroll.cx;
	if (x < 0)
		x = 0;
	else if (x > xMax)
		x = xMax;

	//调整新的y位置
	yOrig = y = GetScrollPos(SB_VERT);
	int yMax = GetScrollLimit(SB_VERT);
	y += sizeScroll.cy;
	if (y < 0)
		y = 0;
	else if (y > yMax)
		y = yMax;

	// 需要调整吗?
	if (x == xOrig && y == yOrig)
		return FALSE;

	if (bDoScroll)
	{
		// 滚动
		ScrollWindow(-(x-xOrig), -(y-yOrig));
		//设置滚动条位置
		if (x != xOrig)
			SetScrollPos(SB_HORZ, x);
		if (y != yOrig)
			SetScrollPos(SB_VERT, y);
	}
	return TRUE;
}

BOOL CMyScrollView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此添加专用代码和/或调用基类
	//添加滚动条支持
	cs.style |= (WS_HSCROLL|WS_VSCROLL);
	return CView::PreCreateWindow(cs);
}

void CMyScrollView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
	//设置视口原点
	CPoint pt(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT));
	ASSERT(pt.x >= 0 && pt.y >= 0);	
	if (!pDC->IsPrinting())
	{
		ASSERT(pDC->GetWindowOrg() == CPoint(0,0));		
		pDC->SetViewportOrg(-pt);
	}
	CView::OnPrepareDC(pDC, pInfo);
}

void CMyScrollView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	int cz = GetKeyState(VK_CONTROL) < 0 ? 1 : 16;

	//OnHScroll
	switch (nChar)
	{
	case VK_LEFT:
		//OnHScroll(SB_LINEUP,0,NULL);		
		SendMessage(WM_HSCROLL,MAKEWPARAM(SB_LINEUP,0),NULL);
		break;
	case VK_RIGHT:
		OnHScroll(SB_LINEDOWN,0,NULL);				
		break;
	case VK_UP:
		OnVScroll(SB_LINEUP,0,NULL);						
		break;
	case VK_DOWN:
		OnVScroll(SB_LINEDOWN,0,NULL);
		break;	
	default:
		CView::OnKeyDown(nChar, nRepCnt, nFlags);
		return;
	}
	
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?