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

📄 ymselector.cpp

📁 选择年/月的控制   选择年/月的控制  
💻 CPP
字号:
// YMSelector.cpp : implementation file
// Control to select year and month
// Designed and developed by Shekar Narayanan, 4th July 1998
// ShekarNarayanan@Hotmail.com
// 
// Modified : Jeremy Davis, 3rd December 1998
//            jmd@jvf.co.uk
//
// Changes :
//	(03/12/98)
//	- Month / Year  display window more "3D"
//	- "Cool-look" flat button for "+" and "-" buttons
//	- Dropdown button enlarged to match height of month/Year display window
//	- Colour of popup window changed
//  - Cell borders removed
//	- 3D borders added to popup window and "+" and "-" buttons
//	- Cursor / Arrow keys now move month selection in popup window
//	- <SPACE> / <RETURN> within the popup window now choose the selection
//  - Keith Rule's (keithr@europa.com) CMemDC class used to stop flickering
//
// Future Changes / Additions :
//	- Click outside popup window cause the same action as <ESC>



#include "stdafx.h"
#include "YMSelector.h"

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


static char *Months[] =
{
    "一月",
    "二月",
    "三月",
    "四月",
    "五月",
    "六月",
    "七月",
    "八月",
    "九月",
    "十月",
    "十一月",
    "十二月"
};

/////////////////////////////////////////////////////////////////////////////
// CYMPopUp

CYMPopUp::CYMPopUp(CPoint p, CWnd* pParent, int nYear, int nMonth) 
: m_bkBrush(::GetSysColor(COLOR_INFOBK))
{
    if  (-1 == nYear)
        m_nYear     = CTime::GetCurrentTime().GetYear();
    else
        m_nYear     = nYear;

    if  (-1 == nMonth)
        m_nMonth    = CTime::GetCurrentTime().GetMonth() -1;
    else
        m_nMonth    = nMonth -1;

	m_inPlus	= FALSE;
	m_inMinus = FALSE;

    ASSERT(m_nYear >= START_YEAR && m_nYear <= END_YEAR);
    ASSERT(m_nMonth >= 0   && m_nMonth <= 11 );

    Create(p, pParent);
}


CYMPopUp::~CYMPopUp()
{
    m_bkBrush.DeleteObject();
}


BEGIN_MESSAGE_MAP(CYMPopUp, CWnd)
	//{{AFX_MSG_MAP(CYMPopUp)
	ON_WM_NCDESTROY()
	ON_WM_LBUTTONUP()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	ON_WM_ERASEBKGND()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CYMPopUp message handlers


BOOL CYMPopUp::Create(CPoint p, CWnd* pParent)
{
    m_pParent = pParent;
    ASSERT(m_pParent);

    CString szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW,
                                              0, (HBRUSH)m_bkBrush,0);

    if (!CWnd::CreateEx(0, szClassName, _T(""), WS_VISIBLE|WS_POPUP/*|WS_BORDER*/, 
                        p.x, p.y, 200, 100, 
                        pParent->GetSafeHwnd(), 0, NULL))
        return FALSE;

    m_pParent->EnableWindow(false);

    UpdateWindow();


    return TRUE;
}

void CYMPopUp::OnNcDestroy() 
{
	CWnd::OnNcDestroy();
    delete this;
	
	
}


