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


// BCGCalendarBar.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" 
#include  
#include  
 
#include "BCGCBPro.h" 
#include "BCGPCalendarBar.h" 
#include "BCGPCalendarMenuButton.h" 
#include "BCGPPopupMenu.h" 
#include "BCGPContextMenuManager.h" 
#include "BCGPDateTimeCtrl.h" 
#include "trackmouse.h" 
#include "BCGPVisualManager.h" 
#include "BCGPWorkspace.h" 
#include "BCGProRes.h" 
#include "BCGPLocalResource.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
#define DISABLE_MONTH_POPUP 
 
static const int SEPARATOR_SIZE = 2; 
static const int nHoldMouseTimerID = 1; 
 
UINT BCGM_CALENDAR_ON_SELCHANGED = ::RegisterWindowMessage (_T("BCGM_CALENDAR_ON_SELCHANGED")); 
 
///////////////////////////////////////////////////////////////////////////// 
 
class CCalendarWeekButton : public CBCGPCalendarButton   
{ 
	friend class CBCGPCalendarBar; 
	friend class CBCGPCalendarMenuButton; 
 
	DECLARE_SERIAL(CCalendarWeekButton) 
 
protected: 
	virtual void SetDate(const COleDateTime& date) 
	{ 
		if (date != m_Calendar) 
		{ 
			CBCGPDefaultLocale dl; 
 
			m_Calendar = date; 
			m_strText = m_Calendar.Format(_T("%a")); 
			m_pParentBar->InvalidateRect(m_rect); 
		} 
	} 
 
	virtual BOOL IsActualDay () const 
	{ 
		return FALSE; 
	} 
}; 
 
IMPLEMENT_SERIAL(CCalendarWeekButton, CBCGPCalendarButton, 1) 
 
class CCalendarWeekNumButton : public CBCGPCalendarButton   
{ 
	friend class CBCGPCalendarBar; 
	friend class CBCGPCalendarMenuButton; 
 
	DECLARE_SERIAL(CCalendarWeekNumButton) 
 
protected: 
	virtual void SetDate(const COleDateTime& date) 
	{ 
		if (date != m_Calendar) 
		{ 
			CBCGPDefaultLocale dl; 
 
			m_Calendar = date; 
			m_strText.Format(_T("%02d"), CBCGPCalendarBar::GetWeekNo(m_Calendar, m_pParentBar->m_nWeekStart));  
			m_pParentBar->InvalidateRect(m_rect); 
		} 
	} 
 
	virtual COLORREF GetTextColor () 
	{ 
		ASSERT_VALID (m_pParentBar); 
		return IsCurrMonth () ?  
			m_pParentBar->m_clrWeekText : m_pParentBar->m_clrWeekTextDisabled; 
	} 
 
	virtual BOOL IsActualDay () const 
	{ 
		return FALSE; 
	} 
}; 
 
IMPLEMENT_SERIAL(CCalendarWeekNumButton, CBCGPCalendarButton, 1) 
 
class CCalendarTodayButton : public CBCGPCalendarButton   
{ 
	friend class CBCGPCalendarBar; 
	friend class CBCGPCalendarMenuButton; 
 
	DECLARE_SERIAL(CCalendarTodayButton) 
 
protected: 
	CCalendarTodayButton(int iImage = -1) 
	{ 
		m_iImage = iImage; 
	} 
 
	virtual BOOL OnToolHitTest(const CWnd* /*pWnd*/, TOOLINFO* pTI) 
	{ 
		if (m_nStyle & TBBS_DISABLED) 
		{ 
			return FALSE; 
		} 
 
		if (!CBCGPToolBar::GetShowTooltips ()) 
		{ 
			return FALSE; 
		} 
 
		ASSERT (pTI != NULL); 
 
		CString str = _T("Today"); 
 
		pTI->lpszText = (LPTSTR) ::calloc ((str.GetLength () + 1), sizeof (TCHAR)); 
		_tcscpy (pTI->lpszText, str); 
 
		return TRUE; 
	} 
 
	virtual void SetDate(const COleDateTime& date) 
	{ 
		if (date != m_Calendar) 
		{ 
			m_Calendar = date; 
			m_pParentBar->InvalidateRect(m_rect); 
		} 
	} 
	 
	virtual BOOL IsActualDay () const 
	{ 
		return FALSE; 
	} 
}; 
 
IMPLEMENT_SERIAL(CCalendarTodayButton, CBCGPCalendarButton, 1) 
 
//******************************************************* 
class CCalendarNavigateButton : public CBCGPCalendarButton   
{ 
	friend class CBCGPCalendarBar; 
	friend class CBCGPCalendarMenuButton; 
 
	DECLARE_SERIAL(CCalendarNavigateButton) 
 
protected: 
	CCalendarNavigateButton(int iImage = -1) 
	{ 
		m_iImage = iImage; 
	} 
 
	virtual BOOL OnToolHitTest(const CWnd* /*pWnd*/, TOOLINFO* pTI) 
	{ 
		if (m_nStyle & TBBS_DISABLED) 
		{ 
			return FALSE; 
		} 
 
		if (!CBCGPToolBar::GetShowTooltips ()) 
		{ 
			return FALSE; 
		} 
 
		ASSERT (pTI != NULL); 
 
		CString str; 
 
		switch (m_iImage) 
		{ 
		case 0: 
			str = _T("Prev. year"); 
			break; 
 
		case 1: 
			str = _T("Prev. month"); 
			break; 
 
		case 2: 
			str = _T("Next month"); 
			break; 
 
		case 3: 
			str = _T("Next year"); 
			break; 
		} 
 
		pTI->lpszText = (LPTSTR) ::calloc ((str.GetLength () + 1), sizeof (TCHAR)); 
		_tcscpy (pTI->lpszText, str); 
 
		return TRUE; 
	} 
 
	virtual void SetDate(const COleDateTime& date) 
	{ 
		if (date != m_Calendar) 
		{ 
			m_Calendar = date; 
			m_pParentBar->InvalidateRect(m_rect); 
		} 
	} 
 
	virtual BOOL IsActualDay () const 
	{ 
		return FALSE; 
	} 
}; 
 
IMPLEMENT_SERIAL(CCalendarNavigateButton, CBCGPCalendarButton, 1) 
 
//******************************************************* 
class CCalendarMonthButton : public CBCGPToolbarButton   
{ 
	friend class CBCGPCalendarBar; 
	friend class CBCGPCalendarMenuButton; 
 
	DECLARE_SERIAL(CCalendarMonthButton) 
 
	 
protected: 
 
	CCalendarMonthButton() 
	{ 
		m_pParentBar = NULL; 
	} 
 
	virtual BOOL OnToolHitTest(const CWnd* /*pWnd*/, TOOLINFO* pTI) 
	{ 
		if (m_nStyle & TBBS_DISABLED) 
		{ 
			return FALSE; 
		} 
 
		if (!CBCGPToolBar::GetShowTooltips ()) 
		{ 
			return FALSE; 
		} 
 
		ASSERT (pTI != NULL); 
 
		CString str = _T("Change month"); 
 
		pTI->lpszText = (LPTSTR) ::calloc ((str.GetLength () + 1), sizeof (TCHAR)); 
		_tcscpy (pTI->lpszText, str); 
 
		return TRUE; 
	} 
 
	virtual void OnDraw (CDC* pDC, const CRect& rect, CBCGPToolBarImages* pImages, 
						BOOL bHorz = TRUE, BOOL bCustomizeMode = FALSE, 
						BOOL bHighlight = FALSE, 
						BOOL bDrawBorder = TRUE, 
						BOOL bGrayDisabledButtons = TRUE); 
	 
	virtual void OnChangeParentWnd (CWnd* pWndParent) 
	{ 
		CBCGPToolbarButton::OnChangeParentWnd (pWndParent); 
		m_pParentBar = DYNAMIC_DOWNCAST (CBCGPCalendarBar, pWndParent); 
	} 
 
	CSize ContextSize (CWnd* pWnd) 
	{ 
		ASSERT (pWnd->GetSafeHwnd () != NULL); 
 
		CClientDC dc (pWnd); 
		CFont* pOldFont = dc.SelectObject (&globalData.fontRegular); 
		 
		CSize btnSize = dc.GetTextExtent(m_strText); 
 
		dc.SelectObject (pOldFont); 
		return btnSize; 
	} 
 
	CBCGPCalendarBar*	m_pParentBar; 
	virtual BOOL IsActualDay () const 
	{ 
		return FALSE; 
	} 
}; 
 
void CCalendarMonthButton::OnDraw (CDC* pDC, const CRect& rect, CBCGPToolBarImages* /*pImages*/, 
								BOOL bHorz, BOOL bCustomizeMode, BOOL bHighlight, 
								BOOL bDrawBorder, BOOL bGrayDisabledButtons) 
{ 
	ASSERT_VALID (pDC); 
	ASSERT_VALID (this); 
	ASSERT_VALID (m_pParentBar); 
 
	CBCGPToolbarButton::OnDraw (pDC, rect, NULL, 
								bHorz, bCustomizeMode, bHighlight, 
								bDrawBorder, bGrayDisabledButtons); 
	 
	int nOldBkMode = pDC->SetBkMode (TRANSPARENT); 
	COLORREF clrOldText = pDC->SetTextColor (m_pParentBar->m_clrNavButton); 
 
	CFont* pOldFont = pDC->SelectObject (&globalData.fontRegular); 
	CRect rectWnd = rect; 
 
	if (m_nStyle ^ TBBS_DISABLED) 
	{	 
		rectWnd.DeflateRect (1, 1, rect.Height(), 1); 
		// Draw menu triangle: 
		CRect rectArrow = rectWnd; 
		rectArrow.left = rect.right; 
 
		int iXMiddle = rectArrow.left + rectArrow.Width () / 2; 
 
		rectArrow.DeflateRect (0, rectArrow.Height () / 3); 
		rectArrow.DeflateRect (rectArrow.Height () / 3, rectArrow.Height () / 3); 
		rectArrow.left = iXMiddle - rectArrow.Height () - 1; 
		rectArrow.right = iXMiddle + rectArrow.Height () + 1; 
 
		int iHalfWidth =	(rectArrow.Width () % 2 != 0) ? 
							(rectArrow.Width () - 1) / 2 : 
							rectArrow.Width () / 2; 
 
		CPoint pts [3]; 
		pts[0].x = rectArrow.left; 
		pts[0].y = rectArrow.top; 
		pts[1].x = rectArrow.right; 
		pts[1].y = rectArrow.top; 
		pts[2].x = rectArrow.left + iHalfWidth; 
		pts[2].y = rectArrow.bottom + 1; 
 
		CBrush brArrow (pDC->GetTextColor ()); 
 
		CPen* pOldPen = (CPen*) pDC->SelectStockObject (NULL_PEN); 
		CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brArrow); 
 
		pDC->SetPolyFillMode (WINDING); 
		pDC->Polygon (pts, 3); 
 
		pDC->SelectObject (pOldBrush); 
		pDC->SelectObject (pOldPen); 
		pDC->DrawText (m_strText, rectWnd, DT_VCENTER | DT_RIGHT | DT_SINGLELINE); 
	} 
	else 
	{ 
		pDC->DrawText (m_strText, rectWnd, DT_VCENTER | DT_CENTER | DT_SINGLELINE); 
	} 
	pDC->SelectObject (pOldFont); 
	pDC->SetTextColor (clrOldText); 
	pDC->SetBkMode (nOldBkMode); 
	 
} 
IMPLEMENT_SERIAL(CCalendarMonthButton, CBCGPToolbarButton, 1) 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPCalendarBar 
 
const UINT CBCGPCalendarBar::CBR_WEEKDAYSEL = 0x1; 
const UINT CBCGPCalendarBar::CBR_WEEKNUMBER = 0x2; 
const UINT CBCGPCalendarBar::CBR_MULTISELECTION = 0x4; 
const UINT CBCGPCalendarBar::CBR_ENABLED = 0x8; // still has not effect - 6.2 
const UINT CBCGPCalendarBar::CBR_NAVIGATION_BUTTONS = 0x10; 
 
 
CString CBCGPCalendarBar::m_strMonthNames[12]; 
 
IMPLEMENT_SERIAL(CBCGPCalendarBar, CBCGPPopupMenuBar, 1) 
 
CBCGPCalendarBar::CBCGPCalendarBar() 
{ 
	CommonInit (); 
 
    m_dateSelected = COleDateTime::GetCurrentTime(); 
	m_nCommandID = 0; 
	m_bIsTearOff = TRUE; 
	m_pParentBtn = NULL; 
} 
//************************************************************************************** 
CBCGPCalendarBar::CBCGPCalendarBar (const COleDateTime& month,  
				UINT nCommandID, CBCGPDateTimeCtrl* pParentBtn) : 
	m_dateSelected (month), 
	m_bIsTearOff (FALSE), 
	m_nCommandID (nCommandID), 
	m_pParentBtn (pParentBtn) 
{ 
	CommonInit (); 
} 
//************************************************************************************** 
CBCGPCalendarBar::CBCGPCalendarBar (CBCGPCalendarBar& src, UINT uiCommandID, BOOL enableSelection) : 
		m_dateSelected (src.m_dateSelected), 
		m_bIsTearOff (TRUE), 
		m_nCommandID (uiCommandID), 
		m_pParentBtn (NULL) 
 
{ 
	CommonInit (); 
 
	if (enableSelection)  
	{ 
		m_styleFlags |= CBR_MULTISELECTION; 
	} 
	else				 
	{ 
		m_styleFlags &= (~CBR_MULTISELECTION); 
	} 
} 
//************************************************************************************** 
void CBCGPCalendarBar::CommonInit () 
{ 
	m_bLocked = TRUE; 
	m_nWeekStart = 1; 
    m_iButtonCapture = -1; 
	m_bIsEnabled = TRUE; 
	m_nVertMargin = 4; 
	m_nHorzMargin = 4; 
	m_bInternal = FALSE; 
	m_nHorzOffset = m_nVertOffset = 0; 
	m_selMode  = Select_BYNONE; 
	m_styleFlags = (CBR_WEEKDAYSEL | CBR_WEEKNUMBER | CBR_ENABLED | CBR_NAVIGATION_BUTTONS) 
					& (~CBR_MULTISELECTION); 
	m_sizeBox = CSize (0, 0); 
	m_sizeBoxMin = CSize (0, 0); 
	m_bIsCtrl = FALSE; 
} 
//************************************************************************************** 
CBCGPCalendarBar::~CBCGPCalendarBar() 
{ 
} 
//***************************************************************************************** 
void CBCGPCalendarBar::SetState(UINT flags, UINT mask) 
{ 
	m_styleFlags &= ~mask; 
	m_styleFlags |= (flags & mask); 
 
	if (!(m_styleFlags & CBR_MULTISELECTION)) 
	{ 
		ClearSelectedDays(); 
	} 
 
	if (GetSafeHwnd () != NULL) 
	{ 
		Rebuild (); 
		AdjustLocations (); 
 
		Invalidate(); 
		UpdateWindow(); 
	} 
} 
//************************************************************************************* 
void CBCGPCalendarBar::AdjustLocations () 
{ 
	ASSERT_VALID(this); 
 
	if (GetSafeHwnd () == NULL || !::IsWindow (m_hWnd)) 
	{ 
		return; 
	} 
 
	m_sizeBox.cx = max (m_sizeBox.cx, m_sizeBoxMin.cx); 
	m_sizeBox.cy = max (m_sizeBox.cy, m_sizeBoxMin.cy); 
 
	CClientDC dc (this); 
 
	CFont* pPrevFont = dc.SelectObject (&globalData.fontRegular); 
	ASSERT (pPrevFont != NULL); 
 
	TEXTMETRIC tm; 
	dc.GetTextMetrics (&tm); 
 
	m_iTitleHeight = tm.tmHeight + m_nVertMargin * 2; 
 
    CRect rectClient; 
	GetClientRect (&rectClient); 
 
	int nWeekBarWidth = CBCGPToolBar::GetMenuImageSize ().cx +  
				2 * CBCGPVisualManager::GetInstance ()->GetMenuImageMargin (); 
	int xDaysStart = rectClient.left + nWeekBarWidth + 2 * m_nHorzMargin; 
 
	rectClient.DeflateRect (m_nHorzMargin, m_nVertMargin); 
 
	int x = rectClient.left; 
	int y = rectClient.top; 
	rectClient.top += m_iTitleHeight; 
 
	int i = 0; 
 
	int iWeekNo = 0; 
	int iWeekNum = 0; 
	int iDayNum = 0; 
	int iNavigate = 0; 
 
	BOOL bPrevSeparator = FALSE; 
 
	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL; i++) 
	{ 
		CRect rectButton (0, 0, 0, 0); 
 
		CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos); 
		ASSERT_VALID (pButton); 
		 
		if (pButton->m_nStyle & TBBS_SEPARATOR) 
		{ 
			if (bPrevSeparator) 
			{ 
				rectButton.SetRectEmpty (); 
			} 
			else 
			{ 
				// Next line 
				x = xDaysStart; 
				y = rectClient.top + m_sizeBox.cy; 
 
				rectButton = CRect ( 
					CPoint (x, y), 
					CSize (rectClient.right - x, SEPARATOR_SIZE)); 
			} 
 
			bPrevSeparator = TRUE; 
		} 
		else 
		{ 
			if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekNumButton))) 
			{ 
				CCalendarWeekNumButton* pCalendarButton = DYNAMIC_DOWNCAST (CCalendarWeekNumButton, pButton); 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
 
				x = m_nHorzMargin / 2; 
				y = rectClient.top  + SEPARATOR_SIZE + m_sizeBox.cy * (iWeekNo + 1) ; 
 
                rectButton = CRect (CPoint (x, y), CSize (nWeekBarWidth - m_nHorzMargin, m_sizeBox.cy)); 
 
				bPrevSeparator = FALSE; 
 
				iWeekNo ++; 
			} 
 
			else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarTodayButton))) 
			{ 
				CCalendarTodayButton* pCalendarButton = DYNAMIC_DOWNCAST (CCalendarTodayButton, pButton); 
				 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
				{ 
					 
					GetClientRect (&rectButton); 
					rectButton.DeflateRect(0, 0, rectButton.Width() - m_iTitleHeight + 1, rectButton.Height () - m_iTitleHeight + 1); 
					rectButton.DeflateRect(1, 1); 
					bPrevSeparator = FALSE; 
				} 
			} 
			else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekButton))) 
			{ 
				CCalendarWeekButton* pCalendarButton = DYNAMIC_DOWNCAST (CCalendarWeekButton, pButton); 
				 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
				{ 
 
					x = xDaysStart + m_sizeBox.cx * (iWeekNum % 7); 
					y = rectClient.top; 
 
					rectButton = CRect (CPoint (x, y), m_sizeBox); 
					bPrevSeparator = FALSE; 
				} 
				iWeekNum ++; 
			} 
			else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarMonthButton))) 
			{ 
				CCalendarMonthButton* pCalendarButton = DYNAMIC_DOWNCAST (CCalendarMonthButton, pButton); 
				 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
				{ 
					pCalendarButton->m_strText = GetMonthName(m_dateSelected.GetMonth ()); 
 
					CSize btnSize = pCalendarButton->ContextSize(this); 
					btnSize.cx += m_iTitleHeight; 
 
					GetClientRect (&rectButton); 
					rectButton.DeflateRect(0, 0, 0, rectButton.Height () - m_iTitleHeight + 1); 
					rectButton.DeflateRect((rectButton.Width () - btnSize.cx) / 2 + 1, 1); 
 
					bPrevSeparator = FALSE; 
				} 
			}			 
			else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarNavigateButton))) 
			{ 
				CCalendarNavigateButton* pCalendarButton = DYNAMIC_DOWNCAST (CCalendarNavigateButton, pButton); 
				iNavigate ++; 
				 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
				 
				CSize btnSize (0, 0); 
				for(int i = 0; i < 12; i ++) 
				{ 
					CString strMonth = GetMonthName (i + 1); 
					CSize textSize = dc.GetTextExtent(strMonth); 
					btnSize.cx = max(textSize.cx, btnSize.cx); 
				} 
 
				btnSize.cx += m_iTitleHeight; 
 
				GetClientRect (&rectButton); 
				rectButton.DeflateRect(0, 0, 0, rectButton.Height () - m_iTitleHeight + 1); 
				rectButton.DeflateRect((rectButton.Width () - btnSize.cx) / 2 + 1, 2); 
				switch(iNavigate) 
				{ 
				case 1: 
					{ 
						rectButton.OffsetRect (- rectButton.Height () * 2, 0); 
					} 
					break; 
				case 2: 
					{ 
						rectButton.OffsetRect (- rectButton.Height (), 0); 
					} 
					break; 
				case 3: 
					{ 
						rectButton.OffsetRect (rectButton.Width (), 0 ); 
					} 
					break; 
				case 4: 
					{ 
						rectButton.OffsetRect (rectButton.Width () + rectButton.Height (), 0); 
					} 
					break; 
				} 
 
				rectButton.right = rectButton.left + rectButton.Height (); 
 
				bPrevSeparator = FALSE; 
			}			 
			else if (pButton->IsKindOf (RUNTIME_CLASS (CBCGPCalendarButton))) 
			{ 
				CBCGPCalendarButton* pCalendarButton = DYNAMIC_DOWNCAST (CBCGPCalendarButton, pButton); 
				 
				if (pCalendarButton == NULL) 
				{ 
					continue; 
				} 
 
				ASSERT_VALID (pCalendarButton); 
 
				x = xDaysStart + m_sizeBox.cx * (iDayNum % 7); 
				y = rectClient.top  + SEPARATOR_SIZE + m_sizeBox.cy * (iDayNum / 7 + 1) ; 
 
				rectButton = CRect ( 
					CPoint (x, y), m_sizeBox); 
 
				bPrevSeparator = FALSE; 
 
				iDayNum ++; 
			} 
		} 
 
		pButton->SetRect (rectButton); 
	} 
	 
	dc.SelectObject (pPrevFont); 
	UpdateTooltips (); 
} 
//*************************************************************************************** 
CSize CBCGPCalendarBar::CalcSize (BOOL /*bVertDock*/) 
{ 
	// Calculate caption width: 
	CClientDC dc (this); 
	CFont* pOldFont = dc.SelectObject (&globalData.fontRegular); 
 
	int nMonthMaxWidth = 0; 
	for(int i = 0; i < 12; i ++) 
	{ 
		CString strMonth = GetMonthName (i + 1); 
		nMonthMaxWidth = max (dc.GetTextExtent(strMonth).cx, nMonthMaxWidth); 
	} 
 
	CString strYear = _T("0000"); 
	int nYearWidth = dc.GetTextExtent(strYear).cx; 
 
	dc.SelectObject (pOldFont); 
 
	return CSize( 
			max (nMonthMaxWidth + 4 * m_sizeBox.cx + nYearWidth, 8 * m_sizeBox.cx) + 2 * m_nVertMargin,  
			7 * (m_sizeBox.cy + 2) + 2 * m_nHorzMargin +  
			SEPARATOR_SIZE + m_iTitleHeight); 
} 
//************************************************************************************* 
CSize CBCGPCalendarBar::GetCalendarGridSize (BOOL bVertDock) const 
// 
// Calculate number of columns and rows in the grid 
// 
{ 
	int nNumColumns = 7; 
	int nNumRows = 7; 
 
	return CSize (nNumColumns, nNumRows); 
} 
//************************************************************************************** 
int CBCGPCalendarBar::GetExtraHeight (int nNumColumns) const 
{ 
	int nExtraHeight = 0; 
	return nExtraHeight; 
} 
 
BEGIN_MESSAGE_MAP(CBCGPCalendarBar, CBCGPPopupMenuBar) 
	//{{AFX_MSG_MAP(CBCGPCalendarBar) 
	ON_WM_CREATE() 
	ON_WM_NCCALCSIZE() 
	ON_WM_NCPAINT() 
	ON_WM_MOUSEMOVE() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_LBUTTONUP() 
	ON_WM_LBUTTONDBLCLK() 
	ON_WM_DESTROY() 
	ON_WM_TIMER() 
	ON_WM_MOUSEACTIVATE() 
	ON_WM_SIZE() 
	//}}AFX_MSG_MAP 
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPCalendarBar message handlers 
 
void CBCGPCalendarBar::ContextToSize () 
{ 
	ASSERT (GetSafeHwnd () != NULL); 
 
	m_nHorzOffset = GetMenuImageSize ().cx +  
			2 * CBCGPVisualManager::GetInstance ()->GetMenuImageMargin () + 1; 
	m_nVertOffset = 0; 
	 
	CRect rectClient; 
	GetClientRect (rectClient); 
 
	rectClient.top += m_iTitleHeight; 
	rectClient.left += m_nHorzOffset; 
 
	m_sizeBox.cx = rectClient.Width () / 7 - 1; 
	m_sizeBox.cy = (rectClient.Height () - SEPARATOR_SIZE) / 7 - 1; 
 
	m_sizeBox.cx = max (m_sizeBox.cx, m_sizeBoxMin.cx); 
	m_sizeBox.cy = max (m_sizeBox.cy, m_sizeBoxMin.cy); 
 
	AdjustLocations (); 
 
	SetWindowPos (&wndTop, -1, -1, -1, -1, 
		SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); 
} 
//************************************************************************************** 
void CBCGPCalendarBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)  
{ 
	if (m_bIsCtrl) 
	{ 
		if (GetStyle() & WS_BORDER)  
		{ 
			lpncsp->rgrc[0].left++;  
			lpncsp->rgrc[0].top++ ; 
			lpncsp->rgrc[0].right--; 
			lpncsp->rgrc[0].bottom--; 
		} 
 
		return; 
	} 
 
	if (m_bIsTearOff) 
	{ 
		CBCGPToolBar::OnNcCalcSize(bCalcValidRects, lpncsp); 
	} 
	else 
	{ 
		CBCGPPopupMenuBar::OnNcCalcSize(bCalcValidRects, lpncsp); 
	} 
} 
//************************************************************************************** 
void CBCGPCalendarBar::OnNcPaint()  
{ 
	if (m_bIsCtrl) 
	{ 
		if (GetStyle () & WS_BORDER) 
		{ 
			CBCGPVisualManager::GetInstance ()->OnDrawControlBorder (this); 
		} 
 
		return; 
	} 
 
	if (m_bIsTearOff) 
	{ 
		CBCGPToolBar::OnNcPaint(); 
	} 
	else 
	{ 
		CBCGPPopupMenuBar::OnNcPaint(); 
	} 
} 
//************************************************************************************** 
int CBCGPCalendarBar::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CBCGPPopupMenuBar::OnCreate(lpCreateStruct) == -1) 
		return -1; 
 
	const CSize sizeNavImage (10, 10); 
	const int nImageMargin = 2; 
 
	// Load navigation images: 
	{ 
		SetLockedSizes (sizeNavImage + CSize (nImageMargin, nImageMargin), sizeNavImage); 
 
		CBCGPLocalResource	lr; 
		BOOL bIsLoaded = LoadBitmap (IDB_BCGBARRES_CALENDAR, 0, 0, TRUE); 
		ASSERT (bIsLoaded); 
	} 
 
	m_sizeBox = sizeNavImage; 
	m_bLeaveFocus = (lpCreateStruct->style & WS_TABSTOP) == 0; 
 
	CClientDC dc (this); 
 
	CFont* pOldFont = dc.SelectObject (&globalData.fontRegular); 
	ASSERT (pOldFont != NULL); 
 
	int year = m_dateSelected.GetYear(); 
	int month = m_dateSelected.GetMonth(); 
	 
	CBCGPDefaultLocale dl; 
 
	CString strDay = _T(" 99"); 
	CSize textSize = dc.GetTextExtent(strDay); 
 
	m_sizeBox.cx = max (textSize.cx, m_sizeBox.cx); 
	m_sizeBox.cy = max (textSize.cy, m_sizeBox.cy); 
 
	for (int i = 1; i <= 7; i ++) 
	{ 
		COleDateTime dt(year, month, i, 0, 0, 0); 
		CString strWeekday = dt.Format(_T("%a")); 
 
		textSize = dc.GetTextExtent(strWeekday); 
 
		m_sizeBox.cx = max (textSize.cx, m_sizeBox.cx); 
		m_sizeBox.cy = max (textSize.cy, m_sizeBox.cy); 
	} 
 
	if (pOldFont != NULL) 
	{ 
		dc.SelectObject (pOldFont); 
	} 
 
	m_sizeBox.cx += nImageMargin; 
	m_sizeBox.cy += nImageMargin; 
 
	m_sizeBoxMin = m_sizeBox; 
 
	Rebuild (); 
	AdjustLocations(); 
 
	if (m_pParentBtn != NULL) 
	{ 
		SetCapture (); 
		SelectDay(m_dateSelected, FALSE, FALSE); 
	} 
	else 
	{ 
		m_LastAddedDate = COleDateTime::GetCurrentTime(); 
	} 
 
	return 0; 
} 
//************************************************************************************* 
void CBCGPCalendarBar::Rebuild () 
{ 
	if (GetSafeHwnd () == NULL) 
	{ 
		return; 
	} 
 
	RemoveAllButtons (); 
 
	InsertButton ( 
		new CCalendarTodayButton(4)); 
 
	InsertButton ( 
		CCalendarMonthButton()); 
 
	if (m_styleFlags & CBCGPCalendarBar::CBR_NAVIGATION_BUTTONS) 
		for(int i = 0; i < 4; i ++) 
			InsertButton ( 
			new CCalendarNavigateButton(i)); 
 
	//TODO: Insert 7 weeks and 42 days of calendar 
	for (int i = 0; i < 7; i ++) 
	{ 
		InsertButton ( 
			new CCalendarWeekButton ()); 
	} 
 
	if (m_styleFlags & CBCGPCalendarBar::CBR_WEEKNUMBER) 
		for (i = 0; i < 6; i ++) 
		{ 
			InsertButton ( 
				new CCalendarWeekNumButton ()); 
		} 
 
	InsertSeparator (); 
	 
	for (i = 0; i < 42; i ++) 
	{ 
		InsertButton ( 
			new CBCGPCalendarButton ()); 
	} 
 
	SetDate (m_dateSelected); 
} 
 
class CBCGPCalendarCCmdUI : public CCmdUI 
{ 
public: 
	CBCGPCalendarCCmdUI(); 
 
public: // re-implementations only 
	virtual void Enable(BOOL bOn); 
	BOOL m_bEnabled; 
}; 
 
CBCGPCalendarCCmdUI::CBCGPCalendarCCmdUI() 
{ 
	m_bEnabled = TRUE;  // assume it is enabled 
} 
//************************************************************************************* 
void CBCGPCalendarCCmdUI::Enable(BOOL bOn) 
{ 
	m_bEnabled = bOn; 
	m_bEnableChanged = TRUE; 
} 
//************************************************************************************* 
void CBCGPCalendarBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) 
{ 
	ASSERT_VALID (this); 
 
	if (m_nCommandID == 0 || m_nCommandID == (UINT)-1) 
	{ 
		CBCGPPopupMenuBar::OnUpdateCmdUI (pTarget, bDisableIfNoHndler); 
		return; 
	} 
 
	CBCGPCalendarCCmdUI state; 
	state.m_pOther = this; 
	state.m_nIndexMax = 1; 
	state.m_nID = m_nCommandID; 
 
	BOOL bIsEnabled = FALSE; 
	if (pTarget->OnCmdMsg (m_nCommandID, CN_UPDATE_COMMAND_UI, &state, NULL)) 
	{ 
		bIsEnabled = state.m_bEnabled; 
	} 
	else if (bDisableIfNoHndler && !state.m_bEnableChanged) 
	{ 
		AFX_CMDHANDLERINFO info; 
		info.pTarget = NULL; 
 
		bIsEnabled = pTarget->OnCmdMsg (m_nCommandID, CN_COMMAND, &state, &info); 
	} 
 
	if (bIsEnabled != m_bIsEnabled) 
	{ 
		m_bIsEnabled = bIsEnabled; 
 
		for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL;) 
		{ 
			CBCGPCalendarButton* pCalendarButton = DYNAMIC_DOWNCAST (CBCGPCalendarButton, m_Buttons.GetNext (pos)); 
			if (pCalendarButton != NULL) 
			{ 
				pCalendarButton->m_nStyle &= ~TBBS_DISABLED; 
				if (!bIsEnabled) 
				{ 
					pCalendarButton->m_nStyle |= TBBS_DISABLED; 
				} 
			} 
		} 
 
		Invalidate (); 
		UpdateWindow (); 
	} 
 
	CBCGPPopupMenuBar::OnUpdateCmdUI (pTarget, bDisableIfNoHndler); 
} 
//************************************************************************************* 
void  CBCGPCalendarBar::OnFillBackground (CDC* pDC) 
{ 
	ASSERT_VALID (pDC); 
 
	CRect rectClient; 
	GetClientRect (rectClient); 
 
	CRect rectWeekColumn = rectClient; 
 
    rectWeekColumn.top += m_iTitleHeight; 
    rectWeekColumn.right = rectWeekColumn.left + CBCGPToolBar::GetMenuImageSize ().cx +  
				2 * CBCGPVisualManager::GetInstance ()->GetMenuImageMargin () + 1; 
 
	CBCGPVisualManager::GetInstance ()->OnFillCalendarBarWeekColumn ( 
		pDC, rectWeekColumn, m_clrWeekText, m_clrWeekTextDisabled); 
 
	CRect rectNavRow = rectClient; 
	rectNavRow.bottom = rectClient.top + m_iTitleHeight; 
 
	m_clrNavButton = CBCGPVisualManager::GetInstance ()->OnFillCalendarBarNavigationRow 
		(pDC, rectNavRow); 
 
	int nOldBkMode = pDC->SetBkMode (TRANSPARENT); 
	COLORREF clrOldText = pDC->SetTextColor (m_clrNavButton); 
 
	CFont* pOldFont = pDC->SelectObject (&globalData.fontRegular); 
 
	CString strYear = m_dateSelected.Format(_T("%Y")); 
	rectNavRow.DeflateRect (m_nHorzMargin, 0); 
	pDC->DrawText (strYear, rectNavRow, DT_VCENTER | DT_RIGHT | DT_SINGLELINE); 
 
	pDC->SelectObject (pOldFont); 
	pDC->SetTextColor (clrOldText); 
	pDC->SetBkMode (nOldBkMode); 
} 
//************************************************************************************* 
BOOL CBCGPCalendarBar::OnSendCommand (const CBCGPToolbarButton* pButton) 
{ 
	BOOL  isCtrlPressed =  (0x8000 & GetKeyState(VK_CONTROL)) != 0; 
	BOOL  isShiftPressed = (0x8000 & GetKeyState(VK_SHIFT)) != 0; 
	 
    COleDateTime date = COleDateTime::GetCurrentTime(); 
	CBCGPCalendarMenuButton* pCalendarMenuButton = NULL; 
 
	CBCGPPopupMenu* pParentMenu = DYNAMIC_DOWNCAST (CBCGPPopupMenu, GetParent ()); 
	if (pParentMenu != NULL) 
	{ 
		pCalendarMenuButton = DYNAMIC_DOWNCAST (CBCGPCalendarMenuButton, pParentMenu->GetParentButton ()); 
	} 
 
	LPARAM buttonKind = Click_NOWHERE; 
	CBCGPCalendarButton* pCalendarButton; 
 
	pCalendarButton = DYNAMIC_DOWNCAST (CCalendarNavigateButton, pButton); 
	if (pCalendarButton) 
	{ 
		if (m_bIsTearOff) 
			SetDate(pCalendarButton->m_Calendar); 
		else 
		{ 
			int iY = pCalendarButton->m_Calendar.GetYear(); 
			int iM = pCalendarButton->m_Calendar.GetMonth(); 
			int iD = m_dateSelected.GetDay (); 
			COleDateTime dateToSelect(iY, iM, 1, 0, 0, 0); 
			int iMaxDay = GetMaxMonthDay(dateToSelect); 
			if (iD > iMaxDay) 
				iD = iMaxDay; 
			SetDate(COleDateTime (iY, iM, iD, 0, 0, 0)); 
		} 
		return TRUE; 
	} 
	else 
	{ 
		pCalendarButton = DYNAMIC_DOWNCAST (CCalendarWeekButton, pButton); 
 
		if (pCalendarButton) 
		{ 
			if (m_bIsTearOff  
				&& (m_styleFlags & CBCGPCalendarBar::CBR_MULTISELECTION) != 0  
				&& (m_styleFlags & CBCGPCalendarBar::CBR_WEEKDAYSEL) != 0) 
			{ 
				buttonKind = Click_WEEKDAY; 
				SelectWeekday(pCalendarButton->m_Calendar, isCtrlPressed, isShiftPressed); 
			} 
			else 
			{ 
				return TRUE; 
			} 
		} 
		else 
		{ 
			pCalendarButton = DYNAMIC_DOWNCAST (CCalendarWeekNumButton, pButton); 
			if (pCalendarButton) 
			{ 
			if (m_bIsTearOff  
				&& (m_styleFlags & CBCGPCalendarBar::CBR_MULTISELECTION) != 0  
				&& (m_styleFlags & CBCGPCalendarBar::CBR_WEEKNUMBER) != 0) 
				{ 
					buttonKind = Click_WEEKNO; 
					CString str = pCalendarButton->m_Calendar.Format (); 
					SelectWeek(pCalendarButton->m_Calendar, isCtrlPressed, isShiftPressed); 
				} 
				else 
				{ 
					return TRUE; 
				} 
			} 
			else 
			{ 
				pCalendarButton = DYNAMIC_DOWNCAST (CBCGPCalendarButton, pButton); 
				if (!isCtrlPressed && !isShiftPressed) 
					buttonKind = Click_DAY; 
				if (pCalendarButton != NULL) 
					SelectDay(pCalendarButton->m_Calendar, isCtrlPressed, isShiftPressed); 
			} 
		} 
	} 
	 
	if (pCalendarButton != NULL) 
	{ 
		date = pCalendarButton->m_Calendar; 
	} 
 
	if (pCalendarMenuButton != NULL) 
	{ 
		pCalendarMenuButton->SetDate (date); 
		InvokeMenuCommand (pCalendarMenuButton->m_nID, pCalendarMenuButton); 
	} 
	else if (m_pParentBtn != NULL) 
	{ 
		m_pParentBtn->SetDate (date); 
		GetParent ()->PostMessage (WM_CLOSE); 
	} 
	else if (Click_DAY == buttonKind) 
	{ 
		ASSERT (m_nCommandID != 0); 
 
		SetDate (date); 
 
		CObList listButtons; 
		if (CBCGPToolBar::GetCommandButtons (m_nCommandID, listButtons) > 0) 
		{ 
			for (POSITION pos = listButtons.GetHeadPosition (); pos != NULL;) 
			{ 
				CBCGPCalendarMenuButton* pButton =  
					DYNAMIC_DOWNCAST (CBCGPCalendarMenuButton, listButtons.GetNext (pos)); 
				if (pButton != NULL) 
				{ 
					pButton->SetDate (date, FALSE); 
				} 
			} 
		} 
 
		CBCGPCalendarMenuButton::SetCalendarByCmdID (m_nCommandID, date); 
		GetOwner()->SendMessage (WM_COMMAND, m_nCommandID);    // send command 
 
		if (BCGCBProGetTopLevelFrame (this) != NULL) 
		{ 
			BCGCBProGetTopLevelFrame (this)->SetFocus (); 
		} 
	} 
 
	return TRUE; 
} 
//************************************************************************************* 
BOOL CBCGPCalendarBar::Create( 
			CWnd*		pParentWnd, 
			DWORD		dwStyle, 
			UINT		nID, 
			BOOL		enableSelection) 
{ 
	if (enableSelection) 
	{ 
		m_styleFlags |= CBR_MULTISELECTION; 
	} 
	else 
	{ 
		m_styleFlags &= (~CBR_MULTISELECTION); 
	} 
 
	//TODO: calc from max(textheight and menuimageHeight) 
	//m_iTitleHeight = GetSystemMetrics(SM_CYCAPTION); 
	 
	 
	return CBCGPPopupMenuBar::Create (pParentWnd, dwStyle, nID); 
} 
//************************************************************************************ 
BOOL CBCGPCalendarBar::CreateControl ( 
				CWnd*			pParentWnd, 
				const CRect&	rect, 
				UINT			nID, 
				BOOL			enableSelection, 
				DWORD			dwStyle) 
{ 
	ASSERT_VALID (pParentWnd); 
 
	EnableLargeIcons (FALSE); 
 
	if (!Create (pParentWnd, dwStyle | CBRS_ALIGN_TOP, nID, enableSelection)) 
	{ 
		return FALSE; 
	} 
 
	//---------------------------- 
	// Remove borders and gripper: 
	//---------------------------- 
	SetBarStyle ( 
		GetBarStyle () 
        & ~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT)); 
 
	CRect rectWnd = rect; 
	MoveWindow (rectWnd); 
	 
	ContextToSize (); 
 
	SetOwner (pParentWnd); 
	SetCommandID (nID); 
 
	m_bIsCtrl = TRUE; 
 
	// All commands will be routed via this dialog, not via the parent frame: 
	SetRouteCommandsViaFrame (FALSE); 
	return TRUE; 
} 
//************************************************************************************* 
void CBCGPCalendarBar::Serialize (CArchive& ar) 
{ 
	CBCGPPopupMenuBar::Serialize (ar); 
 
	if (ar.IsLoading ()) 
	{ 
		ar >> m_bIsTearOff; 
		ar >> m_nCommandID; 
 
		Rebuild (); 
		AdjustLocations (); 
	} 
	else 
	{ 
		ar << m_bIsTearOff; 
		ar << m_nCommandID; 
	} 
} 
//************************************************************************************* 
void CBCGPCalendarBar::ShowCommandMessageString (UINT /*uiCmdId*/) 
{ 
	GetOwner()->SendMessage (WM_SETMESSAGESTRING, 
		m_nCommandID == (UINT) -1 ? AFX_IDS_IDLEMESSAGE : (WPARAM) m_nCommandID); 
} 
//************************************************************************************* 
void CBCGPCalendarBar::SetDate (const COleDateTime& date) 
{ 
	int iOldYear = m_dateSelected.GetYear(); 
	int iOldMonth = m_dateSelected.GetMonth(); 
	m_dateSelected = date; 
 
	if (GetSafeHwnd () == NULL) 
	{ 
		return; 
	} 
 
	COleDateTime firstDate = date; 
	m_LastAddedDate = date; 
	firstDate -= COleDateTimeSpan(firstDate.GetDay () - 1, 0, 0, 0); 
	 
	int iYear = m_dateSelected.GetYear(); 
	int iMonth = m_dateSelected.GetMonth(); 
 
	CRect capRect; 
	GetClientRect (capRect); 
	capRect.bottom = capRect.top + m_iTitleHeight; 
	InvalidateRect (capRect); 
 
	int dDelta = (firstDate.GetDayOfWeek () - m_nWeekStart + 7) % 7; 
 
	firstDate -= COleDateTimeSpan(dDelta, 0, 0, 0); 
	COleDateTime weekDay = firstDate; 
	weekDay += COleDateTimeSpan(7, 0, 0, 0); 
	 
	COleDateTime weekNo = firstDate; 
	weekNo += COleDateTimeSpan(6, 0, 0, 0); 
 
	m_iHighlighted = -1; 
	int iButton = 0; 
	int iNavBtn = 0; 
	COleDateTimeSpan oneDay(1,0,0,0); 
 
	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL; iButton++) 
	{ 
		CRect rectButton; 
 
		CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos); 
		if (pButton->m_nStyle & TBBS_SEPARATOR) 
		{ 
			continue; 
		} 
 
		COleDateTime dateToSet; 
		 
		if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarMonthButton))) 
		{ 
			CCalendarMonthButton* pmonBtn = DYNAMIC_DOWNCAST(CCalendarMonthButton, pButton); 
			pButton->m_strText = GetMonthName(date.GetMonth ()); 
 
			CSize btnSize = pmonBtn->ContextSize(this); 
			btnSize.cx += m_iTitleHeight; 
 
			GetClientRect (&rectButton); 
			rectButton.DeflateRect(0, 0, 0, rectButton.Height () - m_iTitleHeight + 1); 
			rectButton.DeflateRect((rectButton.Width () - btnSize.cx) / 2 + 1, 2); 
 
#ifndef DISABLE_MONTH_POPUP 
 
			if (!m_bIsTearOff || (m_styleFlags & CBCGPCalendarBar::CBR_NAVIGATION_BUTTONS) == 0) 
			{ 
				pButton->m_nStyle |= TBBS_DISABLED; 
			} 
			else 
			{ 
				pButton->m_nStyle &= ~TBBS_DISABLED; 
			} 
#else 
			pButton->m_nStyle |= TBBS_DISABLED; 
#endif 
			CRect invRect = pmonBtn->Rect(); 
			pButton->SetRect (rectButton); 
			InvalidateRect (invRect); 
			InvalidateRect (rectButton); 
			continue; 
		} 
		 
		if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekNumButton))) 
		{ 
			dateToSet = weekNo; 
			weekNo += COleDateTimeSpan(7, 0, 0, 0); 
			if (!(m_styleFlags & CBR_MULTISELECTION)  
				|| !m_bIsTearOff 
				|| !(m_styleFlags & CBR_WEEKNUMBER)) 
				pButton->m_nStyle |= TBBS_DISABLED; 
			else 
				pButton->m_nStyle &= ~TBBS_DISABLED; 
 
		} 
		else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarTodayButton))) 
		{ 
			dateToSet = COleDateTime::GetCurrentTime(); 
			pButton->m_nStyle &= ~TBBS_DISABLED; 
		} 
		else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarNavigateButton))) 
		{ 
			iNavBtn ++; 
			int iToYear = iYear; 
			int iToMonth = iMonth; 
			switch(iNavBtn) 
			{ 
			case 1: 
				{ 
					iToYear --; 
				} 
				break; 
			case 2: 
				{ 
					iToMonth --; 
					if (!iToMonth) 
					{ 
						iToMonth = 12; 
						iToYear --; 
					} 
				} 
				break; 
			case 3: 
				{ 
					iToMonth ++; 
					if (iToMonth > 12) 
					{ 
						iToMonth = 1; 
						iToYear ++; 
					} 
				} 
				break; 
			case 4: 
				{ 
					iToYear ++; 
				} 
				break; 
			} 
 
			dateToSet = COleDateTime(iToYear, iToMonth, 1, 0, 0, 0); 
			pButton->m_nStyle &= ~TBBS_DISABLED; 
		} 
		else if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekButton))) 
		{ 
			dateToSet = weekDay; 
			weekDay += oneDay; 
 
			 
			if (!(m_styleFlags & CBR_MULTISELECTION)  
				|| m_pParentBtn != NULL 
				|| !(m_styleFlags & CBR_WEEKDAYSEL)) 
				pButton->m_nStyle |= TBBS_DISABLED; 
			else 
				pButton->m_nStyle &= ~TBBS_DISABLED; 
		} 
		else if (pButton->IsKindOf (RUNTIME_CLASS (CBCGPCalendarButton))) 
		{ 
			dateToSet = firstDate; 
			firstDate += oneDay; 
		} 
		else  
		{ 
			continue; 
		} 
		 
		CBCGPCalendarButton* pCalendarButton = DYNAMIC_DOWNCAST (CBCGPCalendarButton, pButton); 
		if (pCalendarButton == NULL) 
		{ 
			continue; 
		} 
 
		ASSERT_VALID (pCalendarButton); 
 
		pCalendarButton->SetDate (dateToSet); 
		 
		if (pCalendarButton->m_bHighlight) 
		{ 
			pCalendarButton->m_bHighlight = FALSE; 
			CRect r = pCalendarButton->Rect (); 
			r.InflateRect (2, 2); 
			InvalidateRect (r); 
		} 
	} 
 
	if (iOldMonth != m_dateSelected.GetMonth() ||  
		iOldYear != m_dateSelected.GetYear()) 
	{ 
		OnSelectionChanged (); 
	} 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	if (!IsCustomizeMode () || m_bInternal) 
	{ 
		CBCGPToolBar::OnMouseMove(nFlags, point); 
	} 
 
	if (m_nHoldTimerID && GetCapture() == this) 
	{ 
		int iHit = HitTest (point); 
		if (iHit  == -1) 
		{ 
			KillTimer(m_nHoldTimerID); 
			m_nHoldTimerID = 0; 
		} 
	} 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnTimer(UINT nIDEvent)  
{ 
	if (nIDEvent != nHoldMouseTimerID) 
		return; 
 
	if (m_nElapseInterval > 100) 
	{ 
		m_nHoldTimerID = SetTimer (nHoldMouseTimerID, m_nElapseInterval -= 50, NULL); 
	} 
 
	CBCGPToolbarButton* pBtnHit = GetButton (m_iButtonCapture); 
	CCalendarNavigateButton* pNavi = DYNAMIC_DOWNCAST (CCalendarNavigateButton, pBtnHit); 
	if (pNavi) 
	{ 
		SetDate(pNavi ->m_Calendar); 
	} 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnLButtonDown(UINT nFlags, CPoint point)  
{ 
	//TODO: chech that hit-point is over navigate btn, start timer if so and each timer tick set new navi date 
	// maybe it is necessary to call SetCapture 
	if (IsCustomizeMode () && !m_bInternal) 
	{ 
		return; 
	} 
	int iHit = HitTest (point); 
 
	CBCGPToolBar::OnLButtonDown(nFlags, point); 
	SetFocus (); 
 
	CBCGPToolbarButton* pBtnHit = GetButton (iHit); 
	CCalendarNavigateButton* pNavi = DYNAMIC_DOWNCAST (CCalendarNavigateButton, pBtnHit); 
	if (pNavi) 
	{ 
		m_iButtonCapture = iHit; 
		SetCapture (); 
		CRect rect; 
		GetButtonRect (m_iButtonCapture, rect); 
		InvalidateRect(rect); 
		m_nHoldTimerID = SetTimer (nHoldMouseTimerID, m_nElapseInterval = 500, NULL); 
	} 
	else 
	{ 
		CCalendarMonthButton* pmonth = DYNAMIC_DOWNCAST (CCalendarMonthButton, pBtnHit); 
 
		if (pmonth != NULL) 
		{ 
			CRect rect = pmonth->Rect(); 
			OnSelectMonth(pmonth->Rect()); 
            OnChangeHot (-1); 
			InvalidateRect( rect ); 
			InvalidateRect( pmonth->Rect() ); 
    		UpdateWindow(); // immediate feedback 
		} 
	} 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnLButtonUp(UINT nFlags, CPoint point)  
{ 
	//Reset capturing if navi and finish timer 
		 
	if (!IsCustomizeMode () || m_bInternal) 
	{ 
		if (GetCapture() == this) 
		{ 
			KillTimer(m_nHoldTimerID); 
			m_nHoldTimerID = 0; 
		} 
		 
		HWND hwndSaved = m_hWnd; 
 
		CBCGPToolBar::OnLButtonUp(nFlags, point); 
        m_iButtonCapture = -1; 
 
    	if (::IsWindow (hwndSaved) &&				// "This" may be destoyed now! 
	    	m_bIsTearOff)	 
        { 
            int iPB = m_iHighlighted; 
            OnChangeHot (-1); 
            m_iHighlighted = m_iHot; 
            InvalidateButton(iPB); 
            if (m_iHighlighted >= 0) 
                InvalidateButton(m_iHighlighted); 
        } 
	} 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnLButtonDblClk(UINT nFlags, CPoint point)  
{ 
	if (!IsCustomizeMode () || m_bInternal) 
	{ 
		CBCGPToolBar::OnLButtonDblClk(nFlags, point); 
	} 
} 
//*************************************************************************************** 
BOOL CBCGPCalendarBar::PreTranslateMessage(MSG* pMsg) 
{ 
	if ((m_pParentBtn != NULL ) && !m_bInCommand) 
	{ 
		switch (pMsg->message) 
		{ 
		case WM_LBUTTONDOWN: 
		case WM_RBUTTONDOWN: 
		case WM_MBUTTONDOWN: 
			{ 
				CRect rect; 
				GetClientRect (rect); 
 
				CPoint pt (BCG_GET_X_LPARAM (pMsg->lParam), BCG_GET_Y_LPARAM (pMsg->lParam)); 
				if (!rect.PtInRect (pt)) 
				{ 
					GetParent ()->SendMessage (WM_CLOSE); 
					return TRUE; 
				} 
			} 
			break; 
 
		case WM_SYSKEYDOWN: 
		case WM_CONTEXTMENU: 
			GetParent ()->SendMessage (WM_CLOSE); 
			return TRUE; 
 
		case WM_KEYDOWN: 
			return OnKey(pMsg->wParam); 
		} 
	} 
    else if (m_bIsTearOff) 
    { 
		switch (pMsg->message) 
        { 
    		case WM_KEYDOWN: 
                return OnKey(pMsg->wParam); 
        } 
    } 
 
	return CBCGPPopupMenuBar::PreTranslateMessage(pMsg); 
} 
//************************************************************************************* 
void CBCGPCalendarBar::OnDestroy()  
{ 
	if (m_pParentBtn != NULL) 
	{ 
		m_pParentBtn->m_pPopup = NULL; 
		m_pParentBtn->SetFocus (); 
		m_pParentBtn->OnHideCalendarPopup(); 
		ReleaseCapture (); 
	} 
 
	CBCGPPopupMenuBar::OnDestroy(); 
} 
//**************************************************************************************** 
BOOL CBCGPCalendarBar::OnKey(UINT nChar) 
{ 
	BOOL  isCtrlPressed =  (0x8000 & GetKeyState(VK_CONTROL)) != 0; 
	BOOL  isShiftPressed = (0x8000 & GetKeyState(VK_SHIFT)) != 0; 
 
    switch (nChar) 
	{ 
 
    case VK_HOME: 
        { 
            SetDate (COleDateTime::GetCurrentTime()); 
			SelectDay(m_dateSelected, FALSE, FALSE); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
        } 
 
    case VK_ESCAPE: 
        if (m_pParentBtn != NULL) 
	    { 
		    GetParent ()->SendMessage (WM_CLOSE); 
		    return TRUE; 
	    } 
		break; 
	case VK_RETURN: 
        if (m_pParentBtn != NULL) 
	        { 
		        m_pParentBtn->SetDate (m_LastAddedDate); 
		        GetParent ()->SendMessage (WM_CLOSE); 
                return TRUE; 
	        } 
		break; 
 
    case VK_PRIOR: 
		if (!isCtrlPressed) 
        { 
            int mon = m_dateSelected.GetMonth(); 
            mon --; 
 
            if (mon < 1) 
                mon = 12; 
 
            int days = GetMaxMonthDay(COleDateTime(m_dateSelected.GetYear (), mon,  
                                m_dateSelected.GetDay(), 0, 0, 0)); 
 
            SetDate (m_LastAddedDate - COleDateTimeSpan(days, 0, 0, 0)); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
        } 
        else 
        { 
            SetDate (COleDateTime(m_dateSelected.GetYear () - 1, m_dateSelected.GetMonth(),  
                                m_dateSelected.GetDay(), 0, 0, 0)); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
        } 
 
	case VK_UP: 
		if (!isCtrlPressed) 
        { 
			SelectDay(m_LastAddedDate + COleDateTimeSpan(-7, 0, 0, 0), FALSE, isShiftPressed); 
            SetDate (m_LastAddedDate); 
            Invalidate(); 
            UpdateWindow(); 
		} 
		return TRUE; 
 
    case VK_NEXT: 
		if (!isCtrlPressed) 
        { 
            SetDate (m_LastAddedDate + COleDateTimeSpan(GetMaxMonthDay (m_dateSelected), 0, 0, 0)); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
        } 
        else 
        { 
            SetDate (COleDateTime(m_dateSelected.GetYear () + 1, m_dateSelected.GetMonth(),  
                                m_dateSelected.GetDay(), 0, 0, 0)); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
        } 
 
	case VK_DOWN: 
		if (!isCtrlPressed) 
		{ 
			SelectDay(m_LastAddedDate + COleDateTimeSpan(7, 0, 0, 0), FALSE, isShiftPressed); 
            SetDate (m_LastAddedDate); 
            Invalidate(); 
            UpdateWindow(); 
		} 
		return TRUE; 
 
	case VK_LEFT: 
		if (!isCtrlPressed) 
		{ 
			SelectDay(m_LastAddedDate + COleDateTimeSpan(-1, 0, 0, 0), FALSE, isShiftPressed); 
            SetDate (m_LastAddedDate); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
		} 
	case VK_RIGHT: 
		if (!isCtrlPressed) 
		{ 
			SelectDay(m_LastAddedDate + COleDateTimeSpan(1, 0, 0, 0), FALSE, isShiftPressed); 
            SetDate (m_LastAddedDate); 
            Invalidate(); 
            UpdateWindow(); 
			return TRUE; 
		} 
	} 
 
	return CBCGPPopupMenuBar::OnKey (nChar); 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::OnSelectMonth(LPCRECT lpRect) 
{ 
#ifndef DISABLE_MONTH_POPUP 
 
	if ((m_styleFlags & CBCGPCalendarBar::CBR_NAVIGATION_BUTTONS) && m_bIsTearOff) 
	{ 
		CBCGPWorkspace* pWS = GetWorkspace(); 
 
		if (!pWS) 
			return; 
 
		CMenu menu; 
 
		menu.CreatePopupMenu(); 
		for(int i = 0; i < 12; i ++) 
		{ 
			menu.AppendMenu(MF_STRING, BCGM_SETMONTHFIRST + i, GetMonthName(i + 1)); 
		} 
		CRect capRect(lpRect); 
		ClientToScreen(capRect); 
		int x = capRect.left; 
		int y = capRect.bottom; 
 
		CBCGPPopupMenu monthPopup; 
 
		CWnd* pParent = GetParent(); 
		if (pParent) 
			pParent = pParent->GetParent(); 
 
		if (!pParent) 
			pParent = this; 
 
		 
		UINT retID = pWS->GetContextMenuManager()->TrackPopupMenu (menu.Detach (), x, y, pParent); 
 
		if (retID) 
			OnMonthMenu(retID);	 
		else 
			InvalidateRect(lpRect); 
	} 
 
#endif 
} 
 
void CBCGPCalendarBar::OnMonthMenu(UINT id) 
{ 
#ifndef DISABLE_MONTH_POPUP 
	COleDateTime dt = m_dateSelected; 
	dt.SetDate (dt.GetYear(), id - BCGM_SETMONTHFIRST + 1, dt.GetDay()); 
	SetDate(dt); 
#endif 
} 
 
afx_msg LRESULT CBCGPCalendarBar::OnMouseLeave(WPARAM wp,LPARAM lp) 
{ 
	if (m_hookMouseHelp != NULL ||  
		(m_bMenuMode && !IsCustomizeMode () && GetDroppedDownMenu () != NULL)) 
	{ 
		return 0; 
	} 
 
	m_bTracked = FALSE; 
	m_ptLastMouse = CPoint (-1, -1); 
 
	if (m_iHighlighted >= 0) 
	{ 
		int iButton = m_iHighlighted; 
		m_iHighlighted = -1; 
 
		OnChangeHot (m_iHighlighted); 
 
		InvalidateButton (iButton); 
		UpdateWindow(); // immediate feedback 
 
		GetOwner()->SendMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE); 
	} 
 
	return 0; 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::SetVertMargin (int nVertMargin) 
{ 
	ASSERT_VALID (this); 
 
	m_nVertMargin = nVertMargin; 
	AdjustLayout (); 
} 
//***************************************************************************************** 
void CBCGPCalendarBar::SetHorzMargin (int nHorzMargin) 
{ 
	ASSERT_VALID (this); 
 
	m_nHorzMargin = nHorzMargin; 
	AdjustLayout (); 
} 
//************************************************************************************ 
LPCTSTR CBCGPCalendarBar::GetMonthName(int index) 
{ 
	ASSERT(index > 0 && index <= 12); 
 
	if (m_strMonthNames[0].IsEmpty()) 
	{ 
		CBCGPDefaultLocale dl; 
		COleDateTime today = COleDateTime::GetCurrentTime(); 
 
		for (int i = 0; i < 12; i ++) 
		{ 
			today.SetDate (today.GetYear(), i + 1, 1); 
			m_strMonthNames[i] = today.Format (_T("%B")); 
		} 
	} 
	 
	if (index > 0 && index <= 12) 
	{ 
		return m_strMonthNames[index - 1]; 
	} 
 
	return NULL; 
} 
 
//**************************************************************************************** 
void CBCGPCalendarBar::SelectWeekday(const COleDateTime& date, BOOL isCtrlPressed, BOOL isShiftPressed) 
{ 
	if (!(m_styleFlags & CBR_MULTISELECTION)) 
		return; 
	 
	int iMonth = m_dateSelected.GetMonth (); 
	int iYear = m_dateSelected.GetYear (); 
	int iDaysInMonth = GetMaxMonthDay (m_dateSelected); 
	int iWeekDay = date.GetDayOfWeek (); 
	 
	if (!isCtrlPressed && !isShiftPressed) 
	{ 
		ClearSelectedDays(); 
	} 
 
	for (int iDay = 1; iDay <= iDaysInMonth; iDay ++) 
	{ 
		COleDateTime date (iYear, iMonth, iDay, 0, 0, 0); 
		if (date.GetDayOfWeek () == iWeekDay) 
		{ 
			if (!isShiftPressed && IsDaySelected (date)) 
			{ 
				RemoveSelectedDay (iDay); 
			} 
			else 
			{ 
				m_LastAddedDate = date; 
				AddSelectedDay (iDay); 
			} 
		} 
	} 
 
	Invalidate (); 
	UpdateWindow (); 
 
	OnSelectionChanged (); 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::SelectWeek(const COleDateTime& date, BOOL isCtrlPressed, BOOL isShiftPressed) 
{ 
	if (!(m_styleFlags & CBR_MULTISELECTION)) 
		return; 
 
	int iMonth = m_dateSelected.GetMonth (); 
	int iYear = m_dateSelected.GetYear (); 
	int iDaysInMonth = GetMaxMonthDay (m_dateSelected); 
 
	int iWeekNo = CBCGPCalendarBar::GetWeekNo(date, m_nWeekStart); 
 
	if (!isCtrlPressed && !isShiftPressed) 
	{ 
		ClearSelectedDays(); 
	} 
 
	for (int iDay = 1; iDay <= iDaysInMonth; iDay ++) 
	{ 
		COleDateTime date (iYear, iMonth, iDay, 0, 0, 0); 
 
		if (	iWeekNo == CBCGPCalendarBar::GetWeekNo(date, m_nWeekStart)) 
		{ 
			if (!isShiftPressed && IsDaySelected (date)) 
			{ 
				RemoveSelectedDay (iDay); 
			} 
			else 
			{ 
				m_LastAddedDate = date; 
				AddSelectedDay (iDay); 
			} 
		} 
	} 
 
	Invalidate (); 
	UpdateWindow (); 
 
	OnSelectionChanged (); 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::SelectDaySequence(const COleDateTime& date) 
{ 
	int iFirst = 0, iLast = 0; 
	int d = date.GetDay (); 
	for (POSITION pos = m_lstSelectedDays.GetHeadPosition (); pos != NULL; ) 
	{ 
		int i = m_lstSelectedDays.GetNext (pos); 
		 
		if (!i) 
			continue; 
 
		if (iFirst == 0) 
			iFirst = i; 
 
		if (iLast == 0) 
			iLast = i; 
 
		if (iFirst > i) 
			iFirst = i; 
 
		if (iLast < i) 
			iLast = i; 
	} 
 
	if (d < iFirst) 
	{ 
		iFirst = d; 
	} 
	else  
	{ 
		iLast = d; 
	} 
 
	ASSERT(iFirst <= iLast && iFirst > 0); 
	 
	ClearSelectedDays(); 
 
	for (int i = iFirst; i <= iLast; i ++) 
	{ 
		m_LastAddedDate = date; 
		AddSelectedDay(i); 
	} 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::SelectDay(const COleDateTime& date, BOOL isCtrlPressed, BOOL isShiftPressed) 
{ 
	if (!(m_styleFlags & CBR_MULTISELECTION) || !isCtrlPressed && !isShiftPressed) 
	{ 
		ClearSelectedDays(); 
		m_LastAddedDate = date; 
		AddSelectedDay (date.GetDay()); 
	} 
 
    if (!m_bIsTearOff) 
    { 
        m_dateSelected = date; 
    } 
 
	if (date.GetMonth () == m_dateSelected.GetMonth()) 
		//return; 
	{ 
		if (isCtrlPressed) 
		{ 
			if (!IsDaySelected(date)) 
			{ 
				m_LastAddedDate = date; 
				AddSelectedDay (date.GetDay()); 
			} 
			else 
				RemoveSelectedDay(date.GetDay()); 
		} 
		else if (isShiftPressed) 
		{ 
			SelectDaySequence(date); 
		} 
	} 
 
	OnSelectionChanged(); 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::TranslateSelectionMode(SelectionMODE newMode) 
{ 
	if (m_selMode == newMode) 
		return; 
 
	CList dayList; 
 
	int year = m_dateSelected.GetYear (); 
	int mon = m_dateSelected.GetMonth (); 
 
	//dayList results in Select_BYDAYS mode 
	switch (m_selMode) 
	{ 
	case Select_BYDAYS: 
		{ 
			for (POSITION pos = m_lstSelectedDays.GetHeadPosition (); pos != NULL; ) 
			{ 
				int iDay = m_lstSelectedDays.GetNext (pos); 
				dayList.AddTail (iDay); 
			} 
		} 
		break; 
	case Select_BYWEEKS: 
		{ 
			int maxDays = GetMaxMonthDay(m_dateSelected); 
			for (int iDay = 1; iDay <= maxDays; iDay ++) 
			{ 
				int weekNo = (COleDateTime(year, mon, iDay, 0, 0, 0).GetDayOfYear () / 7); 
				POSITION pos = m_lstSelectedDays.Find(weekNo); 
				if (pos) 
					dayList.AddTail (iDay); 
			} 
		} 
		break; 
	case Select_BYWEEKDAYS: 
		{ 
			int maxDays = GetMaxMonthDay(m_dateSelected); 
			for (int iDay = 1; iDay <= maxDays; iDay ++) 
			{ 
				int weekNo = (COleDateTime(year, mon, iDay, 0, 0, 0).GetDayOfWeek()); 
				POSITION pos = m_lstSelectedDays.Find(weekNo); 
				if (pos) 
					dayList.AddTail (iDay); 
			} 
		} 
		break; 
	} 
 
	m_lstSelectedDays.RemoveAll(); 
 
	for (POSITION pos = dayList.GetHeadPosition (); pos != NULL; ) 
	{ 
		int iDay = dayList.GetNext (pos); 
		switch (newMode) 
		{ 
		case Select_BYDAYS: 
			{ 
				m_lstSelectedDays.AddTail (iDay); 
			} 
		break; 
		case Select_BYWEEKS: 
			{ 
				int weekNo = (COleDateTime(year, mon, iDay, 0, 0, 0).GetDayOfYear () / 7); 
				POSITION p = m_lstSelectedDays.Find (weekNo); 
				if (!p) 
				{ 
					m_lstSelectedDays.AddTail (weekNo); 
				} 
			} 
		break; 
		case Select_BYWEEKDAYS: 
			{ 
				int weekNo = (COleDateTime(year, mon, iDay, 0, 0, 0).GetDayOfWeek ()); 
				POSITION p = m_lstSelectedDays.Find (weekNo); 
				if (!p) 
				{ 
					m_lstSelectedDays.AddTail (weekNo); 
				} 
			} 
		break; 
		} 
	} 
	 
	m_selMode = newMode; 
} 
 
//**************************************************************************************** 
void CBCGPCalendarBar::ClearSelectedDays () 
{ 
	while (!m_lstSelectedDays.IsEmpty ()) 
	{ 
		int iDay = m_lstSelectedDays.RemoveHead (); 
		ASSERT (iDay >= 1 && iDay <= GetMaxMonthDay(m_dateSelected)); 
 
		CRect rect; 
		if (GetButtonRect(iDay, rect)) 
		{ 
			rect.InflateRect (2, 2); 
			InvalidateRect (rect); 
		} 
	} 
 
	UpdateWindow (); 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::AddSelectedDay (int iDay) 
{ 
	ASSERT (iDay >= 1 && iDay <= 31);// GetMaxMonthDay(m_dateSelected)); 
 
	BOOL bInserted = FALSE; 
 
	for (POSITION pos = m_lstSelectedDays.GetHeadPosition (); pos != NULL;) 
	{ 
		POSITION posSave = pos; 
		int iSelDay = m_lstSelectedDays.GetNext (pos); 
 
		if (iSelDay == iDay)	// Already in list, 
		{						// do nothing! 
			return; 
		} 
 
		if (iSelDay > iDay) 
		{ 
			m_lstSelectedDays.InsertBefore (posSave, iDay); 
			bInserted = TRUE; 
			break; 
		} 
	} 
 
	if (!bInserted) 
	{ 
		m_lstSelectedDays.AddTail (iDay); 
	} 
 
	CRect rect; 
	if (GetButtonRect(iDay, rect)) 
	{ 
		rect.InflateRect (2, 2); 
		InvalidateRect (rect); 
	} 
} 
//**************************************************************************************** 
void CBCGPCalendarBar::RemoveSelectedDay (int iDay) 
{ 
	ASSERT (iDay >= 1 && iDay <=  GetMaxMonthDay(m_dateSelected)); 
 
	for (POSITION pos = m_lstSelectedDays.GetHeadPosition (); pos != NULL;) 
	{ 
		POSITION posSave = pos; 
		if (m_lstSelectedDays.GetNext (pos) == iDay) 
		{ 
			m_lstSelectedDays.RemoveAt (posSave); 
 
			CRect rect; 
			if (GetButtonRect(iDay, rect)) 
			{ 
				rect.InflateRect(2, 2); 
				InvalidateRect (rect); 
			} 
			return; 
		} 
	} 
} 
//**************************************************************************************** 
BOOL CBCGPCalendarBar::IsDaySelected (const COleDateTime& date) const 
{ 
	int iDay = date.GetDay (); 
	if (date.GetMonth() !=  m_dateSelected.GetMonth()) 
	{ 
		return FALSE; 
	} 
 
	if (!m_bIsTearOff) 
	{ 
		return (date == m_dateSelected); 
	} 
 
	for (POSITION pos = m_lstSelectedDays.GetHeadPosition (); pos != NULL;) 
	{ 
		if (m_lstSelectedDays.GetNext (pos) == iDay) 
		{ 
			return TRUE; 
		} 
	} 
 
	return FALSE; 
} 
//**************************************************************************************** 
CBCGPCalendarButton* CBCGPCalendarBar::GetDayButton(int iID) const 
{ 
	BOOL isStarted = FALSE; 
	 
	CRuntimeClass* dayRT = RUNTIME_CLASS(CBCGPCalendarButton); 
	CString strRT = dayRT->m_lpszClassName; 
 
	for (POSITION pos = m_Buttons.GetHeadPosition (); pos != NULL; ) 
	{ 
		CBCGPToolbarButton* pButton = (CBCGPToolbarButton*) m_Buttons.GetNext (pos); 
		if (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekNumButton)) 
			|| (pButton->IsKindOf (RUNTIME_CLASS (CCalendarWeekButton)))) 
			continue; 
		if (pButton->m_nStyle & TBBS_SEPARATOR) 
			continue; 
 
		CRuntimeClass* pRunTime = pButton->GetRuntimeClass (); 
		if (pRunTime && strRT == pRunTime->m_lpszClassName) 
		{ 
			CBCGPCalendarButton* pCalendarButton = DYNAMIC_DOWNCAST (CBCGPCalendarButton, pButton);	 
			int day = pCalendarButton->m_Calendar.GetDay(); 
			if (day == 1) 
			{ 
				if (!isStarted) 
					isStarted = TRUE; 
				else break; 
			} 
 
			if (isStarted && day == iID) 
			{ 
				return pCalendarButton; 
			} 
		} 
	} 
 
	return NULL; 
} 
//**************************************************************************************** 
BOOL CBCGPCalendarBar::GetButtonRect (int iID, CRect& rect, BOOL isHitTest) const 
{ 
	CBCGPCalendarButton* pCalendarButton = GetDayButton(iID); 
	if (!pCalendarButton) 
		return FALSE; 
	rect = pCalendarButton->m_rect; 
	return TRUE; 
} 
//**************************************************************************************** 
int CBCGPCalendarBar::GetWeekNo(const COleDateTime& date, int weekStart) 
{ 
	COleDateTime Jan1 (date.GetYear(), 1, 1, 0, 0, 0); 
	int Jan1wd = Jan1.GetDayOfWeek (); 
	Jan1wd = (Jan1wd + 7 - weekStart) % 7 + 1; 
	int datewd = date.GetDayOfWeek (); 
	datewd = (datewd + 7 - weekStart) % 7 + 1; 
	int dd = datewd - Jan1wd; 
		//- weekStart + 1); 
 
	int dateyd = date.GetDayOfYear () - dd; 
	return dateyd / 7 + 1; 
} 
 
//**************************************************************************************** 
int CBCGPCalendarBar::GetMaxMonthDay(COleDateTime date) 
{  
	//for(date)	 
	int y = date.GetYear (); 
	int m = date.GetMonth(); 
	for(int i = 31; i > 0; i --) 
	{ 
		date.SetDate (y, m, i); 
		if (date.GetStatus() == COleDateTime::valid) 
			return i; 
	}	 
	return 0; 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::OnSelectionChanged () 
{ 
	if (!m_bIsTearOff) 
	{ 
		return; 
	} 
 
	CWnd* pOwner = GetOwner (); 
	ASSERT_VALID (pOwner); 
 
	pOwner->SendMessage (BCGM_CALENDAR_ON_SELCHANGED, 
		0, (LPARAM) GetSafeHwnd ()); 
} 
//*************************************************************************************** 
void CBCGPCalendarBar::SetFirstDayOfWeek (int nDay) 
{ 
	ASSERT_VALID (this); 
	ASSERT (nDay >= 0 && nDay < 7); 
 
	m_nWeekStart = nDay + 1; 
	SetDate (m_dateSelected); 
} 
//************************************************************************************* 
int CBCGPCalendarBar::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)  
{ 
	return CBCGPBaseToolBar::OnMouseActivate(pDesktopWnd, nHitTest, message); 
} 
//************************************************************************************* 
void CBCGPCalendarBar::SelectDays (const CList& lstDays, 
									 BOOL bRedraw) 
{ 
	if (!(m_styleFlags & CBR_MULTISELECTION)) 
	{ 
		ASSERT (FALSE); 
		return; 
	} 
 
	m_lstSelectedDays.RemoveAll (); 
	m_lstSelectedDays.AddTail ((CList*) &lstDays); 
 
	if (GetSafeHwnd () != NULL) 
	{ 
		RedrawWindow (); 
	} 
} 
//************************************************************************************* 
void CBCGPCalendarBar::MarkDays (const CList& lstDays, 
								 BOOL bRedraw) 
{ 
	m_lstMarkedDays.RemoveAll (); 
	m_lstMarkedDays.AddTail ((CList*) &lstDays); 
 
	if (GetSafeHwnd () != NULL) 
	{ 
		RedrawWindow (); 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPCalendarButton 
 
IMPLEMENT_SERIAL(CBCGPCalendarButton, CBCGPToolbarButton, 1) 
 
CBCGPCalendarButton::CBCGPCalendarButton(const COleDateTime& date, BOOL bHighlight) 
{ 
	m_Calendar = date; 
	m_bHighlight = bHighlight; 
	m_strText.Format(_T("%d"), date.GetDay ()); 
	m_pParentBar = NULL; 
} 
 
CBCGPCalendarButton::CBCGPCalendarButton() 
{ 
    m_Calendar = COleDateTime::GetCurrentTime(); 
	m_bHighlight = FALSE; 
	m_strText.Format(_T("%d"), m_Calendar.GetDay ()); 
	m_pParentBar = NULL; 
} 
 
BOOL CBCGPCalendarButton::OnToolHitTest(const CWnd* /*pWnd*/, TOOLINFO* pTI) 
{ 
	return FALSE; 
} 
 
void CBCGPCalendarButton::OnChangeParentWnd (CWnd* pWndParent) 
{ 
	CBCGPToolbarButton::OnChangeParentWnd (pWndParent); 
	m_pParentBar = DYNAMIC_DOWNCAST (CBCGPCalendarBar, pWndParent); 
} 
 
void CBCGPCalendarButton::SetDate (const COleDateTime& date) 
{ 
	if (date != m_Calendar) 
	{ 
		m_Calendar = date; 
		m_strText.Format(_T("%d"), date.GetDay ()); 
		CRect invRect = m_rect; 
		invRect.InflateRect (2, 2); 
		m_pParentBar->InvalidateRect(m_rect); 
	} 
} 
 
void CBCGPCalendarButton::OnDraw (CDC* pDC, const CRect& rect, CBCGPToolBarImages* pImages, 
								BOOL bHorz, BOOL bCustomizeMode, BOOL bHighlight, 
								BOOL bDrawBorder, BOOL bGrayDisabledButtons) 
{ 
	ASSERT_VALID (this); 
 
	BOOL isSelected = IsSelected(); 
	UINT nStyle = m_nStyle; 
 
	if (m_bHighlight) 
	{ 
		m_nStyle |= TBBS_CHECKED; 
	} 
 
	if (isSelected) 
		m_nStyle |= TBBS_CHECKED; 
	else 
		m_nStyle &= ~TBBS_CHECKED; 
	 
	CBCGPToolbarButton::OnDraw (pDC, rect, pImages, 
			bHorz, bCustomizeMode, bHighlight, bDrawBorder, bGrayDisabledButtons); 
 
	//------------------ 
	// Draw today frame: 
	//------------------ 
	COleDateTime today = COleDateTime::GetCurrentTime(); 
	if (IsActualDay () && today.GetMonth () == m_Calendar.GetMonth () && 
			today.GetDay () == m_Calendar.GetDay () && 
			today.GetYear () == m_Calendar.GetYear ()) 
	{ 
		CRect rectToday = rect; 
		rectToday.DeflateRect (afxData.cxBorder2 - 1, afxData.cyBorder2 -  1); 
		pDC->Draw3dRect (rectToday, globalData.clrBarShadow, 
									globalData.clrBarShadow); 
		rectToday.bottom = rectToday.top + 2; 
		rectToday.top -= 1; 
		pDC->FillSolidRect (rectToday, globalData.clrBarShadow); 
	} 
 
	//------------ 
	// Draw label: 
	//------------ 
	if (m_iImage < 0) 
	{ 
		CFont* pOldFont = NULL; 
 
		if (IsCurrMonth () && IsActualDay () && 
			m_pParentBar->m_lstMarkedDays.Find (m_Calendar.GetDay()) != NULL) 
		{ 
			pOldFont = pDC->SelectObject (&globalData.fontBold); 
			ASSERT (pOldFont != NULL); 
		} 
 
		CBCGPVisualManager::BCGBUTTON_STATE state = CBCGPVisualManager::ButtonsIsRegular; 
 
		if (bHighlight) 
		{ 
			state = CBCGPVisualManager::ButtonsIsHighlighted; 
		} 
		else if (m_nStyle & (TBBS_PRESSED | TBBS_CHECKED)) 
		{ 
			//----------------------- 
			// Pressed in or checked: 
			//----------------------- 
			state = CBCGPVisualManager::ButtonsIsPressed; 
		} 
 
		COLORREF clrText = CBCGPVisualManager::GetInstance ()->GetToolbarButtonTextColor ( 
			this, state); 
 
		pDC->SetTextColor (clrText); 
 
		CRect rectText = rect; 
		pDC->DrawText (m_strText, &rectText,  
			DT_SINGLELINE | DT_VCENTER | DT_CENTER | DT_END_ELLIPSIS); 
 
		if (pOldFont != NULL) 
		{ 
			pDC->SelectObject (pOldFont); 
		} 
	} 
 
	m_nStyle = nStyle; 
} 
//************************************************************************************* 
BOOL CBCGPCalendarButton::IsCurrMonth () const 
{ 
	ASSERT_VALID (m_pParentBar); 
	return (m_pParentBar->m_dateSelected.GetMonth () == m_Calendar.GetMonth ()); 
} 
//******************************************************************************** 
void CBCGPCalendarBar::OnSize(UINT nType, int cx, int cy)  
{ 
	CBCGPPopupMenuBar::OnSize(nType, cx, cy); 
	 
	ContextToSize (); 
	RedrawWindow (); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CBCGPDefaultLocale 
 
CBCGPDefaultLocale::CBCGPDefaultLocale () 
{ 
	m_strLanguage = CString (_tsetlocale (LC_TIME, NULL)); 
	 
	int nLen = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE , NULL, 0); 
	 
	TCHAR* pzBuffer = new TCHAR [nLen + 1]; 
	pzBuffer[nLen] = NULL; 
 
	nLen = GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, pzBuffer, nLen); 
	CString strLocale = CString (pzBuffer) + _T("_"); 
	delete [] pzBuffer; 
	 
	nLen = GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SENGCOUNTRY, NULL, 0); 
	 
	pzBuffer = new TCHAR [nLen + 1]; 
	pzBuffer [nLen] = NULL; 
 
	nLen = GetLocaleInfo (LOCALE_USER_DEFAULT, LOCALE_SENGCOUNTRY, pzBuffer, nLen); 
	strLocale += pzBuffer; 
	delete [] pzBuffer; 
	 
	_tsetlocale (LC_TIME, strLocale); 
} 
//************************************************************************************** 
CBCGPDefaultLocale::~CBCGPDefaultLocale () 
{ 
	_tsetlocale(LC_TIME, m_strLanguage); 
}