www.gusucode.com > 微软FreeCL开源免费的C++编译器源码源码程序 > 微软FreeCL开源免费的C++编译器源码/FreeCL_Skin.v2.03.Full.Source.ccrun.718306/FreeCL_Skin.v2.03.Full.Source.ccrun.718306/EngineSource/FreeCL/WinEdit.cpp

    #include "WinEdit.h"

namespace FreeCL
{

EditDesc::EditDesc(void)
{
	mEdgeStyle = EdgeStyle_Default;
	mBorderColor = ::GetSysColor(COLOR_3DSHADOW);
	mMultiLine = false;
	mAutoHorzScroll = true;
	mAutoVertScroll = true;
	mShowHorzScroll = true;
	mShowVertScroll = true;
	mLeftScrollBar = false;
	mSkinScrollBar = false;
	InitBool(mTextLeft, mTextRight, mTextCenter);
	mTextLeft = true;
	InitBool(mConvertLowercase, mConvertUppercase);
	mOemConvert = false;
	mHideSelect = true;
	mNumber = false;
	mPassword = false;
	mReadOnly = false;
	mWantReturn = false;
}

void EditDesc::InitEditDesc(long wType, long exStyle)
{  
	if((exStyle & WS_EX_CLIENTEDGE) == WS_EX_CLIENTEDGE)
		mEdgeStyle = EdgeStyle_Client;
	else if((exStyle & WS_EX_STATICEDGE) == WS_EX_STATICEDGE)
		mEdgeStyle = EdgeStyle_Frame;
	else
		mEdgeStyle = EdgeStyle_None;	
	mAutoHorzScroll = bool((wType & ES_AUTOHSCROLL) == ES_AUTOHSCROLL);
	mMultiLine = bool((wType & ES_MULTILINE) == ES_MULTILINE);
	if(mMultiLine)
	{
		mAutoVertScroll = bool((wType & ES_AUTOVSCROLL) == ES_AUTOVSCROLL);
		mShowHorzScroll = bool((wType & WS_HSCROLL) == WS_HSCROLL);
		mShowVertScroll = bool((wType & WS_VSCROLL) == WS_VSCROLL);
	}
	else
	{
		mAutoVertScroll = false;
		mShowHorzScroll = false;
		mShowVertScroll = false;
	}
	mLeftScrollBar = bool((exStyle & WS_EX_LEFTSCROLLBAR) == WS_EX_LEFTSCROLLBAR);
	mSkinScrollBar = false;
	mTextLeft = bool((wType & ES_LEFT) == ES_LEFT);
	mTextCenter = bool((wType & ES_CENTER) == ES_CENTER);
	mTextRight = bool((wType & ES_RIGHT) == ES_RIGHT);
	mConvertLowercase = bool((wType & ES_LOWERCASE) == ES_LOWERCASE);
	mConvertUppercase = bool((wType & ES_UPPERCASE) == ES_UPPERCASE);
	mOemConvert = bool((wType & ES_OEMCONVERT) == ES_OEMCONVERT);
	mHideSelect = bool((wType & ES_NOHIDESEL) == 0);
	mNumber = bool((wType & ES_NUMBER) == ES_NUMBER);
	if(!mMultiLine)
		mPassword = bool((wType & ES_PASSWORD) == ES_PASSWORD);
	else
		mPassword = false;
	mReadOnly = bool((wType & ES_READONLY) == ES_READONLY);
	mWantReturn = bool((wType & ES_WANTRETURN) == ES_WANTRETURN);
}

//-----------------------------------------------------------------------------------------------------------------------

WinEdit::WinEdit(void) : mEventBegin(this), mPropertyBegin(this)
{
	m_SkinColor = ::GetSysColor(COLOR_WINDOW);
	m_TextColor = ::GetSysColor(COLOR_WINDOWTEXT);
	m_Attach = FALSE;
	m_NcPaint = TRUE;
	m_HScroll = FALSE;
	m_VScroll = FALSE;
	m_DrawBrush = NULL;
	m_DrawBitmap = NULL;
}

WinEdit::~WinEdit(void)
{
}

FreeCL_Optimize
bool WinEdit::CreateEdit(WinContainer* parent,int left,int top,int width,int height,EditDesc& desc)
{
	if(parent)
	{		
		if(desc.mEdgeStyle != EdgeStyle_Default && desc.mEdgeStyle != EdgeStyle_Client && desc.mEdgeStyle != EdgeStyle_Frame && 
			desc.mEdgeStyle != EdgeStyle_None && desc.mEdgeStyle != EdgeStyle_Color)
		{	
#ifdef _DEBUG
			::DebugBreak(); //非法的边缘风格  
#endif
			return false;
		}

		if(byte(desc.mTextLeft)+byte(desc.mTextRight)+byte(desc.mTextCenter) == 0)
		{	 
#ifdef _DEBUG
			::DebugBreak();//3个值必须有一个为true!!!
#endif
			return false;
		}	 

		DWORD exStyle = 0;	 
		DWORD wType = WS_TABSTOP | WS_CHILD | WS_CLIPSIBLINGS;
		if(desc.mLeftScrollBar)
			exStyle |= WS_EX_LEFTSCROLLBAR;
		if(desc.mEdgeStyle == EdgeStyle_Client || desc.mEdgeStyle == EdgeStyle_Default)
			exStyle |= WS_EX_CLIENTEDGE;
		else if(desc.mEdgeStyle == EdgeStyle_Frame)
			exStyle |= WS_EX_STATICEDGE;
		else if(desc.mEdgeStyle == EdgeStyle_Color)
			exStyle |= WS_EX_STATICEDGE;
		if(desc.mAutoHorzScroll)
			wType |= ES_AUTOHSCROLL;			 
		if(desc.mMultiLine)
			wType |= ES_MULTILINE;
		if(desc.mMultiLine)
		{
			if(desc.mAutoVertScroll)
				wType |= ES_AUTOVSCROLL;
			if(desc.mShowHorzScroll)
				wType |= WS_HSCROLL; 
			if(desc.mShowVertScroll)
				wType |= WS_VSCROLL;
		}
		if(desc.mTextLeft)
			wType |= ES_LEFT;
		if(desc.mTextRight)
			wType |= ES_RIGHT;
		if(desc.mTextCenter)
			wType |= ES_CENTER;
		if(desc.mConvertLowercase)
			wType |= ES_LOWERCASE;
		if(desc.mConvertUppercase)
			wType |= ES_UPPERCASE;
		if(desc.mOemConvert)
			wType |= ES_OEMCONVERT;
		if(!desc.mHideSelect)
			wType |= ES_NOHIDESEL;
		if(desc.mNumber)
			wType |= ES_NUMBER;
		if(!desc.mMultiLine)
		{
			if(desc.mPassword)
				wType |= ES_PASSWORD;
		}
		if(desc.mReadOnly)
			wType |= ES_READONLY;
		if(desc.mWantReturn)
			wType |= ES_WANTRETURN;
		m_Handle = ::CreateWindowEx(exStyle, "Edit", "", wType, left, top, width, height,
			parent->GetHandle(), NULL, gModule, 0);
		if(m_Handle)
		{		
			m_Desc = desc;	  
			m_Parent = parent;

			if(m_Desc.mEdgeStyle != EdgeStyle_Default)
			{	//关闭桌面主题
				if(FreeCL::GetBaseThemeEnabled())
					FreeCL::SetWindowTheme(m_Handle, L"", L"");
			}
			else if(!FreeCL::GetBaseThemeEnabled())
				m_Desc.mEdgeStyle = EdgeStyle_Client;

			m_Left = left;
			m_Top = top;
			m_Width = width;
			m_Height = height;
			::SendMessage(m_Handle, WM_SETFONT, (WPARAM)parent->GetFont(), FALSE);
			::SetWindowLong(m_Handle, GWL_ID, (LONG)m_Id);

			SetSkin(false, SkinMode_Color, m_SkinColor, "");

			parent->AddWinControl(this);
			InitScrollControl(m_Handle, m_Desc.mSkinScrollBar);
			OnControlCreate();
			::ShowWindow(m_Handle,SW_SHOW);
			return true;
		}  		
#ifdef _DEBUG
		else//窗口创建失败(可能传入了非法的参数)
			::DebugBreak();
#endif
	}
	return false;
}

bool WinEdit::Attach(HWND edit)
{
	if(edit)
	{ 
		m_Handle = edit;
		LONG wType = ::GetWindowLong(m_Handle, GWL_STYLE);	
		LONG exStyle = ::GetWindowLong(m_Handle, GWL_EXSTYLE);	
		m_Desc.InitEditDesc(wType, exStyle);
		if(m_Desc.mEdgeStyle == EdgeStyle_Client)
		{
			if(FreeCL::GetBaseThemeEnabled())
			{
				HTHEME theme = FreeCL::OpenThemeData(m_Handle, L"Edit");
				if(theme)
				{
					m_Desc.mEdgeStyle = EdgeStyle_Default;
					FreeCL::CloseThemeData(theme);
				}
			}
		}
		RECT wRect;
		::GetWindowRect(m_Handle, &wRect);
		m_Width = wRect.right - wRect.left;
		m_Height = wRect.bottom - wRect.top;
		HWND pWnd = ::GetParent(m_Handle);
		::ScreenToClient(pWnd, (POINT*)&wRect);
		m_Left = wRect.left;
		m_Top = wRect.top;
		::SetWindowLong(m_Handle, GWL_ID, (LONG)m_Id);
		//Use edit's old font
		SetSkin(false, SkinMode_Color, m_SkinColor, "");
		WinContainer* parent = (WinContainer*)(WinControl::GetControlPointer(pWnd));
		DebugAssert(parent->IsContainer());
		m_Parent = parent;
		parent->AddWinControl(this);  
		InitScrollControl(m_Handle, BOOL(m_Desc.mSkinScrollBar));
		OnControlCreate();

		m_Attach = TRUE;
		return true;
	}
	return false;
}

bool WinEdit::CreateControl(WinContainer* parent,int left,int top,int width,int height)
{
	EditDesc desc;
	return CreateEdit(parent,left,top,width,height,desc);
}

void WinEdit::DestroyControl()
{
	Parent::DestroyControl();
	m_Desc = EditDesc();
	m_SkinColor = ::GetSysColor(COLOR_WINDOW);
	m_TextColor = ::GetSysColor(COLOR_WINDOWTEXT);
	m_NcPaint = TRUE;
	m_HScroll = FALSE;
	m_VScroll = FALSE;		
	DestroyDrawData();
}

cstr WinEdit::GetClass()
{
	return "WinEdit";
}

bool WinEdit::IsEdit() 
{
	return true;
}

sint WinEdit::GetLineFromChar(sint index)
{
	if(m_Handle && 0 <= index && index < GetCharCount())
		return ::SendMessage(m_Handle, EM_LINEFROMCHAR, (WPARAM)index, 0);
	return -1;
}

sint WinEdit::GetCurrentLine()
{	
	if(m_Handle)
		return ::SendMessage(m_Handle, EM_LINEFROMCHAR, (WPARAM)(-1), 0);
	return -1;
}

sint WinEdit::GetFirstCharFromLine(sint index)
{
	if(m_Handle && 0 <= index)
		return ::SendMessage(m_Handle, EM_LINEINDEX, (WPARAM)index, 0);
	return -1;
}

sint WinEdit::GetLineLengthFromChar(sint index)
{
	if(m_Handle)
	{
		if(0 <= index)
			return ::SendMessage(m_Handle, EM_LINELENGTH, index, 0);
		else
			return 0;
	}
	return -1;
}

sint WinEdit::CopyLine(sint line, char* buffer, ushort bufferSize)
{
	if(m_Handle && 0 <= line && buffer)
	{
		if(m_Desc.mMultiLine)
		{
			if(line < GetLineCount())
			{
				*(ushort*)buffer = bufferSize;
				return ::SendMessage(m_Handle, EM_GETLINE, (WPARAM)line, (LPARAM)buffer);
			}
		}
		else if(line == 0)
		{				 
			*(ushort*)buffer = bufferSize;
			return ::SendMessage(m_Handle, EM_GETLINE, 0, (LPARAM)buffer);
		}
	}
	return 0;
}

void WinEdit::SelectText(sint start,sint end) 
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, EM_SETSEL, start, end);
		UpdateScrollBar();
	}
}

void WinEdit::GetSelectRange(sint* start, sint* end)
{
	if(m_Handle && (start || end))
		::SendMessage(m_Handle, EM_GETSEL, WPARAM(start), LPARAM(end));
}

void WinEdit::SelectAllText()
{
	SelectText(0,-1);
}

void WinEdit::CancelSelect()
{
	SelectText(-1,0);
}

sint WinEdit::GetVertThumb() 
{
	if(m_Handle && m_Desc.mMultiLine && m_Desc.mShowVertScroll)
		return ::SendMessage(m_Handle, EM_GETTHUMB, 0, 0);
	return -1;
}   

void WinEdit::ScrollCaret()
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, EM_SCROLLCARET, 0, 0);
		UpdateScrollBar();
	}
}

void WinEdit::ScrollText(sint horz,sint vert)
{
	if(m_Handle && m_Desc.mMultiLine)
	{
		::SendMessage(m_Handle, EM_LINESCROLL, (WPARAM)horz, (LPARAM)vert);
		UpdateScrollBar();
	}
}

void WinEdit::VertScroll(EditScrollType param)
{
	if(m_Handle && m_Desc.mMultiLine)
	{
		::SendMessage(m_Handle, EM_SCROLL, (WPARAM)param, 0);
		//UpdateScrollBar(); //It is same with WM_VSCROLL
	}
}

bool WinEdit::ReplaceText(cstr string,bool undo)
{
	if(m_Handle)
	{	  
		DWORD start = 0, end = 0;
		::SendMessage(m_Handle, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
		if(start < end)//当前必须存在选择的文本才能执行替换操作
		{
			::SendMessage(m_Handle, EM_REPLACESEL, BOOL(undo), (LPARAM)string);
			UpdateScrollBar();
			return true;
		}
	}
	return false;
}

bool WinEdit::DeleteSelect(bool undo)
{ 
	return ReplaceText("", undo);
}

bool WinEdit::InsertText(cstr string, bool undo)
{	
	if(m_Handle)
	{	  
		DWORD start = 0, end = 0;
		::SendMessage(m_Handle, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
		if(start == end)//必须不存在选择文本方能执行文本插入操作
		{
			::SendMessage(m_Handle, EM_REPLACESEL, BOOL(undo), (LPARAM)string);
			UpdateScrollBar();
			return true;
		}
	}
	return false;
}

void WinEdit::SetTabSpace(uint space, bool redraw)
{
	if(m_Handle && m_Desc.mMultiLine)
	{
		BOOL error = ::SendMessage(m_Handle, EM_SETTABSTOPS, 1, (LPARAM)&space);
		if(error && redraw && IsVisible())
			RedrawControl(false);
	}
}

void WinEdit::SetLimitText(sint limit) 
{
	if(m_Handle)
		::SendMessage(m_Handle, EM_LIMITTEXT, limit, 0);
}

sint WinEdit::GetLimitText()
{
	if(m_Handle) 
		return ::SendMessage(m_Handle, EM_GETLIMITTEXT, 0, 0);
	return -1;
}

void WinEdit::SetLeftMargin(sint margin)
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, EM_SETMARGINS, EC_LEFTMARGIN, (LPARAM)(ushort)(short)margin);
		UpdateScrollBar();
	}
}

sint WinEdit::GetLeftMargin()
{
	if(m_Handle)
		return (int)(short)(ushort)(0x0000FFFF & (DWORD)::SendMessage(m_Handle, EM_GETMARGINS, 0, 0));
	return -1;
}

void WinEdit::SetRightMargin(sint m) 
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, EM_SETMARGINS, EC_RIGHTMARGIN, LPARAM(DWORD(ushort(short(m)))<<16));
		UpdateScrollBar();
	}
}

sint WinEdit::GetRightMargin()
{
	if(m_Handle)
		return (int)(short)(ushort)(DWORD(::SendMessage(m_Handle, EM_GETMARGINS, 0, 0)) >> 16);
	return -1;
}

void WinEdit::SetCaption(cstr text)
{
	if(m_Handle)
	{
		::SetWindowText(m_Handle, text);
		//把光标位置移动到末尾
		int count = GetCharCount();
		SelectText(count, count);
		UpdateScrollBar();
	}
}

cstr WinEdit::GetCaption()
{
	if(m_Handle)
	{
		int len = ::GetWindowTextLength(m_Handle);
		if(len > 0)
		{
			if(int(m_Caption.size()) < len+1)
				m_Caption.resize(len+1);
			::GetWindowText(m_Handle, &m_Caption[0], int(m_Caption.size()));
			return m_Caption.c_str();
		}
		return "";
	}
	return NULL;
} 

bool WinEdit::CanUndo() 
{
	if(m_Handle)
		return bool(::SendMessage(m_Handle, EM_CANUNDO, 0, 0) != 0);
	return false;
}

bool WinEdit::Undo()
{
	if(m_Handle)
	{
		bool bCode = bool(::SendMessage(m_Handle, EM_UNDO, 0, 0) != 0);
		if(bCode)
			UpdateScrollBar();
		return bCode;
	}
	return false;
}

void WinEdit::ResetUndoBuffer() 
{
	if(m_Handle)
		::SendMessage(m_Handle, EM_EMPTYUNDOBUFFER, 0, 0);
}

void WinEdit::Copy()
{
	if(m_Handle)
		::SendMessage(m_Handle, WM_COPY, 0, 0);
}

void WinEdit::Cut()
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, WM_CUT, 0, 0);
		UpdateScrollBar();
	}
}

void WinEdit::Clear()
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, WM_CLEAR, 0, 0);
		UpdateScrollBar();
	}
}

void WinEdit::Paste()
{
	if(m_Handle)
	{
		::SendMessage(m_Handle, WM_PASTE, 0, 0);
		UpdateScrollBar();
	}
}

sint WinEdit::GetCharFromPoint(const Point& p, sint* line)
{
	if(m_Handle)
	{
		DWORD coord = ((DWORD)(ushort)(short)p.x) | (((DWORD)(ushort)(short)p.y) << 16);
		DWORD cl = ::SendMessage(m_Handle, EM_CHARFROMPOS, 0, (LPARAM)coord);
		if(line)
			*line = int(short(HIWORD(cl)));
		return int(short(LOWORD(cl)));
	}
	return -1;
}

Point WinEdit::GetPointFromChar(sint index)
{
	Point p(LONG_MIN, LONG_MIN);
	if(m_Handle && index >= 0)
	{
		LRESULT error = ::SendMessage(m_Handle, EM_POSFROMCHAR, (WPARAM)index, 0);
		if(error != -1)
		{
			DWORD coord = (DWORD)error;
			p.x = (long)(short)(ushort)LOWORD(coord);
			p.y = (long)(short)(ushort)HIWORD(coord);
		}
	}
	return p;
}

void WinEdit::SetText(cstr text) 
{
	SetCaption(text);
}

cstr WinEdit::GetText() 
{
	return GetCaption();
}

void WinEdit::SetTextColor(uint color)
{
	if(m_Handle && color != m_TextColor)
	{
		m_TextColor = color;
		if(IsVisible())
			RedrawControl(false);
	}
}

uint WinEdit::GetTextColor()
{
	return m_TextColor;
}

sint WinEdit::GetCharCount()
{
	if(m_Handle)
		return ::SendMessage(m_Handle, WM_GETTEXTLENGTH, 0, 0);
	return -1;
}

sint WinEdit::GetLineCount()
{
	if(m_Handle)
	{
		if(m_Desc.mMultiLine)
			return ::SendMessage(m_Handle, EM_GETLINECOUNT, 0, 0);
		else
			return 1;
	}
	return -1;
}

