Milán Major

netscape-revival

1 branch
Code

sun-java/awt/win/awt_button.cpp

#include "awt_button.h"
#include "awt_toolkit.h"
#include "awt_defs.h"
// All java header files are extern "C"
extern "C" {
#include "java_awt_Button.h"
#include "java_awt_Checkbox.h"
#include "java_awt_CheckboxGroup.h"

#include "sun_awt_windows_WComponentPeer.h"
#include "sun_awt_windows_WButtonPeer.h"
#include "sun_awt_windows_WCheckboxPeer.h"
};


AwtButton::AwtButton(HWButtonPeer *peer) : AwtWindow((JHandle *)peer)
{
    DEFINE_AWT_SENTINAL("BTN");
    m_dwButtonType = BS_PUSHBUTTON;
#ifdef INTLUNICODE
	m_pLabel = NULL;
	m_checked = FALSE;
#endif	// INTLUNICODE
}

AwtButton::AwtButton(HWCheckboxPeer *peer) : AwtWindow((JHandle *)peer)
{
	
    // get hand on the checkbox object (via peer)
    Hjava_awt_Checkbox *target;
    target = (Hjava_awt_Checkbox *)
                unhand((HWComponentPeer *)m_pJavaPeer)->target;

    if (unhand(target)->group == 0) {
        DEFINE_AWT_SENTINAL("CBX");
        m_dwButtonType = BS_CHECKBOX;
    } else {
        DEFINE_AWT_SENTINAL("RBN");
        m_dwButtonType = BS_RADIOBUTTON;
    }
#ifdef INTLUNICODE
	m_pLabel = NULL;
	m_checked = FALSE;
#endif	// INTLUNICODE
}

#ifdef INTLUNICODE
AwtButton::~AwtButton()
{
	if(m_pLabel)
	{
		delete m_pLabel;
		m_pLabel = NULL;
	}
}
#endif	// INTLUNICODE
// -----------------------------------------------------------------------
//
// Return the window class of an AwtButton window.
//
// -----------------------------------------------------------------------
const char * AwtButton::WindowClass()
{
    return "BUTTON";
}


// -----------------------------------------------------------------------
//
// Return the window style used to create an AwtButton window
//
// -----------------------------------------------------------------------
DWORD AwtButton::WindowStyle()
{
#ifdef INTLUNICODE
    return WS_CHILD | WS_CLIPSIBLINGS | BS_OWNERDRAW;
#else // INTLUNICODE
    return WS_CHILD | WS_CLIPSIBLINGS | m_dwButtonType;
#endif
}


// -----------------------------------------------------------------------
//
// Set the label text for the button
//
// -----------------------------------------------------------------------
void AwtButton::SetLabel(Hjava_lang_String * string)
{
    ASSERT( ::IsWindow(m_hWnd) );
#ifdef	INTLUNICODE
	WinCompStr * newlabel = new WinCompStr(string);
	if(m_pLabel)	{
		WinCompStr *oldlabel = m_pLabel;
		m_pLabel = newlabel;
		delete oldlabel;
	} else {
		m_pLabel = newlabel;
	}
	::SetWindowText(m_hWnd, "");	// To force a redraw
#else	// INTLUNICODE
    int32_t len;
    char *buffer = NULL;

    len    = javaStringLength(string);
    buffer = (char *)malloc(len+1);
    if (buffer) {
        javaString2CString(string, buffer, len+1);

        ::SetWindowText(m_hWnd, buffer);

        free(buffer);
    }
#endif	// INTLUNICODE
}


// -----------------------------------------------------------------------
//
// Set the state for the check box
//
// -----------------------------------------------------------------------
void AwtButton::SetState(long lState)
{
    ASSERT( ::IsWindow(m_hWnd) );
#ifdef INTLUNICODE
	m_checked = (lState) ? TRUE : FALSE;
	::InvalidateRgn(m_hWnd, NULL, FALSE);
	::UpdateWindow(m_hWnd);
#else	// INTLUNICODE
    ::SendMessage(m_hWnd, BM_SETCHECK, (WPARAM)((lState) ? TRUE : FALSE), 0L);
#endif	// INTLUNICODE
}

// -----------------------------------------------------------------------
//
// 
// -----------------------------------------------------------------------
BOOL AwtButton::OnCommand(UINT notifyCode, UINT id)
{
    if (notifyCode == BN_CLICKED) {
        if (m_pJavaPeer) {
            int64 time = PR_NowMS(); // time in milliseconds

            //
            // Call handleAction(...) on the proper button peer 
            //
            if (m_dwButtonType == BS_PUSHBUTTON) {
                AwtToolkit::RaiseJavaEvent(m_pJavaPeer, 
                                            AwtEventDescription::ButtonAction,
                                            time,
                                            NULL);
            }
            else { 
#ifdef INTLUNICODE
                AwtToolkit::RaiseJavaEvent(m_pJavaPeer, 
                                            AwtEventDescription::CheckAction,
                                            time, 
                                            NULL,
                                            ! m_checked);
#else	// INTLUNICODE
                AwtToolkit::RaiseJavaEvent(m_pJavaPeer, 
                                            AwtEventDescription::CheckAction,
                                            time, 
                                            NULL,
                                            !::SendMessage (m_hWnd, BM_GETCHECK, 0, 0L));
#endif	// INTLUNICODE
            }
        }
    }

    return FALSE;
}


