www.pudn.com > ÍøÂç¶Ë¿Ú¼àÊÓ.rar > BCGPDateTimeCtrl.cpp


// BCGCalendarButton.cpp : implementation file 
// This is a part of the BCGControlBar Library 
// Copyright (C) 1998-2000 BCGSoft Ltd. 
// All rights reserved. 
// 
// This source code can be used, distributed or modified 
// only under terms and conditions  
// of the accompanying license agreement. 
// 
 
#include "stdafx.h" 
 
#ifndef BCG_NO_CALENDAR 
 
#include "BCGCBPro.h" 
#include "BCGPDateTimeCtrl.h" 
#include "BCGPCalendarBar.h" 
#include "CalendarPopup.h" 
#include "BCGPWinXPVisualManager.h" 
#include "BCGPToolbarComboBoxButton.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
static const int iSpinWidth = 15; 
static const int iDropButtonWidth = 17; 
static const int iSpinID = 1; 
static const COLORREF clrTransparent = RGB (255, 0, 255); 
 
static const int iFirstAllowedYear = 100;	// COleDateTime limitation 
static const int iLastAllowedYear = 9999;	// COleDateTime limitation 
 
static const UINT BCGDATETIME_HOLDTIMER = ::RegisterWindowMessage (_T("BCGDATETIME_HOLDTIMER")); 
 
const UINT		CBCGPDateTimeCtrl::DTM_SPIN			= 0x1; 
const UINT		CBCGPDateTimeCtrl::DTM_DATE			= 0x2; 
const UINT		CBCGPDateTimeCtrl::DTM_TIME			= 0x4; 
const UINT		CBCGPDateTimeCtrl::DTM_CHECKBOX		= 0x8; 
const UINT		CBCGPDateTimeCtrl::DTM_DROPCALENDAR = 0x10; 
const UINT		CBCGPDateTimeCtrl::DTM_TIME24H		= 0x20; 
const UINT		CBCGPDateTimeCtrl::DTM_CHECKED		= 0x40; 
const UINT		CBCGPDateTimeCtrl::DTM_TIME24HBYLOCALE = 0x80; 
 
static int GetDaysInMonth (int iMonth, int iYear) 
{ 
	static int nMonthLen [] =  
	{	 
		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31  
	}; 
 
	int nRes = nMonthLen [iMonth - 1]; 
	if (iMonth == 2 && iYear % 4 == 0 &&  
		(iYear % 100 != 0 || iYear % 400 == 0)) 
	{ 
		nRes = 29; 
	} 
 
	return nRes; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPDateTimeCtrl 
 
IMPLEMENT_DYNAMIC(CBCGPDateTimeCtrl, CButton) 
 
CBCGPDateTimeCtrl::CBCGPDateTimeCtrl() 
{ 
	m_checkButton = TRUE; 
	m_dropCalendar = TRUE; 
	m_showDate = TRUE; 
	m_showTime = TRUE; 
	m_spinButton = TRUE; 
 
	m_type2DigitsInYear = TRUE; 
	m_maxYear2Digits = 2090; 
 
	m_bCheckBoxIsAvailable = FALSE; 
	m_iPartNum = 0; 
	m_bIsChecked = TRUE; 
	m_Date = COleDateTime::GetCurrentTime (); 
	m_iPrevDigit = -1; 
 
	m_bShowSelection = FALSE; 
	m_bDropButtonIsPressed = FALSE; 
 
	m_pPopup = NULL; 
 
	m_bDropButtonIsPressed = FALSE; 
	m_bMouseOnDropButton = FALSE; 
 
	for (int i = 0; i < MAX_PARTS; i ++) 
	{ 
		m_arPartRects [i].SetRectEmpty (); 
	} 
 
	m_rectText.SetRectEmpty (); 
	m_bAutoResize = TRUE; 
 
	m_iControlWidth = 0; 
	m_iControlHeight = 0; 
 
	m_iYearPos = 0; 
	m_monthFormat = 0; 
 
	m_MinDate = COleDateTime (iFirstAllowedYear, 1, 1, 0, 0, 0); 
	m_MaxDate = COleDateTime (iLastAllowedYear, 12, 31, 23, 59, 59); 
 
	m_weekStart = 1; 
	m_b24HoursByLocale = TRUE; 
 
	m_hFont	= NULL; 
	m_bIsInitialized = FALSE; 
 
	m_bDrawDateTimeOnly = FALSE; 
 
	m_colorText = (COLORREF)-1; 
} 
 
CBCGPDateTimeCtrl::~CBCGPDateTimeCtrl() 
{ 
} 
 
BEGIN_MESSAGE_MAP(CBCGPDateTimeCtrl, CButton) 
	//{{AFX_MSG_MAP(CBCGPDateTimeCtrl) 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_MOUSEMOVE() 
	ON_WM_CREATE() 
	ON_WM_GETDLGCODE() 
	ON_WM_RBUTTONDOWN() 
	ON_WM_RBUTTONUP() 
	ON_WM_KEYDOWN() 
	ON_WM_SETFOCUS() 
	ON_WM_KILLFOCUS() 
	ON_WM_ERASEBKGND() 
	ON_WM_NCCALCSIZE() 
	ON_WM_NCPAINT() 
	ON_WM_SETCURSOR() 
	ON_WM_SIZE() 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(WM_SETFONT, OnSetFont) 
	ON_MESSAGE(WM_GETFONT, OnGetFont) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPDateTimeCtrl message handlers 
 
void CBCGPDateTimeCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS)  
{ 
	ASSERT (lpDIS != NULL); 
	ASSERT (lpDIS->CtlType == ODT_BUTTON); 
 
	CDC* pDC = CDC::FromHandle (lpDIS->hDC); 
	ASSERT_VALID (pDC); 
 
	CBCGPDefaultLocale dl; 
 
	CRect rectClient = lpDIS->rcItem; 
 
	pDC->FillSolidRect (&rectClient,  
		IsWindowEnabled () ? globalData.clrWindow : globalData.clrBtnFace); 
 
	pDC->SetBkMode (TRANSPARENT); 
 
	CFont* pPrevFont = m_hFont == NULL ? 
		(CFont*) pDC->SelectStockObject (DEFAULT_GUI_FONT) : 
		pDC->SelectObject (CFont::FromHandle (m_hFont)); 
	ASSERT (pPrevFont != NULL); 
 
	if (!m_bDrawDateTimeOnly) 
	{ 
		// Draw check box: 
		DrawCheckBox (pDC, lpDIS->itemState); 
 
		// Draw "Drop Date combo" button: 
		DrawDateDropButton (pDC, lpDIS->itemState); 
	} 
 
	// Draw date/time parts: 
	int iStart = m_bCheckBoxIsAvailable ? 1 : 0; 
 
	for (int i = iStart; i < m_iPartsNumber; i ++) 
	{ 
		CString str = m_Date.Format (GetPartFormat (i)); 
		CRect rect = m_arPartRects [i]; 
 
		if (m_bIsChecked && m_bShowSelection && i == m_iPartNum)	// Selected part 
		{ 
			CRect rectFill = rect; 
			pDC->DrawText (str, rectFill,  
				DT_SINGLELINE | DT_VCENTER | DT_CENTER | DT_CALCRECT); 
 
			int iOffset = (m_rectText.Height () - rectFill.Height ()) / 2; 
 
			rectFill.OffsetRect ((rect.Width () - rectFill.Width ()) / 2, iOffset); 
 
			pDC->FillSolidRect (rectFill, globalData.clrHilite); 
			pDC->SetTextColor (globalData.clrTextHilite); 
		} 
		else 
		{ 
			pDC->SetTextColor (m_bIsChecked && IsWindowEnabled () ?  
					(m_colorText == (COLORREF)-1 ? globalData.clrWindowText : m_colorText) :  
					globalData.clrGrayedText); 
		} 
 
		pDC->DrawText (str, rect, DT_SINGLELINE | DT_VCENTER | DT_CENTER); 
 
		//----------------- 
		// Draw separator: 
		//----------------- 
		if (i < m_iPartsNumber - 1) 
		{ 
			CString strSeparator = _T(" "); 
 
			if (IsDatePart (i) && IsDatePart (i + 1)) 
			{ 
				strSeparator = m_strDateSeparator; 
			} 
 
			if (IsTimePart (i) && IsTimePart (i + 1)) 
			{ 
				strSeparator = m_strTimeSeparator; 
			} 
		 
			rect.left = m_arPartRects [i].right; 
			rect.right = m_arPartRects [i + 1].left; 
 
			pDC->SetTextColor (m_bIsChecked && IsWindowEnabled () ?  
					(m_colorText == (COLORREF)-1 ? globalData.clrWindowText : m_colorText) :  
					globalData.clrGrayedText); 
			pDC->DrawText (strSeparator, rect, DT_SINGLELINE | DT_VCENTER); 
		} 
	} 
 
	pDC->SelectObject (pPrevFont); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::OnShowCalendarPopup ()  
{ 
	if (!m_dropCalendar) 
		return; 
 
	if (m_pPopup != NULL) 
	{ 
		m_pPopup->SendMessage (WM_CLOSE); 
		m_pPopup = NULL; 
		return; 
	} 
 
	m_pPopup = new CCalendarPopup (this,  m_Date); 
	m_pPopup->m_bEnabledInCustomizeMode = m_bEnabledInCustomizeMode; 
 
	m_bDropButtonIsPressed = TRUE; 
	RedrawWindow (m_rectDropButton); 
 
	CRect rectWindow; 
	GetWindowRect (rectWindow); 
 
	if (!m_pPopup->Create (this, rectWindow.left, rectWindow.bottom, NULL, TRUE)) 
	{ 
		ASSERT (FALSE); 
		m_pPopup = NULL; 
 
		TRACE(_T ("Calendar menu can't be used in the customization mode. You need to set CBCGPDateTimeCtrl::m_bEnabledInCustomizeMode\n")); 
	} 
	else 
	{ 
        SetFirstDayOfWeek(m_weekStart - 1); 
 
		if (m_bEnabledInCustomizeMode) 
		{ 
	        CBCGPCalendarBar* pCalendarBar = DYNAMIC_DOWNCAST ( 
		        CBCGPCalendarBar, m_pPopup->GetMenuBar()); 
 
			if (pCalendarBar != NULL) 
			{ 
				ASSERT_VALID (pCalendarBar); 
				pCalendarBar->m_bInternal = TRUE; 
			} 
		} 
 
		if (m_bAutoSetFocus) 
		{ 
			m_pPopup->GetMenuBar()->SetFocus (); 
		} 
	} 
} 
//************************************************************************************ 
void CBCGPDateTimeCtrl::OnLButtonDown(UINT /*nFlags*/, CPoint point)  
{ 
	m_iPrevDigit = -1; 
 
	int iPrevPart = m_iPartNum; 
 
	SetFocus (); 
 
	if (m_rectDropButton.PtInRect (point)) 
	{ 
		if (m_dropCalendar && m_bIsChecked && m_showDate) 
		{ 
			m_bDropButtonIsPressed = TRUE; 
 
			SetCapture (); 
			RedrawWindow (m_rectDropButton); 
 
			OnShowCalendarPopup (); 
		} 
 
		return; 
	} 
 
	int iPartNum = GetPartFromPoint (point); 
	if (iPartNum == -1) 
	{ 
		m_CurrPartType = NO; 
 
		if (m_rectText.PtInRect (point)) 
		{ 
			do 
			{ 
				point.x++; 
 
				if (point.x > m_rectText.right) 
				{ 
					return; 
				} 
 
				iPartNum = GetPartFromPoint (point); 
			} 
			while (iPartNum == -1); 
		} 
		else 
		{ 
			return; 
		} 
	} 
 
	if (!m_bIsChecked && 
		m_arPartsOrder [iPartNum] != CHECK_BOX) 
	{ 
		return; 
	} 
 
	m_iPartNum = iPartNum; 
	m_CurrPartType = m_arPartsOrder [m_iPartNum]; 
 
	if (m_CurrPartType == CHECK_BOX) 
	{ 
		ToggleCheck (); 
	} 
 
	if (iPrevPart != m_iPartNum) 
	{ 
		CRect rectPrevPart = m_arPartRects [iPrevPart]; 
		rectPrevPart.InflateRect (1, 1); 
		RedrawWindow (rectPrevPart); 
 
		CRect rectPart = m_arPartRects [m_iPartNum]; 
		rectPart.InflateRect (1, 1); 
		RedrawWindow (rectPart); 
	} 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/)  
{ 
	if (m_bDropButtonIsPressed) 
	{ 
		m_bDropButtonIsPressed = FALSE; 
		RedrawWindow (m_rectDropButton); 
 
		if (GetCapture () == this) 
		{ 
			ReleaseCapture (); 
		} 
 
		ASSERT (m_pPopup != NULL); 
		m_pPopup->SetFocus (); 
	} 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	CButton::OnMouseMove(nFlags, point); 
} 
//**************************************************************************************** 
int CBCGPDateTimeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	BOOL bRC; 
 
	if (CButton::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	 
	CRect rectSpin (0, 0, 1, 1); 
	bRC = m_wndSpin.Create (WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_AUTOBUDDY, 
						rectSpin, this, iSpinID); 
	if (!bRC) 
	{ 
		TRACE (_T ("IETDateTimeCtrl: Can't create spin button!\n")); 
		return -1; 
	} 
 
	CRect rectClient; 
	GetClientRect (rectClient); 
 
	AdjustControl (rectClient); 
	return 0; 
} 
//**************************************************************************************** 
UINT CBCGPDateTimeCtrl::OnGetDlgCode()  
{ 
	return DLGC_WANTARROWS | DLGC_WANTCHARS; 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnRButtonDown(UINT /*nFlags*/, CPoint /*point*/)  
{ 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnRButtonUp(UINT /*nFlags*/, CPoint /*point*/)  
{ 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	if (!IsWindowEnabled ()) 
	{ 
		return; 
	} 
 
	if (isdigit (nChar)) 
	{ 
		PushDigit (nChar - '0'); 
		return; 
	} 
 
	if (nChar >= VK_NUMPAD0 && nChar <= VK_NUMPAD9) 
	{ 
		PushDigit (nChar - VK_NUMPAD0); 
		return; 
	} 
 
	if (isalpha (nChar)) 
	{ 
		switch (m_CurrPartType) 
		{ 
		case MONTH: 
			if (m_monthFormat != 2) 
			{ 
				ChangeMonth (nChar); 
			} 
			break; 
 
		case AMPM: 
			ChangeAmPm (nChar); 
			break; 
		} 
 
		return; 
	} 
 
	m_iPrevDigit = -1; 
 
	switch (nChar) 
	{ 
	case VK_DOWN: 
		ScrollCurrPart (-1); 
		break; 
 
	case VK_UP: 
		ScrollCurrPart (1); 
		break; 
 
	case VK_RIGHT: 
		SelectNext (); 
		break; 
 
	case VK_LEFT: 
		SelectPrev (); 
		break; 
 
	case VK_HOME: 
		ScrollCurrPartToLimit (TRUE); 
		break; 
 
	case VK_END: 
		ScrollCurrPartToLimit (FALSE); 
		break; 
 
	case VK_SPACE: 
		if (m_CurrPartType == CHECK_BOX) 
		{ 
			ToggleCheck (); 
		} 
		else if (m_CurrPartType == AMPM) 
		{ 
			ScrollCurrPart (1); 
		} 
		break; 
	} 
	 
	CButton::OnKeyDown(nChar, nRepCnt, nFlags); 
} 
//**************************************************************************************** 
DATE CBCGPDateTimeCtrl::GetDate()  
{ 
	if (m_bIsChecked) 
	{ 
		COleDateTime today = COleDateTime::GetCurrentTime (); 
 
		COleDateTime date (	m_showDate ? m_Date.GetYear () : today.GetYear (),  
							m_showDate ? m_Date.GetMonth () : today.GetMonth (),  
							m_showDate ? m_Date.GetDay () :  today.GetDay (), 
							m_showTime ? m_Date.GetHour () : 0, 
							m_showTime ? m_Date.GetMinute () : 0, 
							0);	// Always clear seconds 
		return (DATE) date; 
	} 
	else 
	{ 
		COleDateTime dateEmpty; 
		return (DATE) dateEmpty; 
	} 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::SetDate(DATE newValue)  
{ 
	m_Date = COleDateTime (newValue); 
 
	if (m_bCheckBoxIsAvailable) 
	{ 
		COleDateTime dateEmpty; 
		m_bIsChecked = (m_Date != dateEmpty); 
 
		if (m_spinButton) 
		{ 
			m_wndSpin.EnableWindow (m_bIsChecked); 
		} 
	} 
 
	RedrawWindow (); 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::SetMinDate(DATE newValue)  
{ 
	COleDateTime dateMin = newValue; 
	COleDateTime dateEmpty; 
 
	if (m_MaxDate > dateMin || m_MaxDate == dateEmpty) 
	{ 
		m_MinDate = dateMin; 
 
		if (m_Date < m_MinDate) 
		{ 
			m_Date = m_MinDate; 
			OnDateChanged (); 
		} 
 
		RedrawWindow (); 
	} 
} 
//**************************************************************************************** 
DATE CBCGPDateTimeCtrl::GetMaxDate()  
{ 
	return (DATE) m_MaxDate; 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::SetMaxDate(DATE newValue)  
{ 
	COleDateTime dateMax = newValue; 
	COleDateTime dateEmpty; 
 
	if (m_MinDate < dateMax) 
	{ 
		m_MaxDate = dateMax; 
 
		if (m_MaxDate.GetHour () == 0 && m_MaxDate.GetMinute () == 0) 
		{ 
			m_MaxDate -= COleDateTimeSpan (0, 0, 1, 0);	// 1 minute before 
		} 
 
		if (m_Date > m_MaxDate && m_MaxDate != dateEmpty) 
		{ 
			m_Date = m_MaxDate; 
			OnDateChanged (); 
		} 
 
		RedrawWindow (); 
	} 
} 
//************************************************************************************************ 
void CBCGPDateTimeCtrl::AdjustControl (CRect rectClient) 
{ 
	if (GetSafeHwnd () == NULL)	// Control doesn't created yet (e.g., AppStudio) 
	{ 
		return; 
	} 
 
	CClientDC dc (this); 
 
	CFont* pPrevFont = m_hFont == NULL ? 
		(CFont*) dc.SelectStockObject (DEFAULT_GUI_FONT) : 
		dc.SelectObject (CFont::FromHandle (m_hFont)); 
	ASSERT (pPrevFont != NULL); 
 
	if (m_WidestDate == COleDateTime ()) 
	{ 
		BuidWidestDate (&dc); 
	} 
 
	SetPartsOrder (); 
	 
	m_iPartNum = m_bCheckBoxIsAvailable ? 1 : 0; 
	m_CurrPartType = m_arPartsOrder [m_iPartNum]; 
 
	m_rectText = rectClient; 
	m_rectText.InflateRect (0, -2); 
 
	if (m_bAutoResize) 
	{ 
		// Calculate text size: 
		TEXTMETRIC tm; 
 
		dc.GetTextMetrics (&tm); 
 
		m_iControlHeight = tm.tmHeight + 6; 
	} 
	else 
	{ 
		m_iControlHeight = rectClient.Height (); 
	} 
 
	if (m_bCheckBoxIsAvailable) 
	{ 
		m_rectCheck = CRect (rectClient.left + 1, rectClient.top + 1,  
			rectClient.left + m_iControlHeight - 1, rectClient.top + m_iControlHeight - 1); 
		m_rectText.left = m_rectCheck.right + 2; 
	} 
	 
	m_rectText.top = rectClient.top; 
	m_rectText.bottom = rectClient.top + m_iControlHeight; 
 
	// Calculate parts: 
	CalcPartRects (&dc); 
 
	// Adjust control size: 
	m_rectText.right = m_arPartRects [m_iPartsNumber - 1].right + 2; 
	m_iControlWidth = m_rectText.right; 
 
	if (m_spinButton) 
	{ 
		m_iControlWidth += iSpinWidth; 
	} 
 
	if (!m_bAutoResize) 
	{ 
		m_iControlWidth = rectClient.Width (); 
		m_iControlHeight = rectClient.Height (); 
	} 
 
	if (m_dropCalendar && m_showDate) 
	{ 
		if (m_bAutoResize) 
		{ 
			m_iControlWidth += iDropButtonWidth; 
		} 
 
		int iDropStart = rectClient.left + m_iControlWidth - iDropButtonWidth; 
		if (m_spinButton) 
		{ 
			iDropStart -= iSpinWidth - 1; 
		} 
 
		m_rectDropButton = CRect (	iDropStart, 
									rectClient.top, 
									iDropStart + iDropButtonWidth, 
									rectClient.top + m_iControlHeight); 
	} 
 
	if (m_bAutoResize) 
	{ 
		SetWindowPos (NULL, -1, -1, m_iControlWidth + 2, m_iControlHeight + 2, 
			SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); 
	} 
 
	// Adjust spin button: 
	if (m_spinButton) 
	{ 
		if (m_wndSpin.GetSafeHwnd () == NULL) 
		{ 
			m_wndSpin.Create (WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_AUTOBUDDY, 
						CRect (0, 0, 0, 0), this, iSpinID); 
		} 
 
		m_wndSpin.SetWindowPos (NULL,  
				rectClient.left + m_iControlWidth - iSpinWidth, rectClient.top, 
				iSpinWidth, m_iControlHeight, 
				SWP_NOZORDER); 
		m_wndSpin.ShowWindow (SW_SHOW); 
 
		m_wndSpin.EnableWindow (IsWindowEnabled () && m_bIsChecked); 
	} 
	else 
	{ 
		m_wndSpin.SetWindowPos (NULL,  
				0, 0, 
				0, 0, 
				SWP_NOZORDER); 
		m_wndSpin.ShowWindow (SW_HIDE); 
	} 
 
	dc.SelectObject (pPrevFont); 
 
	//----------------------------- 
	// Adjust min./max date values: 
	//----------------------------- 
	COleDateTime minAllowedDate (iFirstAllowedYear, 1, 1, 0, 0, 0); 
	COleDateTime maxAllowedDate (iLastAllowedYear, 12, 31, 23, 59, 59); 
	COleDateTime emptyDate; 
 
	m_MinDate = max (m_MinDate, minAllowedDate); 
 
	if (m_MaxDate != emptyDate) 
	{ 
		m_MaxDate = min (m_MaxDate, maxAllowedDate); 
	} 
	else 
	{ 
		m_MaxDate = maxAllowedDate; 
	} 
 
	RedrawWindow (); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::DrawCheckBox (CDC* pDC, UINT uiState) 
{ 
	if (!m_bCheckBoxIsAvailable) 
	{ 
		return; 
	} 
 
	ASSERT_VALID (pDC); 
 
	CBCGPVisualManager::GetInstance ()->OnDrawCheckBox (pDC, m_rectCheck,  
		m_bShowSelection && m_CurrPartType == CHECK_BOX,  
		m_bIsChecked, !(uiState & ODS_DISABLED)); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::DrawDateDropButton (CDC* pDC, UINT uiState) 
{ 
	if (!m_dropCalendar || !m_showDate) 
	{ 
		return; 
	} 
 
	CBCGPToolbarComboBoxButton buttonDummy; 
	CBCGPVisualManager::GetInstance ()->OnDrawComboDropButton (pDC, m_rectDropButton, 
										(uiState & ODS_DISABLED) || !m_bIsChecked, 
										m_bDropButtonIsPressed, 
										m_bMouseOnDropButton, 
										&buttonDummy); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::SelectNext () 
{ 
	if (m_iPartNum == -1 || !m_bIsChecked) 
	{ 
		return; 
	} 
 
	int iPrevPart = m_iPartNum; 
 
	if (m_iPartNum == m_iPartsNumber - 1)	// Last 
	{ 
		m_iPartNum = 0; 
	} 
	else 
	{ 
		m_iPartNum ++; 
	} 
 
	m_CurrPartType = m_arPartsOrder [m_iPartNum]; 
 
	CRect rectPrevPart = m_arPartRects [iPrevPart]; 
	rectPrevPart.InflateRect (1, 1); 
	RedrawWindow (rectPrevPart); 
 
	CRect rectPart = m_arPartRects [m_iPartNum]; 
	rectPart.InflateRect (1, 1); 
	RedrawWindow (rectPart); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::SelectPrev () 
{ 
	if (m_iPartNum == -1 || !m_bIsChecked) 
	{ 
		return; 
	} 
 
	int iPrevPart = m_iPartNum; 
 
	if (m_iPartNum == 0)	// First 
	{ 
		m_iPartNum = m_iPartsNumber - 1; 
	} 
	else 
	{ 
		m_iPartNum --; 
	} 
 
	m_CurrPartType = m_arPartsOrder [m_iPartNum]; 
 
	CRect rectPrevPart = m_arPartRects [iPrevPart]; 
	rectPrevPart.InflateRect (1, 1); 
	RedrawWindow (rectPrevPart); 
 
	CRect rectPart = m_arPartRects [m_iPartNum]; 
	rectPart.InflateRect (1, 1); 
	RedrawWindow (rectPart); 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::SetPartsOrder () 
{ 
	int i = 0; 
 
	if (m_checkButton) 
	{ 
		m_arPartsOrder [i ++] = CHECK_BOX; 
		m_bCheckBoxIsAvailable = TRUE; 
	} 
	else 
	{ 
		m_bCheckBoxIsAvailable = FALSE; 
	} 
 
	TCHAR szLocaleData [100]; 
	 
	GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SDATE, szLocaleData, 100); 
	m_strDateSeparator = szLocaleData [0] == 0 ? _T ("") : szLocaleData; 
 
	GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_STIME, szLocaleData, 100); 
	m_strTimeSeparator = szLocaleData [0] == 0 ? _T ("") : szLocaleData; 
 
	if (m_showDate) 
	{ 
		GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_IDATE, szLocaleData, 100); 
		switch (szLocaleData [0]) 
		{ 
		case '0':	// Month-Day-Year 
		default: 
			m_arPartsOrder [i ++] = MONTH; 
			m_arPartsOrder [i ++] = DAY; 
			m_arPartsOrder [i ++] = YEAR; 
			break; 
 
		case '1':	// Day-Month-Year 
			m_arPartsOrder [i ++] = DAY; 
			m_arPartsOrder [i ++] = MONTH; 
			m_arPartsOrder [i ++] = YEAR; 
			break; 
 
		case '2':	// Year-Month-Day 
			m_arPartsOrder [i ++] = YEAR; 
			m_arPartsOrder [i ++] = MONTH; 
			m_arPartsOrder [i ++] = DAY; 
			break; 
		} 
	} 
 
	if (m_showTime) 
	{ 
		m_arPartsOrder [i ++] = HOUR; 
		m_arPartsOrder [i ++] = MIN; 
 
		if (m_b24HoursByLocale) 
		{ 
			GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_ITIME, szLocaleData, 100); 
			switch (szLocaleData [0]) 
			{ 
			case '0':	// AM/PM 
			default: 
				m_b24HoursFormat = FALSE; 
				break; 
			case '1': 
				m_b24HoursFormat = TRUE; 
				break; 
			} 
		} 
 
		if (!m_b24HoursFormat) 
		{ 
			m_arPartsOrder [i ++] = AMPM; 
		} 
	} 
 
	m_iPartsNumber = i; 
 
	GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S1159, szLocaleData, 100); 
	m_strAM = szLocaleData; 
	m_strAM.MakeUpper (); 
	GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_S2359, szLocaleData, 100); 
	m_strPM = szLocaleData; 
	m_strPM.MakeUpper (); 
} 
//***************************************************************************************** 
LPCTSTR CBCGPDateTimeCtrl::GetPartFormat (int iPart) const 
{ 
	switch (m_arPartsOrder [iPart]) 
	{ 
	case NO: 
	case CHECK_BOX: 
		return _T (""); 
	case DAY: 
		return _T ("%d"); 
	case MONTH: 
		switch (m_monthFormat) 
		{ 
		case 0:	// Short: 
			return _T ("%b"); 
		case 1:	// Long: 
			return _T ("%B"); 
		case 2:	// Numeric: 
			return _T ("%m"); 
		default: 
			ASSERT (FALSE); 
			return _T ("%b"); 
		} 
 
	case YEAR: 
		return _T ("%Y"); 
	case HOUR: 
		return m_b24HoursFormat ? _T ("%H") : _T ("%I"); 
	case MIN: 
		return _T ("%M"); 
	case AMPM: 
		return _T ("%p"); 
	} 
 
	return _T (""); 
} 
//***************************************************************************************** 
int CBCGPDateTimeCtrl::GetPartFromPoint (POINT point) 
{ 
	for (int i = 0; i < m_iPartsNumber; i ++) 
	{ 
		if (m_arPartRects [i].PtInRect (point)) 
		{ 
			return i; 
		} 
	} 
 
	return -1; 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::CalcPartRects (CDC* pDC) 
{ 
	ASSERT_VALID (pDC); 
 
	CBCGPDefaultLocale dl; 
 
	int iStart = 0; 
	if (m_arPartsOrder [0] == CHECK_BOX) 
	{ 
		m_arPartRects [0] = m_rectCheck; 
		iStart = 1; 
	} 
 
	int x = m_rectText.left; 
 
	for (int i = iStart; i < m_iPartsNumber; i ++) 
	{ 
		CString strPart = m_WidestDate.Format (GetPartFormat (i)); 
 
		m_arPartRects [i] = m_rectText; 
		m_arPartRects [i].left = x; 
		m_arPartRects [i].right = x + pDC->GetTextExtent (strPart).cx; 
 
		//----------------------- 
		// Calc. separator width: 
		//----------------------- 
		CString strSeparator = _T(" "); 
		if (i < m_iPartsNumber - 1) 
		{ 
			if (IsDatePart (i) && IsDatePart (i + 1)) 
			{ 
				strSeparator = m_strDateSeparator; 
			} 
 
			if (IsTimePart (i) && IsTimePart (i + 1)) 
			{ 
				strSeparator = m_strTimeSeparator; 
			} 
		} 
 
		x = m_arPartRects [i].right + pDC->GetTextExtent (strSeparator).cx; 
	} 
 
	// Clean rest: 
	while (i < MAX_PARTS) 
	{ 
		m_arPartRects [i ++].SetRectEmpty (); 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::ScrollCurrPart (int iDir) 
{ 
	int iDay = m_Date.GetDay (); 
	int iMonth = m_Date.GetMonth (); 
	int iYear = m_Date.GetYear (); 
	int iHour = m_Date.GetHour (); 
	int iMin = m_Date.GetMinute (); 
	BOOL bLastDayInMonth = (iDay == GetDaysInMonth (iMonth, iYear)); 
 
	switch (m_CurrPartType) 
	{ 
	case NO: 
	case CHECK_BOX: 
		return; 
 
	case DAY: 
		iDay += iDir; 
		if (iDay <= 0) 
		{ 
			iDay = GetDaysInMonth (iMonth, iYear); 
		} 
 
		if (iDay > GetDaysInMonth (iMonth, iYear)) 
		{ 
			iDay = 1; 
		} 
		break; 
 
	case MONTH: 
		iMonth += iDir; 
		if (iMonth <= 0) 
		{ 
			iMonth = 12; 
		} 
 
		if (iMonth > 12) 
		{ 
			iMonth = 1; 
		} 
		 
		if (bLastDayInMonth || 
			iDay > GetDaysInMonth (iMonth, iYear)) 
		{ 
			iDay = GetDaysInMonth (iMonth, iYear); 
		} 
 
		break; 
 
	case YEAR: 
		iYear += iDir; 
 
		if (iDay > GetDaysInMonth (iMonth, iYear)) 
		{ 
			iDay = GetDaysInMonth (iMonth, iYear); 
		} 
 
		break; 
 
	case HOUR: 
		iHour += iDir; 
		if (iHour < 0) 
		{ 
			iHour = 23; 
		} 
 
		if (iHour > 23) 
		{ 
			iHour = 0; 
		} 
		break; 
 
	case MIN: 
		iMin += iDir; 
		if (iMin < 0) 
		{ 
			iMin = 59; 
		} 
 
		if (iMin > 59) 
		{ 
			iMin = 0; 
		} 
		break; 
 
	case AMPM: 
		if (iHour < 12) 
		{ 
			iHour += 12; 
		} 
		else 
		{ 
			iHour -= 12; 
		} 
	} 
 
	COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0); 
	COleDateTime dateEmpty; 
 
	if (iDir > 0 && date > m_MaxDate && m_MaxDate != dateEmpty) 
	{ 
		date = m_MaxDate; 
	} 
 
	if (iDir < 0 && date < m_MinDate) 
	{ 
		date = m_MinDate; 
	} 
 
	if (m_Date != date && IsDateValid (date)) 
	{ 
		m_Date = date; 
		RedrawWindow (m_rectText); 
 
		OnDateChanged (); 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::ScrollCurrPartToLimit (BOOL bTop) 
{ 
	int iDay = m_Date.GetDay (); 
	int iMonth = m_Date.GetMonth (); 
	int iYear = m_Date.GetYear (); 
	int iHour = m_Date.GetHour (); 
	int iMin = m_Date.GetMinute (); 
 
	switch (m_CurrPartType) 
	{ 
	case NO: 
	case CHECK_BOX: 
	case AMPM: 
	case YEAR: 
		return; 
 
	case DAY: 
		if (bTop) 
		{ 
			iDay = 1; 
		} 
		else 
		{ 
			iDay = GetDaysInMonth (iMonth, iYear); 
		} 
		break; 
 
	case MONTH: 
		if (bTop) 
		{ 
			iMonth = 1; 
		} 
		else 
		{ 
			iMonth = 12; 
		} 
		break; 
 
	case HOUR: 
		if (bTop) 
		{ 
			iHour = 0; 
		} 
		else 
		{ 
			iHour = 23; 
		} 
		break; 
 
	case MIN: 
		if (bTop) 
		{ 
			iMin = 0; 
		} 
		else 
		{ 
			iMin = 59; 
		} 
		break; 
	} 
 
	COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0); 
	if (IsDateValid (date) && m_Date != date) 
	{ 
		m_Date = date; 
		RedrawWindow (m_rectText); 
 
		OnDateChanged (); 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::PushDigit (int iDigit) 
{ 
	int iDay = m_Date.GetDay (); 
	int iMonth = m_Date.GetMonth (); 
	int iYear = m_Date.GetYear (); 
	int iHour = m_Date.GetHour (); 
	int iMin = m_Date.GetMinute (); 
 
	const int iYearDigits = m_type2DigitsInYear ? 2 : 4; 
 
	int iNumber; 
	if (m_iPrevDigit == -1) 
	{ 
		iNumber = iDigit; 
		m_iYearPos = 0; 
	} 
	else 
	{ 
		iNumber = m_iPrevDigit * 10 + iDigit; 
	} 
 
	switch (m_CurrPartType) 
	{ 
	case NO: 
	case CHECK_BOX: 
	case AMPM: 
		return; 
 
	case DAY: 
		iDay = iNumber; 
		break; 
 
	case HOUR: 
		if (!m_b24HoursFormat) 
		{ 
			BOOL bPM = (iHour >= 12); 
			iHour = iNumber; 
 
			if (iHour > 12) 
			{ 
				iHour = iDigit; 
			} 
 
			if (bPM) 
			{ 
				iHour += 12; 
			} 
 
			if (iHour == 24) 
			{ 
				iHour = 0; 
			} 
 
			if (iDigit != 1)	// Only 10, 11 or 12 are allowed! 
			{ 
				iDigit = -1; 
			} 
		} 
		else	// Normal format 
		{ 
			iHour = iNumber; 
		} 
		break; 
 
	case MIN: 
		iMin = iNumber; 
		break; 
 
	case MONTH: 
		if (m_monthFormat == 2 && 
			iNumber >= 1 && iNumber <= 12) 
		{ 
			iMonth = iNumber; 
 
			if (iDigit > 1 && m_iPrevDigit == -1) 
			{ 
				m_iPrevDigit = 0;	// Stimulate junp to the next part 
			} 
		} 
		break; 
 
	case YEAR: 
		if (m_type2DigitsInYear) 
		{ 
			iYear = iYear / 100 * 100 + iNumber; 
 
			if (iYear < m_maxYear2Digits - 99) 
			{ 
//				iYear += 100; 
				iYear = m_maxYear2Digits / 100 * 100 + iNumber; 
			} 
 
			if (iYear > m_maxYear2Digits) 
			{ 
//				iYear -= 100; 
				iYear = (m_maxYear2Digits - 100) / 100 * 100 + iNumber; 
			} 
		} 
		else 
		{ 
			ASSERT (m_iYearPos >= 0); 
			ASSERT (m_iYearPos < iYearDigits); 
 
			//------------------------------------------------ 
			// Replace digit in position m_iYearPos to iDigit: 
			//------------------------------------------------ 
			int iYearNew = 0; 
 
			for (int iPos = 0; iPos < iYearDigits; iPos ++) 
			{ 
				int iTens = 1; 
				for (int i = 0; i < iYearDigits - iPos - 1; i ++) 
				{ 
					iTens *= 10; 
				} 
 
				iYearNew *= 10; 
				if (iPos == m_iYearPos) 
				{ 
					iYearNew += iDigit; 
				} 
				else 
				{ 
					iYearNew += iYear / iTens; 
				} 
 
				iYear %= iTens; 
			} 
 
			iYear = iYearNew; 
		} 
 
		m_iYearPos ++; 
		break; 
	} 
 
	COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0); 
	BOOL bValidDate = IsDateValid (date); 
	 
	if (bValidDate) 
	{ 
		m_Date = date; 
		RedrawWindow (m_rectText); 
 
		OnDateChanged (); 
	} 
 
	if (m_iPrevDigit == -1)	// First push 
	{ 
		m_iPrevDigit = iDigit; 
	} 
	else 
	{ 
		if (bValidDate && m_iPartNum < m_iPartsNumber - 1) 
		{ 
			if (m_CurrPartType != YEAR || m_iYearPos == iYearDigits) 
			{ 
				m_iPrevDigit = -1; 
				SelectNext (); 
			} 
		} 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::ChangeMonth (UINT uiMonthLetter) 
{ 
	ASSERT (m_monthFormat == 0 || m_monthFormat == 1); 
 
	CBCGPDefaultLocale dl; 
 
	int iDay = m_Date.GetDay (); 
	int iMonth = m_Date.GetMonth (); 
	int iYear = m_Date.GetYear (); 
	int iHour = m_Date.GetHour (); 
	int iMin = m_Date.GetMinute (); 
 
	BOOL bLastDayInMonth = (iDay == GetDaysInMonth (iMonth, iYear)); 
 
	BOOL bFound = FALSE; 
	for (int i = iMonth + 1; i != iMonth; i ++) 
	{ 
		if (i > 12) 
		{ 
			i = 1; 
		} 
 
		if (i == iMonth) 
		{ 
			break; 
		} 
 
		//-------------------------------------------------- 
		// Compare manth 'i' first char with the typed char: 
		//-------------------------------------------------- 
		CString strMonth = COleDateTime (iYear, i, 1, 0, 0, 0). 
			Format (m_monthFormat == 0 ? _T ("%b") : _T ("%B")); 
 
		if (strMonth.GetLength () > 1 && 
			strMonth.GetAt (0) == (char) uiMonthLetter) 
		{ 
			iMonth = i; 
			bFound = TRUE; 
			break; 
		} 
	} 
 
	if (bFound) 
	{ 
		if (bLastDayInMonth || 
			iDay > GetDaysInMonth (iMonth, iYear)) 
		{ 
			iDay = GetDaysInMonth (iMonth, iYear); 
		} 
 
		COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0); 
		if (IsDateValid (date)) 
		{ 
			m_Date = date; 
			RedrawWindow (m_rectText); 
 
			OnDateChanged (); 
		} 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::ChangeAmPm (UINT uiAmPm) 
{ 
	int iDay = m_Date.GetDay (); 
	int iMonth = m_Date.GetMonth (); 
	int iYear = m_Date.GetYear (); 
	int iHour = m_Date.GetHour (); 
	int iMin = m_Date.GetMinute (); 
 
	CString str = (char) uiAmPm; 
	str.MakeUpper (); 
 
	if (str == m_strPM [0] && iHour < 12) 
	{ 
		iHour += 12; 
	} 
 
	if (str == m_strAM [0] && iHour >= 12) 
	{ 
		iHour -= 12; 
	} 
 
	COleDateTime date (iYear, iMonth, iDay, iHour, iMin, 0); 
	if (IsDateValid (date) && m_Date != date) 
	{ 
		m_Date = date; 
		RedrawWindow (m_rectText); 
 
		OnDateChanged (); 
	} 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::ToggleCheck () 
{ 
	m_bIsChecked = !m_bIsChecked; 
 
	if (m_spinButton) 
	{ 
		m_wndSpin.EnableWindow (m_bIsChecked); 
	} 
 
	COleDateTime emptyDate; 
	if (m_bIsChecked && m_Date == emptyDate) 
	{ 
		m_Date = COleDateTime::GetCurrentTime (); 
		OnDateChanged (); 
	} 
 
	RedrawWindow (); 
} 
//***************************************************************************************** 
BOOL CBCGPDateTimeCtrl::IsDateValid (COleDateTime& date) const 
{ 
	if (date.GetStatus () == COleDateTime::invalid) 
	{ 
		return FALSE; 
	} 
 
	COleDateTime dateEmpty; 
 
	if (m_MinDate != dateEmpty && date < m_MinDate) 
	{ 
		return FALSE; 
	} 
 
	if (m_MaxDate != dateEmpty && date > m_MaxDate) 
	{ 
		return FALSE; 
	} 
 
	return TRUE; 
} 
//***************************************************************************************** 
BOOL CBCGPDateTimeCtrl::IsDatePart (int iPart) const 
{ 
	PART_TYPE type = m_arPartsOrder [iPart]; 
	return type == DAY || type == MONTH || type == YEAR; 
} 
//***************************************************************************************** 
BOOL CBCGPDateTimeCtrl::IsTimePart (int iPart) const 
{ 
	PART_TYPE type = m_arPartsOrder [iPart]; 
	return type == HOUR || type == MIN; 
} 
//***************************************************************************************** 
void CBCGPDateTimeCtrl::OnHideCalendarPopup () 
{ 
	m_bDropButtonIsPressed = FALSE; 
	RedrawWindow (m_rectDropButton); 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnSetFocus(CWnd* pOldWnd)  
{ 
	CButton::OnSetFocus(pOldWnd); 
 
	if (m_iPartNum >= 0 && m_iPartNum < m_iPartsNumber) 
	{ 
		m_CurrPartType = m_arPartsOrder [m_iPartNum]; 
	} 
 
	m_bShowSelection = TRUE; 
	RedrawWindow (); 
} 
//**************************************************************************************** 
BOOL CBCGPDateTimeCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)  
{ 
	if (wParam == iSpinID) 
	{ 
		NM_UPDOWN* pNM = (NM_UPDOWN*) lParam; 
		ASSERT (pNM != NULL); 
 
		if (pNM->hdr.code == UDN_DELTAPOS) 
		{ 
			ScrollCurrPart (pNM->iDelta < 0 ? 1 : -1); 
		} 
 
		SetFocus (); 
	} 
	 
	return CButton::OnNotify(wParam, lParam, pResult); 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::OnKillFocus(CWnd* pNewWnd)  
{ 
	m_bShowSelection = FALSE; 
	m_iPrevDigit = -1; 
	RedrawWindow (); 
 
	if (m_pPopup == NULL)/* || pNewWnd == NULL || 
		m_pPopup->m_hWnd != pNewWnd->m_hWnd)*/ 
	{		 
//		FireOnKillFocus (pNewWnd == NULL ? 0 : (long) pNewWnd->GetSafeHwnd ()); 
	} 
 
	CButton::OnKillFocus(pNewWnd); 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::BuidWidestDate (CDC* pDC) 
{ 
	ASSERT_VALID (pDC); 
 
	CBCGPDefaultLocale dl; 
 
	//----------------------- 
	// Find the widest month: 
	//----------------------- 
	int iMaxMonth = 1; 
 
	if (m_monthFormat == 2)	// Numeric 
	{ 
		iMaxMonth = 9; 
	} 
	else 
	{ 
		int iMaxMonthWidth = 0; 
		for (int iMonth = 1; iMonth <= 12; iMonth ++) 
		{ 
			COleDateTime date (1998, iMonth, 1, 0, 0, 0); 
			CString strMonth = date.Format (m_monthFormat == 0 ? _T ("%b") : _T("%B")); 
 
			int iMonthWidth = pDC->GetTextExtent (strMonth).cx; 
			if (iMonthWidth > iMaxMonthWidth) 
			{ 
				iMaxMonthWidth = iMonthWidth; 
				iMaxMonth = iMonth; 
			} 
		} 
	} 
 
	m_WidestDate = COleDateTime (2000, iMaxMonth, 20, 0, 0, 0); 
} 
//**************************************************************************************** 
void CBCGPDateTimeCtrl::SizeToContent()  
{ 
	CRect rectClient; 
	GetClientRect (rectClient); 
 
	AdjustControl (rectClient); 
} 
//************************************************************************************* 
void CBCGPDateTimeCtrl::OnDateChanged () 
{ 
	CWnd* pParent = GetParent (); 
	if (pParent != NULL) 
	{ 
		pParent->SendMessage (	WM_COMMAND, 
								MAKEWPARAM (GetDlgCtrlID (), BN_CLICKED), 
								(LPARAM) m_hWnd); 
	} 
} 
 
void CBCGPDateTimeCtrl::SetFirstDayOfWeek(int nDay)	// 0 - 6 
{ 
	m_weekStart = nDay + 1; 
} 
 
UINT CBCGPDateTimeCtrl::GetState () const 
{ 
	UINT stateFlags = 0; 
 
	if (m_spinButton) 
		stateFlags |= DTM_SPIN; 
	if (m_dropCalendar) 
		stateFlags |= DTM_DROPCALENDAR; 
	if (m_showDate) 
		stateFlags |= DTM_DATE; 
	if (m_b24HoursFormat) 
		stateFlags |= DTM_TIME24H; 
	if (m_checkButton) 
		stateFlags |= DTM_CHECKBOX; 
	if (m_showTime) 
		stateFlags |= DTM_TIME; 
	if (m_bIsChecked) 
		stateFlags |= DTM_CHECKED; 
	if (m_b24HoursByLocale) 
		stateFlags |= DTM_TIME24HBYLOCALE; 
 
	return stateFlags; 
} 
 
void CBCGPDateTimeCtrl::SetState (UINT stateFlags, UINT stateMask) 
{ 
	if(!(stateFlags & DTM_DATE) && !(stateFlags & DTM_TIME)) 
		stateFlags |= (DTM_DATE | DTM_TIME); 
 
	if(stateMask & DTM_SPIN) 
		m_spinButton =  
			((stateFlags & DTM_SPIN) != 0); 
 
	if(stateMask & DTM_DROPCALENDAR) 
		m_dropCalendar =  
			((stateFlags & DTM_DROPCALENDAR) != 0); 
 
	if(stateMask & DTM_DATE) 
		m_showDate =  
			((stateFlags & DTM_DATE) != 0); 
 
	if(stateMask & DTM_TIME24H) 
		m_b24HoursFormat =  
			((stateFlags & DTM_TIME24H) != 0); 
 
	if(stateMask & DTM_CHECKBOX) 
		m_checkButton =  
			((stateFlags & DTM_CHECKBOX) != 0); 
 
	if(stateMask & DTM_TIME) 
		m_showTime =  
			((stateFlags & DTM_TIME) != 0); 
 
	if(stateMask & DTM_CHECKED) 
		m_bIsChecked =  
			((stateFlags & DTM_CHECKED) != 0); 
 
	if(stateMask & DTM_TIME24HBYLOCALE) 
		m_b24HoursByLocale =  
			((stateFlags & DTM_TIME24HBYLOCALE) != 0); 
 
	if(::IsWindow (m_hWnd)) 
	{ 
		SizeToContent(); 
	} 
} 
 
void CBCGPDateTimeCtrl::PreSubclassWindow()  
{ 
	if (!m_bIsInitialized) 
	{ 
		ModifyStyle (BS_DEFPUSHBUTTON, BS_OWNERDRAW | WS_BORDER); 
	} 
	else 
	{ 
		ModifyStyle (BS_DEFPUSHBUTTON, BS_OWNERDRAW); 
	} 
 
	CButton::PreSubclassWindow(); 
} 
 
BOOL CBCGPDateTimeCtrl::PreCreateWindow(CREATESTRUCT& cs)  
{ 
	cs.style |= BS_OWNERDRAW; 
	cs.style &= ~BS_DEFPUSHBUTTON; 
 
	m_bIsInitialized = TRUE; 
 
	return CButton::PreCreateWindow(cs); 
} 
 
BOOL CBCGPDateTimeCtrl::OnEraseBkgnd(CDC* /*pDC*/) 
{ 
	return TRUE; 
} 
 
void CBCGPDateTimeCtrl::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)  
{ 
	if (GetStyle() & WS_BORDER)  
	{ 
		lpncsp->rgrc[0].left++;  
		lpncsp->rgrc[0].top++ ; 
		lpncsp->rgrc[0].right--; 
		lpncsp->rgrc[0].bottom--; 
	} 
 
	CButton::OnNcCalcSize(bCalcValidRects, lpncsp); 
} 
 
void CBCGPDateTimeCtrl::OnNcPaint()  
{ 
	if (GetStyle () & WS_BORDER) 
	{ 
		CBCGPVisualManager::GetInstance ()->OnDrawControlBorder (this); 
	} 
} 
 
BOOL CBCGPDateTimeCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)  
{ 
	if (m_bIsChecked) 
	{ 
		CPoint ptCursor; 
		::GetCursorPos (&ptCursor); 
		ScreenToClient (&ptCursor); 
 
		if (m_rectText.PtInRect (ptCursor)) 
		{ 
			::SetCursor (AfxGetApp ()->LoadStandardCursor (IDC_IBEAM)); 
			return TRUE; 
		} 
	} 
 
	return CButton::OnSetCursor(pWnd, nHitTest, message); 
} 
//***************************************************************************** 
LRESULT CBCGPDateTimeCtrl::OnSetFont (WPARAM wParam, LPARAM lParam) 
{ 
	BOOL bRedraw = (BOOL) LOWORD (lParam); 
 
	m_hFont = (HFONT) wParam; 
 
	if (bRedraw) 
	{ 
		Invalidate (); 
		UpdateWindow (); 
	} 
 
	return 0; 
} 
//***************************************************************************** 
LRESULT CBCGPDateTimeCtrl::OnGetFont (WPARAM, LPARAM) 
{ 
	return (LRESULT) m_hFont; 
} 
//****************************************************************************** 
void CBCGPDateTimeCtrl::OnSize(UINT nType, int cx, int cy)  
{ 
	CButton::OnSize(nType, cx, cy); 
 
	CRect rectClient; 
	GetClientRect (rectClient); 
 
	AdjustControl (rectClient); 
} 
//******************************************************************************* 
void CBCGPDateTimeCtrl::SetTextColor (COLORREF color, BOOL bRedraw) 
{ 
	m_colorText = color; 
 
	if (bRedraw && GetSafeHwnd () != NULL) 
	{ 
		RedrawWindow (); 
	} 
} 
 
#endif // BCG_NO_CALENDAR