IM 开源项目 客户端UI框架 Direct UI(01)

过年有些耽搁,深感抱歉。

近日依旧在进行客户端界面使用DirectUI 进行尝试,由于一切控件均需要进行自绘,过程较为耗时。

 

控件的实现由CUIBaseCtrl基类开始

定义如下:

 

/* CLASS_BEGIN *****************************************************
   类名:CUIBaseCtrl
   功能:控件基类
   CLASS_END  ******************************************************/
#ifndef H_CUIBASECTRL_H
#define H_CUIBASECTRL_H
#include "CTypeDef.h"
#include "UIRenderEngine.h"
#include "UICache.h"
#include "UIStructDef.h"
#include "BinarySet.h"

enum e_CheckBordType
{
	e_bIsWorkRange = 0,								// 选中工作区域
	e_bIsCkLBorder,									// 选中左边框
	e_bIsCkRBorder,									// 选中右边框
	e_bIsCkTBorder,									// 选中上边框
	e_bIsCkBBorder,									// 选中上边框
	e_bIsCkLTBorder,								// 选中左顶点
	e_bIsCkRTBorder,								// 选中右顶点
	e_bIsCkLBBorder,								// 选中上底点
	e_bIsCkRBBorder,								// 选中上底点
};

class CWinWnd;
// 控件基类
class CUIBaseCtrl
{
public:
	CUIBaseCtrl(CUICache* apCache, CWinWnd* ahWnd);
	~CUIBaseCtrl(void);


	void	SetVisiable(BOOL abIsVisiable); 										// 设置是否可见
	BOOL	GetVisiable(void);			   											// 获取是否可见

	void	SetCtrlID(ULong aulCtrlID);												// 设置控件ID
	ULong	GetCtrlID(void);														// 获取控件ID
	HWND    GetWnd(void);															// 获取窗口	
	HINSTANCE GetInstance(void);

	int     GetFont(void) {return m_iFont;}											// 获取窗口	
	int     SetFont(int aiFont) {m_iFont = aiFont;}									// 获取窗口	

	void	SetRect(RECT& aoRect);													// 设置控件所在矩形区域
	void	SetRect(int aiXVertex, int aiYVertex, int aiWidth, int aiHeight);		// 设置控件所在矩形区域
	void    SetBordeRect(void);														// 设置边框矩形
	RECT&	GetRect(void);															// 获取控件所在矩形区域

	int		GetWidth(void);															// 获取控件宽度
	int		GetHeight(void);														// 获取控件高度
	int     GetXVertex(void);														// 获取顶点X
	int     GetYVertex(void);														// 获取顶点Y

	void	SetBorderSize(int aiBorderSize);										// 设置控件边框
	int		GetBorderSize(void);													// 获取控件边框
	void	SetBorderRound(SIZE asBorderRound);										// 设置控件圆角
	SIZE	GetBorderRound(void);													// 获取控件圆角

	void	SetWndRound(int aiRound);												// 设置窗体圆角
	int		GetWndRound(void);														// 获取窗体圆角

	void	SetData(unsigned char*);												// 设置控件数据
	UInt8*	GetData(void) const;													// 获取控件数据

	void	SetMaxSize(BOOL abIsMaxSize);											// 设置窗口是否最大化
	BOOL	GetMaxSize(void);														// 获取窗口是否最大化

	BOOL	AddChildCtrl(CUIBaseCtrl*);												// 增加子控件
	BOOL	DelChildCtrl(CUIBaseCtrl*);												// 删除子控件

	BOOL	SetParentCtrl(CUIBaseCtrl*);											// 设置父控件
	CUIBaseCtrl*	GetParentCtrl(void);											// 获取父控件

	void	SetBkColor(ULong aulBkColor);											// 设置背景色
	ULong	GetBkColor(void);														// 获取背景色
	void	SetBkImage(TCHAR* apImageName);											// 获取背图片
	TCHAR*	GetBkImage(void);														// 设置背图片

	void    SetStatusImage(TCHAR* apImageName);
	CStdString& GetStatusImage(void);												
	BOOL	DrawImage(HDC hDC, TCHAR* apImageName, LPCTSTR pStrModify = NULL, int aiNarrow = 0);		// 绘制图片
	void	Invalidate(void);														// 更新

	void	SetFocus(BOOL abIsFocus);												// 是否选中

	RECT&	GetWorkRect(void);														// 获取工作区域矩形
	BOOL	IsPtInCtrlRect(POINT& );												// 坐标是否在控件区域内
	BOOL	IsPtInWorkRect(POINT&);													// 坐标是否在工作区域内
	BOOL	IsPtInLRect(POINT&);													// 坐标是否左边框内
	BOOL	IsPtInRRect(POINT&);													// 坐标是否右边框内
	BOOL	IsPtInTRect(POINT&);													// 坐标是否上边框内
	BOOL	IsPtInBRect(POINT&);													// 坐标是否下边框内
	BOOL	IsPtInLTRect(POINT&);													// 坐标是否左顶点
	BOOL	IsPtInRTRect(POINT&);													// 坐标是否右顶点
	BOOL	IsPtInLBRect(POINT&);													// 坐标是否上底点
	BOOL	IsPtInRBRect(POINT&);													// 坐标是否下底点
	void	OnBReSize(int aiYBefore, int aiYAfter, RECT& aoRedressRect,				// 下边框重新计算
					  RECT& aoParentRect, int aiBorderSize);
	void	OnTReSize(int aiYBefore, int aiYAfter, RECT& aoRedressRect,				// 上边框重新计算
					  RECT& aoParentRect, int aiBorderSize);
	void	OnRReSize(int aiXBefore, int aiXAfter, RECT& aoRedressRect,				// 右边框重新计算
					  RECT& aoParentRect, int aiBorderSize);
	void	OnLReSize(int aiXBefore, int aiXAfter, RECT& aoRedressRect,				// 左边框重新计算
					  RECT& aoParentRect, int aiBorderSize);

	CUIBaseCtrl* FindCtrl(POINT& aoPoint);											// 找到指定坐标所属的子窗口
	CUIBaseCtrl* GetTopCtrl(void);													// 获得底层控件


	void	SetTestMouseHit(BOOL abMouseHit)		{m_bTestMouseHit = abMouseHit;}		// 
	BOOL	GetTestMouseHit(void)					{return m_bTestMouseHit;}
	
	void	SetTestMouseLeave(BOOL abMouseLeave)	{m_bTestMouseLeave = abMouseLeave;}
	BOOL	GetTestMouseLeave(void)                 {return m_bTestMouseLeave;}

	// 设置处理消息回调函数
	BOOL	SetMsgCallBack(ULong aulMsgId, MsgCallBack apFunc);
	// 获取窗口的最大化 还原等属性
	int		GetStytle(void);

	void SetPrintBkColor(BOOL abIsdrawBkCol)		{ m_bPrntBkColor		= abIsdrawBkCol ;}
	void SetPrintBkImage(BOOL abPrntBkImage)		{ m_bPrntBkImage		= abPrntBkImage ;}
	void SetPrintStImage(BOOL abPrntGdiplusImage)	{ m_bPrntGdiPlusImage	= abPrntGdiplusImage ;}
	void SetPrintText(BOOL abPrntText)				{ m_bPrntText			= abPrntText ;}
	void SetPrintBorder(BOOL abPrntBorder)			{ m_bPrntBorder			= abPrntBorder ;}

	CStdString& GetWndText(void)					{ return m_strWinText;}
	void SetWndText(TCHAR* apText);