BOOL AwtButton::OnPaint( HDC hdc, int x, int y, int w, int h )
{                                                             
    return AwtComponent::OnPaint(hdc, x, y, w, h);
}
    
#ifdef INTLUNICODE
#ifdef _WIN32

BOOL AwtButton::DrawWin95Item(UINT idCtl, LPDRAWITEMSTRUCT lpdis)
{
	switch(m_dwButtonType)
	{
	case BS_PUSHBUTTON :	
		DrawWin95Button( lpdis);
		break;
	case BS_RADIOBUTTON :	
		DrawWin95Radio( lpdis);
		break;
	case BS_CHECKBOX :	
		DrawWin95Checkbox( lpdis);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}
//
//	This function draw the button in the case of WIN32 and running on Win95
//
void AwtButton::DrawWin95Button(LPDRAWITEMSTRUCT lpdis)
{
	// 1. fill out the rectangle wiht background brush
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. decide which color we should use to draw the four edges
	COLORREF color1, color2, color3, color4;
	if(lpdis->itemState & ODS_SELECTED)
	{
		color1 = ::GetSysColor(COLOR_3DHILIGHT);
		color2 = ::GetSysColor(COLOR_3DLIGHT);
		color3 = ::GetSysColor(COLOR_3DDKSHADOW);
		color4 = ::GetSysColor(COLOR_3DSHADOW);
	}
	else
	{
		color1 = ::GetSysColor(COLOR_3DDKSHADOW);
		color2 = ::GetSysColor(COLOR_3DSHADOW);
		color3 = ::GetSysColor(COLOR_3DHILIGHT);
		color4 = ::GetSysColor(COLOR_3DLIGHT);
	}

	// 3. create pen and draw them
	HPEN oldPen = (HPEN)::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, color1));

	POINT seg1[3];
	seg1[0].x = lpdis->rcItem.left; 
	seg1[0].y = lpdis->rcItem.bottom-1;
	seg1[1].x =	lpdis->rcItem.right-1;
	seg1[1].y = lpdis->rcItem.bottom-1;
	seg1[2].x =	lpdis->rcItem.right-1;
	seg1[2].y =	lpdis->rcItem.top;
	::Polyline(lpdis->hDC, seg1, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, color2)));

	POINT seg2[3];
	seg2[0].x =	lpdis->rcItem.left+1;
	seg2[0].y =	lpdis->rcItem.bottom-2;
	seg2[1].x =	lpdis->rcItem.right-2;
	seg2[1].y =	lpdis->rcItem.bottom-2; 
	seg2[2].x =	lpdis->rcItem.right-2;
	seg2[2].y =	lpdis->rcItem.top;
	::Polyline(lpdis->hDC, seg2, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, color3)));

	POINT seg3[3];
	seg3[0].x =	lpdis->rcItem.left;	
	seg3[0].y =	lpdis->rcItem.bottom-2; 
	seg3[1].x =	lpdis->rcItem.left;
	seg3[1].y =	lpdis->rcItem.top; 
	seg3[2].x =	lpdis->rcItem.right-1;
	seg3[2].y =	lpdis->rcItem.top;
	::Polyline(lpdis->hDC, seg3, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, color4)));

	POINT seg4[3]; 
	seg4[0].x =	lpdis->rcItem.left+1;
	seg4[0].y =	lpdis->rcItem.bottom-3; 
	seg4[1].x =	lpdis->rcItem.left+1;
	seg4[1].y =	lpdis->rcItem.top+1; 
	seg4[2].x =	lpdis->rcItem.right-2;
	seg4[2].y =	lpdis->rcItem.top+1;
	::Polyline(lpdis->hDC, seg4, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, oldPen));

	// 4. Now we deal with text- only there are text and font

	AwtFont* pFont = this->GetFont();
	if((m_pLabel != NULL ) && (pFont != NULL ))
	{
		// 4.1 set the mode to TRANSPARENT
		::SetBkMode(lpdis->hDC, TRANSPARENT);

		// 4.2 If it is disabled, draw a ghost one first.
		if(lpdis->itemState & ODS_DISABLED)
		{
			// 4.2.1 set the text color to 3DLIGHT to draw to ghost text
			// 	Correct 3DLIGHT
			COLORREF bg = m_BackgroundColor->GetColor();
			COLORREF fg = m_ForegroundColor->GetColor();
			COLORREF gray = RGB(
				((GetRValue(bg) >> 1) + (GetRValue(fg) >> 1)),
				((GetGValue(bg) >> 1) + (GetGValue(fg) >> 1)),
				((GetBValue(bg) >> 1) + (GetBValue(fg) >> 1))
			);
			int lightr = (GetRValue(bg) - (GetRValue(fg) >> 1) + (GetRValue(bg) >> 1));
			int lightg = (GetGValue(bg) - (GetGValue(fg) >> 1) + (GetGValue(bg) >> 1));
			int lightb = (GetBValue(bg) - (GetBValue(fg) >> 1) + (GetBValue(bg) >> 1));
			COLORREF light = RGB(
				((lightr & 0xFF00 ) ? 0x00FF : (lightr)),
				((lightg & 0xFF00 ) ? 0x00FF : (lightg)),
				((lightb & 0xFF00 ) ? 0x00FF : (lightb))
			);

			//::SetTextColor(lpdis->hDC, ::GetSysColor(COLOR_3DLIGHT));
			::SetTextColor(lpdis->hDC, light);

			RECT ghostRect = lpdis->rcItem;
			::OffsetRect(&ghostRect, 1,1);
			m_pLabel->DrawText(lpdis->hDC, pFont ,&ghostRect, DT_CENTER);
			// 4.2.2 set the text color to GRAYTEXT so later we will draw the gray one
			// 	Correct GRAYTEXT
			////::SetTextColor(lpdis->hDC, ::GetSysColor(COLOR_GRAYTEXT));
			::SetTextColor(lpdis->hDC, gray);
		}
		else
		{
			::SetTextColor(lpdis->hDC, m_ForegroundColor->GetColor());
		}

		// 4.3 Find teh rect that we should draw the text
		RECT textrect = lpdis->rcItem;
		if(lpdis->itemState & ODS_SELECTED)
			::OffsetRect(&textrect, 1,1);

		// 4.4 Draw the text
		m_pLabel->DrawText(lpdis->hDC, pFont ,&textrect, DT_CENTER);
	}

	// 5 Draw focus box
	if( (lpdis->itemState & ODS_FOCUS) && 
		!(lpdis->itemState & ODS_DISABLED))
	{
		RECT focus = lpdis->rcItem;
		::InflateRect(&focus, -3, -3);
		::DrawFocusRect(lpdis->hDC, &focus);
	}
}
void AwtButton::DrawWin95RadioAndCheckboxText(LPDRAWITEMSTRUCT lpdis)
{
	AwtFont* pFont = this->GetFont();
	if((m_pLabel != NULL ) && (pFont != NULL ))
	{
		VERIFY(m_pLabel);
		::SetTextColor(lpdis->hDC, m_ForegroundColor->GetColor());
		::SetBkColor(lpdis->hDC, m_BackgroundColor->GetColor());
		::SetBkMode(lpdis->hDC, TRANSPARENT);

		// 1 figure out the rect for the text
		RECT textrect = lpdis->rcItem;
		textrect.left += 18;

		// 2 draw the text
		m_pLabel->DrawText(lpdis->hDC, pFont ,&textrect, DT_LEFT);

		// 3 draw the focus box
		if(lpdis->itemState & ODS_FOCUS)
		{
			// 3.1 figure out hot big is the text
			SIZE size;
			m_pLabel->GetTextExtent(lpdis->hDC, pFont, &size);

			// 3.2 decide the rect of the focus base on the size of the text and rect
			RECT focus;
			focus.top =  (lpdis->rcItem.top + lpdis->rcItem.bottom - size.cy ) / 2 - 1;
			focus.bottom = focus.top + size.cy + 2;
			focus.left = lpdis->rcItem.left + 18 - 1;
			focus.right = focus.left + size.cx + 2;
			// 3.3 draw the focus box
			::DrawFocusRect(lpdis->hDC, &focus);
		}
	}
}
//
//	This function draw the Radiobutton in the case of WIN32 and running on Win95
//
void AwtButton::DrawWin95Radio(LPDRAWITEMSTRUCT lpdis)
{
	// 1. draw the rectangle with the background brush
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. caculate where to draw the radio bullet
	int top = ( lpdis->rcItem.top + lpdis->rcItem.bottom ) / 2 - 6;

	// 3. Draw center of the bullet (not the dot)
	if(lpdis->itemState & ODS_SELECTED)
		::SelectObject(	lpdis->hDC,	m_BackgroundColor->GetBrush());
	else
		::SelectObject(	lpdis->hDC,	::GetSysColorBrush(COLOR_WINDOW));
	::Ellipse(lpdis->hDC,	lpdis->rcItem.left+1 ,	top+1,
							lpdis->rcItem.left + 11,top+11);

	// 4. Draw the dot if checked
	if(m_checked)
	{
		::SelectObject(	lpdis->hDC,	m_ForegroundColor->GetBrush());
		
		::Ellipse(lpdis->hDC,	lpdis->rcItem.left+4,	top+4,
								lpdis->rcItem.left+8,	top+8);
	}

	// 5. Draw the Edge
	int x=lpdis->rcItem.left;
	int y=top;
	HPEN oldPen = (HPEN)::SelectObject(lpdis->hDC,
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW) ));
	
	POINT seg1[12]; 
	seg1[0].x=	x+9;	seg1[0].y=	y+1;
	seg1[1].x=	x+8;	seg1[1].y=	y+1;
	seg1[2].x=	x+7;	seg1[2].y=	y;
	seg1[3].x=	x+4;	seg1[3].y=	y;
	seg1[4].x=	x+3;	seg1[4].y=	y+1;
	seg1[5].x=	x+2;	seg1[5].y=	y+1;
	seg1[6].x=	x+1;	seg1[6].y=	y+2;
	seg1[7].x=	x+1;	seg1[7].y=	y+3;
	seg1[8].x=	x;		seg1[8].y=	y+4;
	seg1[9].x=	x;		seg1[9].y=	y+7;
	seg1[10].x=	x+1;	seg1[10].y=	y+8;
	seg1[11].x=	x+1;	seg1[11].y=	y+10;

	::Polyline(lpdis->hDC, seg1, 12);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DDKSHADOW))));

	POINT seg2[11];
	
	seg2[0].x = x+9;	seg2[0].y = y+2;
	seg2[1].x = x+8;	seg2[1].y = y+2;
	seg2[2].x = x+7;	seg2[2].y = y+1;
	seg2[3].x = x+4;	seg2[3].y = y+1;
	seg2[4].x = x+3;	seg2[4].y = y+2;
	seg2[5].x = x+2;	seg2[5].y = y+2;
	seg2[6].x = x+2;	seg2[6].y = y+3;
	seg2[7].x = x+1;	seg2[7].y = y+4;
	seg2[8].x = x+1;	seg2[8].y = y+7;
	seg2[9].x = x+2;	seg2[9].y = y+8;
	seg2[10].x =	x+2;	seg2[10].y = y+9;
	::Polyline(lpdis->hDC, seg2, 11);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DHILIGHT))));

	POINT seg3[12]; 
	seg3[0].x =	x+10; seg3[0].y =	y+2;
	seg3[1].x = 	x+10; seg3[1].y =	y+3;
	seg3[2].x = 	x+11; seg3[2].y =	y+4;
	seg3[3].x = 	x+11; seg3[3].y =	y+7; 
	seg3[4].x = 	x+10; seg3[4].y =	y+8;
	seg3[5].x = 	x+10; seg3[5].y =	y+9;
	seg3[6].x = 	x+9; seg3[6].y =	y+10;
	seg3[7].x = 	x+8; seg3[7].y =	y+10; 
	seg3[8].x = 	x+7; seg3[8].y =	y+11;
	seg3[9].x = 	x+4; seg3[9].y =	y+11;
	seg3[10].x = 	x+3; seg3[10].y =	y+10;
	seg3[11].x = 	x+1; seg3[11].y =	y+10;
	::Polyline(lpdis->hDC, seg3, 12);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DLIGHT))));

	POINT seg4[10];
	seg4[0].x =	x+9; seg4[0].y =  y+3;
	seg4[1].x =	x+10; seg4[1].y = 	y+4;
	seg4[2].x =	x+10; seg4[2].y = 	y+7;
	seg4[3].x =	x+9; seg4[3].y = 	y+8; 
	seg4[4].x =	x+9; seg4[4].y = 	y+9;
	seg4[5].x =	x+8; seg4[5].y = 	y+9;
	seg4[6].x =	x+7; seg4[6].y = 	y+10;
	seg4[7].x =	x+4; seg4[7].y = 	y+10; 
	seg4[8].x =	x+3; seg4[8].y = 	y+9;
	seg4[9].x =	x+1; seg4[9].y = 	y+9;
	::Polyline(lpdis->hDC, seg4, 10);

	::DeleteObject(::SelectObject(lpdis->hDC, oldPen));

	// 6 Daw the text
	this->DrawWin95RadioAndCheckboxText(lpdis);

}
//
//	This function draw the Checkbox in the case of WIN32 and running on Win95
//
void AwtButton::DrawWin95Checkbox(LPDRAWITEMSTRUCT lpdis)
{
	// 1. fill the rectangle with background color
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. figure out the rect for the box
	int t = ( lpdis->rcItem.top + lpdis->rcItem.bottom ) / 2 - 6;
	int b = t + 13;
	int l = lpdis->rcItem.left;
	int r = l + 13;
	// 3. draw the four edges
	HPEN oldPen = (HPEN)::SelectObject(lpdis->hDC,
		::CreatePen(PS_SOLID, 0,  ::GetSysColor(COLOR_3DHILIGHT)));

	POINT seg1[3];
	seg1[0].x = l; 		seg1[0].y = b-1;
	seg1[1].x = r-1; 	seg1[1].y = b-1;
	seg1[2].x = r-1; 	seg1[2].y = t-1;
	::Polyline(lpdis->hDC, seg1, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DLIGHT))));

	POINT seg2[3];
	seg2[0].x = l+1;	seg2[0].y = b-2;
	seg2[1].x = r-2;	seg2[1].y = b-2;
	seg2[2].x = r-2;	seg2[2].y = t;
	::Polyline(lpdis->hDC, seg2, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DSHADOW))));

	POINT seg3[3];
	seg3[0].x = l;		seg3[0].y = b-2;
	seg3[1].x = l;		seg3[1].y = t;
	seg3[2].x = r-1;	seg3[2].y = t;
	::Polyline(lpdis->hDC, seg3, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, 
		::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_3DDKSHADOW))));

	POINT seg4[3];
	seg4[0].x = l+1,	seg4[0].y = b-3;
	seg4[1].x = l+1,	seg4[1].y = t+1;
	seg4[2].x = r-2,	seg4[2].y = t+1;
	::Polyline(lpdis->hDC, seg4, 3);

	::DeleteObject(::SelectObject(lpdis->hDC, oldPen));

	// 4. fill the inside box with the right color
	RECT inbox = {l+2,t+2,r-2,b-2};
	if(lpdis->itemState & ODS_SELECTED)
		::FillRect(lpdis->hDC,  &inbox,	(HBRUSH) m_BackgroundColor->GetBrush() 	);
	else
		::FillRect(lpdis->hDC,  &inbox,	(HBRUSH) ::GetSysColorBrush(COLOR_WINDOW));

	// 5. if it is checked, draw the check
	if(m_checked)
	{
		// 5.1 get the check mark
		HBITMAP	checkmark = libi18n::GetCheckmarkBitmap();
		if(checkmark != NULL)
		{
			// 5.2 set the BkColor and TextColor 
			if(lpdis->itemState & ODS_SELECTED)
				::SetBkColor(lpdis->hDC,  m_BackgroundColor->GetColor() );
			else
				::SetBkColor(lpdis->hDC, ::GetSysColor(COLOR_WINDOW));
			::SetTextColor(lpdis->hDC, m_ForegroundColor->GetColor());
			// 5.3 do a DrawBitmap
			BITMAP bm;
			HDC	hdcMem;
			DWORD	dwSize;
			POINT	ptSize, ptOrg;
			hdcMem = ::CreateCompatibleDC(lpdis->hDC);
			::SelectObject(hdcMem, checkmark);
			::SetMapMode(hdcMem, GetMapMode(lpdis->hDC));
			::GetObject(checkmark, sizeof(BITMAP), (LPVOID)&bm);
			ptSize.x = bm.bmWidth;
			ptSize.y = bm.bmHeight;
			DPtoLP(lpdis->hDC, &ptSize, 1);
			ptOrg.x = 0;
			ptOrg.y = 0;
			DPtoLP(hdcMem, &ptOrg, 1);
			::BitBlt(lpdis->hDC, 
					l+2,t+2,
					ptSize.x, ptSize.y,
					hdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
			::DeleteDC(hdcMem);
		}
	}

	// 6 Daw the text
	this->DrawWin95RadioAndCheckboxText(lpdis);
}
#endif // _WIN32

