使用soui4实现一个Banner控件

banner演示

#pragma once

#include <vector>
class CBannerCtrl : public SWindow
{
	DEF_SOBJECT(SWindow, L"banner_ctrl")
public:
	CBannerCtrl(void);
	~CBannerCtrl(void);

	void OnMouseHover(WPARAM wParam, SOUI::CPoint ptPos);
	void OnMouseLeave();
	void OnLButtonDown(UINT nFlags, SOUI::CPoint pt);
	void OnMouseMove(UINT nFlags, SOUI::CPoint pt);
	void OnPaint(IRenderTarget* pRT);
	void OnTimer(UINT_PTR idEvent);

protected:
	SOUI_MSG_MAP_BEGIN()
		MSG_WM_PAINT_EX(OnPaint)

		MSG_WM_LBUTTONDOWN(OnLButtonDown)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_MOUSEMOVE(OnMouseMove)
		MSG_WM_MOUSEHOVER(OnMouseHover)
		MSG_WM_MOUSELEAVE(OnMouseLeave)

		MSG_WM_TIMER(OnTimer)
		SOUI_MSG_MAP_END()

private:
	SAutoRefPtr<IBitmap> m_pBitmap;

	int		m_nCurSelected;
	bool	m_bAdd;

	std::vector<CRect> m_vecDots;
public:
	void SetBannerImage(SStringW& sstrPath);
	void StartTimer();

	void CalcDot();
};
#include "stdafx.h"
#include "CBannerCtrl.h"

CBannerCtrl::CBannerCtrl(void)
{
	m_nCurSelected = 0;
	m_bAdd = true;
}

CBannerCtrl::~CBannerCtrl(void)
{
}

void CBannerCtrl::OnMouseHover(WPARAM wParam, SOUI::CPoint ptPos)
{
	SetMsgHandled(FALSE);
	KillTimer(1);
}

void CBannerCtrl::OnMouseLeave()
{
	SetMsgHandled(FALSE);
 	SetTimer(1, 2000);
}

void CBannerCtrl::OnMouseMove(UINT nFlags, SOUI::CPoint pt)
{
	SetMsgHandled(FALSE);
	HCURSOR hCursor = ::LoadCursor(NULL, IDC_HAND);
	::SetCursor(hCursor);
}

void CBannerCtrl::OnLButtonDown(UINT nFlags, SOUI::CPoint pt)
{
	SetMsgHandled(FALSE);
	SetCapture();

	bool bClickDot = false;
	for (int i = 0; i < m_vecDots.size(); i++)
	{
		if (PtInRect(m_vecDots[i], pt))
		{
			bClickDot = true;
			m_nCurSelected = i;
			Invalidate();
			break;
		}
	}

	if (!bClickDot)
	{
		//将当前页面的点击事件通知上层
		//TODO:
	}
}

void CBannerCtrl::OnPaint(IRenderTarget* pRT)
{
	CRect rcClient = GetClientRect();
	CalcDot();

	switch (m_nCurSelected)
	{
	case 0:
		pRT->DrawBitmap(rcClient, m_pBitmap, 0, 0);
		break;
	case 1:
		pRT->DrawBitmap(rcClient, m_pBitmap, 300, 0);
		break;
	case 2:
		pRT->DrawBitmap(rcClient, m_pBitmap, 600, 0);
		break;
	default:
		break;
	}

	//绘制几个点
	for (int i = 0; i < m_vecDots.size(); i++)
	{
		CRect rcDot(m_vecDots[i]);
		if (m_nCurSelected == i)
		{
			COLORREF clrBkgnd = RGBA(255, 255, 255, 255);
			CAutoRefPtr<IBrush> brush, oldbrush;
			pRT->CreateSolidColorBrush(clrBkgnd, &brush);
			pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
			pRT->FillEllipse(&rcDot);
			pRT->SelectObject(oldbrush, NULL);
		}
		else
		{
			CAutoRefPtr<IPen> pen, oldpen;
			COLORREF clrBorder = RGBA(255, 255, 255, 180);
			pRT->CreatePen(PS_SOLID | PS_ENDCAP_SQUARE, clrBorder, 2, &pen);
			pRT->SelectObject(pen, (IRenderObj**)&oldpen);
			pRT->DrawEllipse(rcDot);
			pRT->SelectObject(oldpen, NULL);
		}
	}
}

void CBannerCtrl::OnTimer(UINT_PTR idEvent)
{
	SetMsgHandled(FALSE);
	switch (idEvent)
	{
	case 1:
	{
		if (m_bAdd)
		{
			m_nCurSelected++;
			if (m_nCurSelected >= 2)
			{
				m_bAdd = false;
				m_nCurSelected = 2;
			}
		}
		else
		{
			m_nCurSelected--;
			if (m_nCurSelected <= 0)
			{
				m_bAdd = true;
				m_nCurSelected = 0;
			}
		}
	}
	break;
	default:
		break;
	}

	Invalidate();
}

void CBannerCtrl::SetBannerImage(SStringW& sstrPath)
{
	m_pBitmap = SResLoadFromFile::LoadImage(sstrPath);
}

void CBannerCtrl::StartTimer()
{
	SetTimer(1, 2000);
}

void CBannerCtrl::CalcDot()
{
	//计算操作点
	m_vecDots.clear();
	CRect rcClient = GetClientRect();
	for (int i = 0; i < 3; i++)
	{
		CRect rcDot;
		rcDot.left = rcClient.left + i * 20 + 20;
		rcDot.top = rcClient.bottom - 20;
		rcDot.right = rcDot.left + 8;
		rcDot.bottom = rcDot.top + 8;

		m_vecDots.push_back(rcDot);
	}
}

控件使用:
1、注册:

m_theApp->RegisterWindowClass<CBannerCtrl>();

2、布局中使用

<banner_ctrl name="bannerctrl" pos="|-150,|-250" size="300,415" cursor="hand"></banner_ctrl>

3、代码中使用

CBannerCtrl* pBanner = FindChildByName2<CBannerCtrl>(L"bannerctrl");
SStringW sstrBannerPath = L"banner.png";
pBanner->SetBannerImage(sstrBannerPath);

//启动定时器
pBanner->StartTimer();

在这里插入图片描述在这里插入图片描述在这里插入图片描述
Demo代码:https://github.com/JeanPenty/BannerDemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值