基于soui4实现一个打印排版软件(三)为元素增加拉伸移动操作

以矩形元素为例,为其增加移动、拉伸大小相关功能
定义位置类型

enum EcPosType
{
	Null = -1,
	TopLeft,
	TopCenter,
	TopRight,
	RightCenter,
	BottomRight,
	BottomCenter,
	BottomLeft,
	LeftCenter,
	SelectRect,
};

在基类CEleBase中定义操作点、鼠标光标以及操作点计算相关代码

class CEleBase : public SWindow
{
	//....
public:
	SOUI::CRect	m_rcPos[8];
	HCURSOR	m_hCursorLeft, m_hCursorRight, m_hCursorTop, m_hCursorBottom,
		m_hCursorTopLeft, m_hCursorTopRight, m_hCursorBottomLeft, m_hCursorBottomRight,
		m_hCursorHand, m_hCursorArrow, m_hCursorSelect;
public:
	void CalcPos();
	EcPosType HitPos(SOUI::CPoint& pt);
	void ShowCursor(EcPosType ePos);
}
CEleBase::CEleBase()
{
	//...
	
	m_hCursorSelect = LoadCursor(NULL, IDC_SIZEALL);
	m_hCursorTopRight = LoadCursor(NULL, IDC_SIZENESW);
	m_hCursorBottomRight = LoadCursor(NULL, IDC_SIZENWSE);
	m_hCursorTop = LoadCursor(NULL, IDC_SIZENS);
	m_hCursorBottom = LoadCursor(NULL, IDC_SIZENS);
	m_hCursorLeft = LoadCursor(NULL, IDC_SIZEWE);
	m_hCursorRight = LoadCursor(NULL, IDC_SIZEWE);
	m_hCursorTopLeft = LoadCursor(NULL, IDC_SIZENWSE);
	m_hCursorBottomLeft = LoadCursor(NULL, IDC_SIZENESW);
	m_hCursorHand = LoadCursor(NULL, IDC_HAND);
	m_hCursorArrow = LoadCursor(NULL, IDC_ARROW);
}
void CEleBase::CalcPos()
{
	CRect rc = GetClientRect();
	rc.InflateRect(2, 2, 2, 2);
	SOUI::CPoint center = rc.CenterPoint();
	m_rcPos[(int)EcPosType::TopLeft].SetRect(rc.left, rc.top, rc.left + 8, rc.top + 8);// 上左 方块
	m_rcPos[(int)EcPosType::TopCenter].SetRect(center.x - 4, rc.top, center.x + 4, rc.top + 8);// 上中 方块
	m_rcPos[(int)EcPosType::TopRight].SetRect(rc.right - 8, rc.top, rc.right, rc.top + 8);// 上右 方块
	m_rcPos[(int)EcPosType::RightCenter].SetRect(rc.right - 8, center.y - 4, rc.right, center.y + 4);// 右中 方块
	m_rcPos[(int)EcPosType::BottomRight].SetRect(rc.right - 8, rc.bottom - 8, rc.right, rc.bottom);// 下右 方块
	m_rcPos[(int)EcPosType::BottomCenter].SetRect(center.x - 4, rc.bottom - 8, center.x + 4, rc.bottom);// 下中 方块
	m_rcPos[(int)EcPosType::BottomLeft].SetRect(rc.left, rc.bottom - 8, rc.left + 8, rc.bottom);// 下左 方块
	m_rcPos[(int)EcPosType::LeftCenter].SetRect(rc.left, center.y - 4, rc.left + 8, center.y + 4);// 左中 方块
}
EcPosType CEleBase::HitPos(SOUI::CPoint& pt)
{
	CPoint pt2(pt);
	for (int i = 0; i < 8; ++i)
	{
		if (m_rcPos[i].PtInRect(pt2))
			return EcPosType(i);
	}
	return EcPosType::Null;
}
void CEleBase::ShowCursor(EcPosType ePos)
{
	switch (ePos)
	{
	case EcPosType::TopLeft:
	case EcPosType::BottomRight:
		::SetCursor(m_hCursorTopLeft);
		break;
	case EcPosType::TopCenter:
	case EcPosType::BottomCenter:
		::SetCursor(m_hCursorTop);
		break;
	case EcPosType::TopRight:
	case EcPosType::BottomLeft:
		::SetCursor(m_hCursorTopRight);
		break;
	case EcPosType::LeftCenter:
	case EcPosType::RightCenter:
		::SetCursor(m_hCursorLeft);
		break;
	case EcPosType::SelectRect:
		::SetCursor(m_hCursorSelect);
		break;
	case EcPosType::Null:
		::SetCursor(m_hCursorSelect);
		break;
	default:
		break;
	}
}