	//设置文字风格
	void SetTextStyle(ULong aulTextStyle) { m_ulTextStyle = aulTextStyle ;}
	virtual void OnPaint(HDC ahDC, const RECT& aoRect, S_MsgEventUI& apEvent);		// 绘制控件

// 消息处理
protected:
	friend class CMSGMgr;
	
	virtual void PaintBkColor(HDC ahDC);											// 绘制背景
	virtual void PaintBkImage(HDC ahDC);											// 绘制背景图片
	virtual void PaintGdiplusImage(HDC hDC);										// 绘制状态图
	virtual void PaintText(HDC hDC);												// 绘制文字
	virtual void PaintBorder(HDC hDC);												// 绘制边框
	virtual void PaintMoveBorder(HDC hDC);											// 绘制运动边框
	virtual void PaintChangeSize(HDC hDC);											// 绘制大小改变

	virtual void OnSize(S_MsgEventUI& apEvent);										// 大小改变时

	virtual void OnCtrlMsg(S_MsgEventUI& apEvent);									// 控件消息分派
	virtual void OnLButtonDown(S_MsgEventUI& apEvent);								// 当鼠标左键落下
	virtual void OnLButtonUP(S_MsgEventUI& apEvent);								// 当鼠标左键弹起时
	virtual void OnLBuDbClk(S_MsgEventUI& apEvent);									// 当鼠标左键双击

	virtual void OnRButtonDown(S_MsgEventUI& apEvent);								// 当鼠标右键落下
	virtual void OnRButtonUP(S_MsgEventUI& apEvent);								// 当鼠标右键弹起时
	virtual void OnRBuDbClk(S_MsgEventUI& apEvent);									// 当鼠标右键双击

	virtual void OnMouseMove(S_MsgEventUI& apEvent);								// 鼠标移动到
	virtual void OnMouseHover(S_MsgEventUI& apEvent);								// 鼠标停留
	virtual void OnMouseHit(S_MsgEventUI& apEvent);									// 鼠标撞击
	virtual void OnMouseLeave(S_MsgEventUI& apEvent);								// 鼠标移动到
	virtual void OnKillFocus(S_MsgEventUI& apEvent);								// 失去焦点
	virtual	void OnCtrlBroadcast(S_MsgEventUI& apEvent);							// 控件广播消息
	virtual void OnMaxRestore(void);												// 设置窗口的最大化和恢复

	virtual void OnOCMCommand(S_MsgEventUI& apEvent);

// 动作
protected:
	// 平移控件
	virtual void MoveChildWindow(int aiXMove, int aiYMove);							// 移动子窗口
	virtual void BegMoveWindow(POINT& aoPtMouse);									// 开始移动窗口
	virtual void EndMoveWindow(POINT& aoPtMouse);									// 结束移动窗口
	virtual void DrawMoveRect(POINT& aoPtMouse);									// 绘制移动时区域
	virtual void DrawChangeRect(POINT& aoPtMouse);									// 绘制变化时区域

	// 改变控件大小
	virtual void BegSizeChange(POINT& aoPtMouse);									// 开始改变
	virtual void EndSizeChange(POINT& aoPtMouse);									// 结束改变
	virtual void IsChMouseOnBorder(POINT& aoPtMouse);								// 测试鼠标是否边框上
protected:
	CWinWnd*						m_hWinWnd;										
	ULong							m_ulCtrlID;										// 控件ID
	HWND							m_hWnd;
	CUICache*						m_pUIResCache;									// 界面资源缓冲
	UInt8*							m_pData;										// 控件关联数据

	RECT							m_oRect;										// 当前控件所在的区域
	RECT							m_oWockRect;									// 工作区域
	RECT							m_oRectPrint;									// 相交矩形部分	
 	RECT							m_oMovingRect;									// 移动矩形
	RECT							m_oSCUpDateRect;								// 大小改变时更新区域

	RECT							m_oBordeLRect;									// 左边框矩形
	RECT							m_oBordeRRect;									// 右边框矩形
	RECT							m_oBordeTRect;									// 上边框矩形
	RECT							m_oBordeBRect;									// 下边框矩形
	RECT							m_oBordeLTRect;									// 左顶点
	RECT							m_oBordeRTRect;									// 右顶点
	RECT							m_oBordeLBRect;									// 左底点
	RECT							m_oBordeRBRect;									// 右底点

	CUIBaseCtrl*					m_pParentCtrl;									// 父控件
	TBinarySet		m_pChildCtrlSet;								// 子控件
	CThreadLock						m_oChildCtrlSetLock;							// 子控件锁

	BOOL							m_bColorHSL;									// 色调(H)、饱和度(S)、亮度(L)  
	BOOL							m_bIsFocus;										// 是否选中
	BOOL							m_bTestMouseHit;								// 鼠标是否在控件上
	BOOL							m_bTestMouseLeave;								// 鼠标是否在控件上

	ULong							m_ulBkColor;									// 背景色
	TCHAR*							m_pBkImage;										// 背景图片描述
	CStdString						m_oStatusImage;									// 状态图片描述
	int								m_iBorderSize;									// 边框大小

	SIZE							m_cxyBorderRound;								// 边框圆角
	int								m_iRound;										// 窗体圆角
	ULong							m_ulNomalBordecCl;								// 常规边框颜色
	ULong							m_ulFocusBordecCl;								// 焦点边框颜色

	int								m_iXmove;										// 移动时X坐标平移
	int								m_iYmove;										// 移动时Y坐标平移
	int								m_liMaxLXmove;									// 最大左移		
	int								m_liMaxRXmove;									// 最大右移
	int								m_liMaxUYmove;									// 最大上移
	int								m_liMaxDYmove;									// 最大下移	
	BOOL							m_bIsInMove;									// 是否在移动

	int								m_iXChange;										// 改变时X坐标平移
	int								m_iYChange;										// 改变时Y坐标平移
	e_CheckBordType					m_eCheckBordType;								// 鼠标选中区域类型
	BOOL							m_bIsHitBorder;									// 是否停留在边框
	BOOL							m_bInChangeSize;								// 改变大小中
	TCHAR*							m_pMouseIcon;									// 鼠标图标
	BOOL							m_bIsMaxSize;									// 是否最大化
	

	BOOL							m_bPrntBkColor;
	BOOL							m_bPrntBkImage;
	BOOL							m_bPrntGdiPlusImage;
	BOOL							m_bPrntText;
	BOOL							m_bPrntBorder;
	CStdString						m_strWinText;									 // 文字
	CStdString						m_strTextName;									 // 文字名称
	ULong							m_ulTextColor;									 // 颜色
	ULong							m_ulDisTextColor;
	ULong							m_ulTextStyle;                                   // 风格
	BOOL							m_bIsVisiable;									 // 是否可见(可用)
private:
	RECT							m_oRectBefore;
	int								m_iStytle;
	int								m_iFont;										 // 字体
};


#endif//H_CUIBASECTRL_H


实现如下:

#include "StdAfx.h"
#include "UIBaseCtrl.h"
#include "UIWinWnd.h"

