⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcgpdatetimectrl.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -