recurringtaskedit.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 413 行

CPP
413
字号
// RecurrenceEdit.cpp: implementation of the CRecurringTaskEdit class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RecurringTaskEdit.h"
#include "resource.h"

#include "..\shared\datehelper.h"
#include "..\shared\dialoghelper.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRecurringTaskEdit::CRecurringTaskEdit()
{
	AddButton(1, "...", "Options");
}

CRecurringTaskEdit::~CRecurringTaskEdit()
{

}

BEGIN_MESSAGE_MAP(CRecurringTaskEdit, CEnEdit)
	//{{AFX_MSG_MAP(CRecurringTaskEdit)
	ON_WM_SETCURSOR()
	ON_WM_CTLCOLOR_REFLECT()
	//}}AFX_MSG_MAP
	ON_MESSAGE(EM_SETREADONLY, OnSetReadOnly)
	ON_WM_STYLECHANGING()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////

void CRecurringTaskEdit::PreSubclassWindow()
{
	CEnEdit::PreSubclassWindow();

	SetWindowText(GetRegularity()); // for display purposes
}

void CRecurringTaskEdit::OnBtnClick(UINT nID)
{
	switch (nID)
	{
	case 1:
		if (!m_bReadOnly)
		{
			CRecurringTaskOptionDlg dialog(m_tr, m_dtDefault);

			if (dialog.DoModal() == IDOK)
			{
				TDIRECURRENCE tr;
				dialog.GetRecurrenceOptions(tr);

				if (m_tr != tr)
				{
					m_tr = tr;
					SetWindowText(GetRegularity()); // for display purposes

					// notify parent
					GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(EN_CHANGE, GetDlgCtrlID()), (LPARAM)GetSafeHwnd());
				}
			}
		}
		break;
	}
}

BOOL CRecurringTaskEdit::OnSetCursor(CWnd* /*pWnd*/, UINT /*nHitTest*/, UINT /*message*/) 
{
	::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
	
	return TRUE;//CEnEdit::OnSetCursor(pWnd, nHitTest, message);
}

HBRUSH CRecurringTaskEdit::CtlColor(CDC* pDC, UINT /*nCtlColor*/) 
{
	HBRUSH hbr = NULL;
	pDC->SetBkMode(TRANSPARENT);

	if (!IsWindowEnabled() || m_bReadOnly)
		hbr = GetSysColorBrush(COLOR_3DFACE);
	else
		hbr = GetSysColorBrush(COLOR_WINDOW);

	return hbr;
}

void CRecurringTaskEdit::GetRecurrenceOptions(TDIRECURRENCE& tr) const
{
	tr = m_tr;
}

void CRecurringTaskEdit::SetRecurrenceOptions(const TDIRECURRENCE& tr)
{
	m_tr = tr;

	if (GetSafeHwnd())
		SetWindowText(GetRegularity()); // for display purposes
}

BOOL CRecurringTaskEdit::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT /*nFlags*/)
{
	if ((dwRemove & ES_READONLY) != (dwAdd & ES_READONLY))
	{
		m_bReadOnly = (dwAdd & ES_READONLY);
		
		EnableButton(1, !m_bReadOnly);
		Invalidate();
	}

	// make sure we stay readonly
	return CEnEdit::ModifyStyle(dwRemove & ~ES_READONLY, dwAdd | ES_READONLY);
}

LRESULT CRecurringTaskEdit::OnSetReadOnly(WPARAM wp, LPARAM /*lp*/)
{
	m_bReadOnly = wp;
	EnableButton(1, !m_bReadOnly);

	// always set to readonly
	return DefWindowProc(EM_SETREADONLY, TRUE, 0);
}

void CRecurringTaskEdit::OnStyleChanging(int nStyleType, LPSTYLESTRUCT lpStyleStruct)
{
	CEnEdit::OnStyleChanging(nStyleType, lpStyleStruct);

	if (nStyleType == GWL_STYLE)
	{
		// check for change in readonly style
		if ((lpStyleStruct->styleOld & ES_READONLY) != (lpStyleStruct->styleNew & ES_READONLY))
		{
			m_bReadOnly = (lpStyleStruct->styleNew & ES_READONLY);
			lpStyleStruct->styleNew |= ES_READONLY; // make sure we stay readonly

			EnableButton(1, !m_bReadOnly);
			Invalidate();
		}
	}
}

CString CRecurringTaskEdit::GetRegularity() const
{
	return GetRegularity(m_tr.nRegularity);
}

CString CRecurringTaskEdit::GetRegularity(TDI_REGULARITY nRegularity)
{
	CString sRegularity;

	switch (nRegularity)
	{
	case TDIR_ONCE:    sRegularity.LoadString(IDS_ONCEONLY); break;
	case TDIR_DAILY:   sRegularity.LoadString(IDS_DAILY);    break;
	case TDIR_WEEKLY:  sRegularity.LoadString(IDS_WEEKLY);   break;
	case TDIR_MONTHLY: sRegularity.LoadString(IDS_MONTHLY);  break;
	case TDIR_YEARLY:  sRegularity.LoadString(IDS_YEARLY);   break;
	}

	return sRegularity;
}