BOOL AwtButton::DrawWin31Item(UINT idCtl, LPDRAWITEMSTRUCT lpdis)
{
	switch(m_dwButtonType)
	{
	case BS_PUSHBUTTON :	
		DrawWin31Button(lpdis);
		break;
	case BS_RADIOBUTTON :	
		DrawWin31Radio(lpdis);
		break;
	case BS_CHECKBOX :	
		DrawWin31Checkbox(lpdis);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

//
//	This function draw the Button for Win16 or WIN32 for NT 3.5
//
void AwtButton::DrawWin31Button(LPDRAWITEMSTRUCT lpdis)
{
	// 1. fill out the background rectangle
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. draw the four edge with RoundRect
	::SelectObject(	lpdis->hDC,	m_BackgroundColor->GetBrush());
	::RoundRect(lpdis->hDC,	lpdis->rcItem.left ,lpdis->rcItem.top ,
							lpdis->rcItem.right ,lpdis->rcItem.bottom,
							2, 2);

	// 3. draw the shadow of the four edges
	if(lpdis->itemState & ODS_SELECTED)
	{
		// 3.1 in the case of selected 

		HPEN oldPen = (HPEN)::SelectObject(lpdis->hDC, 
			::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)));

		POINT seg1[3];
		seg1[0].x = lpdis->rcItem.left+1;	
		seg1[0].y = lpdis->rcItem.bottom-2;
		seg1[1].x = lpdis->rcItem.left+1;	
		seg1[1].y = lpdis->rcItem.top+1;
		seg1[2].x = lpdis->rcItem.right-1;	
		seg1[2].y = lpdis->rcItem.top+1;
		::Polyline(lpdis->hDC, seg1, 3);

		::DeleteObject(::SelectObject(lpdis->hDC, oldPen));
	}
	else
	{
		// 3.2 in the case of normal 
		HPEN oldPen = (HPEN)::SelectObject(lpdis->hDC, 
			::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNSHADOW)));

		POINT seg2[3];
		seg2[0].x = lpdis->rcItem.left+1;
		seg2[0].y = lpdis->rcItem.bottom-2;
		seg2[1].x = lpdis->rcItem.right-2;
		seg2[1].y = lpdis->rcItem.bottom-2;
		seg2[2].x = lpdis->rcItem.right-2;
		seg2[2].y = lpdis->rcItem.top;
		::Polyline(lpdis->hDC, seg2, 3);

		POINT seg3[3];
		seg3[0].x = lpdis->rcItem.left+2;	
		seg3[0].y = lpdis->rcItem.bottom-3;
		seg3[1].x = lpdis->rcItem.right-3;
		seg3[1].y = lpdis->rcItem.bottom-3;
		seg3[2].x = lpdis->rcItem.right-3;
		seg3[2].y = lpdis->rcItem.top+1;
		::Polyline(lpdis->hDC, seg3, 3);

		HPEN shadowpen = (HPEN)::SelectObject(lpdis->hDC, 
			::CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNHIGHLIGHT)));
		::DeleteObject(shadowpen);

		
		POINT seg4[3];
		seg4[0].x = lpdis->rcItem.left+1;   
		seg4[0].y = lpdis->rcItem.bottom-3;
		seg4[1].x = lpdis->rcItem.left+1;
		seg4[1].y = lpdis->rcItem.top+1;
		seg4[2].x = lpdis->rcItem.right-2;
		seg4[2].y = lpdis->rcItem.top+1;
		::Polyline(lpdis->hDC, seg4, 3);

		POINT seg5[3];
		seg5[0].x = lpdis->rcItem.left+2;	
		seg5[0].y = lpdis->rcItem.bottom-4;
		seg5[1].x = lpdis->rcItem.left+2;
		seg5[1].y = lpdis->rcItem.top+2;
		seg5[2].x = lpdis->rcItem.right-3;
		seg5[2].y = lpdis->rcItem.top+2;
		::Polyline(lpdis->hDC, seg5, 3);

		::DeleteObject(::SelectObject(lpdis->hDC, oldPen));
	}

	// 4. draw the text
	AwtFont *pFont = this->GetFont();
	if((m_pLabel != NULL ) && (pFont != NULL ))
	{
		VERIFY(m_pLabel);

		// 4.1 decide the color first
		if(lpdis->itemState & ODS_DISABLED)
			::SetTextColor(lpdis->hDC, ::GetSysColor(COLOR_GRAYTEXT));
		else
			::SetTextColor(lpdis->hDC, m_ForegroundColor->GetColor());
		::SetBkMode(lpdis->hDC, TRANSPARENT);
		::SetBkColor(lpdis->hDC, m_BackgroundColor->GetColor());

		// 4.2 Find teh rect that we should draw the text
		RECT textrect = lpdis->rcItem;
		if(lpdis->itemState & ODS_SELECTED)
			::OffsetRect(&textrect, 1,1);

		// 4.3 draw the text
		m_pLabel->DrawText(lpdis->hDC, pFont ,&textrect, DT_CENTER);

		// 4.4 draw the focus if necessary
		if( (lpdis->itemState & ODS_FOCUS) && 
			!(lpdis->itemState & ODS_DISABLED))
		{
			// 4.4.1 figure out where should we draw the focus base on the size of the text
			SIZE size;
			m_pLabel->GetTextExtent(lpdis->hDC, pFont, &size);
			RECT focus;
			focus.top =  (lpdis->rcItem.top + lpdis->rcItem.bottom - size.cy ) / 2 ;
			focus.bottom = focus.top + size.cy + 1;
			focus.left = ( lpdis->rcItem.right + lpdis->rcItem.left - size.cx ) / 2 - 1;
			focus.right = focus.left + size.cx + 2;
			// 4.4.2 adjust it if it is selected
			if(lpdis->itemState & ODS_SELECTED)
				::OffsetRect(&focus, 1,1);
			// 4.4.3 draw the rect
			::DrawFocusRect(lpdis->hDC, &focus);
		}
	}
}
void AwtButton::DrawWin31RadioAndCheckboxText(LPDRAWITEMSTRUCT lpdis)
{
	AwtFont *pFont = this->GetFont();
	if((m_pLabel != NULL ) && (pFont != NULL ))
	{
		VERIFY(m_pLabel);
		// 1 set up the color
		if(lpdis->itemState & ODS_DISABLED)
			::SetTextColor(lpdis->hDC, ::GetSysColor(COLOR_GRAYTEXT));
		else
			::SetTextColor(lpdis->hDC, m_ForegroundColor->GetColor());
		::SetBkMode(lpdis->hDC, TRANSPARENT);
		::SetBkColor(lpdis->hDC, m_BackgroundColor->GetColor());

		// 2 figure out where to draw
		RECT textrect = lpdis->rcItem;
		textrect.left += 18;

		// 3 draw the text
		m_pLabel->DrawText(lpdis->hDC, pFont ,&textrect, DT_LEFT);

		// 4 draw the focus box if necessary
		if(lpdis->itemState & ODS_FOCUS)
		{
			// 4.1 decide the focus rect base on the size of the text
			SIZE size;
			m_pLabel->GetTextExtent(lpdis->hDC, pFont, &size);

			RECT focus;
			focus.top =  (lpdis->rcItem.top + lpdis->rcItem.bottom - size.cy ) / 2 - 1;
			focus.bottom = focus.top + size.cy + 2;
			focus.left = lpdis->rcItem.left + 18 - 1;
			focus.right = focus.left + size.cx + 2;

			// 4.2 draw the rectangle
			::DrawFocusRect(lpdis->hDC, &focus);
		}
	}
}
//
//	This function draw the Radio for Win16 or WIN32 for NT 3.5
//
void AwtButton::DrawWin31Radio(LPDRAWITEMSTRUCT lpdis)
{
	// 1. fill out the background rectangle
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. figure out where for the bullet
	int top = ( lpdis->rcItem.top + lpdis->rcItem.bottom ) / 2 - 6;

	// 3. draw the outter bullet
	::SelectObject(	lpdis->hDC,	m_BackgroundColor->GetBrush());
	::Ellipse(lpdis->hDC,	lpdis->rcItem.left,	top,
							lpdis->rcItem.left + 13,	top+13);	
	// 4. draw the inner bullet if selected
	if(lpdis->itemState & ODS_SELECTED)
	{
		::Ellipse(lpdis->hDC,	lpdis->rcItem.left + 1 ,	top + 1,
								lpdis->rcItem.left + 12 ,	top+12);
	}
	// 5. draw the dot if checked
	if(m_checked)
	{
		::SelectObject(	lpdis->hDC,	m_ForegroundColor->GetBrush());

		::Ellipse(lpdis->hDC,	lpdis->rcItem.left + 3 ,		top + 3,
								lpdis->rcItem.left + 10,	top+10);
	}
	// 6. draw the text
	this->DrawWin31RadioAndCheckboxText(lpdis);
}
//
//	This function draw the Checkbox for Win16 or WIN32 for NT 3.5
//
void AwtButton::DrawWin31Checkbox(LPDRAWITEMSTRUCT lpdis)
{
	// 1. fill out the background rectangle
	::FillRect(	lpdis->hDC,	&lpdis->rcItem,	m_BackgroundColor->GetBrush());

	// 2. figure out where for the bullet
	int top = ( lpdis->rcItem.top + lpdis->rcItem.bottom ) / 2 - 6;

	// 3. draw the outter box
	::SelectObject(	lpdis->hDC,	m_BackgroundColor->GetBrush());
	::Rectangle(lpdis->hDC,	lpdis->rcItem.left,	top,
							lpdis->rcItem.left + 13,	top+13);	
	// 4. draw the inner box
	if(lpdis->itemState & ODS_SELECTED)
		::Rectangle(lpdis->hDC,	lpdis->rcItem.left + 1 ,		top + 1,
								lpdis->rcItem.left + 12,	top+12);	
	// 5. draw the check
	if(m_checked)
	{
		::MoveToEx(lpdis->hDC,	lpdis->rcItem.left	, top,		NULL);
		::LineTo(lpdis->hDC,	lpdis->rcItem.left	+ 13, top+13);
		::MoveToEx(lpdis->hDC,	lpdis->rcItem.left	, top+12 ,	NULL);
		::LineTo(lpdis->hDC,	lpdis->rcItem.left	+ 12, top);
	}
	// 6. draw the text
	this->DrawWin31RadioAndCheckboxText(lpdis);
}
BOOL AwtButton::OnDrawItem(UINT idCtl, LPDRAWITEMSTRUCT lpdis)
{
#ifdef _WIN32
	if(libi18n::iswin95())
			return DrawWin95Item(idCtl, lpdis);
#endif	// _WIN32

	return DrawWin31Item(idCtl, lpdis);
}
BOOL AwtButton::OnDeleteItem(UINT idCtl, LPDELETEITEMSTRUCT lpdis)
{
	return FALSE;
}

