📄 clockst.cpp
字号:
#include "stdafx.h"
#include "ClockST.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define OFSX_H1 5
#define OFSY_H1 33
#define OFSX_H2 32
#define OFSY_H2 33
#define OFSX_M1 65
#define OFSY_M1 33
#define OFSX_M2 92
#define OFSY_M2 33
#define OFSX_S1 120
#define OFSY_S1 50
#define OFSX_S2 134
#define OFSY_S2 50
#define OFSX_MDAY1 5
#define OFSY_MDAY1 5
#define OFSX_MDAY2 19
#define OFSY_MDAY2 5
#define OFSX_MON1 41
#define OFSY_MON1 5
#define OFSX_MON2 55
#define OFSY_MON2 5
#define OFSX_YEAR1 77
#define OFSY_YEAR1 5
#define OFSX_YEAR2 91
#define OFSY_YEAR2 5
#define OFSX_YEAR3 105
#define OFSY_YEAR3 5
#define OFSX_YEAR4 119
#define OFSY_YEAR4 5
#define WIDTH_BIG 24
#define HEIGHT_BIG 34
#define WIDTH_SMALL 12
#define HEIGHT_SMALL 17
// 数组m_Digit 中的元素:
// 0 hour-left
// 1 hour-right
// 2 min-left
// 3 min-right
// 4 sec-left
// 5 sec-right
// 6 day-left
// 7 day-right
// 8 month-left
// 9 month-right
// 10 century-left
// 11 century-right
// 12 year-left
// 13 year-right
CClockST::CClockST()
{
m_bMonthFirst = FALSE;
::ZeroMemory(&m_Digit, sizeof(m_Digit));
}
CClockST::~CClockST()
{
if (m_thrParam.hThrHandle)
{
m_thrParam.bRun = FALSE;
::WaitForSingleObject(m_thrParam.hThrHandle, 1500);
}
if (m_cdcBufClock.bValid == TRUE)
m_cdcBufClock.bValid = FALSE;
if (m_cdcBufBig.bValid == TRUE)
m_cdcBufBig.bValid = FALSE;
if (m_cdcBufSmall.bValid == TRUE)
m_cdcBufSmall.bValid = FALSE;
Clean();
}
BEGIN_MESSAGE_MAP(CClockST, CStatic)
//{{AFX_MSG_MAP(CClockST)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CClockST::Clean() // Detach先前的资源
{
m_bmClock.DeleteObject();
m_bmBig.Detach();
m_bmSmall.Detach();
m_palPalette.DeleteObject();
}
BOOL CClockST::GetBitmapAndPalette(UINT nIDResource, CBitmap& bitmap, CPalette& pal)
{
HBITMAP hBmp = (HBITMAP)::LoadImage(::AfxGetResourceHandle(),
MAKEINTRESOURCE(nIDResource),
IMAGE_BITMAP,
0,0, LR_CREATEDIBSECTION);
if (hBmp == NULL) return FALSE;
bitmap.Attach(hBmp);
//给位图创建一个逻辑调色板
DIBSECTION ds;
BITMAPINFOHEADER &bmInfo = ds.dsBmih;
bitmap.GetObject(sizeof(ds), &ds);
int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;
CClientDC dc(NULL); //桌面DC
if(nColors > 256) // 如果超过256色,就创建一个中间 调色板
pal.CreateHalftonePalette(&dc);
else
{
RGBQUAD *pRGB = new RGBQUAD[nColors]; //创建调色板
CDC memDC;
memDC.CreateCompatibleDC(&dc);
memDC.SelectObject( &bitmap );
::GetDIBColorTable( memDC, 0, nColors, pRGB );
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = nColors;
for (int i=0; i < nColors; i++)
{
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pLP->palPalEntry[i].peFlags = 0;
}
pal.CreatePalette( pLP );
delete[] pLP;
delete[] pRGB;
}
return TRUE;
}
void CClockST::Refresh()
{
char szDate[15], szTime[15];
SYSTEMTIME sysTime;
::GetLocalTime(&sysTime); //获得当前的日期和时间
if (m_bMonthFirst == TRUE)
sprintf(szDate, "%02d-%02d-%04d", sysTime.wMonth, sysTime.wDay, sysTime.wYear);
else
sprintf(szDate, "%02d-%02d-%04d", sysTime.wDay, sysTime.wMonth, sysTime.wYear);
sprintf(szTime, "%02d:%02d:%02d", sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
//设置日
m_Digit[6] = szDate[0] - 48;
m_Digit[7] = szDate[1] - 48;
//设置月
m_Digit[8] = szDate[3] - 48;
m_Digit[9] = szDate[4] - 48;
// 设置年
m_Digit[10] = szDate[6] - 48;
m_Digit[11] = szDate[7] - 48;
m_Digit[12] = szDate[8] - 48;
m_Digit[13] = szDate[9] - 48;
//设置小时
m_Digit[0] = szTime[0] - 48;
m_Digit[1] = szTime[1] - 48;
//设置分
m_Digit[2] = szTime[3] - 48;
m_Digit[3] = szTime[4] - 48;
//设置秒
m_Digit[4] = szTime[6] - 48;
m_Digit[5] = szTime[7] - 48;
if (::IsWindow(m_hWnd))
Invalidate();
}
BOOL CClockST::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CClockST::OnPaint()
{
CPaintDC dc(this);
if (m_cdcBufClock.bValid == FALSE)
{
m_cdcBufClock.dcMemory.CreateCompatibleDC(&dc);
m_cdcBufClock.pOldBmp = m_cdcBufClock.dcMemory.SelectObject(&m_bmClock);
m_cdcBufClock.bValid = TRUE;
}
if (m_cdcBufBig.bValid == FALSE)
{
m_cdcBufBig.dcMemory.CreateCompatibleDC(&dc);
m_cdcBufBig.pOldBmp = m_cdcBufBig.dcMemory.SelectObject(&m_bmBig);
m_cdcBufBig.bValid = TRUE;
}
if (m_cdcBufSmall.bValid == FALSE)
{
m_cdcBufSmall.dcMemory.CreateCompatibleDC(&dc);
m_cdcBufSmall.pOldBmp = m_cdcBufSmall.dcMemory.SelectObject(&m_bmSmall);
m_cdcBufSmall.bValid = TRUE;
}
// 更新小时
m_cdcBufClock.dcMemory.BitBlt(OFSX_H1, OFSY_H1, WIDTH_BIG, HEIGHT_BIG, &m_cdcBufBig.dcMemory, WIDTH_BIG*m_Digit[0], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_H2, OFSY_H2, WIDTH_BIG, HEIGHT_BIG, &m_cdcBufBig.dcMemory, WIDTH_BIG*m_Digit[1], 0, SRCCOPY);
// 更新分钟
m_cdcBufClock.dcMemory.BitBlt(OFSX_M1, OFSY_M1, WIDTH_BIG, HEIGHT_BIG, &m_cdcBufBig.dcMemory, WIDTH_BIG*m_Digit[2], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_M2, OFSY_M2, WIDTH_BIG, HEIGHT_BIG, &m_cdcBufBig.dcMemory, WIDTH_BIG*m_Digit[3], 0, SRCCOPY);
// 更新秒
m_cdcBufClock.dcMemory.BitBlt(OFSX_S1, OFSY_S1, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[4], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_S2, OFSY_S2, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[5], 0, SRCCOPY);
//更新日
m_cdcBufClock.dcMemory.BitBlt(OFSX_MDAY1, OFSY_MDAY1, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[6], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_MDAY2, OFSY_MDAY2, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[7], 0, SRCCOPY);
//更新月
m_cdcBufClock.dcMemory.BitBlt(OFSX_MON1, OFSY_MON1, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[8], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_MON2, OFSY_MON2, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[9], 0, SRCCOPY);
//更新年
m_cdcBufClock.dcMemory.BitBlt(OFSX_YEAR1, OFSY_YEAR1, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[10], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_YEAR2, OFSY_YEAR2, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[11], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_YEAR3, OFSY_YEAR3, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[12], 0, SRCCOPY);
m_cdcBufClock.dcMemory.BitBlt(OFSX_YEAR4, OFSY_YEAR4, WIDTH_SMALL, HEIGHT_SMALL, &m_cdcBufSmall.dcMemory, WIDTH_SMALL*m_Digit[13], 0, SRCCOPY);
dc.BitBlt(0, 0, m_bmInfoClock.bmWidth, m_bmInfoClock.bmHeight, &m_cdcBufClock.dcMemory, 0, 0, SRCCOPY);
// 请不要调用CStatic::OnPaint()
}
UINT /*WINAPI*/ CClockST::ClockThread(void* pParam) //线程函数
{
STRUCT_THRCLOCK* p;
CClockST* pParent;
p = (STRUCT_THRCLOCK*)pParam;
pParent = (CClockST*)p->pParent;
TRACE(_T("ClockThread: Enter \n"));
while (p->bRun == TRUE)
{
pParent->Refresh();
::Sleep(1000);
}
TRACE(_T("ClockThread: Exit \n"));
return 0;
}
void CClockST::Start(int nPaneID, int nBigID, int nSmallID, BOOL bAlternateDateFormat)
{
BOOL bFailed = FALSE;
if (m_thrParam.hThrHandle) //如果已经开始了
return ;
Clean(); //解除先前的资源
if (GetBitmapAndPalette(nSmallID, m_bmSmall, m_palPalette) == FALSE) // 加载位图和调色板
bFailed = TRUE;
m_palPalette.DeleteObject();
if (GetBitmapAndPalette(nBigID, m_bmBig, m_palPalette) == FALSE)
bFailed = TRUE;
m_palPalette.DeleteObject();
if (GetBitmapAndPalette(nPaneID, m_bmClock, m_palPalette) == FALSE)
bFailed = TRUE;
if (bFailed) //如果加载位图失败
{
Clean();
return;
}
m_bmClock.GetObject(sizeof(m_bmInfoClock), &m_bmInfoClock); //获取整个时钟面板的尺寸
CRect rect; //修改控件的尺寸,以适应钟表的大小
GetWindowRect(rect);
rect.right = rect.left + m_bmInfoClock.bmWidth;
rect.bottom = rect.top + m_bmInfoClock.bmHeight;
SetWindowPos(NULL, 0, 0, rect.Width(), rect.Height(), SWP_NOZORDER | SWP_NOMOVE);
m_bMonthFirst = bAlternateDateFormat; //日期格式
::ZeroMemory(&m_thrParam, sizeof(m_thrParam));
m_thrParam.pParent = this;
m_thrParam.bRun = TRUE;
CWinThread* cw = AfxBeginThread( &ClockThread, (LPVOID)&m_thrParam ); //创建新线程
if (cw == NULL)
{
Clean();
return ;
}
m_thrParam.hThrHandle = cw->m_hThread;
m_thrParam.dwThrId = cw->m_nThreadID;
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -