#define RECT_VRT_MOVE 0x01 //垂直移动
#define RECT_HRN_MOVE 0x02 //水平移动
#define ROUND 0x04
class CRectObject
{
public:
CRectObject(void);
~CRectObject(void);
enum CursorMode
{
WECursor =0x00, //鼠标在矩形东西时的形状模式
NSCursor =0x01, //鼠标在矩形南北时的形状模式
AllCursor =0x02, //鼠标在矩形四个角时的形状模式
InCursor =0x03, //鼠标在矩形内部时的形状模式
OutCursor =0x04 //鼠标在矩形外部时的形状模式
};
enum Operator
{
RECT_MOVE =0x01, //移动信息框
RECT_RESIZE =0x02, //改变信息框的大小
RECT_NULL =0xFF //没有操作
};
enum ResizeMode
{
WE_RESIZE=0x00,
NS_RESIZE=0x01,
ALL_RESIZE=0x02
};
public:
/**********************************************************************************
**函数名称:SetStyle
**函数功能:设置矩形风格
**入口参数:style :风格
**出口参数:无
**特殊说明:矩形风格有RECT_VRT_MOVE(垂直移动)RECT_HRN_MOVE(水平移动)
**开 发 者:miaozhengwei
**创建日期:2010-07-30
************************************************************************************/
void SetStyle(UINT32 style){m_Style=style;}
/**********************************************************************************
**函数名称:SetActiveRange
**函数功能:设置矩形的活动范围
**入口参数:rt :矩形的活动范围
**出口参数:无
**特殊说明:
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
void SetActiveRange(CRect rt); //设置信息窗口的活动范围
void GetActiveRange(CRect & rt){rt=m_rtActive;}
/**********************************************************************************
**函数名称:SetRectCursor
**函数功能:设置鼠标在矩形周围的形状
**入口参数:mode :鼠标在矩形周围的模式
hCursor:鼠标的形状名柄
**出口参数:无
**特殊说明:鼠标与矩形位置有四种 WECursor(东西)NSCursor(南北)AllCursor(四角)
InCursor(内部)OutCursor(外部)
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
void SetRectCursor(CursorMode mode,HCURSOR hCursor);
/**********************************************************************************
**函数名称:GetRectCursor
**函数功能:获取鼠标在矩形周围的形状
**入口参数:pt :鼠标当前的位置
**出口参数:鼠标形状句柄
**特殊说明:鼠标与矩形位置有四种 WECursor(东西)NSCursor(南北)AllCursor(四角)
InCursor(内部)OutCursor(外部)
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
HCURSOR GetRectCursor(CPoint pt);
void ClientConvert(CRect & rt);
public: //message handle
/**********************************************************************************
**函数名称:OnDraw
**函数功能:画矩形
**入口参数:pDC :
**出口参数:无
**特殊说明:由视图中的OnDraw或OnPaint函数来调用,如何绘制由子类决定
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
virtual void OnDraw(CDC * pDC)=0; //
/**********************************************************************************
**函数名称:MouseMove
**函数功能:处理鼠标在矩形周围移动
**入口参数:
**出口参数:返回TRUE时,需要调用者刷新视图,false不用
**特殊说明:由WM_MOUSEMOVE消息处理
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
virtual BOOL MouseMove(UINT nFlags, CPoint point);
/**********************************************************************************
**函数名称:LButtonDown
**函数功能:鼠标左键按下处理
**入口参数:
**出口参数:无
**特殊说明:由WM_LBUTTONDOWN消息处理
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
virtual void LButtonDown(UINT nFlags, CPoint point);
/**********************************************************************************
**函数名称:LButtonUp
**函数功能:鼠标弹起
**入口参数:
**出口参数:无
**特殊说明:由WM_LBUTTONUP消息处理
**开 发 者:miaozhengwei
**创建日期:2010-07-29
************************************************************************************/
virtual void LButtonUp(UINT nFlags, CPoint point);
protected:
/**********************************************************************************
**函数名称:SetPos
**函数功能:设置矩形的位置
**入口参数:rt :矩形相对活动区域的位置
**出口参数:无
**特殊说明:
**开 发 者:miaozhengwei
**创建日期:2010-07-30
************************************************************************************/
void SetPos(CRect rt);
/**********************************************************************************
**函数名称:PointInWndEdge
**函数功能:判断点是否在矩形边缘
**入口参数:pt :鼠标位置
**出口参数:无
**特殊说明:
**开 发 者:miaozhengwei
**创建日期:2010-07-30
************************************************************************************/
BOOL PointInWndEdge(CPoint pt);
/**********************************************************************************
**函数名称:PointInWnd
**函数功能:判断点是否在矩形内部
**入口参数:pt :鼠标位置
**出口参数:无
**特殊说明:
**开 发 者:miaozhengwei
**创建日期:2010-07-30
************************************************************************************/
BOOL PointInWnd(CPoint pt);
/**********************************************************************************
**函数名称:AdjustPosition
**函数功能:调整矩形的位置和大小
**入口参数:point :鼠标当前位置
**出口参数:无
**特殊说明:
**开 发 者:miaozhengwei
**创建日期:2010-07-30
************************************************************************************/
void AdjustPosition(CPoint point);
protected:
Operator m_uState;
BOOL m_bLBtnDown;
CRect m_rtActive; //信息窗口的活动范围
CRect m_rtPos; //信息在父窗客户区的位置
HCURSOR m_hWECursor;
HCURSOR m_hNSCursor;
HCURSOR m_hAllCursor;
HCURSOR m_hInCursor;
HCURSOR m_hOutCursor;
HCURSOR m_hCurCursor;
UINT32 m_Style;
ResizeMode m_ResizeMode;
};
#include "RectObject.h"
CRectObject::CRectObject(void)
{
m_rtPos=CRect(2,3,300,33);
m_rtActive=CRect();
m_bLBtnDown=FALSE;
m_uState=RECT_NULL;
m_hWECursor=LoadCursor(NULL,IDC_SIZEWE);
m_hNSCursor=LoadCursor(NULL,IDC_SIZENS);
m_hAllCursor=LoadCursor(NULL,IDC_SIZEALL);
m_hInCursor=LoadCursor(NULL,IDC_HAND);
m_hOutCursor=LoadCursor(NULL,IDC_ARROW);
m_hCurCursor=LoadCursor(NULL,IDC_ARROW);
m_Style=RECT_VRT_MOVE|RECT_HRN_MOVE;
m_ResizeMode=WE_RESIZE;
}
CRectObject::~CRectObject(void)
{
}
void CRectObject::SetPos( CRect rt )
{
if(m_Style&RECT_VRT_MOVE)
{
m_rtPos.top=rt.top;
m_rtPos.bottom=rt.bottom;
}
if(m_Style&RECT_HRN_MOVE)
{
m_rtPos.left=rt.left;
m_rtPos.right=rt.right;
}
}
BOOL CRectObject::PointInWndEdge( CPoint pt)
{
CRect rt=m_rtPos;
ClientConvert(rt);
return (abs(pt.x-rt.left)<10)||(abs(pt.x-rt.right)<10)
||(abs(pt.y-rt.top)<10)||(abs(pt.y-rt.bottom)<10);
}
HCURSOR CRectObject::GetRectCursor( CPoint pt )
{
CRect rt=m_rtPos;
ClientConvert(rt);
if(((abs(pt.x-rt.left)<10)||(abs(pt.x-rt.right)<10)) //四角
&((abs(pt.y-rt.top)<10)||(abs(pt.y-rt.bottom)<10)))
{
m_ResizeMode=ALL_RESIZE;
return m_hAllCursor;
}
if((abs(pt.x-rt.left)<10)||(abs(pt.x-rt.right)<10)) //东西
{
m_ResizeMode=WE_RESIZE;
return m_hWECursor;
}
if((abs(pt.y-rt.top)<10)||(abs(pt.y-rt.bottom)<10)) //南北
{
m_ResizeMode=NS_RESIZE;
return m_hNSCursor;
}
if((pt.x>=(rt.left+10))&&(pt.x<=(rt.right-10)) //内部
&&(pt.y>=(rt.top+10))&&(pt.y<=(rt.bottom-10)))
return m_hInCursor;
return m_hOutCursor; //外部
}
BOOL CRectObject::PointInWnd( CPoint pt )
{
CRect rt=m_rtPos;
ClientConvert(rt);
rt.DeflateRect(5,5,5,5);
return (pt.x>rt.left)&&(pt.xrt.top)&&(pt.y}
BOOL CRectObject::MouseMove( UINT nFlags, CPoint point )
{
BOOL bRet=FALSE;
CPoint pt(point);
if(m_uState==RECT_NULL) //提示窗口没有操作
{
m_hCurCursor=GetRectCursor(pt);
if(PointInWndEdge(pt)) //鼠标在边沿
{
if(m_bLBtnDown)
{
m_uState=RECT_RESIZE;
bRet=TRUE;
}
}
else if(PointInWnd(pt)) //鼠标在内部
{
if(m_bLBtnDown)
{
m_uState=RECT_MOVE;
bRet=TRUE;
}
}
}
SetCursor(m_hCurCursor);
AdjustPosition(point);
return bRet;
}
void CRectObject::AdjustPosition( CPoint point )
{
static CPoint PrePt(0,0);
CRect rt(m_rtPos);
switch(m_uState)
{
case RECT_RESIZE:
switch(m_ResizeMode)
{
case WE_RESIZE:
if(abs(m_rtPos.right-point.x) rt.right=point.x;
else
rt.left=point.x;
break;
case NS_RESIZE:
if(abs(m_rtPos.bottom-point.y) rt.bottom=point.y;
else
rt.top=point.y;
break;
case ALL_RESIZE:
if(abs(m_rtPos.right-point.x) rt.right=point.x;
else
rt.left=point.x;
if(abs(m_rtPos.bottom-point.y) rt.bottom=point.y;
else
rt.top=point.y;
break;
}
SetPos(rt);
break;
case RECT_MOVE:
rt.left+=point.x-PrePt.x;
rt.right+=point.x-PrePt.x;
rt.top+=point.y-PrePt.y;
rt.bottom+=point.y-PrePt.y;
SetPos(rt);
break;
}
PrePt=point;
}
void CRectObject::LButtonDown( UINT nFlags, CPoint point )
{
if(PointInWnd(point)||PointInWndEdge(point))
{
m_bLBtnDown=TRUE;
}
SetCursor(GetRectCursor(point)); //当鼠标点击下后修改鼠标形状
}
void CRectObject::LButtonUp( UINT nFlags, CPoint point )
{
m_bLBtnDown=FALSE;
m_uState=RECT_NULL;
}
void CRectObject::SetActiveRange( CRect rt )
{
if(rt!=m_rtActive)
{
m_rtActive=rt;
SetPos(m_rtPos);
}
}
void CRectObject::ClientConvert( CRect & rt )
{
rt.top+=m_rtActive.top;
rt.left+=m_rtActive.left;
rt.bottom+=m_rtActive.top;
rt.right+=m_rtActive.left;
}
void CRectObject::SetRectCursor( CursorMode mode,HCURSOR hCursor )
{
switch (mode)
{
case WECursor: m_hWECursor=hCursor; break;
case NSCursor: m_hNSCursor=hCursor; break;
case AllCursor: m_hAllCursor=hCursor; break;
case InCursor: m_hInCursor=hCursor; break;
case OutCursor: m_hOutCursor=hCursor; break;
}
}