1、日期控件的自绘
这里需要介绍几个日期控件的事件:
(1)OnDropdown
此消息是点击右侧按钮,弹出月历控件时的响应函数。
(2)OnSetfocus
此事件是右侧按钮获得焦点时候的响应函数,它在OnDropdown之前执行。
(3)OnCloseup
此事件是当选择完日期关闭月历控件时的响应函数。
日期控件的自绘包括右侧按钮的自绘和月历控件的自绘,比较麻烦。本人只针对右侧按钮控件自绘详细说明。
CDateTimeCtrl派生类CNewDateTimeCtrl在OnPaint()函数中实现按钮的自绘:
// CPaintDC dc(this); // device context for painting
CDateTimeCtrl::OnPaint();
CDC* dc = GetDC();
// TODO: Add your message handler code here
CRect rcPic;
GetClientRect(&rcPic);
rcPic.left = rcPic.right - 17;
rcPic.bottom = 17;
// rcPic.Width()= rcPic.right - rcPic.left;
if (m_bDown || (GetMonthCalCtrl() != NULL))
{
CBitmap *pOldBitmap;
CDC* pMemDC = new CDC;
CDC *pDC = dc;
int iwidth = rcPic.Width();
int iheight = rcPic.Height();
//读位图到内存
pMemDC->CreateCompatibleDC(pDC);
pOldBitmap = pMemDC->SelectObject(&m_bmpDownBtn);
pDC->BitBlt(rcPic.left, rcPic.top, rcPic.Width(), rcPic.Height(), pMemDC, rcPic.Width()*2, 0, SRCCOPY);
pMemDC->SelectObject(pOldBitmap);
//释放内存
ReleaseDC(pMemDC);
delete pMemDC;
}
else
{
CBitmap *pOldBitmap;
CDC* pMemDC = new CDC;
CDC *pDC = dc;
int iwidth = rcPic.Width();
//读位图到内存
pMemDC->CreateCompatibleDC(pDC);
pOldBitmap = pMemDC->SelectObject(&m_bmpDownBtn);
pDC->BitBlt(rcPic.left, rcPic.top, rcPic.Width(), rcPic.Height(), pMemDC, rcPic.Width(), 0, SRCCOPY);
pMemDC->SelectObject(pOldBitmap);
//释放内存
ReleaseDC(pMemDC);
delete pMemDC;
}
ReleaseDC(dc);
这样就实现了按钮的自绘,但是存在问题:
左键点击按钮,再松开时按钮变回默认状态。我查了一下日期时间控件没有OnLButtonUp事件,似乎只能通过子类化按钮的方法来解决。
注意:GetMonthCalCtrl() 用于获得月历控件的窗口句柄。同事告诉我一个新方法:定时器。也就是在OnLButtonDown()时,SetTimer(1,200,NULL)这里设置200ms比较合适,不会让用户觉得很假:)
然后在OnTimer函数里Invalidate()强制重绘。在OnKillFocus()里面关闭定时器即可。
好了,时间控件下次介绍。。