MFC使用CScrollView

mfc 专栏收录该内容
34 篇文章 0 订阅

头文件

class CourseSituationView :
	public CScrollView
{
	DECLARE_DYNCREATE(CourseSituationView)
protected:
	//DECLARE_MESSAGE_MAP()//CDialog中调用CScrollView不知道为什么不响应message map,只能自己响应WiondowProc
public:
	CourseSituationView();
	~CourseSituationView();
	virtual void OnInitialUpdate();

private:
	virtual void OnDraw(CDC *);//OnDraw不会主动触发,是CView在OnPaint的后面自动调用的虚函数
	LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
	void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	BOOL OnEraseBkgnd(CDC *pDC);
	HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
	VOID OnPaint();

private:
	int maxControlID;
	COLORREF m_bkColor;
	CBrush   m_Brush;
};

cpp文件



CourseSituationView::CourseSituationView()
{
	m_bkColor = RGB(0xff, 0xff, 0xff);
	m_Brush.CreateSolidBrush(m_bkColor);
}


CourseSituationView::~CourseSituationView()
{
}

VOID CourseSituationView::OnDraw(CDC* pDC)
{
	//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("scroll view on draw"));
	//onDraw时cview的成员函数,会在onPaint的最后调用
}

VOID CourseSituationView::OnPaint()
{
	CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("scroll view paint"));

	//onDraw时cview的成员函数,会在onPaint的最后调用
	CScrollView::OnPaint();
}

BOOL CourseSituationView::OnEraseBkgnd(CDC *pDC)
{
	CPaintDC dc(this);

	RECT rect;
	GetClientRect(&rect);

	CBrush brush(RGB(0xff, 0x63, 0x21));
	dc.FillRect(&rect, &brush);

	return FALSE;
}


HBRUSH CourseSituationView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CScrollView::OnCtlColor(pDC, pWnd, nCtlColor);

	 TODO:  在此更改 DC 的任何特性 
	//CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("course situation view onctlcolor"));

	//if (nCtlColor == CTLCOLOR_STATIC)
	//{
	//	//pDC->SetBkMode(TRANSPARENT);//设置透明,实际上没有真正的透明
	//	return   (HBRUSH)::GetStockObject(WHITE_BRUSH);//设置背景色,透明应该用NULL_BRUSH
	//}
	//else if (nCtlColor == CTLCOLOR_DLG)
	//{
	//	return m_Brush;
	//}

	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return m_Brush;
}

void CourseSituationView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();
	CSize size, sizePage, sizeLine;
	size.cx = 500;
	size.cy = 600;

	SetScrollSizes(MM_TEXT, size/*, sizePage, sizeLine*/);

}

void CourseSituationView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	SCROLLINFO si;
	memset(&si, 0, sizeof(si));
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_ALL;
	GetScrollInfo(SB_VERT, &si);
	int scrollPos = si.nPos;
	int step = 10;
	switch (nSBCode)
	{
	case SB_TOP:
		si.nPos = si.nMin; break;
	case SB_BOTTOM:
		si.nPos = si.nMax; break;
	case SB_LINEUP:
		si.nPos -= step; break;
	case SB_LINEDOWN:
		si.nPos += step; break;
	case SB_PAGEUP:
		si.nPos -= si.nPage; break;
	case SB_PAGEDOWN:
		si.nPos += si.nPage; break;
	case SB_THUMBTRACK:
		si.nPos = si.nTrackPos; break;
	default: break;
	}
	if (si.nPos >= (si.nMax + 1 - (int)si.nPage))  //****注意:在这儿滚动框滚到最底部了,其位置却是si.nMax+1-(int)si.nPage,而不是si.nMax, 其原因我也没去深究。
		si.nPos = (si.nMax + 1 - (int)si.nPage);
	else if (si.nPos <= si.nMin)
		si.nPos = si.nMin;
	si.fMask = SIF_ALL;
	si.fMask = SIF_POS;
	SetScrollInfo(SB_VERT, &si);
	if (scrollPos != si.nPos)
		::ScrollWindow(m_hWnd, 0, scrollPos - si.nPos, NULL, NULL);
	UpdateWindow();
}

