www.pudn.com > SDKSkin.rar > SkinButton.h


/**************************************************** 
**  Fujitsu Copyright (C) 2006 - 2007 
**	功    能:	SkinButton封装了Button的相关处理。 
 
**	文件名称: 	SkinButton 
**	文件基类:	 
**	扩 展 名:	h 
**	创建日期:	2006-8-19 15:25 
**	作    者:	汪荣 
*****************************************************/ 
 
#ifndef _SKINBUTTON_ONCE_ 
#define _SKINBUTTON_ONCE_ 
 
#define WM_MOUSEHOVER                   0x02A1 
#define WM_MOUSELEAVE                   0x02A3 
#define ODS_HOTLIGHT					0x0040 
 
#include "../SkinBase.h" 
 
 
void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime) 
{ 
	POINT pt; 
	::GetCursorPos(&pt); 
	RECT rcClnt; 
	ScreenToClient(hwnd,&pt); 
	GetClientRect(hwnd,&rcClnt); 
	if(::PtInRect(&rcClnt,pt) == TRUE) 
	{ 
		//m_bOver = true; 
		//if(bPaint == false) 
		{ 
			//InvalidateRect(hwnd,&rcClnt,TRUE); 
			//bPaint = true; 
		} 
	} 
	else 
	{ 
		KillTimer(hwnd,idEvent); 
		//m_bOver = false; 
		InvalidateRect(hwnd,&rcClnt,TRUE); 
		//bPaint = false; 
	} 
} 
 
class SkinButton : public SkinBase 
{ 
public: 
	SkinButton() 
	{ 
	} 
 
	static void SetOver(HWND _hWnd,bool bOver) 
	{ 
		if(bOver) 
		{ 
			SkinResList::GetWndFlag(_hWnd)->wnMOver = 1; 
		} 
		else SkinResList::GetWndFlag(_hWnd)->wnMOver = 0; 
	} 
	static void SetLDown(HWND _hWnd,bool bLDown) 
	{ 
		if(bLDown) 
		{ 
			SkinResList::GetWndFlag(_hWnd)->wnLBDown = 1; 
		} 
		else SkinResList::GetWndFlag(_hWnd)->wnLBDown = 0; 
	} 
	static void SetPainted(HWND _hWnd,bool bPainted) 
	{ 
		if(bPainted) 
		{ 
			SkinResList::GetWndFlag(_hWnd)->wnPainted = 1; 
		} 
		else SkinResList::GetWndFlag(_hWnd)->wnPainted = 0; 
	} 
	 
	static bool IsOver(HWND _hWnd) 
	{ 
		return (SkinResList::GetWndFlag(_hWnd)->wnMOver == 1); 
	} 
	static bool IsLDown(HWND _hWnd) 
	{ 
		return (SkinResList::GetWndFlag(_hWnd)->wnLBDown == 1); 
	} 
	static bool IsPainted(HWND _hWnd) 
	{ 
		return (SkinResList::GetWndFlag(_hWnd)->wnPainted == 1); 
	} 
	 
	LRESULT BTNMMove(HWND _hWnd,UINT fwKeys,POINT curPos) 
	{ 
		//SetTimer(_hWnd,1,10,TimerProc); 
		if(::GetCapture() != _hWnd) 
		{ 
			SetCapture(_hWnd); 
		} 
		RECT rcClnt; 
		GetClientRect(_hWnd,&rcClnt); 
		if(::PtInRect(&rcClnt,curPos)) 
		{ 
			if(!IsPainted(_hWnd)) 
			{ 
				SetPainted(_hWnd,true); 
				InvalidateRect(_hWnd,&rcClnt,TRUE); 
			} 
			SetOver(_hWnd,true); 
		} 
		else 
		{ 
			if(::GetCapture() == _hWnd) 
			{ 
				::ReleaseCapture(); 
			} 
			SetOver(_hWnd,false); 
			SetLDown(_hWnd,false); 
			InvalidateRect(_hWnd,&rcClnt,TRUE); 
			SetPainted(_hWnd,false);	 
		} 
		return 0L; 
	} 
	 