sint WinEdit::GetTopLine()
{
	if(m_Handle)
	{
		if(m_Desc.mMultiLine)
			return ::SendMessage(m_Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
		else
			return 0;
	}
	return -1;
} 

void WinEdit::SetModifyFlag(bool f) 
{
	if(m_Handle)
		::SendMessage(m_Handle, EM_SETMODIFY, BOOL(f), 0);
}

bool WinEdit::GetModifyFlag()
{
	if(m_Handle)
		return bool(::SendMessage(m_Handle, EM_GETMODIFY, 0, 0) != 0);
	return false;
}

void WinEdit::SetPassword(char c)
{
	if(m_Handle && !m_Desc.mMultiLine && m_Desc.mPassword)
		::SendMessage(m_Handle, EM_SETPASSWORDCHAR, WPARAM(c), 0);
}			

char WinEdit::GetPassword() 
{
	if(m_Handle && !m_Desc.mMultiLine && m_Desc.mPassword)
		return(char)::SendMessage(m_Handle, EM_GETPASSWORDCHAR, 0, 0);
	return 0;
}

void WinEdit::SetSelectStart(sint start)
{
	SelectText(start, start);
}

sint WinEdit::GetSelectStart() 
{
	int start = -1;
	GetSelectRange(&start, NULL);
	return start;
} 

void WinEdit::SetSelectEnd(sint end)
{
	if(m_Handle)
		SelectText(GetSelectStart(), end);
}

sint WinEdit::GetSelectEnd() 
{
	int end = -1;
	GetSelectRange(NULL, &end);
	return end;
}

void WinEdit::SetFormatRect(Rect rect)
{
	if(m_Handle && m_Desc.mMultiLine)
	{
		if(rect != Rect())
			::SendMessage(m_Handle, EM_SETRECT, 0, (LPARAM)&rect);
		else
			::SendMessage(m_Handle, EM_SETRECT, 0, 0);   
		UpdateScrollBar();
	}
}  

Rect WinEdit::GetFormatRect() 
{
	Rect rect;
	if(m_Handle && m_Desc.mMultiLine)
		::SendMessage(m_Handle, EM_GETRECT, 0, (LPARAM)&rect);
	return rect;
}

void WinEdit::SetReadOnly(bool ro) 
{
	if(m_Handle)
		::SendMessage(m_Handle, EM_SETREADONLY, BOOL(ro), 0);
} 

bool WinEdit::GetReadOnly()
{
	if(m_Handle)
	{
		if((::GetWindowLong(m_Handle, GWL_STYLE) & EM_SETREADONLY) == EM_SETREADONLY)
			return true;
	}
	return false;
}

void WinEdit::SetMemHandle(HLOCAL h) 
{
	if(m_Handle && m_Desc.mMultiLine)
		::SendMessage(m_Handle, EM_SETHANDLE, WPARAM(h), 0);
}

HLOCAL WinEdit::GetMemHandle()
{
	if(m_Handle && m_Desc.mMultiLine)
		return (HLOCAL)::SendMessage(m_Handle, EM_GETHANDLE, 0, 0);
	return NULL;
}

LRESULT WinEdit::WmMove(WPARAM wParam, LPARAM lParam)
{   
	if(!m_MoveSize)
	{	//系统可能会自动调整控件位置(如Rebar控件可能更改其所捆绑的控件位置)
		RECT wRect;
		::GetWindowRect(m_Handle, &wRect);
		::ScreenToClient(GetParent()->GetHandle(), (POINT*)&wRect);
		m_Left = wRect.left;
		m_Top = wRect.top;
	}					   

	if(UseDrawData())
	{			 
		DestroyDrawData();
		RedrawControl(true);
	}
	else if(m_ParentSkin)
	{
		SkinMode pMode = GetSkinMode();
		if(pMode == SkinMode_BitmapResource || pMode == SkinMode_BitmapFile)
			RedrawControl(true);
	}
	return TRUE;
}

LRESULT WinEdit::WmSize(WPARAM wParam, LPARAM lParam)
{	
	if(!m_MoveSize)
	{	//系统可能会自动调整控件尺寸
		RECT wRect;
		::GetWindowRect(m_Handle, &wRect);
		m_Width = wRect.right - wRect.left;
		m_Height = wRect.bottom - wRect.top;
	}  					   
		   
	if(UseDrawData())
	{			  
		DestroyDrawData(); 
		RedrawControl(true);
	}
	return TRUE;
}

LRESULT WinEdit::WmChar(WPARAM wParam, LPARAM lParam)
{	  
	if(mOnChar != NULL)
	{			
		CallDefaultProc(WM_CHAR, wParam, lParam);

		if(!mOnChar.mThis)
			(GetParent()->*mOnChar)(this, char(wParam));
		else
			mOnChar(this, char(wParam)); 
		return 0;
	}
	return TRUE;
}

LRESULT WinEdit::WmLButtonUp(WPARAM wParam, LPARAM lParam)
{
	if(!IsMinXP())//这几行代码对XP或更新的系统似乎多余,老系统可能需要。若有问题,用户可注释if语句
	{	
		if(UseBitmapSkin())
			RedrawControl(false);
	}
	return TRUE;
}

LRESULT WinEdit::WmHScroll(WPARAM wParam, LPARAM lParam)
{	
	if(UseBitmapSkin() && !m_HScroll && !m_VScroll)
	{	//某些老版本的系统可能会因键盘按下事件而引发滚动条事件
		WORD code = LOWORD(wParam);
		if(code != SB_ENDSCROLL && code != SB_THUMBPOSITION)
		{		   
			if(code == SB_THUMBTRACK)
			{	//拖拽抓取器时,系统并不触发画布滚动事件
				if(int(SHORT(HIWORD(wParam))) == GetHorzThumbPosition())
					return TRUE;
			}
			else
			{	//单击滚动条的箭头按钮或单击其空白区域会有画布的滚动事件
				if(code == SB_LINELEFT || code == SB_PAGELEFT || code == SB_LEFT)
				{
					if(GetHorzThumbPosition() == GetHorzScrollMin())
						return TRUE;
				}
				else if(code == SB_LINERIGHT || code == SB_PAGERIGHT || code == SB_RIGHT)
				{
					if(GetHorzThumbPosition() == GetHorzScrollMax())
						return TRUE;
				}
			}
			//第一步:Edit对滚动消息的处理会滚动客户区,导致皮肤位图也发生平移,因此我们主动这个滚动操作
			::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); 
			CallDefaultProc(WM_HSCROLL, wParam, lParam);
			::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0);
			//第二步:主动刷新背景,但这个操作会导致滚动条刷新异常,因此在滚动条刷新的WM_NCPAINT处理直接绕过去
			m_NcPaint = FALSE;
			::InvalidateRect(m_Handle, NULL, TRUE);
			::UpdateWindow(m_Handle); // This call can triger WM_NCPAINT & WM_PAINT
			m_NcPaint = TRUE;
			SetHorzThumbPosition(GetHorzThumbPosition(), true);

			if(code == SB_THUMBTRACK && mOnHorzScroll != NULL)
			{
				if(!mOnHorzScroll.mThis)
					(GetParent()->*mOnHorzScroll)(this);
				else
					mOnHorzScroll(this);
			}
			return 0;
		}   
	}
	return TRUE;
}

