基于soui4实现一个标尺控件

#pragma once
class CRulerBar : public SWindow
{
	DEF_SOBJECT(SWindow, L"rulerbar")
public:
	CRulerBar();
	~CRulerBar();

protected:
	void OnPaint(IRenderTarget* pRT);

protected:
	SOUI_MSG_MAP_BEGIN()
		MSG_WM_PAINT_EX(OnPaint)
		SOUI_MSG_MAP_END()

		SOUI_ATTRS_BEGIN()
		ATTR_INT(L"bar_position", m_nBarPos, FALSE) //标尺位置
		ATTR_INT(L"bar_pix2cm", m_nPix2CM, FALSE)	//厘米像素比例
		SOUI_ATTRS_END()
private:
	int     m_nBarPos;
	int		m_nPix2CM;
};
#include "stdafx.h"
#include "CRulerBar.h"

CRulerBar::CRulerBar()
{
	m_nBarPos = 0;
	m_nPix2CM = 20;
}

CRulerBar::~CRulerBar()
{
}
void CRulerBar::OnPaint(IRenderTarget* pRT)
{
	pRT->SetAntiAlias(FALSE);

	CAutoRefPtr<IPen> pen, oldpen;
	pRT->CreatePen(PS_SOLID, RGBA(0, 0, 0, 255), 1, &pen);
	pRT->SelectObject(pen, (IRenderObj**)&oldpen);

	COLORREF crRulerText(RGBA(0, 0, 0, 100));
	CRect rcRuler = GetWindowRect();
	switch (m_nBarPos)
	{
	case 0:
	{
		{//边线(下边)
			double dXStart = rcRuler.left;
			double dYStart = rcRuler.bottom - 1;
			double dXEnd = rcRuler.right;
			double dYEnd = rcRuler.bottom - 1;

			CPoint pts[2];
			pts[0].x = dXStart;
			pts[0].y = dYStart;

			pts[1].x = dXEnd;
			pts[1].y = dYEnd;
			pRT->DrawLines(pts, 2);
		}

		{//刻度线
			for (int i = 0; i < 100; i++)
			{
				double dXStart = rcRuler.left + i * m_nPix2CM;
				double dYStart = rcRuler.top + 5;
				double dXEnd = dXStart;
				double dYEnd = rcRuler.bottom;
				{//长刻度线
					CPoint pts[2];
					pts[0].x = dXStart;
					pts[0].y = dYStart;

					pts[1].x = dXEnd;
					pts[1].y = dYEnd;
					pRT->DrawLines(pts, 2);
				}

				//文本绘制区域
				SOUI::CRect rcText;
				rcText.left = dXStart;
				rcText.top = dYStart;
				rcText.right = dXStart + m_nPix2CM;
				rcText.bottom = dYEnd;

				{//短刻度线
					for (int j = 1; j < 5; j++)
					{
						double startX = rcText.left + j * (rcText.Width() / 5);
						double startY = rcText.top + (rcText.Height() / 2);
						double endX = startX;
						double endY = rcText.bottom;

						CPoint pts[2];
						pts[0].x = startX;
						pts[0].y = startY;

						pts[1].x = endX;
						pts[1].y = endY;
						pRT->DrawLines(pts, 2);
					}
				}

				SStringT sstrContent;
				sstrContent.Format(_T("%d"), i);
				pRT->SetTextColor(crRulerText);
				pRT->DrawText(sstrContent, sstrContent.GetLength(), rcText, DT_SINGLELINE | DT_LEFT | DT_TOP);
			}
		}
	}
	break;
	case 1:
	{
		//right ruler
		//TODO:
	}
	break;
	case 2:
	{
		//bottom ruler
		//TODO:
	}
	break;
	case 3:
	{
		{//边线(右边)
			CPoint pts[2];
			pts[0].x = rcRuler.right - 1;
			pts[0].y = rcRuler.top;

			pts[1].x = rcRuler.right - 1;
			pts[1].y = rcRuler.bottom;
			pRT->DrawLines(pts, 2);
		}

		{//刻度线
			for (int i = 0; i < 100; i++)
			{
				double dXStart = rcRuler.left + 5;
				double dYStart = rcRuler.top + i * m_nPix2CM;
				double dXEnd = rcRuler.right;
				double dYEnd = dYStart;
				{//长刻度线
					CPoint pts[2];
					pts[0].x = dXStart;
					pts[0].y = dYStart;

					pts[1].x = dXEnd;
					pts[1].y = dYEnd;
					pRT->DrawLines(pts, 2);
				}

				//文本绘制区域
				SOUI::CRect rcText;
				rcText.left = dXStart;
				rcText.top = dYStart;
				rcText.right = dXEnd;
				rcText.bottom = dYStart + m_nPix2CM;

				{//短刻度线
					for (int j = 1; j < 5; j++)
					{
						double startX = rcText.left + (rcText.Width() / 2);
						double startY = rcText.top + j * (rcText.Height() / 5);

						double endX = rcText.right;
						double endY = startY;

						CPoint pts[2];
						pts[0].x = startX;
						pts[0].y = startY;

						pts[1].x = endX;
						pts[1].y = endY;
						pRT->DrawLines(pts, 2);
					}
				}

				SStringT sstrContent;
				sstrContent.Format(_T("%d"), i);
				pRT->SetTextColor(crRulerText);
				pRT->DrawText(sstrContent, sstrContent.GetLength(), rcText, DT_SINGLELINE | DT_LEFT | DT_TOP);
			}
		}
		pRT->SelectObject(oldpen, NULL);
	}
	break;
	default:
		break;
	}

	pRT->SelectObject(oldpen, NULL);
}

控件使用:
Step1:注册

m_theApp->RegisterWindowClass<CRulerBar>();

Step2:布局中使用

			  <caption pos="[0,{0,-0,-0" colorBkgnd="#FFFFFF" font="face:微软雅黑,size:10">
				  <caption pos="0,0,@40,@40">
					  <text  pos="|0,|0" offset="-0.5,-0.5" >cm</text>
				  </caption>
				  <!--顶部游标-->
				  <caption pos="40,0,-0,@40" colorBkgnd="#FFFFFF">
					  <scrollview name="scrollview_topruler" pos="0,0,-0,-0" viewSize="-1,-1" sbwid="0" scrollSpeed="40" >
						  <rulerbar name="ruler_top" pos="0,0,@2000,@40" bar_position="0"></rulerbar>
					  </scrollview>
				  </caption>
				  <!--左侧游标-->
				  <caption pos="0,40,@40,-0" colorBkgnd="#FFFFFF">
					  <scrollview name="scrollview_leftruler" pos="0,0,-0,-0" viewSize="-1,-1" sbwid="0" scrollSpeed="40" >
						  <rulerbar name="ruler_left" pos="0,0,@40,@2000" bar_position="3"></rulerbar>
					  </scrollview>
				  </caption>
			  </caption>

效果图:
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值