int CRecurringTaskEdit::CalcMaxRegularityWidth(CDC* pDC, BOOL bIncOnce)
{
	int nReg = (int)TDIR_YEARLY + 1;
	int nMax = 0;

	while (nReg-- && (bIncOnce || nReg > TDIR_ONCE))
	{
		int nItem = pDC->GetTextExtent(GetRegularity((TDI_REGULARITY)nReg)).cx;
		nMax = max(nItem, nMax);
	}

	return nMax;
}

/////////////////////////////////////////////////////////////////////////////
// CRecurringTaskOptionDlg dialog

#define WM_VALUECHANGE (WM_APP+1)

CRecurringTaskOptionDlg::CRecurringTaskOptionDlg(const TDIRECURRENCE& tr, const COleDateTime& dtDefault, CWnd* pParent /*=NULL*/)
	: CDialog(IDD_RECURRING_TASK_DIALOG, pParent)
{
	//{{AFX_DATA_INIT(CRecurringTaskOptionDlg)
	m_nRegularity = tr.nRegularity;
	m_bRecalcFromDue = tr.bRecalcFromDue;
	//}}AFX_DATA_INIT
	m_nNumDays = 1;
	m_nNumWeeks = 1;
	m_dwWeekdays = 0;
	m_nNumMonths = 1;
	m_nMonthDay = 1;
	m_nMonth = 0;
	m_nYearMonthDay = 1;

	// first set to default values
	if (dtDefault.m_dt > 0.0)
	{
		SYSTEMTIME stDefault;
		dtDefault.GetAsSystemTime(stDefault);

		m_dwWeekdays = 2 << (stDefault.wDayOfWeek - 1);
		m_nMonthDay = stDefault.wDay;
		m_nMonth = stDefault.wMonth - 1;
		m_nYearMonthDay = stDefault.wDay;
	}
	
	// then overwrite specific values
	switch (tr.nRegularity)
	{
	case TDIR_DAILY:
		m_nNumDays = tr.dwSpecific1;
		break;

	case TDIR_WEEKLY:
		m_nNumWeeks = tr.dwSpecific1;
		m_dwWeekdays = tr.dwSpecific2;
		break;

	case TDIR_MONTHLY:
		m_nNumMonths = tr.dwSpecific1;
		m_nMonthDay = tr.dwSpecific2;
		break;

	case TDIR_YEARLY:
		m_nMonth = tr.dwSpecific1 - 1;
		m_nYearMonthDay = tr.dwSpecific2;
		break;
	}
}


void CRecurringTaskOptionDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRecurringTaskOptionDlg)
	DDX_Radio(pDX, IDC_ONCE, m_nRegularity);
	DDX_CBIndex(pDX, IDC_RECALCFROM, m_bRecalcFromDue);
	//}}AFX_DATA_MAP
	CDialogHelper::DDX_Text(pDX, IDC_DAYS, m_nNumDays);
	DDX_Control(pDX, IDC_WEEKDAYS, m_lbWeekdays);

	CDialogHelper::DDX_Text(pDX, IDC_WEEKS, m_nNumWeeks);

	if (pDX->m_bSaveAndValidate)
	{
		m_dwWeekdays = 0;

		if (m_lbWeekdays.GetCheck(0))
			m_dwWeekdays |= TDIW_SUNDAY;

		if (m_lbWeekdays.GetCheck(1))
			m_dwWeekdays |= TDIW_MONDAY;

		if (m_lbWeekdays.GetCheck(2))
			m_dwWeekdays |= TDIW_TUESDAY;

		if (m_lbWeekdays.GetCheck(3))
			m_dwWeekdays |= TDIW_WEDNESDAY;

		if (m_lbWeekdays.GetCheck(4))
			m_dwWeekdays |= TDIW_THURSDAY;

		if (m_lbWeekdays.GetCheck(5))
			m_dwWeekdays |= TDIW_FRIDAY;

		if (m_lbWeekdays.GetCheck(6))
			m_dwWeekdays |= TDIW_SATURDAY;
	}
	else
	{
		m_lbWeekdays.SetCheck(0, (m_dwWeekdays & TDIW_SUNDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(1, (m_dwWeekdays & TDIW_MONDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(2, (m_dwWeekdays & TDIW_TUESDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(3, (m_dwWeekdays & TDIW_WEDNESDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(4, (m_dwWeekdays & TDIW_THURSDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(5, (m_dwWeekdays & TDIW_FRIDAY) ? 1 : 0);
		m_lbWeekdays.SetCheck(6, (m_dwWeekdays & TDIW_SATURDAY) ? 1 : 0);
	}
	CDialogHelper::DDX_Text(pDX, IDC_MONTHS, m_nNumMonths);
	CDialogHelper::DDX_Text(pDX, IDC_MONTHDAY, m_nMonthDay);

	DDX_Control(pDX, IDC_MONTHLIST, m_cbMonths);
	DDX_CBIndex(pDX, IDC_MONTHLIST, m_nMonth);
	DDX_Text(pDX, IDC_YEARMONTHDAY, m_nYearMonthDay);
}

BEGIN_MESSAGE_MAP(CRecurringTaskOptionDlg, CDialog)
	//{{AFX_MSG_MAP(CRecurringTaskOptionDlg)
	//}}AFX_MSG_MAP
//	ON_MESSAGE(WM_VALUECHANGE, OnValueChange)
	ON_BN_CLICKED(IDC_ONCE, OnSelchangeRegularity)
	ON_BN_CLICKED(IDC_DAILY, OnSelchangeRegularity)
	ON_BN_CLICKED(IDC_WEEKLY, OnSelchangeRegularity)
	ON_BN_CLICKED(IDC_MONTHLY, OnSelchangeRegularity)
	ON_BN_CLICKED(IDC_YEARLY, OnSelchangeRegularity)
	ON_EN_CHANGE(IDC_DAYS, OnChangeDailyValues)
	ON_EN_CHANGE(IDC_WEEKS, OnChangeWeeklyValues)
	ON_CLBN_CHKCHANGE(IDC_WEEKDAYS, OnChangeWeeklyValues)
	ON_EN_CHANGE(IDC_MONTHDAY, OnChangeMonthlyValues)
	ON_EN_CHANGE(IDC_MONTHS, OnChangeMonthlyValues)
	ON_CBN_SELCHANGE(IDC_MONTHLIST, OnChangeYearlyValues)
	ON_EN_CHANGE(IDC_YEARMONTHDAY, OnChangeYearlyValues)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRecurringTaskOptionDlg message handlers
/////////////////////////////////////////////////////////////////////////////

void CRecurringTaskOptionDlg::GetRecurrenceOptions(TDIRECURRENCE& tr) const
{
	tr.nRegularity = (TDI_REGULARITY)m_nRegularity;
	tr.bRecalcFromDue = m_bRecalcFromDue;

	switch (tr.nRegularity)
	{
	case TDIR_DAILY:
		tr.dwSpecific1 = m_nNumDays;
		break;

	case TDIR_WEEKLY:
		tr.dwSpecific1 = m_nNumWeeks;
		tr.dwSpecific2 = m_dwWeekdays;
		break;

	case TDIR_MONTHLY:
		tr.dwSpecific1 = m_nNumMonths;
		tr.dwSpecific2 = m_nMonthDay;
		break;

	case TDIR_YEARLY:
		tr.dwSpecific1 = m_nMonth + 1;
		tr.dwSpecific2 = m_nYearMonthDay;
		break;
	}
}

void CRecurringTaskOptionDlg::OnSelchangeRegularity() 
{
	UpdateData();

	GetDlgItem(IDC_RECALCFROM)->EnableWindow(m_nRegularity != TDIR_ONCE);
	GetDlgItem(IDC_DAYS)->EnableWindow(m_nRegularity == TDIR_DAILY);
	GetDlgItem(IDC_WEEKDAYS)->EnableWindow(m_nRegularity == TDIR_WEEKLY);
	GetDlgItem(IDC_WEEKS)->EnableWindow(m_nRegularity == TDIR_WEEKLY);
	GetDlgItem(IDC_MONTHDAY)->EnableWindow(m_nRegularity == TDIR_MONTHLY);
	GetDlgItem(IDC_MONTHS)->EnableWindow(m_nRegularity == TDIR_MONTHLY);
	GetDlgItem(IDC_MONTHLIST)->EnableWindow(m_nRegularity == TDIR_YEARLY);
	GetDlgItem(IDC_YEARMONTHDAY)->EnableWindow(m_nRegularity == TDIR_YEARLY);
}

BOOL CRecurringTaskOptionDlg::OnInitDialog()  
{
	CDialog::OnInitDialog();
	
	// init weekdays
	for (int nDay = 1; nDay <= 7; nDay++)
		m_lbWeekdays.AddString(CDateHelper::GetWeekday(nDay, FALSE));

	// restore check states
	UpdateData(FALSE);

	// set the listbox column width to be half the width
	CRect rListbox;
	m_lbWeekdays.GetClientRect(rListbox);
	m_lbWeekdays.SetColumnWidth(rListbox.Width() / 2);

	OnSelchangeRegularity();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CRecurringTaskOptionDlg::OnChangeDailyValues()
{
	UpdateData();

	GetDlgItem(IDOK)->EnableWindow(m_nNumDays > 0);
}

void CRecurringTaskOptionDlg::OnChangeWeeklyValues()
{
	UpdateData();

	GetDlgItem(IDOK)->EnableWindow(m_nNumWeeks > 0/* && m_dwWeekdays != 0*/);
}

void CRecurringTaskOptionDlg::OnChangeMonthlyValues()
{
	UpdateData();

	GetDlgItem(IDOK)->EnableWindow(m_nNumMonths && (m_nMonthDay > 0 && m_nMonthDay <= 31));
}

void CRecurringTaskOptionDlg::OnChangeYearlyValues()
{
	UpdateData();

	GetDlgItem(IDOK)->EnableWindow(m_nMonth >= 0 && m_nMonth < 12) && (m_nYearMonthDay > 0 && m_nYearMonthDay <= 31);
}

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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