代码简介或代码解析:
在实时的应用程序中,有时候需要显示时间,那么在对话框中显示时钟是个好主意,
可是怎么来实现呢?一般要从CStatic类派生一个类CXJWDigitClock.
实现步骤:
1 把EDClock.h / cpp加入到工程中,当然您也可以自己来派生
2 把res目录下12个BMP资源导入到工程中,当然您也可以自己制作12个类似的BMP图象
注意他们在Resource.h中的标识必须按一定的顺序,
例如不能将IDB_BITMAP4 189而IDB_BITMAP5 188 ,因为代码中会用到这些ID
3 创建必要的static控件IDC_CLOCK_ONE,IDC_CLOCK_TWO
4 在StaticDigitalClockDlg.h的头部添加
#include " EDClock.h "
5 在StaticDigitalClockDlg.h中添加:
CXJWDigitClock m_ClockOne;
CXJWDigitClock m_ClockTwo;
CXJWDigitClock m_ClockThree;
6 在CStaticDigitalClockDlg::OnInitDialog()中
// TODO: Add extra initialization here
m_ClockOne.SetStyle(CXJWDigitClock::XDC_SECOND);
m_ClockTwo.SubclassDlgItem(IDC_CLOCK_TWO, this );
m_ClockTwo.SetColor(RGB( 0 , 255 , 0 ));
m_ClockThree.Create(NULL, SS_SUNKEN | WS_CHILD | WS_VISIBLE, CRect( 5 , 5 , 170 , 35 ), this , 1001 );
m_ClockThree.SetStyle(CXJWDigitClock::XDC_SECOND);
m_ClockThree.SetAlarm();
7 写关闭声音的消息响应
void CStaticDigitalClockDlg::OnButtonClosewav()
... {
m_ClockOne.SetStyle(CXJWDigitClock::XDC_NOSECOND);
m_ClockTwo.SetColor(RGB(0, 128, 128));
m_ClockThree.SetAlarm(FALSE);
}
8 附相关代码:
CXJWDigitClock::CXJWDigitClock()
... {
m_bAlarm = FALSE;
m_style = XDC_NOSECOND;
m_color = origin;
for(int i = 0; i< 12; i++) ...{
HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0, NULL, 0);
m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
}
}
CXJWDigitClock:: ~ CXJWDigitClock()
... {
for(int i = 0; i< 12; i++) ...{
if(m_hBitmap[i])
::DeleteObject(m_hBitmap[i]);
}
}
void CXJWDigitClock::PreSubclassWindow()
... {
//设置时钟,注意不要在OnCreate()中设置时钟。
//因为当创建对话框模板时,收不到WM_CREATE消息
m_nTimer = SetTimer(1, 1000, NULL);
::GetObject(m_hBitmap[0], sizeof BITMAP, &m_bm);
CStatic::PreSubclassWindow();
}
void CXJWDigitClock::OnDestroy()
... {
CStatic::OnDestroy();
KillTimer(m_nTimer);
}
void CXJWDigitClock::OnPaint()
... {
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
//不要调用CStatic::OnPaint()
}
BOOL CXJWDigitClock::OnEraseBkgnd(CDC * pDC)
... {
// TODO: Add your message handler code here and/or call default
CBrush brush;
brush.CreateSolidBrush( ::GetSysColor(COLOR_WINDOWTEXT) );
CBrush* pOldBrush = pDC->SelectObject(&brush);
CRect rectClient;
GetClientRect(&rectClient);
pDC->PatBlt(0, 0, rectClient.Width(), rectClient.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
return CStatic::OnEraseBkgnd(pDC);
}
void CXJWDigitClock::OnTimer(UINT nIDEvent)
... {
// TODO: Add your message handler code here and/or call default
if(nIDEvent == m_nTimer) ...{
m_nCount++;
CRect rectClient;
GetClientRect(&rectClient);
m_h = rectClient.Height();
if(m_style == XDC_SECOND) ...{
m_w = rectClient.Width()/8;
} else ...{
m_w = rectClient.Width()/5;
}
CTime time = CTime::GetCurrentTime();
int nh1 = time.GetHour()/10; //取得小时的第一位
if(nh1)
Output(nh1, 0);
else
Output(11, 0);
int nh2 = time.GetHour()%10; //取得小时的第二位
Output(nh2, 1);
int nm1 = time.GetMinute()/10;
Output(nm1, 3);
int nm2 = time.GetMinute()%10;
Output(nm2, 4);
switch(m_style) ...{
case XDC_SECOND:
...{
int ns1 = time.GetSecond()/10;
Output(ns1, 6);
int s2 = time.GetSecond()%10;
Output(s2, 7);
Output(10, 2); //显示两点
Output(10, 5); // 显示两点
}
break;
case XDC_NOSECOND:
default:
if(m_bAlarm)
Output(10, 2);
else
if(m_nCount%2)
Output(10, 2); // 显示两点
else
Output(11, 2);
break;
}
if(m_bAlarm)
MessageBeep(-1);
}
CStatic::OnTimer(nIDEvent);
}
void CXJWDigitClock::Output(UINT digit, UINT pos)
... {
//绘制位图
CClientDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
//
// Alarm mode
//
if(m_bAlarm && m_nCount%2)
digit = 11;
CBitmap* pBitmap = CBitmap::FromHandle( m_hBitmap[digit] );
CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
dc.StretchBlt(m_w*pos, 0, m_w, m_h,
&dcMem, 0, 0, m_bm.bmWidth, m_bm.bmHeight, SRCCOPY);
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();
}
CXJWDigitClock::CClockStyle CXJWDigitClock::SetStyle(CClockStyle style)
... {
CClockStyle temp = m_style;
m_style = style;
// if(::IsWindow(m_hWnd))
// Invalidate();
return temp;
}
COLORREF CXJWDigitClock::SetColor(COLORREF color)
... {
if(m_color == color)
return color;
COLORREF temp = m_color;
m_color = color;
for(int i = 0; i< 12; i++) ...{
if(m_hBitmap[i])
::DeleteObject(m_hBitmap[i]);
COLORMAP mapColor;
mapColor.from = origin;
mapColor.to = color;
HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0, &mapColor, 1);
m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
}
return temp;
}
BOOL CXJWDigitClock::SetAlarm(BOOL bAlarm /**/ /*= TRUE*/ )
... {
BOOL temp = m_bAlarm;
m_bAlarm = bAlarm;
return temp;
}
在实时的应用程序中,有时候需要显示时间,那么在对话框中显示时钟是个好主意,
可是怎么来实现呢?一般要从CStatic类派生一个类CXJWDigitClock.
实现步骤:
1 把EDClock.h / cpp加入到工程中,当然您也可以自己来派生
2 把res目录下12个BMP资源导入到工程中,当然您也可以自己制作12个类似的BMP图象
注意他们在Resource.h中的标识必须按一定的顺序,
例如不能将IDB_BITMAP4 189而IDB_BITMAP5 188 ,因为代码中会用到这些ID
3 创建必要的static控件IDC_CLOCK_ONE,IDC_CLOCK_TWO
4 在StaticDigitalClockDlg.h的头部添加
#include " EDClock.h "
5 在StaticDigitalClockDlg.h中添加:
CXJWDigitClock m_ClockOne;
CXJWDigitClock m_ClockTwo;
CXJWDigitClock m_ClockThree;
6 在CStaticDigitalClockDlg::OnInitDialog()中
// TODO: Add extra initialization here
m_ClockOne.SetStyle(CXJWDigitClock::XDC_SECOND);
m_ClockTwo.SubclassDlgItem(IDC_CLOCK_TWO, this );
m_ClockTwo.SetColor(RGB( 0 , 255 , 0 ));
m_ClockThree.Create(NULL, SS_SUNKEN | WS_CHILD | WS_VISIBLE, CRect( 5 , 5 , 170 , 35 ), this , 1001 );
m_ClockThree.SetStyle(CXJWDigitClock::XDC_SECOND);
m_ClockThree.SetAlarm();
7 写关闭声音的消息响应
void CStaticDigitalClockDlg::OnButtonClosewav()
... {
m_ClockOne.SetStyle(CXJWDigitClock::XDC_NOSECOND);
m_ClockTwo.SetColor(RGB(0, 128, 128));
m_ClockThree.SetAlarm(FALSE);
}
8 附相关代码:
CXJWDigitClock::CXJWDigitClock()
... {
m_bAlarm = FALSE;
m_style = XDC_NOSECOND;
m_color = origin;
for(int i = 0; i< 12; i++) ...{
HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0, NULL, 0);
m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
}
}
CXJWDigitClock:: ~ CXJWDigitClock()
... {
for(int i = 0; i< 12; i++) ...{
if(m_hBitmap[i])
::DeleteObject(m_hBitmap[i]);
}
}
void CXJWDigitClock::PreSubclassWindow()
... {
//设置时钟,注意不要在OnCreate()中设置时钟。
//因为当创建对话框模板时,收不到WM_CREATE消息
m_nTimer = SetTimer(1, 1000, NULL);
::GetObject(m_hBitmap[0], sizeof BITMAP, &m_bm);
CStatic::PreSubclassWindow();
}
void CXJWDigitClock::OnDestroy()
... {
CStatic::OnDestroy();
KillTimer(m_nTimer);
}
void CXJWDigitClock::OnPaint()
... {
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
//不要调用CStatic::OnPaint()
}
BOOL CXJWDigitClock::OnEraseBkgnd(CDC * pDC)
... {
// TODO: Add your message handler code here and/or call default
CBrush brush;
brush.CreateSolidBrush( ::GetSysColor(COLOR_WINDOWTEXT) );
CBrush* pOldBrush = pDC->SelectObject(&brush);
CRect rectClient;
GetClientRect(&rectClient);
pDC->PatBlt(0, 0, rectClient.Width(), rectClient.Height(), PATCOPY);
pDC->SelectObject(pOldBrush);
return CStatic::OnEraseBkgnd(pDC);
}
void CXJWDigitClock::OnTimer(UINT nIDEvent)
... {
// TODO: Add your message handler code here and/or call default
if(nIDEvent == m_nTimer) ...{
m_nCount++;
CRect rectClient;
GetClientRect(&rectClient);
m_h = rectClient.Height();
if(m_style == XDC_SECOND) ...{
m_w = rectClient.Width()/8;
} else ...{
m_w = rectClient.Width()/5;
}
CTime time = CTime::GetCurrentTime();
int nh1 = time.GetHour()/10; //取得小时的第一位
if(nh1)
Output(nh1, 0);
else
Output(11, 0);
int nh2 = time.GetHour()%10; //取得小时的第二位
Output(nh2, 1);
int nm1 = time.GetMinute()/10;
Output(nm1, 3);
int nm2 = time.GetMinute()%10;
Output(nm2, 4);
switch(m_style) ...{
case XDC_SECOND:
...{
int ns1 = time.GetSecond()/10;
Output(ns1, 6);
int s2 = time.GetSecond()%10;
Output(s2, 7);
Output(10, 2); //显示两点
Output(10, 5); // 显示两点
}
break;
case XDC_NOSECOND:
default:
if(m_bAlarm)
Output(10, 2);
else
if(m_nCount%2)
Output(10, 2); // 显示两点
else
Output(11, 2);
break;
}
if(m_bAlarm)
MessageBeep(-1);
}
CStatic::OnTimer(nIDEvent);
}
void CXJWDigitClock::Output(UINT digit, UINT pos)
... {
//绘制位图
CClientDC dc(this);
CDC dcMem;
dcMem.CreateCompatibleDC(&dc);
//
// Alarm mode
//
if(m_bAlarm && m_nCount%2)
digit = 11;
CBitmap* pBitmap = CBitmap::FromHandle( m_hBitmap[digit] );
CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
dc.StretchBlt(m_w*pos, 0, m_w, m_h,
&dcMem, 0, 0, m_bm.bmWidth, m_bm.bmHeight, SRCCOPY);
dcMem.SelectObject(pOldBitmap);
dcMem.DeleteDC();
}
CXJWDigitClock::CClockStyle CXJWDigitClock::SetStyle(CClockStyle style)
... {
CClockStyle temp = m_style;
m_style = style;
// if(::IsWindow(m_hWnd))
// Invalidate();
return temp;
}
COLORREF CXJWDigitClock::SetColor(COLORREF color)
... {
if(m_color == color)
return color;
COLORREF temp = m_color;
m_color = color;
for(int i = 0; i< 12; i++) ...{
if(m_hBitmap[i])
::DeleteObject(m_hBitmap[i]);
COLORMAP mapColor;
mapColor.from = origin;
mapColor.to = color;
HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_BITMAP1, 0, &mapColor, 1);
m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
}
return temp;
}
BOOL CXJWDigitClock::SetAlarm(BOOL bAlarm /**/ /*= TRUE*/ )
... {
BOOL temp = m_bAlarm;
m_bAlarm = bAlarm;
return temp;
}