www.pudn.com > WinGOS.rar > Button.cpp


#include "gos.h" 
#include "button.h" 
 
LRESULT CButton::MsgProc(UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch(message) 
	{ 
	case WM_PAINT: 
		OnPaint(PDC(wParam)); 
		break; 
	case WM_LBUTTONDOWN: 
		AddStyle(BS_PUSHED); 
		Invalidate(NULL); 
		break; 
	case WM_LBUTTONUP: 
		RemoveStyle(BS_PUSHED); 
		Invalidate(NULL); 
		if(!GetWindowRect().PtInRect(CPoint(lParam))) 
			break; 
		switch(GetStyle() & BS_TYPEMASK) 
		{ 
		case BS_CHECKBOX: 
			SetCheck(-1); 
			break; 
		case BS_RADIOBUTTON: 
			SetCheck(1); 
			break; 
		} 
		PostMessage(WM_COMMAND,BN_CLICKED,0); 
		break; 
	case WM_SETFOCUS: 
	case WM_KILLFOCUS: 
		Invalidate(NULL); 
		break; 
	case WM_COMMAND: 
		GetParent()->PostMessage(message,WPARAM(this),wParam); 
		break; 
	default: 
		wParam=CWnd::MsgProc(message,wParam,lParam); 
	} 
	return wParam; 
} 
 
void CButton::OnEraseBkgnd(CDC* pDC) 
{ 
	switch(GetStyle() & BS_TYPEMASK) 
	{ 
	case BS_CHECKBOX: 
		SetCheck(-1); 
		break; 
	case BS_RADIOBUTTON: 
		SetCheck(1); 
		break; 
	} 
	CWnd::OnEraseBkgnd(pDC); 
} 
 
void CButton::OnPaint(CDC* pDC) 
{ 
	DWORD nStyle=GetStyle(); 
	LPCRECT pRect=GetClientRect(); 
	switch(nStyle & BS_TYPEMASK) 
	{ 
	case BS_PUSHBUTTON: 
		if(nStyle & BS_BITMAP) 
			DrawBitmap(pDC,pRect,GetBitmap(),nStyle); 
		else if(nStyle & BS_LINKLIKE) 
			DrawLinkButton(pDC,pRect); 
		else 
			DrawButton(pDC,GetClientRect()); 
		break; 
	case BS_CHECKBOX: 
	case BS_RADIOBUTTON: 
		if(nStyle & BS_BITMAP) 
			DrawBitmap(pDC,pRect,GetBitmap(),nStyle); 
		else if(nStyle & BS_PUSHLIKE) 
			DrawButton(pDC,pRect); 
		else 
			DrawCheckBox(pDC,pRect); 
		break; 
	case BS_OWNERDRAW: 
		GetParent()->MsgProc(WM_DRAWITEM,WPARAM(this),LPARAM(pDC)); 
		break; 
	} 
} 
 
void CButton::DrawBitmap(CDC* pDC,LPCRECT pRect,CBitmap* pBitmap,DWORD nStyle) 
{ 
	if(!pBitmap || !pBitmap->GetBitmap().bmBits) 
		return; 
 
	if(nStyle & (BS_CHECKED|WS_FOCUSED)) 
	{ 
		COLORREF clr=GetCtlColor(COLOR_HIGHLIGHT)|(128<<24); 
		clr=pDC->SetTextColor(clr); 
		pDC->BitBlt(pRect,pBitmap,NULL,(nStyle&BS_STYLEMASK)|R2_ALPHABLENDPEN); 
		pDC->SetTextColor(clr); 
	} 
	else 
		pDC->BitBlt(pRect,pBitmap,NULL,nStyle&BS_STYLEMASK); 
} 
 
void CButton::DrawButton(CDC* pDC,LPCRECT pRect) 
{ 
	DWORD nStyle=GetStyle(); 
	CFont* pFont=pDC->SelectObject(GetFont());; 
	COLORREF clr0,clr=GetCtlColor(COLOR_WINDOWTEXT); 
	CRect r(pRect); 
 
	pDC->DrawRect(r,clr,PS_SOLID); 
	r.DeflateRect(1); 
	if(nStyle & WS_FOCUSED) 
		pDC->DrawRect(r,clr,PS_SOLID); 
	if(nStyle&BS_PUSHED) 
		r.OffsetRect(1,1); 
	clr0=pDC->SetBkColor(CLR_NONE); 
	clr=pDC->SetTextColor(clr); 
	nStyle &= BS_DTMASK; 
	pDC->DrawText(this,r,nStyle); 
	pDC->SetTextColor(clr); 
	pDC->SetBkColor(clr0); 
	pDC->SelectObject(pFont); 
} 
 