CUIBaseCtrl::CUIBaseCtrl(CUICache* apCache, CWinWnd* apWinWnd) 
: m_bColorHSL(FALSE)
, m_bTestMouseHit(TRUE)
, m_bTestMouseLeave(TRUE)
, m_bIsInMove(FALSE)
, m_bIsHitBorder(FALSE)
, m_bInChangeSize(0)
, m_bIsMaxSize(FALSE)
, m_bIsFocus(FALSE)
, m_bPrntBkColor(TRUE)
, m_bPrntBkImage(TRUE)
, m_bPrntGdiPlusImage(FALSE)
, m_bPrntText(TRUE)
, m_bPrntBorder(FALSE)
, m_pBkImage(NULL)
, m_pUIResCache(apCache)
, m_ulNomalBordecCl(0x999999) 
, m_ulFocusBordecCl(0x388E8E) // 选中后的颜色
, m_iBorderSize(1)
, m_pParentCtrl(0)
, m_pMouseIcon(0)
, m_iXmove(0)
, m_iYmove(0)
, m_iStytle(SW_RESTORE)
, m_iRound(0)
, m_iFont(-1)
, m_liMaxLXmove(0)
, m_liMaxRXmove(0)
, m_liMaxUYmove(0)
, m_liMaxDYmove(0)	
, m_ulTextColor(0x555555)
, m_bIsVisiable(TRUE)
, m_strTextName(_T("Default"))
{
	memset(&m_oRectPrint, 0, sizeof(RECT));
	m_cxyBorderRound.cx = 0;
	m_cxyBorderRound.cy = 0;
	m_hWinWnd = apWinWnd;
	m_hWnd = m_hWinWnd->GetWnd();
}

CUIBaseCtrl::~CUIBaseCtrl(void)
{
}

// 设置控件ID
void	CUIBaseCtrl::SetCtrlID(ULong aulCtrlID)
{
	m_ulCtrlID = aulCtrlID;
}

// 设置是否可见
void	CUIBaseCtrl::SetVisiable(BOOL abIsVisiable)
{
	m_bIsVisiable =  abIsVisiable;
	::InvalidateRect(m_hWnd, &GetRect(), TRUE);
} 

// 获取是否可见
BOOL	CUIBaseCtrl::GetVisiable(void)
{
	return m_bIsVisiable;
}					

// 获取控件ID
ULong	CUIBaseCtrl::GetCtrlID(void)
{
	return m_ulCtrlID;
}

 HWND CUIBaseCtrl::GetWnd(void) 
 {
 	return m_hWinWnd->GetWnd();
 }

 HINSTANCE CUIBaseCtrl::GetInstance(void)
 {
 	return m_hWinWnd->GetInstance();
 }

void CUIBaseCtrl::SetRect(int aiXVertex, int aiYVertex, int aiWidth, int aiHeight)
{
	if (aiWidth < m_iBorderSize*3)	
		aiWidth =  m_iBorderSize*3;

	if (aiHeight < m_iBorderSize*3)	
		aiHeight = m_iBorderSize*3;

	m_oRect.left   = aiXVertex;
	m_oRect.right  = aiXVertex + aiWidth;
	m_oRect.top    = aiYVertex;
	m_oRect.bottom = aiYVertex + aiHeight;
	m_oWockRect    = m_oRect;
	if (m_iBorderSize) SetBordeRect();
}

// 设置控件所在矩形区域
void CUIBaseCtrl::SetRect(RECT& aoRect)
{
	if ((aoRect.right - aoRect.left) < (m_iBorderSize*3))
		aoRect.right = aoRect.left + (m_iBorderSize*3);

	if ((aoRect.bottom - aoRect.top) < (m_iBorderSize*3))
		aoRect.bottom = aoRect.top + (m_iBorderSize*3);
	m_oRect     = aoRect;
	m_oWockRect = aoRect;
	if (m_iBorderSize) 
		SetBordeRect();
	::InvalidateRect(m_hWnd,&m_oRect,TRUE);
}


void CUIBaseCtrl::SetBordeRect(void)
{

	// 矫正工作区域
	m_oWockRect.left		+= m_iBorderSize;
	m_oWockRect.right		-= m_iBorderSize;
	m_oWockRect.top			+= m_iBorderSize;
	m_oWockRect.bottom		-= m_iBorderSize;

	// 计算左边界矩形
	m_oBordeLRect.left		=  m_oRect.left;
	m_oBordeLRect.right		=  m_oBordeLRect.left		+ m_iBorderSize;
	m_oBordeLRect.top		=  m_oRect.top				+ m_iBorderSize ;
	m_oBordeLRect.bottom	=  m_oRect.bottom			- m_iBorderSize ;

	// 计算右边界矩形
	m_oBordeRRect.left      =  m_oRect.right			- m_iBorderSize;
	m_oBordeRRect.right     =  m_oRect.right;
	m_oBordeRRect.top		=  m_oRect.top				+ m_iBorderSize ;
	m_oBordeRRect.bottom	=  m_oRect.bottom			- m_iBorderSize ;

	// 计算上边界矩形
	m_oBordeTRect.left      =  m_oRect.left				+ m_iBorderSize ;
	m_oBordeTRect.right     =  m_oRect.right			- m_iBorderSize ;
	m_oBordeTRect.top		=  m_oRect.top;
	m_oBordeTRect.bottom	=  m_oRect.top				+ m_iBorderSize;

	// 计算下边界矩形
	m_oBordeBRect.left      =  m_oRect.left				+ m_iBorderSize;
	m_oBordeBRect.right     =  m_oRect.right			- m_iBorderSize;
	m_oBordeBRect.top		=  m_oRect.bottom	        - m_iBorderSize;
	m_oBordeBRect.bottom	=  m_oRect.bottom;

	// 计算左顶点
	m_oBordeLTRect.left     =  m_oRect.left;
	m_oBordeLTRect.right    =  m_oRect.left				+ m_iBorderSize*4;
	m_oBordeLTRect.top		=  m_oRect.top;
	m_oBordeLTRect.bottom	=  m_oRect.top				+ m_iBorderSize*4;

	// 计算右顶点
	m_oBordeRTRect.left     =  m_oRect.right            - m_iBorderSize*4;
	m_oBordeRTRect.right    =  m_oRect.right;
	m_oBordeRTRect.top		=  m_oRect.top;
	m_oBordeRTRect.bottom	=  m_oRect.top				+ m_iBorderSize*4;

	// 计算左底点
	m_oBordeLBRect.left     =  m_oRect.left;
	m_oBordeLBRect.right    =  m_oRect.left				+ m_iBorderSize*4;
	m_oBordeLBRect.top		=  m_oRect.bottom			- m_iBorderSize*4;
	m_oBordeLBRect.bottom	=  m_oRect.bottom;

	// 计算右底点
	m_oBordeRBRect.left     =  m_oRect.right			- m_iBorderSize*4;
	m_oBordeRBRect.right    =  m_oRect.right;
	m_oBordeRBRect.top		=  m_oRect.bottom			- m_iBorderSize*4;
	m_oBordeRBRect.bottom	=  m_oRect.bottom;
}

// 获取控件所在矩形区域
RECT& CUIBaseCtrl::GetRect(void)
{
	return m_oRect;
}	

// 获取工作区域矩形
RECT& CUIBaseCtrl::GetWorkRect(void)
{
	return m_oWockRect;
}													

// 获取控件宽度
int	CUIBaseCtrl::GetWidth(void)
{
	 return (m_oRect.right - m_oRect.left);
}

// 获取控件高度
int	CUIBaseCtrl::GetHeight(void)
{
	return (m_oRect.bottom - m_oRect.top);
}														
// 获取顶点X
int CUIBaseCtrl::GetXVertex(void)
{
	return  m_oRect.left;
}
// 获取顶点Y
int CUIBaseCtrl::GetYVertex(void)
{
	return  m_oRect.top;
}														

// 设置控件边框
void CUIBaseCtrl::SetBorderSize(int aiBorderSize)
{
	m_iBorderSize = aiBorderSize;
	Invalidate();
}	

// 获取控件边框
int	 CUIBaseCtrl::GetBorderSize(void)
{
	return m_iBorderSize;
}

// 设置控件圆角
void CUIBaseCtrl::SetBorderRound(SIZE asBorderRound)
{
	m_cxyBorderRound.cx = asBorderRound.cx;
	m_cxyBorderRound.cy = asBorderRound.cy;
	Invalidate();
}

