//FILE: user control bank
#ifndef __RV_UCB_H_INCLUDED_
#define __RV_UCB_H_INCLUDED_



#ifdef UCB_EXPORTS
#define UCB_API __declspec(dllexport)
#else
#define UCB_API __declspec(dllimport)
#endif



#include <rvb\xgui.h>
#include <sst\ucut.h>
  
 
//indicater state
#define RV_IS_PLAYING    1
#define RV_IS_STOPPED    0
#define RV_IS_PAUSED    -1

#define RV_UC_DEFAULT_STYLE  -1




#define UC_INDT_BASE    (0)          // -4096
#define UC_CALI_BASE    (5000)       //0 
#define UC_RACT_BASE    (10000)      //4096

#define RV_CALIBER_TAG         UC_CALI_BASE
#define RV_INDICATOR_TAG       UC_INDT_BASE
#define RV_REACTER_TAG         UC_RACT_BASE


#define RV_UC_CALIBER    UC_CALI_BASE
#define RV_UC_INDICATER  UC_INDT_BASE
#define RV_UC_REACTER    UC_RACT_BASE

 
#define RV_UC_PARENT     (UC_INDT_BASE-1)
#define RV_UC_DELEGATE   (UC_INDT_BASE-2)

#define RV_UC_UNKNOWN    (UC_INDT_BASE - 9999)
#define RV_UC_TAG         RV_UC_UNKNOWN


#define MAX_UCOBJ_NAME_LEN  36

#define MAX_UCOBJ_TEXT_LEN     128
#define MAX_UCOBJ_REMARKS_LEN  512

typedef HANDLE  HGPD;


#define RV_DEF_TEXT_COLOR    GRGB(0, 0, 0)
#define RV_DEF_BODY_COLOR    GRGB(0, 0, 0)
#define RV_DEF_BORDER_COLOR  GRGB(123,0,123)

#define RV_DEF_GRABBER_COLOR    GRGB(0,129,255)
#define RV_DEF_EXTENDER_COLOR   GRGB(155,0,0)

#define RV_DEF_ROTATER_COLOR    GRGB(0, 123, 255)


#define RV_UCO_EXTENDER_COUNT  4

 


//SetCtrlRect Flags
#define SCR_DEFAULT     0
#define SCR_NOMOVE_X    (1<<1)
#define SCR_NOMOVE_Y    (1<<2)
#define SCR_NOMOVE      ( SCR_NOMOVE_X | SCR_NOMOVE_Y)
#define SCR_NOSIZE_W    (1<<3)
#define SCR_NOSIZE_H    (1<<4)
#define SCR_NOSIZE       (SCR_NOSIZE_W | SCR_NOSIZE_H)

//
//#define RC_SHP_UNKNOWN   -1
//#define RC_SHP_RECT      0x00
//#define RC_SHP_CIRCLE    0x01
//#define RC_SHP_RING      0x02
//#define RC_SHP_ANNULUS   0x03
//#define RC_SHP_ADAPT     0x04
//#define RC_SHP_CUSTOM    0x05
 
//UC Style, used when first created.
//style为整型，最多31种风格，最高位为符号位，
//需要保留。
//仅低16位绘制产生影响
#define RV_UCS_ENABLE        (1 )
#define RV_UCS_VISIBLE       (1 << 1)
#define RV_UCS_TABSTOP       (1 << 2)  //tab键选择
#define RV_UCS_FIXPOS        (1 << 3)
#define RV_UCS_FIXSIZE       (1 << 4)
#define RV_UCS_ROTATABLE     (1 << 5)
#define RV_UCS_ANIMATION     (1 << 6)  //动画显示
#define RV_UCS_BORDER        (1 << 7)  
#define RV_UCS_CAPTION       (1 << 8)
#define RV_UCS_FILLBKG       (1 << 9)   //填充背景区域
#define RV_UCS_SYMMSIZING    (1 << 10)  //uc改变大小时，是否对称改变。
#define RV_UCS_URL           (1 << 11)  //URL链接。
 

 

#define RV_REDRAW_ALL      0xFFFFFFFF

  

//状态
//仅高16位对绘制产生影响
#define RV_CS_TEXT_COLOR         1
#define RV_CS_BODY_COLOR        (1<<1)
#define RV_CS_BORDER_COLOR      (1<<2)
#define RV_CS_CONTENT_TXT       (1<<3)
#define RV_CS_CONTENT_IMG       (1<<4)
#define RV_CS_CURUC_CHANGE      (1<<5)  //当前选择的UC变了(一般组合对象有效)

  
#define RV_CS_LOCKED          (1 << 16)   //锁住的
#define RV_CS_SELECTED        (1 << 17)   //已经选择
#define RV_CS_FOCUSED         (1 << 18)   //焦点
#define RV_CS_MOUSEOVER       (1 << 19)   //鼠标活动
#define RV_CS_MOUSEDOWN       (1 << 20)   //鼠标按下
#define RV_CS_CURSORIN        (1 << 21)   //游标
#define RV_CS_ASDEFAULT       (1 << 22)   //作为默认
#define RV_CS_THEME_CHANGED   (1 << 23)   //主题改变
#define RV_CS_APPEAR_CHANGED  (1 << 24)   //外观改变
#define RV_CS_OPACITY_CHANGED (1 << 25)   //透明，对透明度改变有效
#define RV_CS_COLOR_CHANGED   (1 << 26)   //颜色改变了


 



#define RV_SWITCH_STYLE(style, flag, val)   {if (val) style |= (flag); else   style &= (~(flag));  }
#define RV_IS_STYLE_ON(style, flag)         ((style) & (flag))
#define RV_IS_STYLE_OFF(style, flag)        ( !RV_IS_STYLE_ON(style, flag) )

//#define RV_SWITCH_STYLE(flag, val)   {if (val) m_nStyle |= (flag); else   m_nStyle &= (~(flag));  }
//#define RV_IS_STYLE_ON(flag)         ((m_nStyle) & (flag))
//#define RV_IS_STYLE_OFF(flag)        ( !IS_STYLE_ON( flag) )
 
#define RV_RETURN_UNCHANGED_STYLE(style, flag, val)  {if (val){ if (RV_IS_STYLE_ON(style, flag)) return; }else{  if (RV_IS_STYLE_OFF(style, flag)) return; } }

/*
typedef struct __rv_msgmap_entry_
{
	UINT  eventID ;   // event id
	UINT  objID ;     // object id
 	void* pfn;        // routine to call (or special value)
}RV_MSGMAP_ENTRY;
 */

#define RV_RECT_TOLER   5


#define RV_UC_BEGIN_DRAW(bRedraw)       if ((!m_nDrawFlags) && (!(bRedraw))) return; else if (bRedraw) m_hStroke=NULL;

#define RV_UC_END_DRAW(delegater)                {  m_nDrawFlags = 0; UpdateVisibility(delegater); }


#ifdef _DEBUG 

    #define RV_UC_ASSERT_STROKE(bForceDraw)   if (m_nDrawFlags && (!bForceDraw)) RV_ASSERT(m_hStroke); 
#else   
    #define RV_UC_ASSERT_STROKE(bForceDraw)
#endif   


#define RV_UC_ASSERT_MODIFY(bRedraw)       

//flag为style 或 state的标记宏
#define RV_UC_NOTIFY_REDRAW(flag)       m_nDrawFlags |= (flag);


#define RV_RM_STROKE_COUNT  3

 


class UCB_API CRotatorMark
{
public:
	CRotatorMark();
	~CRotatorMark();

	BOOL Create(HGDC dc/*, int radius, int size*/);
	void Destroy();

	void Draw(GPoint center,  double angle,int poleLength =13, int grabberSize=8, GPen* pPen =NULL, GBrush* pBrush=NULL);

	//如果bThoroughly为TRUE，将绘制产生的笔画对象也删除。
	//注意，如果在Delegate的其他地方删除了笔画对象的话，
	//bThoroughly必须为FALSE，否则产生一些不可预料的错误。
	void Erase(BOOL bThoroughly);


private:
 	HANDLE   m_hRotaterStrokes[RV_RM_STROKE_COUNT];
	 HGDC      m_dc;
	 
	//int       m_nRadius,  m_nSize;

	//

};



class UCB_API CSketchMark
{
public:
	CSketchMark();
	~CSketchMark();

	BOOL Create(HGDC dc );
	void Destroy();

	//如果bThoroughly为TRUE，将绘制产生的笔画对象也删除。
	//注意，如果在Delegate的其他地方删除了笔画对象的话，
	//bThoroughly必须为FALSE，否则产生一些不可预料的错误。
	void Erase(BOOL bThoroughly);
 
	void Prepare();

	void DrawPoint(GPen* pPen, int x, int y);
	void DrawLine(GPen* pPen, int x0, int y0, int x1, int y1);
	void DrawArc(GPen* pPen, int cx, int cy, int radius, float startAngle, float endAngle);
	void DrawRect(GPen* pPen, int left, int top, int right, int bottom  );
	void DrawEllipse(GPen* pPen, int cx, int cy, int rx, int ry, float angle);
	void DrawCircle(GPen* pPen, int cx, int cy, int radius);

	
	void DrawPolyline(GPen* pPen,GPoint* pVertexArray, int nVertexCount );
	void DrawPolygon(GPen* pPen,GPoint* pVertexArray, int nVertexCount );

	void Commit();
	
 
private:
	//HANDLE*   m_pStrokeArray;
	//int      m_nStrokeSize;
	//int      m_nStrokeCount;
	 
	RvCluster m_cluster;

	//HANDLE   m_hComposite;

	 HGDC      m_dc;
 

	GPen     m_curPen;
	 
	int       m_nPreviousLayer;
	//GPen*     m_pPreviousPen;
};

 

class UCB_API CLeadMark
{
public:
	CLeadMark();
	~CLeadMark();

	//Mark形状
	enum
	{
		LM_SQUARE  = 0, //方形
		LM_ROUND,       //圆形
		LM_TRIANGLE,    //三角形
		LM_DIAMOND,     //菱形
		LM_ARROW,       //箭头
		LM_CROSS,       //十字线
		LM_CROSS_X,     //乘号线
	};

	BOOL Create(HGDC dc);
	void Destroy();

	//如果bThoroughly为TRUE，将绘制产生的笔画对象也删除。
	//注意，如果在Delegate的其他地方删除了笔画对象的话，
	//bThoroughly必须为FALSE，否则产生一些不可预料的错误。
	void Erase(BOOL bThoroughly);
 
