过年有些耽搁,深感抱歉。
近日依旧在进行客户端界面使用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 方式,但是数据维护过于繁琐。
截几个图片: