winston 发表于 2012-2-8 22:05:27

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<CUIBaseCtrl*>                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)
{
        returnm_oRect.left;
}
// 获取顶点Y
int CUIBaseCtrl::GetYVertex(void)
{
        returnm_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;
        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;
                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;
                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;
                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;
                        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;
                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);

        // 平移
        intliXmove               = aoPtMouse.x - m_iXmove;
        intliYmove               = 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&nbsp 文本框

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

http://blog.csdn.net/jptaozhantaozhan/article/details/7242451

页: [1]
查看完整版本: IM 开源项目 客户端UI框架 Direct UI(01)