在Rect元素中绘制操作点

void CEleRect::OnPaint(IRenderTarget* pRT)
{
	//...
	
	CalcPos();
	if (m_bSelected)
	{
		CAutoRefPtr<IBrush> brush, oldbrush;
		pRT->CreateSolidColorBrush(RGBA(255, 0, 0, 255), &brush);
		pRT->SelectObject(brush, (IRenderObj**)&oldbrush);
		for (int i = 0; i < 8; ++i)
		{
			CRect rcDot(m_rcPos[i]);
			pRT->FillRectangle(rcDot);
		}
		pRT->SelectObject(oldbrush, NULL);
	}
}

定义元素鼠标事件

#pragma once
#include "CEleBase.h"
class CEleRect : public CEleBase
{
	DEF_SOBJECT(SWindow, L"ele_rect")
public:
	CEleRect();
	~CEleRect();
public:
	void OnPaint(IRenderTarget* pRT);
protected:
	LRESULT OnCreate(LPVOID);
	void OnLButtonDown(UINT nFlags, SOUI::CPoint point);
	void OnLButtonUp(UINT nFlags, SOUI::CPoint point);
	void OnMouseMove(UINT nFlags, SOUI::CPoint point);
	void OnLButtonDblClk(UINT nFlags, SOUI::CPoint point);
	void OnRButtonUp(UINT nFlags, CPoint point);
protected:
	SOUI_MSG_MAP_BEGIN()
		MSG_WM_CREATE(OnCreate)
		MSG_WM_PAINT_EX(OnPaint)