	void Prepare();

	//bRound is reserved so far.
	void Draw(int shape, GRect* pRect, float angle = 0.f,  GPen* pPen =NULL, GBrush* pBrush =NULL , BOOL bNoFill=FALSE);
	 
	void Commit();
	
private:

	void DrawCircle(GRect* pRect, GPen* pPen, GBrush* pBrush , BOOL bNoFill);
	void DrawPolygon( int shape, GRect* pRect, float angle,  GPen* pPen, GBrush* pBrush , BOOL bNoFill);
	void DrawArrow(GRect* pRect, float angle, GPen* pPen, GBrush* pBrush , BOOL bNoFill);
	void DrawCross(GRect* pRect, float angle, GPen* pPen, BOOL bX);

	RvCluster m_cluster;

	 HGDC      m_dc; 
	 

	int       m_nPreviousLayer; 

}; 



//
//#define UC_BEGIN_WRITE_UC(hfile, tag)     if (!CDiskHelper::BEGIN_OBJ_OUT(hfile, tag)) return FALSE; 
//#define UC_END_WRITE_UC(hfile, tag)       if (!CDiskHelper::END_OBJ_OUT(hfile, tag)) return FALSE; 
//
//#define UC_WRITE_VAR(hfile, v)         if (!CDiskHelper::Write(hfile, v)) return FALSE;
//
//#define UC_WRITE_TEXT(hfile, text )    if (!CDiskHelper::Write(hfile, text)) return FALSE;
//#define UC_WRITE_OBJ(hfile, obj, size) if (!CDiskHelper::Write(hfile, obj, size)) return FALSE;
//
//
//#define UC_BEGIN_READ_UC(hfile, tag)        if (!CDiskHelper::BEGIN_OBJ_IN(hfile, tag )) return FALSE; 
//#define UC_END_READ_UC(hfile, tag)          if (!CDiskHelper::END_OBJ_IN(hfile, tag)) return FALSE; 
//
//#define UC_READ_VAR(hfile, v)                if (!CDiskHelper::Read(hfile, v)) return FALSE;
//#define UC_READ_TEXT(hfile, text, max_size ) if (!CDiskHelper::Read(hfile, text, max_size)) return FALSE;
//#define UC_READ_OBJ(hfile, obj, size)        if (!CDiskHelper::Read(hfile, obj, size)) return FALSE;

 
class UCB_API CDelegate{

public:
	//如果要清除图像帧，需要调用函数清除，然后RT_REALIZE	
	enum REFRESH_TYPE{
		RT_REALIZE =0  , //重新将笔画绘制效果实现,调用rvgRealize
		RT_UPDATE ,      //绘制原来的笔画对象（如需）。
		RT_REDRAW ,      //清除笔画并强制重画笔画（可能调用各个类的RT_PURE）。
		RT_PURE,         //仅绘制当前类需要实现的笔画，无重画,无清除（无rvgRealize，rvgClear）
		//RT_FRAME  ,      //仅绘制图像帧，不清除笔画，也不绘制笔画，目前效果同RT_REALIZE。
	};

	enum DESIGN_MODE
	{
         DM_EDITION =0 ,   //编辑状态
         DM_RUNTIME ,      //运行态
		 DM_ADDING =10 ,    //正在添加
		 DM_DIALOG     ,    //对话框，运行态，编辑态
		 DM_EXTENT =100,    //扩展, 建议扩展的模式从100开始
    };

	//enum SELECT_STATE{
	//	SS_TABSTOP = -1,  //TAB所在的位置（没有选择状态）
	//	SS_NONE=0,
	//	SS_SELECTED= 1,
	//	SS_FOCUSED = 2,  //选择里面中的带焦点的,有焦点的肯定也是选择的状态
	//	SS_MULTI   = 3,   //多选		
	//};	 


	enum HIT_POS{
		HP_NOTHING    =  -100,
		HP_CAPTION    =  -5,    //标题，检测算子
		HP_BORDER     =  -4,    //边缘，新增on 2019/03/10
		HP_ROTATER    =  -3,
		HP_GRABBER    =  -2,
		HP_MIDDLE     =  -1,
		HP_EXTENDER   =   0,
	};

	enum TRACK_TYPE{
		TT_NONE=-1,
		TT_RESIZE =0,
		TT_MOVE ,
		TT_ROTATE,
		TT_CAPTION, //检测算子标题的位置
	};

public:
	CDelegate();
	virtual ~CDelegate();

	HGDC GetDC() {return m_dc;};
	HWND GetBindWnd(){ return m_hBindWnd; };


	virtual BOOL Create(HWND hWnd,  RV_CONTEXT_TYPE canvasType=RV_CT_GENERIC, int canvasWidth=-1, int canvasHeight=-1);
	//       BOOL InitializeEx(HWND hWnd, HGDC dc);
	virtual  void Destroy();
	 
	virtual void Refresh(REFRESH_TYPE type)=0 ;


 	CSketchMark*  GetSketchMark() { return &m_sketchMark; };
	CRotatorMark* GetRotatorMark(){ return &m_rotaterMark; };
 	CLeadMark* GetExtenderMark(){ return &m_extenderMark; };
	CLeadMark* GetGrabberMark()    { return &m_moverMark; };
	