LRESULT WinEdit::WmVScroll(WPARAM wParam, LPARAM lParam)
{	//Only multi-line edit	
	if(UseBitmapSkin() && !m_HScroll && !m_VScroll)
	{
		WORD code = LOWORD(wParam);
		if(code != SB_ENDSCROLL && code != SB_THUMBPOSITION)
		{			
			if(code == SB_THUMBTRACK)
			{	
				if(int(SHORT(HIWORD(wParam))) == GetVertThumbPosition())
					return TRUE;
			}
			else
			{	
				if(code == SB_LINEUP || code == SB_PAGEUP || code == SB_TOP)
				{
					if(GetVertThumbPosition() == GetVertScrollMin())
						return TRUE;
				}
				else if(code == SB_LINEDOWN || code == SB_PAGEDOWN || code == SB_BOTTOM)
				{
					if(GetVertThumbPosition() == GetVertScrollMax())
						return TRUE;
				}
			}

			::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); 
			CallDefaultProc(WM_VSCROLL, wParam, lParam);
			::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0);
			m_NcPaint = FALSE;
			::InvalidateRect(m_Handle, NULL, TRUE);
			::UpdateWindow(m_Handle); 			
			m_NcPaint = TRUE;
			SetVertThumbPosition(GetVertThumbPosition(), true);

			if(code == SB_THUMBTRACK && mOnVertScroll != NULL)
			{
				if(!mOnVertScroll.mThis)
					(GetParent()->*mOnVertScroll)(this);
				else
					mOnVertScroll(this); 
			}

			return 0;
		}  
	}
	return TRUE;
}

LRESULT WinEdit::WmKeyDown(WPARAM wParam, LPARAM lParam)
{		
	if(UseBitmapSkin())
	{
		if((wParam == VK_LEFT || wParam == VK_RIGHT || wParam == VK_HOME || wParam == VK_END) || 
		   (m_Desc.mMultiLine && (wParam == VK_UP || wParam == VK_DOWN || wParam == VK_NEXT || wParam == VK_PRIOR)))
		{	
			m_HScroll = TRUE;	//
			m_VScroll = TRUE;	//这两个标志监视画布的滚动
			CallDefaultProc(WM_KEYDOWN, wParam, lParam);
			if(!m_HScroll || !m_VScroll)
			{
				::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0);
				::InvalidateRect(m_Handle, NULL, TRUE);
				::UpdateWindow(m_Handle);
			}
			m_HScroll = FALSE;
			m_VScroll = FALSE;
			return 0;			
		}
	}
	return TRUE;
}

LRESULT WinEdit::WmMouseWheel(WPARAM wParam, LPARAM lParam)
{   //鼠标滚轮事件仅对多行编辑控件有效	
	if(m_Desc.mMultiLine && UseBitmapSkin())
	{	  
		m_HScroll = TRUE;	//
		m_VScroll = TRUE;	//这两个标志监视画布的滚动	
		CallDefaultProc(WM_MOUSEWHEEL, wParam, lParam);
		if(!m_HScroll || !m_VScroll)
		{
			::SendMessage(m_Handle, WM_SETREDRAW, TRUE, 0);
			::InvalidateRect(m_Handle, NULL, TRUE);
			::UpdateWindow(m_Handle);
		}
		m_HScroll = FALSE;
		m_VScroll = FALSE;
		return 0;
	}
	return TRUE;
}

LRESULT WinEdit::WmEraseBkGnd(WPARAM wParam, LPARAM lParam)
{	
	/*返回TRUE在多行编辑控件产生渲染上的一些问题,此消息似乎不可重载*/
	return 0;
} 

LRESULT WinEdit::WmThemeChanged(WPARAM wParam, LPARAM lParam)
{
	static BOOL sReEnter = FALSE;
	if(sReEnter)
		return TRUE;

	DestroyDrawData();

	CallDefaultProc(WM_THEMECHANGED, wParam, lParam);
		
	FreeCL::InitTheme();
	::SendMessage(m_Handle, WM_SETFONT, WPARAM(m_Parent->GetFont()), (LPARAM)TRUE);
	if(!FreeCL::GetBaseThemeEnabled())
	{		
		if(m_Desc.mEdgeStyle == EdgeStyle_Default)
			m_Desc.mEdgeStyle = EdgeStyle_Client;
	}
	else if(m_Desc.mEdgeStyle != EdgeStyle_Default)
	{
		sReEnter = TRUE;
		FreeCL::SetWindowTheme(m_Handle, L"", L"");
		sReEnter = FALSE;
	}   
	
	return 0;
}

bool WinEdit::UseDrawData()
{	
	if(mOnDrawSkin != NULL || (m_ParentSkin && GetBrush() == NULL))
		return true;
	return false;
}  