	LRESULT TransMsg(SKINMSG &skMsg) 
	{ 
		LRESULT lr = 0; 
		BOOL bCurState = FALSE; 
		 
		switch(skMsg._msg) 
		{ 
		case WM_SETFOCUS: 
		case WM_KILLFOCUS: 
		case WM_LBUTTONDOWN: 
		case WM_LBUTTONUP: 
		case BM_SETCHECK: 
			if(WM_LBUTTONDOWN == skMsg._msg) 
			{ 
				SetLDown(skMsg._hWnd,true); 
				SetPainted(skMsg._hWnd,false); 
				SetOver(skMsg._hWnd,false); 
			} 
 
			if(WM_LBUTTONUP == skMsg._msg) 
			{ 
				SetLDown(skMsg._hWnd,false); 
			} 
			 
			SkinWndState::SetRedraw(skMsg._hWnd,FALSE); 
			lr = SkinResList::CallDefWndProc(skMsg); 
			SkinWndState::SetRedraw(skMsg._hWnd,TRUE); 
			 
			SkinWndState::InvalidRect(skMsg._hWnd,TRUE); 
			UpdateWindow(skMsg._hWnd); 
			return lr;		 
		case BM_SETSTATE: 
			bCurState = (SendMessage(skMsg._hWnd,BM_GETSTATE,0,0) & BST_PUSHED); 
			 
			if((skMsg._wPm && bCurState) ||  
				(!skMsg._wPm && !bCurState)) 
			{ 
				break; 
			} 
			 
			SkinWndState::SetRedraw(skMsg._hWnd,FALSE); 
			lr = SkinResList::CallDefWndProc(skMsg); 
			SkinWndState::SetRedraw(skMsg._hWnd,TRUE); 
			 
			SkinWndState::InvalidRect(skMsg._hWnd,TRUE); 
			UpdateWindow(skMsg._hWnd); 
			return lr; 
		} 
		 
		return SkinResList::CallDefWndProc(skMsg); 
	} 
	 
	LRESULT CALLBACK SkinButtonProc(SKINMSG &skMsg) 
	{ 
		if(WM_MOUSEMOVE == skMsg._msg) 
		{ 
			POINT pt = {LOWORD(skMsg._lPm),HIWORD(skMsg._lPm)}; 
			BTNMMove(skMsg._hWnd,(UINT)skMsg._wPm,pt); 
		} 
		/*else if(skMsg._msg == WM_PAINT) 
		{ 
			PAINTSTRUCT ps; 
			HDC hDc = BeginPaint(skMsg._hWnd,&ps); 
			PaintButton(hDc,ps,skMsg); 
			EndPaint(skMsg._hWnd,&ps); 
			return TRUE; 
		}*/ 
		return TransMsg(skMsg); 
	} 
 
	HBITMAP DrawRadio(HDC hDc,RNHBitmap bmDraw,bool bCheck,bool bEnable,RECT &rcBm,COLORREF clr) 
	{ 
		int iRadioWid = bmDraw.Width() / 4; 
		int iHei = bmDraw.Height() + 1; 
		rcBm.right = rcBm.left + iRadioWid; 
		 
		RNHDC memDc(CreateCompatibleDC(hDc)); 
		RNHBitmap bmp(CreateCompatibleBitmap(hDc,rcBm.right - rcBm.left,rcBm.bottom - rcBm.top)); 
		 
		HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp); 
		 
		HBRUSH hb = CreateSolidBrush(clr); 
		FillRect(memDc,&rcBm,hb); 
		DeleteObject(hb); 
		 
		int idx = 0; 
		if(bCheck) 
		{ 
			idx = 1; 
			if(!bEnable) idx = 3; 
		} 
		else 
		{ 
			if(!bEnable) idx = 2; 
		} 
		 