		MSG_WM_LBUTTONDOWN(OnLButtonDown)
		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
		MSG_WM_RBUTTONUP(OnRButtonUp)
		MSG_WM_MOUSEMOVE(OnMouseMove)
		SOUI_MSG_MAP_END()
private:
	CPoint	m_ptDown;
	EcPosType m_curEcPosType;
};
void CEleRect::OnLButtonDown(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	SetCapture();
	m_ptDown = point;
	m_bSelected = true;

	EcPosType posType = HitPos(point);
	ShowCursor(posType);
	m_curEcPosType = posType;

	Invalidate();
}
void CEleRect::OnLButtonUp(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	ReleaseCapture();
	switch (m_curEcPosType)
	{
	case Null:
	{
		CPoint ptLT(m_ptLT);
		int nWid = m_ptRB.x - m_ptLT.x;
		int nHei = m_ptRB.y - m_ptLT.y;
		if (m_ptDown.x > point.x)
			ptLT.x -= (m_ptDown.x - point.x);
		else
			ptLT.x += (point.x - m_ptDown.x);
		if (m_ptDown.y > point.y)
			ptLT.y -= (m_ptDown.y - point.y);
		else
			ptLT.y += (point.y - m_ptDown.y);

		if (ptLT.x < 0) ptLT.x = 0;
		if (ptLT.y < 0) ptLT.y = 0;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d", ptLT.x, ptLT.y);
		SetAttribute(L"pos", sstrPos);

		CPoint ptRB(ptLT.x + nWid, ptLT.y + nHei);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
	}
	break;
	case TopLeft:
	{
		CPoint ptLT(m_ptLT);
		if (m_ptDown.x > point.x)  //x往左
			ptLT.x -= (m_ptDown.x - point.x);
		else//x往右
			ptLT.x += (point.x - m_ptDown.x);

		if (m_ptDown.y > point.y)//y往上
			ptLT.y -= (m_ptDown.y - point.y);
		else //y往下
			ptLT.y += (point.y - m_ptDown.y);

		if (ptLT.x < 0)
			ptLT.x = 0;
		if (ptLT.y < 0)
			ptLT.y = 0;

		int nWid = m_ptRB.x - ptLT.x;
		int nHei = m_ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		CalcPos();
	}
	break;
	case TopCenter:
	{
		CPoint ptLT(m_ptLT);
		if (m_ptDown.y > point.y)//y往上
			ptLT.y -= (m_ptDown.y - point.y);
		else //y往下
			ptLT.y += (point.y - m_ptDown.y);
		if (ptLT.y < 0)
			ptLT.y = 0;

		int nWid = m_ptRB.x - ptLT.x;
		int nHei = m_ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		CalcPos();
	}
	break;
	case TopRight:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.x > point.x)  //to left
			ptRB.x -= m_ptDown.x - point.x;
		else
			ptRB.x += point.x - m_ptDown.x;

		if (m_ptDown.y > point.y) //to down
			ptLT.y -= m_ptDown.y - point.y;
		else
			ptLT.y += point.y - m_ptDown.y;

		if (ptLT.y < 0)
			ptLT.y = 0;

		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);

		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case RightCenter:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.x > point.x)  //to left
			ptRB.x -= m_ptDown.x - point.x;
		else
			ptRB.x += point.x - m_ptDown.x;
	
		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case BottomRight:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.x > point.x)  //to left
			ptRB.x -= m_ptDown.x - point.x;
		else
			ptRB.x += point.x - m_ptDown.x;
	
		if (m_ptDown.y > point.y) //to down
			ptRB.y -= m_ptDown.y - point.y;
		else
			ptRB.y += point.y - m_ptDown.y;
	
		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case BottomCenter:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.y > point.y) //to down
			ptRB.y -= m_ptDown.y - point.y;
		else
			ptRB.y += point.y - m_ptDown.y;

		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case BottomLeft:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.x > point.x)  //to left
			ptLT.x -= m_ptDown.x - point.x;
		else
			ptLT.x += point.x - m_ptDown.x;
		if (m_ptDown.y > point.y) //to down
			ptRB.y -= m_ptDown.y - point.y;
		else
			ptRB.y += point.y - m_ptDown.y;

		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case LeftCenter:
	{
		CPoint ptLT(m_ptLT);
		CPoint ptRB(m_ptRB);
		if (m_ptDown.x > point.x)  //to left
			ptLT.x -= m_ptDown.x - point.x;
		else
			ptLT.x += point.x - m_ptDown.x;

		int nWid = ptRB.x - ptLT.x;
		int nHei = ptRB.y - ptLT.y;

		SStringW sstrPos;
		sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
		SetAttribute(L"pos", sstrPos);
		m_ptLT = ptLT;
		m_ptRB = ptRB;
		CalcPos();
	}
	break;
	case SelectRect:
		break;
	default:
		break;
	}
	m_curEcPosType = Null;
	Invalidate();
}