bool WinEdit::UseBitmapSkin()
{   
	if(UseDrawData())
		return true;

	SkinMode cMode = GetSkinMode();
	if(cMode == SkinMode_BitmapResource || cMode == SkinMode_BitmapFile)
		return true;

	return false;
}

void WinEdit::CreateDrawData(HDC dc)
{	
	if(!m_DrawBrush)
	{
		RECT cRect;
		::GetClientRect(m_Handle, &cRect);
		HDC memDC = ::CreateCompatibleDC(dc);
		m_DrawBitmap = ::CreateCompatibleBitmap(dc, cRect.right-cRect.left, cRect.bottom-cRect.top);
		HGDIOBJ iBitmap = ::SelectObject(memDC, m_DrawBitmap);

		EditSkinData data;
		data.mDC = memDC;
		bool bCode = true;
		if(mOnDrawSkin != NULL)
		{
			if(!mOnDrawSkin.mThis)
				bCode = (GetParent()->*mOnDrawSkin)(this, data);
			else
				bCode = mOnDrawSkin(this, data);
		}
		if(bCode)
			DrawSkin(memDC, &cRect); 

		::SelectObject(memDC, iBitmap);
		::DeleteDC(memDC);
		m_DrawBrush = ::CreatePatternBrush(m_DrawBitmap);
	}
}

void WinEdit::DestroyDrawData()
{
	if(m_DrawBrush)
	{
		::DeleteObject(m_DrawBrush);
		m_DrawBrush = NULL;
	}
	if(m_DrawBitmap)
	{
		::DeleteObject(m_DrawBitmap);
		m_DrawBitmap = NULL;
	}
}

LRESULT WinEdit::WmOwnerCtlColor(WPARAM wParam, LPARAM lParam)
{					 
	HDC dc = (HDC)wParam;   
	::SetTextColor(dc, this->GetTextColor());//注意:必须返回一个有效的刷子,颜色设置才能生效
	::SetBrushOrgEx(dc, 0, 0, NULL);

	HBRUSH brush = NULL;
	if(UseDrawData())
	{				 
		::SetBkMode(dc, TRANSPARENT);
		CreateDrawData(dc);
		brush = m_DrawBrush; 
	}						 
	else
	{							 
		brush = GetBrush();
		SkinMode cMode = GetSkinMode();
		if(cMode == SkinMode_Color)
			::SetBkColor(dc, GetSkinColor());
		else if(cMode == SkinMode_BitmapResource || cMode == SkinMode_BitmapFile)
		{	//位图背景
			WINDOWINFO wInfo;
			memset(&wInfo, 0, sizeof(wInfo));
			wInfo.cbSize = sizeof(wInfo);
			::GetWindowInfo(m_Handle, &wInfo);
			POINT iPoint;
			iPoint.x = wInfo.rcClient.left;
			iPoint.y = wInfo.rcClient.top;
			::ScreenToClient(GetSkinControl()->GetHandle(), (POINT*)&iPoint); 
			::SetBrushOrgEx(dc, -iPoint.x, -iPoint.y, NULL);//刷子对齐
			::SetBkMode(dc, TRANSPARENT);				
		}
	}
	
	return (LRESULT)brush;
}				

BOOL WinEdit::DrawScrollBarSkin(HDC dc, const RECT& cRect, const POINT& rOffset)
{
	if(mOnDrawScrollSkin != NULL)
	{
		bool bCode;
		ScrollBarSkinData data;
		data.mDC = dc;
		data.mClipRect = *(Rect*)&cRect;
		if(!mOnDrawScrollSkin.mThis)
			bCode = (GetParent()->*mOnDrawScrollSkin)(this, data);
		else
			bCode = mOnDrawScrollSkin(this, data);
		if(!bCode)
			return FALSE;//返回FALSE阻止默认的灰色背景绘制
	}
	if(GetSkinEnabled())
	{
		DrawSkin(dc, &cRect, rOffset.x, rOffset.y);
		return FALSE;
	}

	return TRUE;
}

BOOL WinEdit::DrawScrollBarPart(HDC dc, const RECT& iRect, const RECT& cRect,const POINT& rOffset, 								   
							   ScrollPart part, BOOL enabled, BOOL pressed, BOOL hilited)
{
	if(mOnDrawScrollPart != NULL)
	{
		ScrollBarDrawData data;
		data.mDC = dc;
		data.mRect = *(Rect*)&iRect;
		data.mClipRect = *(Rect*)&cRect;
		data.mOffset = *(Point*)&rOffset;
		data.mElement = part;
		data.mEnabled = bool(enabled != FALSE);
		data.mPressed = bool(pressed != FALSE);
		data.mHilited = bool(hilited != FALSE);	
		bool bCode = true;
		if(!mOnDrawScrollPart.mThis)
			bCode = (GetParent()->*mOnDrawScrollPart)(this, data);
		else
			bCode = mOnDrawScrollPart(this, data);
		if(!bCode)
			return FALSE;
	}
	if(GetSkinEnabled())
	{
		BOOL frame = BOOL(m_Desc.mEdgeStyle == EdgeStyle_Frame || m_Desc.mEdgeStyle == EdgeStyle_Color || 
			m_Desc.mEdgeStyle == EdgeStyle_None || m_Desc.mEdgeStyle == EdgeStyle_Default);
		if(part == ScrollPart_Left)
		{
			DrawButtonBox(dc, iRect, frame, pressed, TRUE);
			DrawArrow(dc, iRect, TRUE, TRUE, enabled, pressed);
		}
		else if(part == ScrollPart_Right)
		{
			DrawButtonBox(dc, iRect, frame, pressed, TRUE);
			DrawArrow(dc, iRect, TRUE, FALSE, enabled, pressed);
		}
		else if(part == ScrollPart_HorzThumb || part == ScrollPart_VertThumb)
			DrawButtonBox(dc, iRect, frame, FALSE);
		else if(part == ScrollPart_Top)
		{
			DrawButtonBox(dc, iRect, frame, pressed, TRUE);
			DrawArrow(dc, iRect, FALSE, TRUE, enabled, pressed);
		}
		else if(part == ScrollPart_Bottom)
		{
			DrawButtonBox(dc, iRect, frame, pressed, TRUE);
			DrawArrow(dc, iRect, FALSE, FALSE, enabled, pressed);
		}		
		return FALSE;
	}

	return TRUE;
}