	//bRefresh仅在UI线程下有效，其他线程无效
	//SetDesignMode将影响：
	//1  DM_DESIGN: 编辑锁为FALSE， RVB标识不可见。
	//2  DM_RUNTIME: 编辑锁为TRUE, RVB标识可见,所有UC的选择状态为SS_NONE
	//在调用该函数以后，请重新调用相关的函数，对影响的参数进行恢复。
	virtual void SetDesignMode(int mode, BOOL bRefresh=FALSE) ;
	int  GetDesignMode();


	BOOL         IsEditionLocked();
	virtual void SetEditionState(BOOL bLock, BOOL bRefresh=TRUE);

	CRITICAL_SECTION*  GetLockUI(){return &m_csGui;};
	//锁住GUI刷新
	void LockUI(){ ::EnterCriticalSection(&m_csGui); }
	void UnlockUI(){::LeaveCriticalSection(&m_csGui); };

	//窗口函数大小和位置
	virtual GRect GetDisplayRect()=0;
	virtual void  SetDisplayRect(int left, int top, int width, int height,  BOOL bRefresh= FALSE)=0;
	virtual void  SetDisplaySize( int width, int height,  BOOL bRefresh= FALSE)=0;
	virtual void  SetDisplayPos( int left, int top)=0;

public:	 

	int   m_nExtenderSize;
	int   m_nGrabberSize;//including rotator size
	int   m_nPoleLength; //rotator length

	//去掉颜色变量，减少类之间耦合
 	GRgb     m_grabberColor;
 	GRgb     m_extenderColor;
 	GRgb     m_rotaterColor;

	int    m_nLineWidth;//决定gabber, externder等的边框的线条的粗细
	 
 
protected:

	HGDC         m_dc;
	int          m_nMode;

	CRITICAL_SECTION m_csGui;
	 
	BOOL m_bActive;   //将来使用
	BOOL m_bEditLocked;

 	CSketchMark   m_sketchMark;
 	CRotatorMark  m_rotaterMark;
	CLeadMark     m_extenderMark;
	CLeadMark     m_moverMark;    //移动模块

	HWND   m_hBindWnd;
	BOOL   m_bReserved1;//保留将来使用

	
};


class UCB_API CUCObj
{
	//friend class CDelegate; del by hdy
public:

	enum LINE_TYPE{
		LT_SOLID = RV_PS_SOLID,
		LT_HIDDEN = RV_PS_HIDDEN,
		LT_CENTER = RV_PS_CENTER,
		LT_INCLUSION = RV_PS_INCLUSION,
	};

	enum FONT_STYLE{
	   FS_DEFAULT = RV_FS_DEFAULT    ,
       FS_BOLD =   RV_FS_BOLD          ,
       FS_ITALIC = RV_FS_ITALIC       ,
       FS_UNDERLINE  = RV_FS_UNDERLINE     ,
       FS_STRIKEOUT =  RV_FS_STRIKEOUT     ,
       FS_OUTLINE =    RV_FS_OUTLINE   ,
       FS_NOBKGROUND = RV_FS_NOBKGROUND     ,
	};

	CUCObj();
	virtual ~CUCObj();


 	virtual BOOL  Create(/*CDelegate* pDelegate=NULL,*/ const TCHAR* strName = NULL, UINT id =-1, int style = RV_UC_DEFAULT_STYLE) ;

	virtual void  Destroy(/*BOOL bEraseStroke=FALSE*/) ;
	

	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
	virtual CUCObj* Clone( CUCObj* twin) ;
	 
 
	void  SetFontStyle(const TCHAR* strFaceName, int size, int flags);
	const TCHAR*  GetFontName();
	int   GetFontSize();
	int   GetFontFlags();

	void SetFontName(const TCHAR*  strFaceName);
	void SetFontSize(int size);
	void SetFontFlags(int flags);
	 

	//控件的客户区大小
	//一般情况下客户区大小与控件大小是一样的
	RvRect GetClientRect();
//	virtual void  SetClientRect(int x, int y, int w, int h) ;
	
	//获得控件的RECT
	//新增接口 on 2020/02/26
	
	virtual void   SetCtrlRect(int left, int top, UINT width, UINT height) ;
	void   SetCtrlRectEx(int left, int top, int right, int bottom, int flags) ;
	void   SetCtrlRect(RvRect rect);
	void   SetCtrlRect(RvPoint leftTop, RvPoint rightBottom);
	RvRect GetCtrlRect();
	 
	virtual void   SetCtrlPos(int x, int y);
    void           SetCtrlPos(RvPoint pos);

	RvPoint GetCtrlPos();
	 

	int      GetSubclassType() { return m_objType; };
	int      GetID()        { return m_uid; };
	void     SetID(int id)  { m_uid = id; };

	//所在层
	int  GetLayer() { return m_nLayer;};
	void SetLayer(int layer){
		m_nLayer = layer;
	    RV_UC_NOTIFY_REDRAW(RV_REDRAW_ALL); 
	}

	void     SetName(const TCHAR* strName);
	const TCHAR* GetName(){return m_strName; };

	int      GetStyle()     { return m_nStyle; };
	virtual void     SetStyle(int style) ;      
 
	int     GetState()     { return m_nState; };
	virtual void     SetState(int state) ;      
	void    ClearState(){ SetState(0);  };