// 获取控件圆角
SIZE CUIBaseCtrl::GetBorderRound(void)
{
	return m_cxyBorderRound;
}		
// 设置窗体圆角
void CUIBaseCtrl::SetWndRound(int aiRound)
{
	m_iRound = aiRound;
	SIZE liSize;
	liSize.cx = m_iRound;
	liSize.cy = m_iRound;
	SetBorderRound(liSize);

}
// 获取窗体圆角
int CUIBaseCtrl::GetWndRound(void)
{
	return m_iRound;
}


// 增加子控件
BOOL CUIBaseCtrl::AddChildCtrl(CUIBaseCtrl* apCtrl)
{
	if (!apCtrl)
	    return FALSE;
	m_pChildCtrlSet.Insert(apCtrl);
	apCtrl->SetParentCtrl(this);

	return TRUE;
}	
// 设置父控件
BOOL CUIBaseCtrl::SetParentCtrl(CUIBaseCtrl* apParentCtrl)
{
	if (! apParentCtrl)
		return FALSE;
	m_pParentCtrl = apParentCtrl;
	return TRUE;
}		
// 获取父控件
CUIBaseCtrl*	CUIBaseCtrl::GetParentCtrl(void)
{
	return m_pParentCtrl;
}

// 设置控件数据
void CUIBaseCtrl::SetData(unsigned char* apData)
{
	m_pData = apData;
}	

// 获取控件数据
UInt8* CUIBaseCtrl::GetData(void) const
{
	return m_pData;
}

// 设置窗口是否最大化
void CUIBaseCtrl::SetMaxSize(BOOL abIsMaxSize)
{
	m_bIsMaxSize = abIsMaxSize;
	if (m_pParentCtrl)
		m_pParentCtrl->SetMaxSize(abIsMaxSize);
}

// 获取窗口是否最大化
BOOL CUIBaseCtrl::GetMaxSize(void)
{
	return m_bIsMaxSize;
}												

void CUIBaseCtrl::SetBkColor(ULong aulBkColor)
{
	m_ulBkColor = aulBkColor;
}

ULong CUIBaseCtrl::GetBkColor(void)
{
	return m_ulBkColor;
}

// 设置背图片
void   CUIBaseCtrl::SetBkImage(TCHAR* apImageName)
{
	if (NULL == apImageName)
		return;
	
	if (m_pBkImage)
		 delete [] m_pBkImage;

	int liCnt = 0;
#ifdef UNICODE
	liCnt = wcslen(apImageName);
#else
	liCnt = strlen(apImageName);
#endif

	m_pBkImage = new TCHAR[liCnt+1];
	memset(m_pBkImage, 0 , sizeof(TCHAR)* (liCnt+1));
	memcpy(m_pBkImage, apImageName,sizeof(TCHAR)* liCnt);
}	

// 获取背图片
TCHAR* CUIBaseCtrl::GetBkImage(void)
{
	return m_pBkImage;
}		


// 设置状态图片
void   CUIBaseCtrl::SetStatusImage(TCHAR* apImageName)
{
	if (apImageName)
		m_oStatusImage = apImageName;
}

// 获取状态图片
CStdString& CUIBaseCtrl::GetStatusImage(void)
{
	return m_oStatusImage;
}

// 删除子控件
BOOL CUIBaseCtrl::DelChildCtrl(CUIBaseCtrl* apCtrl)
{
	if (!apCtrl)
		return FALSE;
	m_pChildCtrlSet.Erase(apCtrl);
	return TRUE;
}	

void CUIBaseCtrl::OnPaint(HDC ahDC, const RECT& aoRect, S_MsgEventUI& apEvent)
{
	//如果没有重叠区域
  	if( !::IntersectRect(&m_oRectPrint, &aoRect, &m_oRect)) 
 		return;
	// 分派给控件
	OnCtrlMsg(apEvent);

	// 如果可见的话再绘制
	if (m_bIsVisiable)
	{
		// 绘制背景
 		if (m_bPrntBkColor)
 			PaintBkColor(ahDC);
		// 背景贴图
		if(m_bPrntBkImage)	
			PaintBkImage(ahDC);
		// 状态贴图
		if(m_bPrntGdiPlusImage)
			PaintGdiplusImage(ahDC);
		// 文字
		if(m_bPrntText)
			PaintText(ahDC);
		// 边框
		if(m_bPrntBorder)
			PaintBorder(ahDC);
	}

	CUIBaseCtrl* lpChildCtrl = NULL;
	for (int i = m_pChildCtrlSet.Size() -1; i>=0 ; i--)
	{
		lpChildCtrl = m_pChildCtrlSet[i];
		if (lpChildCtrl)
		{
			apEvent.m_ulCtrlId = lpChildCtrl->GetCtrlID();
			apEvent.m_pCtrl    = lpChildCtrl;
			lpChildCtrl->OnPaint(ahDC, aoRect, apEvent);
		}
	}
	SetFocus(FALSE);
}

// 大小改变时
void CUIBaseCtrl::OnSize(S_MsgEventUI& apEvent)
{
	CUIBaseCtrl* lpChildCtrl = NULL;
	for (int i = m_pChildCtrlSet.Size() -1; i>=0 ; i--)
	{
		lpChildCtrl = m_pChildCtrlSet[i];
		if (lpChildCtrl)
		{
			apEvent.m_ulCtrlId = lpChildCtrl->GetCtrlID();
			apEvent.m_pCtrl    = lpChildCtrl;
			lpChildCtrl->OnSize(apEvent);
		}
	}
}									

// 控件广播消息
void CUIBaseCtrl::OnCtrlBroadcast(S_MsgEventUI& apEvent)
{
	CUIBaseCtrl* lpChildCtrl = NULL;
	apEvent.m_ulCtrlId	= m_ulCtrlID;
	apEvent.m_pCtrl		= this;
	OnCtrlMsg(apEvent);
	for (int i = m_pChildCtrlSet.Size() -1; i>=0 ; i--)
	{
		lpChildCtrl = m_pChildCtrlSet[i];
		if (lpChildCtrl)
			lpChildCtrl->OnCtrlBroadcast(apEvent);
	}
}

// 绘制背景
void CUIBaseCtrl::PaintBkColor(HDC ahDC)
{
 	if (m_ulBkColor != 0)
 		CRenderEngine::DrawColor(ahDC, m_oRect, m_ulBkColor);
}	

void CUIBaseCtrl::PaintBkImage(HDC hDC)
{
	if (m_pBkImage)
		DrawImage(hDC, m_pBkImage);
}

// 是否选中
void	CUIBaseCtrl::SetFocus(BOOL abIsFocus)
{
	m_bIsFocus = abIsFocus;
}	

// 绘制图片
BOOL CUIBaseCtrl::DrawImage(HDC hDC, TCHAR* apImageName, LPCTSTR pStrModify/* = NULL*/, int aiNarrow/* = 0*/)
{
	if (aiNarrow)
	{
		RECT loRect = m_oRect;
		loRect.left   += aiNarrow;
		loRect.right  -= aiNarrow;
		loRect.bottom -= aiNarrow;
		loRect.top	  += aiNarrow;
		return CRenderEngine::DrawImageString(m_pUIResCache, hDC, loRect, m_oRectPrint,  apImageName,  pStrModify );
	}
	else
		return CRenderEngine::DrawImageString(m_pUIResCache, hDC, m_oRect, m_oRectPrint,  apImageName,  pStrModify);
}

// 更新
void	CUIBaseCtrl::Invalidate(void)
{  
	::InvalidateRect(m_hWnd,&m_oRect, TRUE); 
}			
									