void CYMPopUp::OnPaint() 
{
	CPaintDC	PaintDC(this);
	CMemDC		dc(&PaintDC);
    CString     Buffer;
    CRect       rClient;
    CRect       rCell;
    CRect       rStart;
    CFont       fText;
    CFont*      pfdc;
    short       nCellHeight;
    short       nCellWidth;
    short       nIndex = 0;


    GetClientRect(rClient);
	dc.FillSolidRect(rClient, ::GetSysColor(COLOR_BTNFACE));
	dc.DrawEdge(rClient, EDGE_RAISED, BF_RECT);
    rClient.DeflateRect(2,2);

    m_rMinus.CopyRect(rClient);
	m_rMinus.left	= rClient.left + 1;
	m_rMinus.top	= rClient.top + 1;
    m_rMinus.right  = m_rMinus.left + 30;
    m_rMinus.bottom = m_rMinus.top + 16;

    m_rPlus.CopyRect(rClient);
	m_rPlus.right	= rClient.right - 1;
	m_rPlus.top		= rClient.top + 1;
    m_rPlus.left    = m_rPlus.right - 30;
    m_rPlus.bottom  = m_rPlus.top + 16;

    m_rYear.CopyRect(rClient);
    m_rYear.left    = m_rMinus.right + 5;
    m_rYear.right   = m_rPlus.left   - 5;
    m_rYear.bottom  = m_rYear.top    + 20;
	
    fText.DeleteObject();
    fText.CreateFont(-12, 0, 0, 0, 700, 0, 0, 0, 1, 0, 0, DRAFT_QUALITY, 0, _T("MS Sans Serif") );
    pfdc = dc.SelectObject(&fText);

    dc.SetBkColor(::GetSysColor(COLOR_BTNFACE));
    dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT));

	dc.SetBkMode(TRANSPARENT);
    Buffer.Format("%d", m_nYear);
    dc.DrawText(Buffer, m_rYear, DT_CENTER|DT_VCENTER|DT_SINGLELINE);


	if (m_inMinus)
		dc.DrawEdge(&m_rMinus, EDGE_RAISED, BF_RECT);
	if (m_inPlus)
		dc.DrawEdge(&m_rPlus, EDGE_RAISED, BF_RECT);

	dc.SelectObject(pfdc);
    fText.DeleteObject();
    fText.CreatePointFont(80,"MS Sans Serif");
	pfdc = dc.SelectObject(&fText);

    dc.DrawText("<<", m_rMinus, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    dc.DrawText(">>", m_rPlus, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
    dc.SetBkMode(OPAQUE);

    

    nCellHeight     = rClient.Height() / 5;
    nCellWidth      = rClient.Width() / 3;

    rCell.left      = rClient.left;
    rCell.top       = rClient.top + nCellHeight;
    rCell.right     = rCell.left  + nCellWidth;
    rCell.bottom    = rCell.top   + nCellHeight;

    rStart.CopyRect(rCell);
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            CRect   rCurSel(rCell);
            
            if  ( m_nMonth == nIndex )
            {
                dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_HIGHLIGHT));
                dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
            }
            else
            {
                dc.FillSolidRect(rCurSel,::GetSysColor(COLOR_BTNFACE));
                dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
            }

            dc.DrawText(Months[nIndex], rCell, DT_VCENTER|DT_CENTER|DT_SINGLELINE);
            m_rCells[nIndex].CopyRect(rCell);

            rCell.OffsetRect(nCellWidth,0);
            nIndex++;
        }

        rStart.OffsetRect(0,nCellHeight);
        rCell.CopyRect(rStart);
    }

    dc.SelectObject(pfdc);
    fText.DeleteObject();

}

void CYMPopUp::OnLButtonDown(UINT nFlags, CPoint point) 
{
    CClientDC   dc(this);
	CWnd::OnLButtonDown(nFlags, point);

    for (int i = 0; i < 12; i++)
    {
        if  (m_rCells[i].PtInRect(point))
        {
            InvalidateRect(m_rCells[m_nMonth]);
            m_nMonth = i;
            InvalidateRect(m_rCells[i]);
            return;
        }
    }

    if  (m_rMinus.PtInRect(point))
        dc.InvertRect(m_rMinus);

    if  (m_rPlus.PtInRect(point))
        dc.InvertRect(m_rPlus);

}

void CYMPopUp::OnLButtonUp(UINT nFlags, CPoint point) 
{
    CClientDC   dc(this);
    CRect       rClient;
    int         nCellHeight;

    if  (m_rMinus.PtInRect(point))
    {
        m_nYear--; 
		if   (m_nYear < START_YEAR)m_nYear = START_YEAR;
        dc.InvertRect(m_rMinus);
        InvalidateRect(m_rYear);
        return;
    }

    if  (m_rPlus.PtInRect(point))
    {
        m_nYear++; if   (m_nYear > END_YEAR)m_nYear = END_YEAR;
        dc.InvertRect(m_rPlus);
        InvalidateRect(m_rYear);
        return;
    }



    GetClientRect(rClient);
    rClient.DeflateRect(2,2);

    nCellHeight     = rClient.Height() / 5;
    rClient.top += nCellHeight;

    if  (rClient.PtInRect(point))
    {
        m_pParent->EnableWindow(true);
        m_pParent->PostMessage(YM_SELECTED, (WPARAM)m_nYear, (LPARAM)m_nMonth);
        DestroyWindow();
    }

}


void CYMPopUp::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
	switch(nChar)
	{
	case VK_ESCAPE:
		m_pParent->EnableWindow(true);
        m_pParent->SendMessage(YM_ABORTED);
        DestroyWindow();
		break;
	case VK_RIGHT:
		m_nMonth++;
		if(m_nMonth == 12)
		{
			m_nMonth = 0;
			m_nYear++;
		}
		Invalidate();
		break;
	case VK_LEFT:
		m_nMonth--;
		if(m_nMonth < 0)
		{
			m_nMonth = 11;
			m_nYear--;
		}
		Invalidate();
		break;
	case VK_UP:
		m_nMonth -= 3;
		if(m_nMonth < 0)
		{
			m_nMonth += 12;
			m_nYear--;
		}
		Invalidate();
		break;
	case VK_DOWN:
		m_nMonth += 3;
		if (m_nMonth > 11)
		{
			m_nMonth -= 12;
			m_nYear++;
		}
		Invalidate();
		break;
	case VK_SPACE:
	case VK_RETURN:
		m_pParent->EnableWindow(true);
        m_pParent->PostMessage(YM_SELECTED, (WPARAM)m_nYear, (LPARAM)m_nMonth);
        DestroyWindow();
		break;
    }
	
}