	virtual void SetEnable( BOOL state ) {
		RV_RETURN_UNCHANGED_STYLE(m_nStyle, RV_UCS_ENABLE, state);
		
		RV_SWITCH_STYLE(m_nStyle, RV_UCS_ENABLE, state); 
		
		RV_UC_NOTIFY_REDRAW(RV_UCS_ENABLE); 
	};

    BOOL IsEnabled() { return (m_nStyle & RV_UCS_ENABLE) == RV_UCS_ENABLE; };

    virtual void SetVisible( BOOL state ) ;	
    BOOL IsVisible() { return ((m_nStyle & RV_UCS_VISIBLE) == RV_UCS_VISIBLE); };

	virtual void Lock( BOOL state )  {
		RV_RETURN_UNCHANGED_STYLE(m_nState, RV_CS_LOCKED, state);

		RV_SWITCH_STYLE(m_nState, RV_CS_LOCKED, state);  
		RV_UC_NOTIFY_REDRAW(RV_CS_LOCKED); 
	};
    BOOL IsLocked() { return ( (m_nState & RV_CS_LOCKED) == RV_CS_LOCKED); };

	
		
	virtual void  SetPosFixed(BOOL state) {
		RV_RETURN_UNCHANGED_STYLE(m_nStyle, RV_UCS_FIXPOS, state); 
		RV_SWITCH_STYLE(m_nStyle, RV_UCS_FIXPOS, state); 
	}
	BOOL  IsPosFixed() { return ((m_nStyle & RV_UCS_FIXPOS) == RV_UCS_FIXPOS); }

	virtual void  SetSizeFixed(BOOL state) {
		RV_RETURN_UNCHANGED_STYLE(m_nStyle, RV_UCS_FIXSIZE, state); 

		RV_SWITCH_STYLE(m_nStyle, RV_UCS_FIXSIZE, state); 
	}

	BOOL  IsSizeFixed() { return ((m_nStyle & RV_UCS_FIXSIZE) == RV_UCS_FIXSIZE); }

	virtual void  SetRotatable(BOOL state) {
		RV_RETURN_UNCHANGED_STYLE(m_nStyle, RV_UCS_ROTATABLE, state); 
		RV_SWITCH_STYLE(m_nStyle, RV_UCS_ROTATABLE, state); 
	}
	BOOL  IsRotatable() { return ((m_nStyle & RV_UCS_ROTATABLE) == RV_UCS_ROTATABLE); }
 
	//清除RV_CS_CURUC_CHANGE
	virtual void   SetSelectState(BOOL state) ;
	BOOL  IsSelected() { return ((m_nState & RV_CS_SELECTED) == RV_CS_SELECTED); }

	virtual void  SetTransparence(int ratio)
	{ 
		if (ratio>100) ratio =100; if (ratio<0) ratio=0; 
		m_nTransparence = ratio; 

		RV_UC_NOTIFY_REDRAW(RV_CS_OPACITY_CHANGED);
	};

	int   GetTransparence(){ return m_nTransparence; };
 
	int  GetLineWidth();
	virtual void SetLineWidth(int width);

	int  GetLineType();
	virtual void SetLineType(CUCObj::LINE_TYPE type);

	GRgb    GetTextColor() { return m_textColor; };
	virtual void    SetTextColor(GRgb& val);

	GRgb    GetBodyColor() { return m_bodyColor; };
	virtual void    SetBodyColor(GRgb& val);

	GRgb    GetBorderColor() { return m_borderColor; };
	virtual void    SetBorderColor(GRgb& val);
	

	double GetRotationAngle();
	virtual void   SetRotationAngle(double angle);

	//支持自动变色
	virtual GRgb GetCurTextColor();
	virtual GRgb GetCurBodyColor();
	virtual GRgb GetCurBorderColor();
	virtual GRgb GetCurFillColor();


	//直接使用BORDER COLOR
//	virtual GRgb GetCurPatchColor();  //调节盘的方框颜色
	 
public:

	virtual void Show(CDelegate* pDelegate, int mode, BOOL bRedraw);

		
	virtual void Move(RvOffset &offset) ;
	virtual void Move(double dx, double dy) ;


// Windows message handler
    virtual BOOL MsgProc( UINT uMsg, WPARAM wParam, LPARAM lParam ) { return FALSE; }

 //   virtual BOOL HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam ) { return FALSE; }
 //   virtual BOOL HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam ) { return FALSE; }

	//显示坐标，非画布坐标
	virtual BOOL IsPointInside_( GPoint& pt ) ;
   
	virtual GRect GetCurRect()  ;

//for delegate only(internal use).
public:
	virtual int   HitTest(CDelegate* pDelegate, GPoint point) ;
	
	//for mouse cursor type
	virtual int   CheckHit(CDelegate* pDelegate, GPoint point) { return HitTest(pDelegate, point);} ;

	virtual BOOL  SetCursor( HWND hWnd, int mode,  UINT nHitTest );
	 
	GRect         GetHotRect(GSize& size, GPoint& point, CDelegate::TRACK_TYPE type/*, BOOL bActualSize*/) ;

	//virtual  void  SetSelectState(CDelegate::SELECT_STATE state) { m_selState = state;  };
	//CDelegate::SELECT_STATE GetSelectState() {return m_selState; };