// 绘制状态图
void CUIBaseCtrl::PaintGdiplusImage(HDC hDC)
{
	if (m_bPrntGdiPlusImage)
		CRenderEngine::DrawImageGdiPlus(m_pUIResCache, hDC, m_oStatusImage,  Gdiplus::RectF(m_oRect.left, m_oRect.top, (m_oRect.right - m_oRect.left), (m_oRect.bottom - m_oRect.top)));
}

// 绘制文字
void CUIBaseCtrl::PaintText(HDC hDC)
{

}

// 绘制边框
void CUIBaseCtrl::PaintBorder(HDC hDC)
{
 	if( m_iBorderSize > 0 )
 	{
 		if( m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0 )
 		{
 			if (m_bIsFocus && m_ulFocusBordecCl != 0)
 				CRenderEngine::DrawRoundRect(hDC, m_oRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulFocusBordecCl);
 			else
 				CRenderEngine::DrawRoundRect(hDC, m_oRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulNomalBordecCl);
 		}
 		else
 		{
  			if (m_bIsFocus && m_ulFocusBordecCl != 0)
  				CRenderEngine::DrawRect(hDC, m_oRect, m_iBorderSize, m_ulFocusBordecCl);
			else if (m_ulNomalBordecCl != 0)
				CRenderEngine::DrawRect(hDC, m_oRect, m_iBorderSize,m_ulNomalBordecCl);	
 		}
	}
}

void CUIBaseCtrl::PaintMoveBorder(HDC hDC)
{
	if (m_bIsInMove)
	{
		if( m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0 )
		{
			if (m_bIsFocus && m_ulFocusBordecCl != 0)
				CRenderEngine::DrawRoundRect(hDC, m_oMovingRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulFocusBordecCl);
			else
				CRenderEngine::DrawRoundRect(hDC, m_oMovingRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulNomalBordecCl);
		}
		else
		{
			if (m_bIsFocus && m_ulFocusBordecCl != 0)
				CRenderEngine::DrawRect(hDC, m_oMovingRect, m_iBorderSize, m_ulFocusBordecCl);
			else if (m_ulNomalBordecCl != 0)
				CRenderEngine::DrawRect(hDC, m_oMovingRect, m_iBorderSize,m_ulNomalBordecCl);
		}
	}
}

void CUIBaseCtrl::PaintChangeSize(HDC hDC)
{
	if (m_bInChangeSize)
	{
		if( m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0 )
		{
			if (m_bIsFocus && m_ulFocusBordecCl != 0)
				CRenderEngine::DrawRoundRect(hDC, m_oMovingRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulFocusBordecCl);
			else
				CRenderEngine::DrawRoundRect(hDC, m_oMovingRect, m_iBorderSize, m_cxyBorderRound.cx, m_cxyBorderRound.cy, m_ulNomalBordecCl);
		}
		else
		{
			if (m_bIsFocus && m_ulFocusBordecCl != 0)
				CRenderEngine::DrawRect(hDC, m_oMovingRect, m_iBorderSize, m_ulFocusBordecCl);
			else if (m_ulNomalBordecCl != 0)
				CRenderEngine::DrawRect(hDC, m_oMovingRect, m_iBorderSize, m_ulNomalBordecCl);
		}
	}
}



// 坐标是否在控件区域内
BOOL CUIBaseCtrl::IsPtInCtrlRect(POINT& aoPoint)
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oRect);
}	

// 坐标是否在工作区域内
BOOL CUIBaseCtrl::IsPtInWorkRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oWockRect);
}	

// 坐标是否左边框内
BOOL CUIBaseCtrl::IsPtInLRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeLRect);
}		

// 坐标是否右边框内
BOOL CUIBaseCtrl::IsPtInRRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeRRect);
}

// 坐标是否上边框内
BOOL CUIBaseCtrl::IsPtInTRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeTRect);
}

// 坐标是否下边框内
BOOL CUIBaseCtrl::IsPtInBRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeBRect);
}

// 坐标是否左顶点
BOOL CUIBaseCtrl::IsPtInLTRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeLTRect);
}

// 坐标是否右顶点
BOOL CUIBaseCtrl::IsPtInRTRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeRTRect);
}

// 坐标是否上底点
BOOL CUIBaseCtrl::IsPtInLBRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeLBRect);
}

// 坐标是否下底点
BOOL CUIBaseCtrl::IsPtInRBRect(POINT& aoPoint)													
{
	return CRenderEngine::IsPtInRect(aoPoint, m_oBordeRBRect);
}

// 找到指定坐标所属的子窗口
CUIBaseCtrl* CUIBaseCtrl::FindCtrl(POINT& aoPoint)
{
	CUIBaseCtrl* lpFindCtrl = NULL;
	// 如果在当前区域内
	if (IsPtInCtrlRect(aoPoint))
	{
		for (int i = m_pChildCtrlSet.Size() -1; i>=0 ; i--)
		{
			lpFindCtrl = m_pChildCtrlSet[i];
			if (lpFindCtrl)
				if (NULL !=  lpFindCtrl->FindCtrl(aoPoint)) 
					return lpFindCtrl->FindCtrl(aoPoint);
		}
		return this;
	}
	return NULL;
}
// 获得底层控件
CUIBaseCtrl* CUIBaseCtrl::GetTopCtrl(void)
{
	if (NULL != m_pParentCtrl)
		return m_pParentCtrl->GetTopCtrl();
	return this;
}
								

// 控件消息分派
void CUIBaseCtrl::OnCtrlMsg(S_MsgEventUI& apEvent)
{
	if (m_pUIResCache)
	{
		MsgCallBack lpfCBack = m_pUIResCache->GetMsgBack(apEvent.m_ulMsgId, apEvent.m_ulCtrlId);
		if ((lpfCBack)&&(m_hWinWnd))
			(m_hWinWnd->*lpfCBack)(apEvent);
	}
}							