void CourseSituationView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	SCROLLINFO si;
	memset(&si, 0, sizeof(si));
	si.cbSize = sizeof(SCROLLINFO);
	si.fMask = SIF_ALL;
	GetScrollInfo(SB_HORZ, &si);
	int scrollPos = si.nPos;
	int step = 10;
	switch (nSBCode)
	{
	case SB_LEFT:
		si.nPos = si.nMin; break;
	case SB_RIGHT:
		si.nPos = si.nMax; break;
	case SB_LINELEFT:
		si.nPos -= step; break;
	case SB_LINERIGHT:
		si.nPos += step; break;
	case SB_PAGELEFT:
		si.nPos -= si.nPage; break;
	case SB_PAGERIGHT:
		si.nPos += si.nPage; break;
	case SB_THUMBTRACK:
		si.nPos = si.nTrackPos; break;
	default: break;
	}
	if (si.nPos > (si.nMax + 1 - (int)si.nPage)) //****注意:在这儿滚动框滚到最底部了,其位置却是si.nMax+1-(int)si.nPage,而不是si.nMax, 其原因我也没去深究。
		si.nPos = si.nMax + 1 - (int)si.nPage;
	else if (si.nPos < si.nMin)
		si.nPos = si.nMin;
	si.fMask = SIF_ALL;
	si.fMask = SIF_POS;
	SetScrollInfo(SB_HORZ, &si);
	if (scrollPos != si.nPos)
		::ScrollWindow(m_hWnd, scrollPos - si.nPos, 0, NULL, NULL);
	UpdateWindow();
}

LRESULT CourseSituationView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_LBUTTONDOWN:
		{
			break;
		}
		case WM_PAINT:
		{
			OnPaint();
			break;
		}
		case WM_ERASEBKGND:
		{
			return OnEraseBkgnd((CDC*)wParam);
			break;
		}
		case WM_CTLCOLOR:
		{
			break;
		}
		case WM_CTLCOLORSTATIC://static的onctlcolor,还可以接收其他需要onctlcolor的消息
		{
			HDC hdcStatic = (HDC)wParam;
			CDC *pDC = CDC::FromHandle(hdcStatic);
			//SetTextColor(hdcStatic, RGB(255, 255, 255));
			//SetBkColor(hdcStatic, RGB(0, 0, 0));

			//HBRUSH hbrBkgnd = CreateSolidBrush(RGB(0, 0, 0));
			//return (INT_PTR)hbrBkgnd;

			HWND hWnd = (HWND)lParam;
			CWnd* pWnd = CWnd::FromHandle(hWnd);
			return (INT_PTR)OnCtlColor(pDC, pWnd, CTLCOLOR_STATIC);
		}
		case WM_COMMAND:
		{
			break;
		}
		case WM_VSCROLL:
		{
			UINT nSBCode = LOWORD(wParam);
			UINT nPos = HIWORD(wParam);
			CScrollBar* pScrollBar = (CScrollBar*)lParam;

			OnVScroll(nSBCode, nPos, pScrollBar);
			break;
		}
		default:
			break;
	}

	return CView::DefWindowProcW(message, wParam, lParam);
}

1、在onDraw不是消息触发的,是CView在OnPaint中调用的虚函数

2、滚动需要自己处理部分事情,否则会出现滚动条自动回退到0

3、设置滚动区域SetScrollSizes,详见OnInitialUpdate中的实现

4、我是在CDialogEx的子类中调用的CScrollView,不知道为什么

BEGIN_MESSAGE_MAP(CourseSituationView, CScrollView)
    ON_WM_VSCROLL()
    ON_WM_ERASEBKGND()
    ON_WM_CTLCOLOR()
    ON_WM_PAINT()
END_MESSAGE_MAP()

不能响应,只能无奈响应WindowProc,然后根据消息自己调用OnCtlColor、OnPaint

5、要在OnDraw中自己处理刷新,不然会出现花屏,一个绘图被拉的老长。怎么处理还不想深究

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

youyudexiaowangzi

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值