 	virtual void  ShowExtender(CDelegate* pDelegate, CLeadMark* pMark/*, BOOL bGrabber=FALSE*/);
 	virtual void  ShowGrabber(CDelegate* pDelegate, CLeadMark* pMark/*, BOOL bGrabber=FALSE*/);

	virtual void  ShowRotater(CDelegate* pDelegate,CRotatorMark* pMark );

	//这个是添加以后，修改时的框架
	virtual void ShowSketch(CDelegate* pDelegate, CSketchMark* pMark,  HGPD hGpd,  int grabType, GPoint grabPos)  ;

	//用于添加以前的显示框架
	virtual void ShowSketch(CDelegate* pDelegate, RvPoint leftTop, RvPoint rightBottom);

	virtual BOOL OnPositionChange( HGPD hOri, HGPD hCur, HGPD hNew, GPoint grabPos, RvOffset &offset) ;
	virtual BOOL OnExtenderChange( HGPD hCur, HGPD hNew, int index, GPoint &curPos) ;
	virtual BOOL OnRotationChange( HGPD hCur, HGPD hNew, GPoint &curPos) ;

	virtual void OnBeginTrack(CDelegate* pDelegate, HGPD hCur, GPoint point, int nHitTest)  ;
	virtual void OnEndTrack(CDelegate* pDelegate,  HGPD hCur,  GPoint point, int nHitTest) ;

	virtual void DestroyGraphicDescriptor(HGPD hGpd)  ;
	virtual HGPD CreateGraphicDescriptor(CDelegate* pDelegate) ;
	virtual void CopyGraphicDescriptor(const HGPD src, HGPD dest);

	//virtual void SetBoundRect(GRect rect){ m_boundRect = rect; };
	//GRect GetBoundRect(){ return m_boundRect; };
	 
	//下面的函数访问权限必须公开
	//坐标为显示坐标系
	virtual GRect  GetGrabberRect(CDelegate* pDelegate,RvSize size/*, BOOL bActualSize*/) ;
	virtual GRect  GetExtenderRect(CDelegate* pDelegate,int index, RvSize size/*, BOOL bActualSize*/) ;
	virtual GRect  GetRotaterRect(CDelegate* pDelegate,GPoint& center, double angle, RvSize size/*BOOL bActualSize*/) ;
	
	//热点方块颜色
	virtual GRgb GetCurGrabberColor(CDelegate* pDelegate);
	virtual GRgb GetCurExtenderColor(CDelegate* pDelegate);
	virtual GRgb GetCurRotaterColor(CDelegate* pDelegate);

	virtual int     GetExtenderCount() { return m_nExtenderCount; };

	////需要指定源点所在的层
	//static RvPoint ConvertPointToDisplay(CDelegate* pDelegate,  RvPoint point);

	////需要指定目标层(如virtual or canvas)
	//static RvPoint ConvertPointToCanvas(CDelegate* pDelegate,   RvPoint point);



protected: 
	//bWrap为保留参数
	RV_HANDLE DrawText(HGDC dc,  const TCHAR* strText,  RvRect rect,  BOOL  bWrap, RV_HANDLE hStroke);
	RV_HANDLE DrawBorder(HGDC dc, GRgb& color , int lineWidth, int lineType, RV_HANDLE hStroke);
	void      UpdateVisibility(CDelegate* pDelegate);

	//显示坐标计算，获得旋转柄末端位置
	GPoint GetRotaterEndpos(GPoint center, int length, double angle);
 
	//x,y, pVertexArray为相同坐标系
	BOOL IsPointInPolygon (int x, int y, GPoint* pVertexArray, int nVertexCount) ;
	
	// 该函数仅判断点是否在限制矩形里面,
	// 不会进行坐标转换。
	// 需要将STYLE 设置为RV_UCS_BOUND_IN
	//BOOL IsPointInBoundRect(GPoint& point);

	///hit为窗口坐标，全部转成窗口坐标
	BOOL IsLineSelected_(GPoint& p1, GPoint& p2, GPoint& hit);
	//new definition
	BOOL IsLineSelected (GPoint& p1, GPoint& p2, GPoint  hit);


	//相同层的点
	BOOL IsPolylineSelected(GPoint* pPtArr, int count, BOOL bClosed, GPoint  hit);

	
	//hit为窗口坐标，center,radius为窗口坐标
	BOOL IsCircleSelected_(GPoint& center, int radius, GPoint& hit );

	//hit为窗口坐标，center,radius, startAngle, endAngle为窗口坐标,角度单位为度
	BOOL IsArcSelected_(GPoint& center, int radius, double startAngle, double endAngle, GPoint& hit );

	//curPos为窗口坐标，center，rx， ry为窗口坐标
	BOOL IsEllipseSelected_(GPoint   center, int  rx, int ry, GPoint  curPos );

	
	void     SetDefaults();

protected:
	
	
typedef struct _obj_graphic_descriptor{
	GPoint  p1,p2,p3,p4; 
	RvPoint rotcent;
	double  angle;
}GdObj;

	int   m_uid;
	int   m_objType;
	int   m_nStyle;  //风格与外观操作或外观有关，存储
	int   m_nState;  //控件状态，如锁定,选择等， 不存储
	int   m_nTransparence;  //透明度 [0..100]
    int   m_nLayer;   //所在层