// 当鼠标左键落下
void CUIBaseCtrl::OnLButtonDown(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 当鼠标左键弹起时						
void CUIBaseCtrl::OnLButtonUP(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}		

// 当鼠标左键双击
void CUIBaseCtrl::OnLBuDbClk(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 当鼠标右键落下
void CUIBaseCtrl::OnRButtonDown(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 当鼠标右键弹起时
void CUIBaseCtrl::OnRButtonUP(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 当鼠标右键双击
void CUIBaseCtrl::OnRBuDbClk(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}									

void CUIBaseCtrl::OnMouseHover(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}
void CUIBaseCtrl::OnMouseMove(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}


void CUIBaseCtrl::OnMouseHit(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 鼠标移动到
void CUIBaseCtrl::OnMouseLeave(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 失去焦点
void CUIBaseCtrl::OnKillFocus(S_MsgEventUI& apEvent)
{
	OnCtrlMsg(apEvent);
}

// 开始移动
void CUIBaseCtrl::BegMoveWindow(POINT& aoPtMouse)
{
	// 优先改变
	if (IsPtInWorkRect(aoPtMouse))
	{
		m_iXmove = aoPtMouse.x;
		m_iYmove = aoPtMouse.y;
		m_bIsInMove = TRUE;
	}
}

// 窗口移动
void CUIBaseCtrl::MoveChildWindow(int aiXMove, int aiYMove)
{
	CUIBaseCtrl* lpChildCtrl = NULL;
	CRect loCholdRect;

	for (int i = m_pChildCtrlSet.Size() -1; i>=0 ; i--)
	{
		lpChildCtrl = m_pChildCtrlSet[i];
		if (lpChildCtrl)
		{
			loCholdRect = lpChildCtrl->GetRect();
			loCholdRect.left  += aiXMove;
			loCholdRect.right += aiXMove;
			loCholdRect.top	  += aiYMove;
			loCholdRect.bottom+= aiYMove;
			lpChildCtrl->SetRect(loCholdRect);
			lpChildCtrl->MoveChildWindow(aiXMove, aiYMove);
		}
	}
}

// 结束移动
void CUIBaseCtrl::EndMoveWindow(POINT& aoPtMouse)
{
	DrawMoveRect(aoPtMouse);
	if((((0 == m_iXmove) && (0 == m_iYmove)) || 
		((0 == aoPtMouse.x) && (0 == aoPtMouse.y))))
	{ return;}
	RECT loRectUpdate = m_oRect;
	// 平移
	m_iXmove				=	aoPtMouse.x - m_iXmove;
	m_iYmove				=	aoPtMouse.y - m_iYmove;
	RECT loCtrlRect			=	m_oRect;
	loCtrlRect.left			+=	m_iXmove;
	loCtrlRect.right		+=	m_iXmove;
	loCtrlRect.top			+=	m_iYmove;
	loCtrlRect.bottom		+=	m_iYmove;
	m_iXmove = 0;
	m_iYmove = 0;
	// 矫正
	RECT loRectParent;

	if (!m_pParentCtrl) 
		::GetClientRect(m_hWnd, &loRectParent);

	else loRectParent = m_pParentCtrl->GetRect();
	if (loCtrlRect.left < loRectParent.left)		m_iXmove = loRectParent.left	- loCtrlRect.left;
	if (loCtrlRect.right > loRectParent.right)		m_iXmove = loRectParent.right	- loCtrlRect.right;
	if (loCtrlRect.top < loRectParent.top)			m_iYmove = loRectParent.top		- loCtrlRect.top;
	if (loCtrlRect.bottom > loRectParent.bottom)	m_iYmove = loRectParent.bottom	- loCtrlRect.bottom;
	// 平移
	loCtrlRect.left		+= m_iXmove;
	loCtrlRect.right	+= m_iXmove;
	loCtrlRect.top		+= m_iYmove;
	loCtrlRect.bottom	+= m_iYmove;

	// 移动子窗口
	int liXChildMove = loCtrlRect.left  - m_oRect.left;
	int liYChildMove = loCtrlRect.top - m_oRect.top;
	MoveChildWindow(liXChildMove, liYChildMove);
	// 重置控件矩形
	SetRect(loCtrlRect);
	
	loRectUpdate.left     = min(loRectUpdate.left, loCtrlRect.left);
	loRectUpdate.right    = max(loRectUpdate.right, loCtrlRect.right);
	loRectUpdate.top      = min(loRectUpdate.top, loCtrlRect.top	);
	loRectUpdate.bottom   = max(loRectUpdate.bottom,loCtrlRect.bottom);

	// 更新
	::InvalidateRect(m_hWnd, &loRectUpdate,TRUE);
	m_bIsInMove = FALSE;
	m_liMaxLXmove = 0;
	m_liMaxRXmove = 0;
	m_liMaxUYmove = 0;
	m_liMaxDYmove = 0;	
}	

// 绘制移动时区域
void CUIBaseCtrl::DrawMoveRect(POINT& aoPtMouse)
{
	if((0 == m_iXmove) && (0 == m_iYmove) && (!m_bIsInMove))
	{ return;}

	if (m_liMaxLXmove > (aoPtMouse.x - m_iXmove)) m_liMaxLXmove = (aoPtMouse.x - m_iXmove);
	if (m_liMaxRXmove < (aoPtMouse.x - m_iXmove)) m_liMaxRXmove = (aoPtMouse.x - m_iXmove);
	if (m_liMaxUYmove > (aoPtMouse.y - m_iYmove)) m_liMaxUYmove = (aoPtMouse.y - m_iYmove);
	if (m_liMaxDYmove < (aoPtMouse.y - m_iYmove)) m_liMaxDYmove = (aoPtMouse.y - m_iYmove);

	// 平移
	int  liXmove		 = aoPtMouse.x - m_iXmove;
	int  liYmove		 = aoPtMouse.y - m_iYmove;
	m_oMovingRect		 = m_oRect;

	// 矫正
	RECT loRectParent;
	if (!m_pParentCtrl) 
		::GetClientRect(m_hWnd, &loRectParent);
	else 
		loRectParent = m_pParentCtrl->GetRect();

	if (m_oMovingRect.left < loRectParent.left)			liXmove = loRectParent.left - m_oMovingRect.left;
	if (m_oMovingRect.right > loRectParent.right)			liXmove = loRectParent.right - m_oMovingRect.right;
	if (m_oMovingRect.top < loRectParent.top)				liYmove = loRectParent.top - m_oMovingRect.top;
	if (m_oMovingRect.bottom > loRectParent.bottom)		liYmove = loRectParent.bottom - m_oMovingRect.bottom;
	// 平移
	m_oMovingRect.left		+= liXmove;
	m_oMovingRect.right		+= liXmove;
	m_oMovingRect.top		+= liYmove;
	m_oMovingRect.bottom	+= liYmove;

	//
	RECT loRectUpdate = m_oRect;
	loRectUpdate.left   += m_liMaxLXmove;
	loRectUpdate.right  += m_liMaxRXmove;
	loRectUpdate.top    += m_liMaxUYmove;
	loRectUpdate.bottom += m_liMaxDYmove;
 	// 更新
	::InvalidateRect(m_hWnd, &loRectUpdate,TRUE);
}


void CUIBaseCtrl::IsChMouseOnBorder(POINT& aoPtMouse)
{
	// 如果落在非工作区域
// 	if ( !IsPtInWorkRect(aoPtMouse))
// 	{
		if (IsPtInLRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkLBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZEWE));
			m_pMouseIcon = IDC_SIZEWE;
			m_bIsHitBorder  = TRUE; 
		}
		else if( IsPtInRRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkRBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZEWE));
			m_pMouseIcon = IDC_SIZEWE;
			m_bIsHitBorder  = TRUE; 
			
		}
		else if( IsPtInTRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkTBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENS));
			m_bIsHitBorder  = TRUE; 
			m_pMouseIcon = IDC_SIZENS;
		}
		else if( IsPtInBRect(aoPtMouse))
		{

			m_eCheckBordType = e_bIsCkBBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENS));
			m_bIsHitBorder  = TRUE; 
			m_pMouseIcon = IDC_SIZENS;
		}
		else if( IsPtInLTRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkLTBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
			m_bIsHitBorder  = TRUE; 
			m_pMouseIcon = IDC_SIZENWSE;
		}
		else if( IsPtInRTRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkRTBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENESW));
			m_bIsHitBorder  = TRUE; 
			m_pMouseIcon = IDC_SIZENESW;
		}
		else if( IsPtInLBRect(aoPtMouse))
		{ 
			m_eCheckBordType = e_bIsCkLBBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENESW));
			m_bIsHitBorder  = TRUE;
			m_pMouseIcon = IDC_SIZENESW;
		}
		else if( IsPtInRBRect(aoPtMouse))
		{
			m_eCheckBordType = e_bIsCkRBBorder;
			::SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
			m_bIsHitBorder  = TRUE; 
			m_pMouseIcon = IDC_SIZENWSE;
		}
		return;
	//}
	m_eCheckBordType = e_bIsWorkRange;
	m_bIsHitBorder   = FALSE;
	m_pMouseIcon	 = NULL;
}

// 开始改变
void CUIBaseCtrl::BegSizeChange(POINT& aoPtMouse)
{
	// 如果边框被选中
	if (m_bIsHitBorder)
	{
		m_iXChange = aoPtMouse.x;
		m_iYChange = aoPtMouse.y;
		m_bInChangeSize = TRUE;
		m_oSCUpDateRect = m_oRect;
		::SetCursor(LoadCursor(NULL, m_pMouseIcon));
	}
}

