网上有很多类似显示时间的方法,但是很简单,并不使用。我这里给大家提供的是在static控件上显示时间,而且static控件的背景是透明的,也不会出现闪烁情况。
头文件中定义成员变量,在使用前最好先初始化一下。
int m_Second; ///秒
int m_Minute; ///分钟
int m_Hour; ///小时
CString m_sTimeValue; ///time 格式化字符串
CRect m_TimeRect; ///显示时间占用的rect
void CBaseDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
// Do not call CDialog::OnPaint() for painting messages
CDC MemDC; ///首先定义一个显示设备对象
CBitmap MemBmp; ///定义一个位图对象
CDC *pDC=GetDlgItem(IDC_STATIC_TIMER)->GetDC();
///随后建立与屏幕显示兼容的内存显示设备
MemDC.CreateCompatibleDC(pDC);
///这时还不能绘图,因为没有地方画
///下面建立一个与屏幕显示兼容的位图,至于位图的大小,可以用窗口的大小,也可以自定义
MemBmp.CreateCompatibleBitmap(pDC, m_TimeRect.Width()*2, m_TimeRect.Height()*2);
///将位图选入到内存显示设备中
///只有选入位图的内存显示设备才有地方绘图,画到指定的位图上
CBitmap *pOldBit = MemDC.SelectObject(&MemBmp);
///先用背景色将位图清除干净(如果背景是图片则可以不清除)
// MemDC.FillSolidRect(m_TimeRect,RGB(255,255,255));
//绘图,接下来所有的图片、点、线、圆、文字都要绘制在这个上面
Gdiplus::Graphics graphics(MemDC.GetSafeHdc());
Gdiplus::Image image(m_strExePath + _T("image\\chenxi.jpg"));//若路径不对,则无法实现在客户区里绘图
graphics.DrawImage(&image, 0, 0);
///向窗口中写时间字符串
//Use new Font, store old font ///实心字
CFont* pOldFont = MemDC.SelectObject(myFont);
MemDC.SetBkMode(TRANSPARENT);
CPen pen(PS_SOLID, 1, RGB(255,0,0));
CPen *pOldPen=MemDC.SelectObject(&pen);
//MemDC.TextOut(m_TimeRect.left, m_TimeRect.top,m_sTimeValue);
SetBkMode(MemDC.m_hDC, TRANSPARENT);
//DrawText(MemDC.m_hDC, m_sTimeValue, 18, &m_TimeRect, DT_CALCRECT);
DrawText(MemDC.m_hDC, m_sTimeValue, -1, &m_TimeRect, DT_VCENTER);
MemDC.SelectObject(pOldFont);
MemDC.SelectObject(pOldPen);
///将内存中的图拷贝到屏幕上进行显示
pDC->BitBlt(0, 0, m_TimeRect.Width(), m_TimeRect.Height(), &MemDC, m_TimeRect.left, m_TimeRect.top, SRCCOPY);
///绘图完成后的清理
MemBmp.DeleteObject();
MemDC.DeleteDC();
ReleaseDC( pDC);
pDC=NULL;
}
单是上面的代码还是会出现背景被擦除问题,需要在擦除背景后重绘背景图片。
BOOL CBaseDlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
Gdiplus::Graphics graphics(pDC->GetSafeHdc());
Gdiplus::Image image(m_strExePath + _T("image\\chenxi.jpg"));
graphics.DrawImage(&image, 0, 0);
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);//函数原来的返回值
}
接下来需要重载Timer函数
void CBaseDlg::OnTimer(UINT_PTR nIDEvent)
{
// Print out the day of the week using localized day name
UINT DayOfWeek[] = {
LOCALE_SDAYNAME7, // Sunday
LOCALE_SDAYNAME1,
LOCALE_SDAYNAME2,
LOCALE_SDAYNAME3,
LOCALE_SDAYNAME4,
LOCALE_SDAYNAME5,
LOCALE_SDAYNAME6 // Saturday
};
CTime timer=CTime::GetCurrentTime();
TCHAR strWeek[255];
::GetLocaleInfo(LOCALE_USER_DEFAULT, DayOfWeek[timer.GetDayOfWeek()-1], strWeek, sizeof(strWeek));
m_sTimeValue.Format(_T("北京时间:%d年%02d月%02d日 %s %02d:%02d:%02d"),
timer.GetYear(),timer.GetMonth(),timer.GetDay(), strWeek,
timer.GetHour(), timer.GetMinute(), timer.GetSecond());
//GetDlgItem(IDC_STATIC_TIMER)->SetWindowText(m_sTimeValue);
CRect TimeRect;
GetDlgItem(IDC_STATIC_TIMER)->GetWindowRect(&TimeRect);
ScreenToClient(&TimeRect);
InvalidateRect(TimeRect, FALSE);
UpdateWindow();
CDialog::OnTimer(nIDEvent);
}