BOOL CYMPopUp::OnEraseBkgnd(CDC* pDC) 
{	
 	return FALSE;
}

void CYMPopUp::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC   dc(this);
    BOOL oinPlus	= m_inPlus;
	BOOL oinMinus	= m_inMinus;

    if  (m_rMinus.PtInRect(point))
		m_inMinus = TRUE;
	else
		m_inMinus = FALSE;

    if  (m_rPlus.PtInRect(point))
		m_inPlus = TRUE;
	else
		m_inPlus = FALSE;

	if (oinMinus != m_inMinus)
		InvalidateRect(&m_rMinus);

	if (oinPlus != m_inPlus)
		InvalidateRect(&m_rPlus);

	CWnd::OnMouseMove(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
// CYMSelector

CYMSelector::CYMSelector()
{
    m_nMonth = CTime::GetCurrentTime().GetMonth();
    m_nYear  = CTime::GetCurrentTime().GetYear();
}

CYMSelector::~CYMSelector()
{
}


BEGIN_MESSAGE_MAP(CYMSelector, CButton)
	//{{AFX_MSG_MAP(CYMSelector)
	ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)
	//}}AFX_MSG_MAP
    ON_MESSAGE(YM_SELECTED, YMSelected)
    ON_MESSAGE(YM_ABORTED,  YMAborted)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CYMSelector message handlers

void CYMSelector::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
    ASSERT(lpDrawItemStruct);

    CString BtnText;
    CDC*    pDC     = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect   rect    = lpDrawItemStruct->rcItem;
    UINT    state   = lpDrawItemStruct->itemState;
    
    CRect   rArrow(rect);

    rArrow.left    = rArrow.right - 20;
	rArrow.InflateRect(0, 1);

    CSize Margins(::GetSystemMetrics(SM_CXEDGE), ::GetSystemMetrics(SM_CYEDGE));

    pDC->DrawFrameControl(&rArrow, DFC_SCROLL, DFCS_SCROLLDOWN  | 
                          ((state & ODS_SELECTED) ? DFCS_PUSHED : 0) |
                          ((state & ODS_DISABLED) ? DFCS_INACTIVE : 0));


    rect.right -= rArrow.Width();

    pDC->FillSolidRect(rect,::GetSysColor(COLOR_WINDOW));

    GetWindowText(BtnText);
    if  (state & ODS_DISABLED)
        pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
    else
        pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));

    pDC->DrawText(BtnText, rect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);

    if (state & ODS_FOCUS) 
    {
        rect.DeflateRect(2,2);
        pDC->DrawFocusRect(rect);
		rect.InflateRect(2,2);
    }

    rect.InflateRect(1,1);
    pDC->DrawEdge(rect,EDGE_SUNKEN,BF_RECT);
	rect.DeflateRect(1,1);
    pDC->DrawEdge(rect,EDGE_SUNKEN,BF_RECT);
	
}

void CYMSelector::PreSubclassWindow() 
{
	CButton::PreSubclassWindow();
    CString buffer;
    CTime   tCurrent = CTime::GetCurrentTime();
    buffer = tCurrent.Format("%B, %Y");
    SetWindowText(buffer);

    m_nYear  = tCurrent.GetYear();
    m_nMonth = tCurrent.GetMonth() - 1;
}

void CYMSelector::OnClicked() 
{
    CRect rect;
    GetWindowRect(rect);
    rect.OffsetRect(0,rect.Height());
    GetParent()->EnableWindow(false);

    new CYMPopUp(CPoint(rect.left,rect.top), this,GetYear(),GetMonth());

    return;

}


LONG CYMSelector::YMSelected(WPARAM wParam , LPARAM lParam )
{
    m_nYear   = (int) wParam;
    m_nMonth  = (int)lParam;

    CString buffer;
    buffer.Format("%s, %d", GetMonthString(), GetYear());
    SetWindowText(buffer);
    GetParent()->EnableWindow(true);
    GetParent()->SetFocus();

    return 0;
}

LONG CYMSelector::YMAborted(WPARAM wParam , LPARAM lParam )
{
    GetParent()->EnableWindow(true);
    GetParent()->SetFocus();

    return 0;
}

int CYMSelector::GetYear()
{
    return m_nYear;
}

int CYMSelector::GetMonth()
{
    return m_nMonth + 1;
}

LPCTSTR CYMSelector::GetMonthString()
{
    return Months[m_nMonth];
}

void CYMSelector::SetMonth(int m)
{
    m--;
    ASSERT(m >= 0 && m <= 11);
    m_nMonth = m;

    CString buffer;
    buffer.Format("%s, %d", GetMonthString(), GetYear());
    SetWindowText(buffer);
}


void CYMSelector::SetYear(int y)
{

    ASSERT( y >= START_YEAR && y <= END_YEAR);
    m_nYear = y;

    CString buffer;
    buffer.Format("%s, %d", GetMonthString(), GetYear());
    SetWindowText(buffer);
}

⌨️ 快捷键说明

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