void CUIBaseCtrl::OnLReSize(int aiXBefore, int aiXAfter, RECT& aoRedressRect, RECT& aoParentRect, int aiBorderSize)
{
	if ((aiXAfter - aiXBefore) < 0)
	{
		aoRedressRect.left -= (aiXBefore - aiXAfter);
		if(aoRedressRect.left < aoParentRect.left) 
			aoRedressRect.left = aoParentRect.left;
	}
	else
	{
 		aoRedressRect.left += (aiXAfter - aiXBefore);
 		if (aoRedressRect.left > ( aoRedressRect.right - (aiBorderSize*3)))
 			aoRedressRect.left = ( aoRedressRect.right - (aiBorderSize*3));
	}
}

void CUIBaseCtrl::OnRReSize(int aiXBefore, int aiXAfter, RECT& aoRedressRect, RECT& aoParentRect, int aiBorderSize)
{
	if ((aiXAfter - aiXBefore) > 0)
	{
		aoRedressRect.right += (aiXAfter  - aiXBefore);
		if (aoRedressRect.right > aoParentRect.right) 
			aoRedressRect.right = aoParentRect.right;
	}
	// 变小了
	else
	{
		aoRedressRect.right -= (aiXBefore - aiXAfter);
		if (aoRedressRect.right < ( aoRedressRect.left + (aiBorderSize*3)))
			aoRedressRect.right = ( aoRedressRect.left + (aiBorderSize*3));
	}
}

void CUIBaseCtrl::OnTReSize(int aiYBefore, int aiYAfter, RECT& aoRedressRect, RECT& aoParentRect, int aiBorderSize)
{
	if (aiYAfter < aiYBefore)
	{
		aoRedressRect.top += (aiYAfter - aiYBefore);
		if (aoRedressRect.top < aoParentRect.top)
			aoRedressRect.top = aoParentRect.top;
	}
	else
	{
		aoRedressRect.top -= aiYBefore - aiYAfter;
		if (aoRedressRect.top > (aoRedressRect.bottom - (aiBorderSize*3)))
			aoRedressRect.top = aoRedressRect.bottom - (aiBorderSize*3);
	}
}

void CUIBaseCtrl::OnBReSize(int aiYBefore, int aiYAfter, RECT& aoRedressRect, RECT& aoParentRect, int aiBorderSize)
{
	// 变大
	if (aiYAfter < aiYBefore)
	{
		aoRedressRect.bottom += (aiYAfter - aiYBefore);
		if (aoRedressRect.bottom < aoRedressRect.top +  (aiBorderSize*3))
			aoRedressRect.bottom = (aoRedressRect.top +  (aiBorderSize*3));
	}
	else
	{
		aoRedressRect.bottom += (aiYAfter - aiYBefore);
		if (aoRedressRect.bottom > aoParentRect.bottom)
			aoRedressRect.bottom = aoParentRect.bottom;
	}
}
//GetDesktopWindow
//GetWindowRect
// 绘制变化时区域
void CUIBaseCtrl::DrawChangeRect(POINT& aoPtMouse)
{
	if (!m_bInChangeSize)
	{
		IsChMouseOnBorder(aoPtMouse);
		return;
	}
	// 设置鼠标状态
	::SetCursor(LoadCursor(NULL, m_pMouseIcon));
	if (!m_pParentCtrl)
		::GetClientRect(m_hWnd, &m_oMovingRect);
	else
		m_oMovingRect = m_oRect;

	HWND lhTopWnd = NULL;
	RECT loParentRect;
	if (m_pParentCtrl)
	{
		loParentRect = m_pParentCtrl->GetRect();
		loParentRect.left	+= m_pParentCtrl->GetBorderSize();
		loParentRect.right	-= m_pParentCtrl->GetBorderSize();
		loParentRect.top	+= m_pParentCtrl->GetBorderSize();
		loParentRect.bottom	+= m_pParentCtrl->GetBorderSize();
	}
	else 
		::GetClientRect(m_hWnd, &loParentRect);
// 	{
// 		lhTopWnd  = ::GetDesktopWindow();
// 		::GetClientRect(lhTopWnd, &loParentRect);
// 	}

	switch (m_eCheckBordType)
	{
	case e_bIsCkLBorder:	// 选中左边框
		OnLReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRBorder:	// 选中右边框
		OnRReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		break;		
	case e_bIsCkTBorder:	// 选中上边框	
		OnTReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkBBorder:	// 选中下边框
		OnBReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkLTBorder:	// 选中左顶点
		OnLReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		OnTReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRTBorder:	// 选中右顶点
		OnRReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		OnTReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkLBBorder:	// 选中左底点
		OnLReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		OnBReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRBBorder:	// 选中右底点
		OnRReSize(m_iXChange, aoPtMouse.x , m_oMovingRect, loParentRect, m_iBorderSize);
		OnBReSize(m_iYChange, aoPtMouse.y ,m_oMovingRect, loParentRect, m_iBorderSize);
		break;
	default:
		{
			m_bIsHitBorder  = 0;
			m_bInChangeSize = 0;
			m_pMouseIcon	= 0;
		}
		break;
	}

	// 更新
	if (m_oSCUpDateRect.left	> m_oMovingRect.left)
		m_oSCUpDateRect.left	=  m_oMovingRect.left;

	if (m_oSCUpDateRect.right	< m_oMovingRect.right)
		m_oSCUpDateRect.right	= m_oMovingRect.right;

	if (m_oSCUpDateRect.top		> m_oMovingRect.top)
		m_oSCUpDateRect.top		= m_oMovingRect.top;

	if (m_oSCUpDateRect.bottom	< m_oMovingRect.bottom)
		m_oSCUpDateRect.bottom	= m_oMovingRect.bottom;


//   	if (lhTopWnd)
//   		::InvalidateRect(lhTopWnd, &loParentRect,TRUE);
//   	else
		::InvalidateRect(m_hWnd, &m_oSCUpDateRect,TRUE);
}

// 结束改变
void CUIBaseCtrl::EndSizeChange(POINT& aoPtMouse)
{
	if (!m_bInChangeSize)
	{
		IsChMouseOnBorder(aoPtMouse);
		return;
	}
	// 设置鼠标状态
	RECT loTempRect = m_oRect;
	RECT loParentRect;
	if (m_pParentCtrl)
	{
		loParentRect = m_pParentCtrl->GetRect();
		loParentRect.left	+= m_pParentCtrl->GetBorderSize();
		loParentRect.right	-= m_pParentCtrl->GetBorderSize();
		loParentRect.top	+= m_pParentCtrl->GetBorderSize();
		loParentRect.bottom	+= m_pParentCtrl->GetBorderSize();
	}
	else ::GetClientRect(m_hWnd, &loParentRect);

	switch (m_eCheckBordType)
	{
	case e_bIsCkLBorder:	// 选中左边框
		OnLReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRBorder:	// 选中右边框
		OnRReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		break;		
	case e_bIsCkTBorder:	// 选中上边框	
		OnTReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkBBorder:	// 选中下边框
		OnBReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkLTBorder:	// 选中左顶点
		OnLReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		OnTReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRTBorder:	// 选中右顶点
		OnRReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		OnTReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkLBBorder:	// 选中左底点
		OnLReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		OnBReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	case e_bIsCkRBBorder:	// 选中右底点
		OnRReSize(m_iXChange, aoPtMouse.x , loTempRect, loParentRect, m_iBorderSize);
		OnBReSize(m_iYChange, aoPtMouse.y ,loTempRect, loParentRect, m_iBorderSize);
		break;
	default:
		break;
	}
	// 更新
 	if (m_oSCUpDateRect.left   > loTempRect.left)		m_oSCUpDateRect.left	=  loTempRect.left;
 	if (m_oSCUpDateRect.right  < loTempRect.right)		m_oSCUpDateRect.right	=  loTempRect.right;
 	if (m_oSCUpDateRect.top	   > loTempRect.top)		m_oSCUpDateRect.top		=  loTempRect.top;
 	if (m_oSCUpDateRect.bottom < loTempRect.bottom)	    m_oSCUpDateRect.bottom	=  loTempRect.bottom;

	SetRect(loTempRect);

	m_bIsHitBorder  = 0;
	m_bInChangeSize = 0;
	m_pMouseIcon	= 0;
	::InvalidateRect(m_hWnd, &m_oSCUpDateRect,TRUE);
}	