		RECT rcDraw = rcBm; 
		int  iOffset = max(0,rcBm.bottom-rcBm.top-iHei); 
		 
		rcDraw.left = 0; 
		rcDraw.top += iOffset/2; 
		if(iOffset > 0) 
		{ 
			rcDraw.bottom =  rcDraw.top + iHei; 
		} 
		else 
		{ 
			rcDraw.bottom =  rcDraw.top + rcBm.bottom-rcBm.top; 
		} 
 
		//rcBm = rcDraw; 
		 
		SkinDraw::DrawStretch(memDc,rcDraw,bmDraw, 
			iRadioWid * idx,0,iRadioWid,iHei,false); 
		 
		SelectObject(memDc,obmp); 
		return bmp.Detach(); 
	} 
	 
	LRESULT BTNTimerFunc(HWND _hWnd) 
	{ 
		return 0; 
	} 
	 
	static LRESULT BTNLButtonDown() 
	{ 
		return 0L; 
	} 
	static LRESULT BTNLButtonUp() 
	{ 
		return 0L; 
	} 
 
	LRESULT PaintButton(HDC hDc,PAINTSTRUCT &ps,SKINMSG &skMsg) 
	{ 
		bool m_bSelected,m_bFocus,m_bOver; 
		m_bSelected = m_bFocus = false; 
		m_bOver = IsOver(skMsg._hWnd); 
		RECT rcDraw = ps.rcPaint; 
		GetClientRect(skMsg._hWnd,&rcDraw); 
		RNHDC  _hDc(hDc,false); 
		TCHAR strText[MAX_PATH + 1] = {0}; 
		::GetWindowText(skMsg._hWnd,strText,MAX_PATH); 
		 
		//获取按钮的状态 
		if(GetFocus() == skMsg._hWnd) 
		{ 
			m_bFocus = true; 
			m_bSelected = true; 
		} 
		else 
		{ 
			m_bFocus = false; 
			m_bSelected = false; 
		} 
		 
		if(IsLDown(skMsg._hWnd)) 
		{ 
			m_bFocus = true; 
		}		 
	 
		RNHBitmap bmBtn(SkinIni::Instance()->GetBTNImg()); 
		int		  iBtnWid = bmBtn.Width()/5; 
		WNDSTATE wState = SKIN_NORMAL; 
		if(IsLDown(skMsg._hWnd)) 
		{ 
			wState = SKIN_DOWN; 
		} 
		else if(m_bFocus) 
		{ 
			wState = SKIN_FOCUS; 
		} 
		else if(m_bSelected && !m_bOver) 
		{ 
			wState = SKIN_DOWN; 
		} 
		else if(SkinWndState::GetWndStyle(skMsg._hWnd) & WS_DISABLED) 
		{ 
			wState = SKIN_DISABLE; 
		} 
		else if(m_bOver) 
		{ 
			wState = SKIN_HOT; 
		} 
		 
		BTNPOS	  btPos = SkinIni::Instance()->GetBtnPos(); 
		RNHBitmap bmp; 
		bmp.Attach(DrawBtn(_hDc,bmBtn,rcDraw,wState)); 
		HRGN wnRgn = SkinRgn::ImageToRgn(_hDc,bmp,btPos.clrTran); 
		SetWindowRgn(skMsg._hWnd,wnRgn,TRUE);		 
		 
		HRGN hRgn = CreateRectRgn(0,0,0,0); 
		GetWindowRgn(skMsg._hWnd,hRgn);				 
		::SelectClipRgn(_hDc,hRgn); 
		 
		RECT dsRc = {0,0,bmp.Width(),bmp.Height()}; 
		RNHDC memDc(CreateCompatibleDC(_hDc)); 
		HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp); 
		SkinDraw::DrawStretch(_hDc,memDc,rcDraw,dsRc); 
		 
		SelectClipRgn(_hDc,NULL); 
		DeleteObject(hRgn); 
		SelectObject(memDc,obmp); 
 
		//显示按钮的文本 
		if(_tcslen(strText) > 0) 
		{ 
			HFONT hFont = (HFONT)SendMessage(skMsg._hWnd,WM_GETFONT,0,0); 
			HFONT hOldFont = (HFONT)SelectObject(_hDc,hFont); 
			SIZE szExtent; 
			GetTextExtentPoint32(_hDc,strText, _tcslen(strText),&szExtent); 
			int	  nCenterPointX = rcDraw.left + (rcDraw.right-rcDraw.left)/2; 
			int	  nCenterPointY = rcDraw.top + (rcDraw.bottom-rcDraw.top)/2; 
			 
			POINT pt = {nCenterPointX - szExtent.cx/2,nCenterPointY-szExtent.cy/2}; 
			if(IsLDown(skMsg._hWnd))  
			{ 
				pt.x += 1; 
				pt.y += 1; 
			} 
			int nMode = SetBkMode(_hDc,TRANSPARENT); 
			RECT rcDr = rcDraw; 
			rcDr.left = pt.x;rcDr.top = pt.y; 
			rcDr.right = pt.x + szExtent.cx; 
			rcDr.bottom = pt.y + szExtent.cy; 
			if(SkinWndState::GetWndStyle(skMsg._hWnd) & WS_DISABLED) 
			{ 
				DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);//|DT_CENTER|DT_VCENTER); 
			} 
			else 
			{ 
				DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE); 
			} 
			 
			SelectObject(_hDc,hOldFont); 
			SetBkMode(_hDc,nMode); 
		} 
 
		return TRUE; 
	} 
	static HBITMAP DrawBtn(RNHDC &hDc,RNHBitmap &bmBtn,RECT rcDraw,WNDSTATE wState) 
	{ 
		int		  iBtnWid = bmBtn.Width()/5; 
		BTNPOS	  btPos = SkinIni::Instance()->GetBtnPos(); 
		int		  iBegPos = 0; 
		if(wState == SKIN_NORMAL) 
		{ 
			iBegPos = 0; 
		} 
		else if(wState == SKIN_FOCUS) 
		{ 
			iBegPos = iBtnWid*3; 
		} 
		else if(wState == SKIN_DOWN) 
		{ 
			iBegPos = iBtnWid*1; 
		} 
		else if(wState == SKIN_HOT) 
		{ 
			iBegPos = iBtnWid*3;			 
		} 
		else if(wState == SKIN_DISABLE) 
		{ 
			iBegPos = iBtnWid*2; 
		} 
 
		int	 iLFWid = max(btPos.iLTLen,btPos.iLBLen); 
		int	 iRFWid = max(btPos.iRTLen,btPos.iRBLen); 
		int	 iTFHei = max(btPos.iLTHei,btPos.iRTHei); 
		int	 iBFHei = max(btPos.iLBHei,btPos.iRBHei); 
 
		RECT rcTmp = {0,0,rcDraw.right,rcDraw.bottom}; 
		if(rcTmp.right < (iLFWid + iRFWid)) 
		{ 
			//rcTmp.right = iLFWid + iRFWid; 
		} 
		if(rcTmp.bottom < (iTFHei + iBFHei)) 
		{ 
			//rcTmp.bottom = iTFHei + iBFHei; 
		} 
		RNHDC memDc(CreateCompatibleDC(hDc)); 
		RNHBitmap bmp(CreateCompatibleBitmap(hDc,rcTmp.right-rcTmp.left,rcTmp.bottom-rcTmp.top)); 
		HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp); 
		// 画左上角 
		RECT drTmp = rcDraw; 
		int  iHei = rcDraw.bottom-rcDraw.top; 
		int	 iWid = rcDraw.right-rcDraw.left; 
		drTmp.bottom = btPos.iLTHei; 
		drTmp.right = btPos.iLTLen; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,0,btPos.iLTLen,btPos.iLTHei); 
		drTmp.left = iWid - btPos.iRTLen; 
		drTmp.bottom = btPos.iRTHei; 
		drTmp.right = iWid; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-btPos.iRTLen),0, 
					   btPos.iRTLen,btPos.iRTHei); 
		drTmp.left = 0; 
		drTmp.top = iHei-btPos.iLBHei; 
		drTmp.right = btPos.iLBLen; 
		drTmp.bottom = iHei; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,bmBtn.Height()-btPos.iLBHei,btPos.iLBLen,btPos.iLBHei); 
		drTmp.left = iWid - btPos.iRBLen; 
		drTmp.right = iWid; 
		drTmp.top = iHei - btPos.iRBHei; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-btPos.iRTLen),bmBtn.Height()-btPos.iRBHei, 
					   btPos.iRBLen,btPos.iRBHei); 
 
		drTmp.left = 0; 
		drTmp.top = btPos.iLTHei; 
		drTmp.bottom = iHei - btPos.iLBHei; 
		drTmp.right = iLFWid; 
		if(iHei > (btPos.iLTHei+btPos.iLBHei)) 
		{ 
			int iMid = (drTmp.bottom - drTmp.top) / 2; 
			drTmp.bottom = drTmp.top + iMid; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,btPos.iLTHei+1,iLFWid,1); 
			drTmp.top = drTmp.bottom; 
			drTmp.bottom = iHei - btPos.iLBHei; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos,bmBtn.Height()-iBFHei-1,iLFWid,1); 
		} 
		drTmp.left = drTmp.right; 
		drTmp.top = 0; 
		drTmp.bottom = iTFHei; 
		drTmp.right = iWid - iLFWid; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,0, 
					   iBtnWid-iLFWid-iRFWid,iTFHei); 
 
		drTmp.left = iWid - iRFWid; 
		drTmp.top = btPos.iRTHei; 
		drTmp.bottom = iHei - btPos.iRBHei; 
		drTmp.right = iWid; 
		if(iHei > (btPos.iRTHei+btPos.iRBHei)) 
		{ 
			int iMid = (drTmp.bottom - drTmp.top) / 2; 
			drTmp.bottom = drTmp.top + iMid; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-iRFWid),iTFHei+1, 
				iRFWid,1); 
			drTmp.top = drTmp.bottom; 
			drTmp.bottom = iHei - btPos.iRBHei; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+(iBtnWid-iRFWid), 
				bmBtn.Height()-iBFHei-1,iRFWid,1); 
		} 
		drTmp.left = iLFWid; 
		drTmp.top = iHei - iBFHei; 
		drTmp.bottom = iHei; 
		drTmp.right = iWid - iRFWid; 
		SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,bmBtn.Height()-iBFHei, 
			iBtnWid-iLFWid-iRFWid,iBFHei); 
 
		drTmp.left = iLFWid; 
		drTmp.top = iTFHei; 
		drTmp.bottom = iHei - iBFHei; 
		drTmp.right = iWid - iRFWid; 
		if(iHei > (btPos.iRTHei+btPos.iRBHei)) 
		{ 
			int iMid = (drTmp.bottom - drTmp.top) / 2; 
			drTmp.bottom = drTmp.top + iMid; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,iTFHei + 1, 
				iBtnWid-iLFWid-iRFWid,1); 
			drTmp.top = drTmp.bottom; 
			drTmp.bottom = iHei - btPos.iRBHei; 
			SkinDraw::Draw(memDc,bmBtn,drTmp,iBegPos+iLFWid,bmBtn.Height()-iBFHei-1, 
				iBtnWid-iLFWid-iRFWid,1); 
		} 
 
		SelectObject(memDc,obmp); 
 
		return bmp.Detach(); 
	} 
	LRESULT DrawCtrlItem(UINT idCtrl,LPDRAWITEMSTRUCT lpdis) 
	{ 
		//return 0L; 
		bool m_bSelected,m_bFocus,m_bOver; 
		m_bSelected = m_bFocus = false; 
		m_bOver = IsOver(lpdis->hwndItem); 
		RECT rcDraw =  lpdis->rcItem; 
		RNHDC  _hDc(lpdis->hDC,false); 
		int nSaveDC= SaveDC(_hDc); 
		UINT uState = lpdis->itemState; 
 
		TCHAR strText[MAX_PATH + 1]; 
		::GetWindowText(lpdis->hwndItem,strText,MAX_PATH); 
		RNHBitmap bmBtn(SkinIni::Instance()->GetBTNImg()); 
		int		  iBtnWid = bmBtn.Width()/5; 
		WNDSTATE wState = SKIN_NORMAL; 
		if(IsLDown(lpdis->hwndItem)) 
		{ 
			wState = SKIN_DOWN; 
		} 
		else if(uState & ODS_FOCUS) 
		{ 
			wState = SKIN_FOCUS; 
		} 
		else if(SkinWndState::GetWndStyle(lpdis->hwndItem) & WS_DISABLED) 
		{ 
			wState = SKIN_DISABLE; 
		} 
		else if(m_bOver) 
		{ 
			wState = SKIN_HOT; 
		} 
 
		BTNPOS	  btPos = SkinIni::Instance()->GetBtnPos(); 
		RNHBitmap bmp; 
		bmp.Attach(DrawBtn(_hDc,bmBtn,rcDraw,wState)); 
		HRGN wnRgn = SkinRgn::ImageToRgn(_hDc,bmp,btPos.clrTran); 
		SetWindowRgn(lpdis->hwndItem,wnRgn,TRUE); 
				 
		HRGN hRgn = CreateRectRgn(0,0,0,0); 
		GetWindowRgn(lpdis->hwndItem,hRgn);				 
		::SelectClipRgn(_hDc,hRgn); 
 
		RECT dsRc = {0,0,bmp.Width(),bmp.Height()}; 
		RNHDC memDc(CreateCompatibleDC(_hDc)); 
		HBITMAP obmp = (HBITMAP)SelectObject(memDc,bmp); 
		SkinDraw::DrawStretch(_hDc,memDc,rcDraw,dsRc); 
 
		SelectClipRgn(_hDc,NULL); 
		DeleteObject(hRgn); 
 
		//显示按钮的文本 
		if(_tcslen(strText) > 0) 
		{ 
			HFONT hFont = (HFONT)SendMessage(lpdis->hwndItem,WM_GETFONT,0,0); 
			HFONT hOldFont = (HFONT)SelectObject(_hDc,hFont); 
			SIZE szExtent; 
			GetTextExtentPoint32(_hDc,strText, _tcslen(strText),&szExtent); 
			int	  nCenterPointX = rcDraw.left + (rcDraw.right-rcDraw.left)/2; 
			int	  nCenterPointY = rcDraw.top + (rcDraw.bottom-rcDraw.top)/2; 
			 
			POINT pt = {nCenterPointX - szExtent.cx/2,nCenterPointY-szExtent.cy/2}; 
			if(uState & ODS_SELECTED)  
			{ 
				pt.x += 1; 
				pt.y += 1; 
			} 
			int nMode = SetBkMode(_hDc,TRANSPARENT); 
			RECT rcDr = rcDraw; 
			rcDr.left = pt.x;rcDr.top = pt.y; 
			rcDr.right = pt.x + szExtent.cx; 
			rcDr.bottom = pt.y + szExtent.cy; 
			if(uState & ODS_DISABLED || 
				!IsWindowEnabled(lpdis->hwndItem)) 
			{ 
				SKinDrawState(_hDc,pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL); 
				//DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE);//|DT_CENTER|DT_VCENTER); 
			} 
			else 
			{ 
				SKinDrawState(_hDc,pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL); 
				//DrawText(_hDc,strText,_tcslen(strText),&rcDr,DT_SINGLELINE); 
			} 
			 
			SelectObject(_hDc,hOldFont); 
			SetBkMode(_hDc,nMode); 
		}	 
			 
		RestoreDC(_hDc,nSaveDC);	 
 
		return TRUE; 
	} 
}; 
 
#endif