void CButton::DrawCheckBox(CDC* pDC,LPCRECT pRect) 
{ 
	CRect rclText,r(pRect); 
	COLORREF clr0,clr; 
	CFont* pFont=pDC->SelectObject(GetFont()); 
	DWORD nStyle=GetStyle(); 
	SIZE size=pDC->GetTextExtent(" ",1); 
 
	r.top=(r.top+r.bottom-size.cy)>>1; 
	r.bottom=r.top+size.cy; 
	rclText=r; 
	if(nStyle & BS_LEFTTEXT) 
	{ 
		r.left=r.right-(size.cx<<1); 
		rclText.right=r.left-3; 
	} 
	else 
	{ 
		r.right=r.left+(size.cx<<1); 
		rclText.left=r.right+3; 
	} 
	clr=GetCtlColor(COLOR_WINDOWTEXT); 
	pDC->DrawRect(r,clr); 
	r.DeflateRect(1); 
 
	clr=GetCtlColor(COLOR_WINDOWTEXT); 
	if(nStyle & BS_PUSHED) 
	{ 
		clr0=GetCtlColor(COLOR_3DFACE); 
		pDC->FillSolidRect(r,clr0); 
	} 
	else if(nStyle & BS_CHECKED) 
	{ 
		r.DeflateRect(2); 
		pDC->FillSolidRect(r,clr); 
	} 
 
	clr=pDC->SetTextColor(clr); 
	clr0=pDC->SetBkColor(CLR_NONE); 
	if(!(nStyle&BS_CENTER)) 
		nStyle|=(nStyle& BS_LEFTTEXT)?BS_RIGHT:BS_LEFT; 
	nStyle &= BS_DTMASK; 
	pDC->DrawText(this,rclText,nStyle); 
 
	pDC->SetBkColor(clr0); 
	pDC->SetTextColor(clr); 
	pDC->SelectObject(pFont); 
} 
 
void CButton::DrawLinkButton(CDC* pDC,LPCRECT pRect) 
{ 
	CFont* pFont=pDC->SelectObject(GetFont()); 
	DWORD nStyle=GetStyle(); 
	COLORREF clr0,crText; 
 
	crText=GetCtlColor(COLOR_HOTLIGHT); 
	crText=pDC->SetTextColor(crText); 
	clr0=pDC->SetBkColor(CLR_NONE); 
	 
	nStyle &= BS_DTMASK; 
	pDC->DrawText(this,pRect,nStyle); 
 
	pDC->SetBkColor(clr0); 
	pDC->SetTextColor(crText); 
	pDC->SelectObject(pFont); 
} 
 
void CButton::SetCheck(BOOL bCheck) 
{ 
	DWORD nStyle=GetStyle(); 
	switch(nStyle & BS_TYPEMASK) 
	{ 
	case BS_RADIOBUTTON: 
	{ 
		if(!(nStyle & BS_CHECKED)) 
		{ 
			PWND pWnd,pChild=GetParent()->GetChild()->GetPrevWindow(); 
			for(pWnd=GetPrevWindow();pWnd!=pChild;pWnd=pWnd->GetPrevWindow()) 
			{ 
				nStyle=pWnd->GetStyle(); 
				if(nStyle & BS_RADIOBUTTON) 
				{ 
					if(nStyle & BS_CHECKED) 
					{ 
						pWnd->RemoveStyle(BS_CHECKED); 
						pWnd->Invalidate(NULL); 
						break; 
					} 
				} 
				if(!(nStyle & WS_SUBGROUP)) 
					break; 
			} 
			pChild=GetParent()->GetChild(); 
			for(pWnd=pWnd?GetNextWindow():pChild;pWnd!=pChild;pWnd=pWnd->GetNextWindow()) 
			{ 
				nStyle=pWnd->GetStyle(); 
				if(!(nStyle & WS_SUBGROUP)) 
					break; 
				if(nStyle & BS_RADIOBUTTON) 
				{ 
					if(nStyle & BS_CHECKED) 
					{ 
						pWnd->RemoveStyle(BS_CHECKED); 
						pWnd->Invalidate(NULL); 
						pWnd=NULL; 
						break; 
					} 
				} 
			} 
			AddStyle(BS_CHECKED); 
			Invalidate(NULL); 
		} 
	} 
	default: 
		if(bCheck<0) 
			bCheck=(nStyle & BS_CHECKED)?FALSE:TRUE; 
		if(bCheck) 
			AddStyle(BS_CHECKED); 
		else 
			RemoveStyle(BS_CHECKED); 
	} 
}