void CUIBaseCtrl::OnMaxRestore(void)
{
	if (m_pParentCtrl)
		m_pParentCtrl->OnMaxRestore();
	else
	{
		if (SW_MAXIMIZE == m_iStytle )
		{
			m_iStytle = SW_RESTORE;
			::MoveWindow( m_hWnd, m_oRectBefore.left, 
				          m_oRectBefore.top,
						  m_oRectBefore.right  - m_oRectBefore.left,
						  m_oRectBefore.bottom - m_oRectBefore.top,
						  TRUE);
			m_iStytle = SW_RESTORE;
		}
		else 
		{
			m_iStytle = SW_MAXIMIZE;
			RECT	Screen;
			GetWindowRect(m_hWnd,&m_oRectBefore);
			SystemParametersInfo(SPI_GETWORKAREA,0,&Screen,0);
			::MoveWindow( m_hWnd, Screen.left, 
					      Screen.top, 
						  Screen.right,
					      Screen.bottom,
						  TRUE);
		}
	}
}

int CUIBaseCtrl::GetStytle(void)
{
	if (NULL != m_pParentCtrl)
		return m_pParentCtrl->GetStytle();
	return m_iStytle;
}

void CUIBaseCtrl::OnOCMCommand(S_MsgEventUI& apEvent)
{

}

void CUIBaseCtrl::SetWndText(TCHAR* apText)
{
	if (apText)
		m_strWinText = apText;
}

代码实现的很烂,稍后再做调整和优化,目前的目标,就是实现功能。
由此基类派生出具体的控件,目前可以使用的包括:
 CUIAreaCtrl      区域

 CUIPicAreaCtrl   图片区域

 CUIButtonCtrl    按钮

 CUIProgressCtrl  进度条

 CUITextCtrl  文本框

 CUITitleBarCtrl  台头

 CUITreeCtrl      树 --- 进行中ing

 其中也CUITreeCtrl 的实现较为复杂,现在还在进行中,其具体定义如下:
 
 
/* CLASS_BEGIN *****************************************************
   类名:CUITreeCtrl
   功能:树控件
   说嘛:目前用链表实现了这颗树是否合理有待验证
   CLASS_END  ******************************************************/
#ifndef H_UITREECTRL_H
#define H_UITREECTRL_H
#include "UIBaseCtrl.h"

// 节点状态
enum E_TNodeStatu
{
	e_Statu_Shrink	= 0,	// 收缩状态
	e_Statu_Stretch,		// 伸展状态
	e_Statu_Hide,			// 隐藏状态
};

class CUITreeCtrl;
// 树节点
class CUITreeNodeCtrl : public CUIBaseCtrl
{
public:
	CUITreeNodeCtrl(CUICache* apCache, CWinWnd* apWinWnd);
	~CUITreeNodeCtrl(void);

public:
	// 设置Y顶点位置
	int SetYVertex(SInt32 aiYVertex);
	// 设置节点高度
	void SetNodeHigth(SInt32 aiNodeHigth);
	// 获取节点高度
	SInt32 GetNodeHigth(void);
	// 绘制
	virtual void OnPaint(HDC ahDC, const RECT& aoRect, S_MsgEventUI& apEvent);     
protected:
	// 绘制背景
	virtual void PaintBkColor(HDC ahDC);	
	// 绘制背景图片
	virtual void PaintBkImage(HDC ahDC);
	// 绘制状态图
	virtual void PaintGdiplusImage(HDC hDC);
	// 绘制文字
	virtual void PaintText(HDC hDC);
	// 绘制边框
	virtual void PaintBorder(HDC hDC);												
private:	
	friend class CUITreeCtrl;
	SInt32									m_iNodeHigth;			// 节点高度
	SInt32									m_iYVertex;				// Y顶点位置
	E_TNodeStatu							m_eTNodeStatu;			// 节点状态
	CUITreeNodeCtrl*						m_pNodeUp;				// 上一个节点
	CUITreeNodeCtrl*						m_pNodeDown;			// 下一个节点
	CUITreeCtrl*							m_pChildTree;			// 节点可以连接子树
	BOOL									m_bIsChoose;			// 是否被选中

};

// 树控件
class CUITreeCtrl : public CUIBaseCtrl
{
public:
	CUITreeCtrl(CUICache* apCache, CWinWnd* apWinWnd);
	~CUITreeCtrl(void);
	friend class CUITreeNodeCtrl;
public:

	// 增加节点到指定节点上方
	CUITreeNodeCtrl* AddNodeUp(CUITreeNodeCtrl* apConnectNode/* = NULL*/);

	// 增加节点到指定节点下方
	CUITreeNodeCtrl* AddNodeDown(CUITreeNodeCtrl* apConnectNode/* = NULL*/);

	// 增加子节点到指定节点下方
	CUITreeNodeCtrl* AddNodeChild(CUITreeNodeCtrl* apConnectNode/* = NULL*/);

	// 删除指定节点
	BOOL DeleteNode(CUITreeNodeCtrl*& apChildNode);

	// 检查子节点是否属于
	BOOL IsCTNode(CUITreeNodeCtrl* apChildTNode, CUITreeNodeCtrl* apFaterNode);

	// 查询子树
	CUITreeCtrl* FindChildTree(CUITreeNodeCtrl* apCurNode);

	// 查询首节点
	CUITreeNodeCtrl* FindHeadNode(void);

	// 查询尾节点
	CUITreeNodeCtrl* FindTailNode(void);

	// 查询下一个节点
	CUITreeNodeCtrl* FindUpNode(CUITreeNodeCtrl* apCurNode);

	// 查询下一个节点
	CUITreeNodeCtrl* FindDownNode(CUITreeNodeCtrl* apCurNode);
 
	// 重新计算所有节点的位置
	int ResetNodePos(int aiStartPos = 0);

	// 绘制
	virtual void OnPaint(HDC ahDC, const RECT& aoRect, S_MsgEventUI& apEvent); 

	// 计算控件大小
	void CacuRectSize(RECT& loWorkRect);

private:
	//	首节点
	CUITreeNodeCtrl*						m_pHeadNodeCtrl;
	//	尾节点
	CUITreeNodeCtrl*						m_pTailNodeCtrl;
	//  线程安全
	CThreadLock								m_oTreeLock;
	//  是否是顶层控件
	BOOL									m_bIsTopCtrl;
};

#endif//H_UITREECTRL_H

由于没有想到好的方式来处理树的底层数据结构, 目前采用的是双向链表 + 子链表的方式来实现, 待完成后看看效率是否达标吧。

忘各位大神能提好的意见,建议。最初我的想法是Set+List 方式,但是数据维护过于繁琐。

截几个图片:

 

 
 

你可能感兴趣的:(架构设计)