void CEleRect::OnMouseMove(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
	ShowCursor(HitPos(point));
	if ((nFlags & MK_LBUTTON))
	{
		switch (m_curEcPosType)
		{
		case Null:
		{
			CPoint ptPos(m_ptLT);
			if (m_ptDown.x > point.x)
				ptPos.x -= (m_ptDown.x - point.x);
			else
				ptPos.x += (point.x - m_ptDown.x);
			if (m_ptDown.y > point.y)
				ptPos.y -= (m_ptDown.y - point.y);
			else
				ptPos.y += (point.y - m_ptDown.y);

			if (ptPos.x < 0) ptPos.x = 0;
			if (ptPos.y < 0) ptPos.y = 0;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d", ptPos.x, ptPos.y);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case TopLeft:
		{
			CPoint ptPos(m_ptLT);
			if (m_ptDown.x > point.x)  //x往左
				ptPos.x -= (m_ptDown.x - point.x);
			else//x往右
				ptPos.x += (point.x - m_ptDown.x);

			if (m_ptDown.y > point.y)//y往上
				ptPos.y -= (m_ptDown.y - point.y);
			else //y往下
				ptPos.y += (point.y - m_ptDown.y);

			if (ptPos.x < 0)
				ptPos.x = 0;
			if (ptPos.y < 0)
				ptPos.y = 0;

			int nWid = m_ptRB.x - ptPos.x;
			int nHei = m_ptRB.y - ptPos.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptPos.x, ptPos.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case TopCenter:
		{
			CPoint ptPos(m_ptLT);
			if (m_ptDown.y > point.y)//y往上
				ptPos.y -= (m_ptDown.y - point.y);
			else //y往下
				ptPos.y += (point.y - m_ptDown.y);

			if (ptPos.y < 0)
				ptPos.y = 0;

			int nWid = m_ptRB.x - ptPos.x;
			int nHei = m_ptRB.y - ptPos.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptPos.x, ptPos.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case TopRight:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.x > point.x)  //to left
				ptRB.x -= m_ptDown.x - point.x;
			else
				ptRB.x += point.x - m_ptDown.x;
			if (m_ptDown.y > point.y) //to down
				ptLT.y -= m_ptDown.y - point.y;
			else
				ptLT.y += point.y - m_ptDown.y;

			if (ptLT.y < 0)
				ptLT.y = 0;

			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case RightCenter:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.x > point.x)  //to left
				ptRB.x -= m_ptDown.x - point.x;
			else
				ptRB.x += point.x - m_ptDown.x;
			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case BottomRight:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.x > point.x)  //to left
				ptRB.x -= m_ptDown.x - point.x;
			else
				ptRB.x += point.x - m_ptDown.x;

			if (m_ptDown.y > point.y) //to down
				ptRB.y -= m_ptDown.y - point.y;
			else
				ptRB.y += point.y - m_ptDown.y;
			
			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case BottomCenter:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.y > point.y) //to down
				ptRB.y -= m_ptDown.y - point.y;
			else
				ptRB.y += point.y - m_ptDown.y;
			
			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case BottomLeft:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.x > point.x)  //to left
				ptLT.x -= m_ptDown.x - point.x;
			else
				ptLT.x += point.x - m_ptDown.x;
			if (m_ptDown.y > point.y) //to down
				ptRB.y -= m_ptDown.y - point.y;
			else
				ptRB.y += point.y - m_ptDown.y;
			
			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case LeftCenter:
		{
			CPoint ptLT(m_ptLT);
			CPoint ptRB(m_ptRB);
			if (m_ptDown.x > point.x)  //to left
				ptLT.x -= m_ptDown.x - point.x;
			else
				ptLT.x += point.x - m_ptDown.x;
			
			int nWid = ptRB.x - ptLT.x;
			int nHei = ptRB.y - ptLT.y;

			SStringW sstrPos;
			sstrPos.Format(L"%d,%d,@%d,@%d", ptLT.x, ptLT.y, nWid, nHei);
			SetAttribute(L"pos", sstrPos);
		}
		break;
		case SelectRect:
			break;
		default:
			break;
		}
	}
	Invalidate();
}

void CEleRect::OnLButtonDblClk(UINT nFlags, SOUI::CPoint point)
{
	SetMsgHandled(FALSE);
}

void CEleRect::OnRButtonUp(UINT nFlags, CPoint point)
{
	SetMsgHandled(FALSE);
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值