bool WinEdit::SetSkin(bool parentSkin, SkinMode mode, uint color, cstr name)
{
	if(Parent::SetSkin(parentSkin, mode, color, name))
	{
		DestroyDrawData();
		return true;
	}
	return false;
}

LRESULT WinEdit::WmNcPaint(WPARAM wParam, LPARAM lParam)
{
	if(!m_NcPaint)
		return 0;

	if(m_Desc.mEdgeStyle == EdgeStyle_Color)
	{						  
		int bWidth = ::GetSystemMetrics(SM_CXBORDER);
		RECT cRect,wRect;
		::GetWindowRect(m_Handle, &wRect);
		cRect = wRect;
		::InflateRect(&cRect, -bWidth, -bWidth);
		HRGN wRgn = NULL;
		if(wParam == 1)
			wRgn = ::CreateRectRgn(wRect.left, wRect.top, wRect.right, wRect.bottom);
		else
			wRgn = (HRGN)wParam;
		HRGN sRgn = ::CreateRectRgn(cRect.left, cRect.top, cRect.right, cRect.bottom);
		::CombineRgn(wRgn, wRgn, sRgn, RGN_AND);
		::DeleteObject(sRgn);

		LRESULT lReturn = CallDefaultProc(WM_NCPAINT, WPARAM(wRgn), 0);
		
		if(wParam == 1)
			::DeleteObject(wRgn);
		DrawColorBorder(m_Handle, m_Desc.mBorderColor);
		
		return lReturn;
	}
	return TRUE;
}

LRESULT WinEdit::WmOwnerCommand(WPARAM wParam, LPARAM lParam)
{
	WORD hw = HIWORD(wParam);
	if(hw == EN_UPDATE)
	{		  
		if(mOnUpdate != NULL)
		{
			if(!mOnUpdate.mThis)
				(GetParent()->*mOnUpdate)(this);
			else
				mOnUpdate(this);
			return 0;
		}
	}
	else if(hw == EN_CHANGE)
	{
		if(!IsMinVista())
		{	//这3行代码对Vista似乎多余,屏蔽则减轻闪烁,XP是必须的。若有问题,用户可注释if语句
			if(UseBitmapSkin())
			{
				::InvalidateRect(m_Handle, NULL, TRUE);
				::UpdateWindow(m_Handle);
			}
		}
		
		if(mOnChange != NULL)
		{
			if(!mOnChange.mThis)
				(GetParent()->*mOnChange)(this);
			else
				mOnChange(this); 
			return 0;
		}
	}
	else if(hw == EN_ERRSPACE)
	{
		if(mOnErrorSpace != NULL)
		{
			if(!mOnErrorSpace.mThis)
				(GetParent()->*mOnErrorSpace)(this);
			else
				mOnErrorSpace(this);  
			return 0;
		}
	}
	else if(hw == EN_HSCROLL)
	{	//当用户拖拽滚动条时,却不触发滚动消息
		if(m_HScroll)
		{
			::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); 
			m_HScroll = FALSE;
		}
		if(mOnHorzScroll != NULL)
		{
			if(!mOnHorzScroll.mThis)
				(GetParent()->*mOnHorzScroll)(this);
			else
				mOnHorzScroll(this);  
			return 0;
		}
	}
	else if(hw == EN_VSCROLL)
	{		
		if(m_VScroll)
		{
			::SendMessage(m_Handle, WM_SETREDRAW, FALSE, 0); 
			m_VScroll = FALSE;
		}
		if(mOnVertScroll != NULL)
		{
			if(!mOnVertScroll.mThis)
				(GetParent()->*mOnVertScroll)(this);
			else
				mOnVertScroll(this);  
			return 0;
		}
	}
	else if(hw == EN_KILLFOCUS)
	{
		if(mOnKillFocus != NULL)
		{
			if(!mOnKillFocus.mThis)
				(GetParent()->*mOnKillFocus)(this);
			else
				mOnKillFocus(this);	 
			return 0;
		}
	}
	else if(hw == EN_SETFOCUS)
	{
		if(mOnSetFocus != NULL)
		{
			if(!mOnSetFocus.mThis)
				(GetParent()->*mOnSetFocus)(this);
			else
				mOnSetFocus(this);
			return 0;
		}
	}
	else if(hw == EN_MAXTEXT)
	{
		if(mOnMaxText != NULL)
		{
			if(!mOnMaxText.mThis)
				(GetParent()->*mOnMaxText)(this);
			else
				mOnMaxText(this);  
			return 0;
		}
	}

	return TRUE;
}

}