#endif	// INTLUNICODE

//-------------------------------------------------------------------------
//
// Capture the mouse (if it's not the left button) so that mouse events 
// get re-direct to the proper component. 
// This allow MouseDrag to work correctly and MouseUp to be sent to the 
// component which received the mouse down.
// Left down is a special case because windows needs to handle that.
//
//-------------------------------------------------------------------------
void AwtButton::CaptureMouse(AwtButtonType button, UINT metakeys)
{
    // capture the mouse if it was not captured already.
    // This may happen because of a previous call to CaptureMouse
    // or because the left mouse was clicked and windows captured
    // the mouse for us.
    // Here we use m_nCaptured with a different semantic.
    // It's setted to 1 if SetCapture gets called, otherwise is 0
    if (button == AwtLeftButton)
        m_nCaptured = 0;
    else if (!(metakeys & MK_LBUTTON) && !m_nCaptured) {
        ::SetCapture(m_hWnd);
        m_nCaptured = 1;
    }
}


//-------------------------------------------------------------------------
//
// Release the mouse if it was captured previously. We might not have 
// captured the mouse at all if the left button is the first to be pressed
// and the last released
//
//-------------------------------------------------------------------------
BOOL AwtButton::ReleaseMouse(AwtButtonType button, UINT metakeys, int x, int y)
{
    // if at least the left button is pressed don't bother...
    if (!(metakeys & MK_LBUTTON)) {

        // check if no button is pressed and if we called SetCapture release it
        if (!(metakeys & MK_RBUTTON) && !(metakeys & MK_MBUTTON)) {
            if (m_nCaptured) {
                ::ReleaseCapture();
                m_nCaptured = 0;
            }
        }

        // the left button has just been released...
        else if (button == AwtLeftButton) {
            // ...see if there is any other button pressed...
            if ((metakeys & MK_RBUTTON) || (metakeys & MK_MBUTTON)) {
                    // Windows is giving up the mouse capture, it's time to take it. 
                    // Let the defproc do MouseUp first so it will release the mouse 
                    // before we capture otherwise WM_LBUTTONUP will release our capture
                    ::CallWindowProc(m_PrevWndProc, 
                                        m_hWnd, 
                                        WM_LBUTTONUP, 
                                        (WPARAM)metakeys, 
                                        MAKELPARAM(x, y));
                    ::SetCapture(m_hWnd);
                    m_nCaptured = 1;
                    return TRUE;
            }
        }

    }

    return FALSE;
}