	CUtString m_strName;
	 
	//CDelegate*       m_pDelegate;
 
	//CDelegate::SELECT_STATE m_selState;

	//UC对象本身包含的区域
	GRect    m_ctrlRect;	
	
	//UC对象的父窗区域， 坐标为VIEW坐标，目前没有用，保留
	//GRect    m_boundRect;

	double   m_nRotationAngle; // in degree [0 .. 360]
	
	int        m_nExtenderCount;
	int        m_nDrawFlags; //需要重绘部分的标记
	RV_HANDLE  m_hStroke;


	//apperance
	LINE_TYPE m_nLineType;
	int       m_nLineWidth;
	GRgb      m_textColor;
	GRgb      m_bodyColor;  
	GRgb      m_borderColor;  

	//font 
	GFont*    m_pFont;
	CUtString m_strFontName;
	int       m_nFontSize;
	int       m_nFontFlags;

};


class UCB_API CCaliber: public CUCObj
{
public:
	  
	CCaliber();
	virtual ~CCaliber();
	 
	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
	virtual CUCObj* Clone( CUCObj* twin) ;
	virtual void Reset() ;
	 
	void  SetCaption(const TCHAR* strCaption);
	const TCHAR* GetCaption();
		
	//先移动，然后绕中心点旋转
	//位移，中心点，角度
	//子类至少重载EndAlign();,才能实现整个对齐效果
	virtual void BeginAlign();
	virtual void Offset(double dx, double dy, int dir = RV_DIR_BOTH)  ;
	//目前unbias仅最后一次调用有效
	virtual void Unbias(double cx, double cy, double angle) ;

	
	virtual void EndAlign(BOOL bUpdate);
	 
	virtual void Show(CDelegate* pDelegate, int mode, BOOL bRedraw);
	 
	virtual void Shot(int mode , const RvImage image   ) =0 ;
	virtual void ShotEx( int mode, const RvImage image , int left, int top) = 0 ;

	// 检测以后，获得读数结果。
	// 检测可以没有读数结果
	virtual RV_BOOL Inspect(int* pErrCode=NULL) { return RV_FALSE;};
	
	//检测前ShotEx， 然后调用Inspect, 建议使用该函数输出reading
	RV_BOOL InspectEx(const RvImage image, int left, int top, int* pErrCode=NULL) ;

	//virtual RvReadingBank GetResult() {return NULL;};  

	//支持读数函数
	virtual RvReadingBank GetReading() { return m_rb; };  

	//同步检测结果，两个相同的caliber，一个检测，一个显示检测结果时用。
	//与Clone不同的是，该函数仅支持拷贝检测结果相关数据，而且是本类数据
	//不涉及父类。主要目的是同步检测结果的显示。
	//该函数在多线程下，需要UI锁锁住后操作,否则，可能会引起异常。
	//子类重写可以如下:
	//   if (pMutex) EnterCriticalSection(pMutex);
	//   do something to synchronize
	//   ...   
	//   if (pMutex) LeaveCriticalSection(pMutex);
	virtual void SynchResult(CUCObj* twin, CRITICAL_SECTION* pMutex =NULL){};

public:

	void Transform(RvPoint_f* pVtx , int count);
	void Transform(RvPoint* pVtx , int count);
	void Transform(RvPoint_f64* pVtx , int count);
	RvPoint Transform( RvPoint_f64 pos );
	RvPoint Transform(  RvPoint_f  pos );
	RvPoint Transform( RvPoint pos );
	void Transform(  RvPoint_f   ptIn, RvPoint_f& ptOut );
 	void Transform(  RvPoint_f64 ptIn, RvPoint_f& ptOut );

	//纠偏参数
	RvPoint_f64 GetUnbiasOffset();
	RvPoint_f64 GetUnbiasCenter();
	double      GetUnbiasAngle();

	void CutImage(const RvImage imSrc, int x, int y, int w, int h, RvImage imDest);
	RV_HANDLE DrawMask(HGDC dc, const RvMask mask, int dx, int dy, RV_HANDLE hStroke);

	 
public:
	virtual int   HitTest(CDelegate* pDelegate,    GPoint point) ;
	virtual void  OnEndTrack(CDelegate* pDelegate,  HGPD hCur,  GPoint point, int nHitTest) ;
 
public: 
	//标题显示位置,默认情况下，将随着m_ctrlRect变动。
 	//在绘制函数里面改变这个变量，将影响caption
 	//的显示位置。
 	RvPoint   m_captionAnchor;
    CUtString m_strCaption;	  

protected:
	 
	//计算包围多段线的矩形
	GRect GetPolygonRect(GPoint* pVertexes , int vertexCount);
	RV_HANDLE DrawCaption(HGDC dc ,  RV_HANDLE hStroke);
	RV_HANDLE DrawText(HGDC dc , int x, int y, const TCHAR* strText,  RV_HANDLE hStroke);

	GRect     GetCaptionAnchorRect(CDelegate* pDelegate ) ;
protected:

	//global align related
	double m_nOffsetX, m_nOffsetY, m_nUnbiasX, m_nUnbiasY, m_nUnbiasAngle;
	int    m_nAlignFlags;