//-------------------------------------------------------------------------
//
// Native method implementations for sun.awt.WButtonPeer
//
//-------------------------------------------------------------------------

extern "C" {

void
sun_awt_windows_WButtonPeer_create(HWButtonPeer *self, 
                                   HWComponentPeer *hParent)
{
    AwtButton    *pNewButton;

    CHECK_NULL(self,    "ButtonPeer is null.");
    CHECK_NULL(hParent, "ComponentPeer is null.");

    pNewButton = new AwtButton(self);
    CHECK_ALLOCATION(pNewButton);

// What about locking the new object??
    pNewButton->CreateWidget( pNewButton->GetParentWindowHandle(hParent) );
}


void
sun_awt_windows_WButtonPeer_setLabel(HWButtonPeer *self, 
                                     Hjava_lang_String *string)
{
    CHECK_PEER(self);
    if(string == NULL) //Do not use CHECK_NULL_AND_RETURN as this is
    {                  //a error condition to break to debugger
       return;
    }

    AwtButton *obj = GET_OBJ_FROM_PEER(AwtButton, self);

    obj->SetLabel(string);
}


void 
sun_awt_windows_WCheckboxPeer_create(HWCheckboxPeer* self,
                                     HWComponentPeer * hParent)
{
    AwtButton *pNewCheckbox;

    CHECK_NULL(self,    "ButtonPeer is null.");
    CHECK_NULL(hParent, "ComponentPeer is null.");

    pNewCheckbox = new AwtButton(self);
    CHECK_ALLOCATION(pNewCheckbox);

// What about locking the new object??
    pNewCheckbox->CreateWidget( pNewCheckbox->GetParentWindowHandle(hParent) );
}


void 
sun_awt_windows_WCheckboxPeer_setLabel(HWCheckboxPeer* self,
                                       Hjava_lang_String * string)
{
    CHECK_PEER(self);
    if(string == NULL) //Do not use CHECK_NULL_AND_RETURN as this is
    {                  //a error condition to break to debugger
       return;
    }

    AwtButton *obj = GET_OBJ_FROM_PEER(AwtButton, self);

    obj->SetLabel(string);
}


void 
sun_awt_windows_WCheckboxPeer_setState(HWCheckboxPeer* self,
                                      /*boolean*/ long lState)
{
    CHECK_PEER(self);

    AwtButton *obj = GET_OBJ_FROM_PEER(AwtButton, self);

    obj->SetState(lState);
}


void 
sun_awt_windows_WCheckboxPeer_setCheckboxGroup(HWCheckboxPeer* self,
                                               Hjava_awt_CheckboxGroup *)
{
    // not implemented!

    //CHECK_PEER(self);

    //AwtButton *obj = GET_OBJ_FROM_PEER(AwtButton, self);

    //obj->SetCheckboxGroup();
}


};  // end of extern "C"