	RvReadingBank m_rb;   
// 
//private:
//
//	CRITICAL_SECTION* m_pLock;
//	//GRgb m_textColor;
 
	
};




class UCB_API CIndicater: public CUCObj
{
public:
	

	 CIndicater();
	 virtual ~CIndicater();

	 virtual BOOL Serialize(HANDLE device, BOOL bIn )  ;
     virtual CUCObj* Clone( CUCObj *twin) ;

	 void        SetURLText(const TCHAR* strURL);
	 const TCHAR* GetURLText(){ return m_strURL; }

	 
	virtual void OnMouseEnter();
    virtual void OnMouseLeave();
    virtual void OnMouseClick();
	 
	virtual void EnableAnimation(BOOL flag, CDelegate* pDelegate =NULL){ 
		if (flag) m_nStyle |= RV_UCS_ANIMATION;
		else m_nStyle &= ~RV_UCS_ANIMATION;
	};
	  
	//动态控件如滚动条，动画，时间显示的内容切换
	virtual void Beat(CDelegate* pDelegate = NULL){ 
		if (RV_IS_STYLE_ON(m_nStyle,RV_UCS_ANIMATION)){ 
			/*TO DO: SOMETHING*/; 
		} 
	};
	BOOL IsAnimationEnabled(){ return ((m_nStyle & RV_UCS_ANIMATION) ==  RV_UCS_ANIMATION) ; };
	  
	void OpenURL();

public:
	void*  m_pUserData;  //用户数据，临时，不存储
	 
	 
protected:
	virtual BOOL SetCursor( HWND hWnd, int mode, UINT nHitTest );


	CUtString m_strURL;


};



// Minimum scroll bar thumb size
#define SCROLLBAR_MINTHUMBSIZE 8

// Delay and repeat period when clicking on the scroll bar arrows
#define SCROLLBAR_ARROWCLICK_DELAY  0.33
#define SCROLLBAR_ARROWCLICK_REPEAT 0.05
 


// DX_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes,
// including the NULL terminator.
// 
// Uniscribe does not support strings having bigger-than-16-bits length.
// This means that the string must be less than 65536 characters long,
// including the NULL terminator.
#define DX_MAX_EDITBOXLENGTH 0xFFFF



//--------------------------------------------------------------------------------------
// Enums for pre-defined control types
//--------------------------------------------------------------------------------------
enum RV_REACTER_TYPE 
{ 
    RV_UC_PUSHBUTTON = (UC_RACT_BASE +1),  
    RV_ID_CHECKBOX,
    RV_UC_RADIOBOX,
    RV_UC_COMBOBOX,
    RV_UC_SLIDER,
    RV_UC_EDITBOX,
    RV_UC_LISTBOX,
    RV_UC_SCROLLBAR,
    RV_UC_PROGRESSBAR,
	RV_UC_PICBOX,
	RV_UC_TABLE,
};

//enum RV_REACTER_STATE
//{
//   RV_RS_NORMAL = 0,
//   RV_RS_FOCUSED =   (1<<1),
//   RV_RS_MOUSEOVER = (1<<2),
//   RV_RS_PRESSED   = (1<<3),
//};

#define MAX_CONTROL_STATES  4

class UCB_API CReacter: public CUCObj
{
public:
	 CReacter();
	 virtual  ~CReacter();

	 virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
	 virtual CUCObj* Clone( CUCObj* twin) ;

	 void SetBorder(BOOL flag) { 
		RV_RETURN_UNCHANGED_STYLE(m_nStyle, RV_UCS_BORDER, flag);
		RV_SWITCH_STYLE(m_nStyle,RV_UCS_BORDER, flag); 

		RV_UC_NOTIFY_REDRAW(RV_UCS_BORDER);
	};

	BOOL IsBorderVisible() { return ((m_nStyle & RV_UCS_BORDER) == RV_UCS_BORDER);};
	BOOL IsFocused() { return ((m_nState & RV_CS_FOCUSED) == RV_CS_FOCUSED); };

	void SetHotkey( UINT nHotkey ) { m_nHotkey = nHotkey; }
    UINT GetHotkey() { return m_nHotkey; }

	void SetUserData( void* pUserData ) { m_pUserData = pUserData; }
    void* GetUserData() const { return m_pUserData; }

	//int  GetCurState(){ return m_nCurState; }

//内部使用
public:
	  
	virtual void OnMouseEnter(){};
	virtual void OnMouseLeave(){};

	virtual void OnSetFocus(){};
	virtual void OnKillFocus(){};
	  
	virtual void OnLButtonDown( WPARAM wParam, LPARAM lParam){};
	virtual void OnLButtonUp( WPARAM wParam, LPARAM lParam){};
 
    virtual void OnKeyDown(WPARAM wParam, LPARAM lParam) {};
    virtual void OnKeyUp(WPARAM wParam, LPARAM lParam) {};
 
protected:
	 
	RV_HANDLE DrawBorder(HGDC dc,  RvRect rect, RV_HANDLE hStroke);
  
    UINT  m_nHotkey;          // Virtual key code for this control's hotkey
    void *m_pUserData;       // Data associated with this control that is set by user.
 

};

 

UCB_API BOOL rubAuthorize(const TCHAR* strFilePath, const TCHAR* strAppName , const TCHAR* strLicence );
UCB_API BOOL rubIsAuthorized();







#endif