📄 digclockdlg.cpp
字号:
// DigClockDlg.cpp : implementation file
//
#include "stdafx.h"
#include "DigClock.h"
#include "DigClockDlg.h"
#include "math.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDigClockDlg dialog
CDigClockDlg::CDigClockDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDigClockDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDigClockDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CDigClockDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDigClockDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDigClockDlg, CDialog)
//{{AFX_MSG_MAP(CDigClockDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDigClockDlg message handlers
BOOL CDigClockDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// Kick off the timer.
SetTimer( 1, 1000, NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CDigClockDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDigClockDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDC* pDC;
pDC = GetDC();
CRect rect;
GetClientRect(&rect);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC); //创建与视图的设备相兼容的内存设备
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,rect.right,rect.bottom); //创建一个与视图兼容的位图
CBitmap* pOldBmp=dcMem.SelectObject(&bmp); //选择位图
// Get the client rectangle so that we
// can dynamically fit the clock to
// the window.
RECT Rect;
GetClientRect( &Rect );
// For easier calculations, get the
// x and y coordinates of the
// window center.
int nCenterX = Rect.right / 2;
int nCenterY = Rect.bottom / 2;
// Get the current time.
CTime Time = CTime::GetCurrentTime();
CString strDigits,strDigitsNum;
int i, x, y;
CSize size;
/*
// Create a yellow pen with which we'll
// draw the ellipse.
CPen Pen( PS_SOLID, 5, RGB( 255, 255, 0 ) );
// Select the new pen into the DC and
// remember the pen that was selected out.
CPen *pOldPen = dcMem->SelectObject( &Pen );
// Draw the clock face border with
// the Ellipse function.
dcMem->Ellipse( 60, 60, Rect.right - 60,
Rect.bottom - 60 );
dcMem->SelectObject( pOldPen );
*/
CBrush *oldBrush;
CBrush newBrush(RGB(123,255,123));
oldBrush = dcMem.SelectObject(&newBrush);
dcMem.Ellipse(58, 58, Rect.right - 58,Rect.bottom - 58) ;
dcMem.SelectObject(oldBrush);
double Radians,DeltaRadians;
// Out text color will be red.
dcMem.SetTextColor( RGB( 255, 0, 0 ));
dcMem.SetBkMode(TRANSPARENT);
CPoint pHour[12]; //用来描述时针各点
CPoint pMinute[48]; //用来描述分针各点
for( i=1; i<=12; i++ ){
// Format the digit CString object
// for the current clock number.
strDigits.Format( "%d", i );
// Get the text extent of the
// text so that we can center
// it about a point.
size =
dcMem.GetTextExtent( strDigits,
strDigits.GetLength() );
// Calculate the number of radians
// for the current clock number.
Radians = (double) i * 6.28 / 12.0;
DeltaRadians = (double) 6.28 / 60.0;
pHour[i-1].x = nCenterX +
(int) ( (double) ( nCenterX -60) *
sin( Radians ) );
pHour[i-1].y = nCenterY +
(int) ( (double) ( nCenterY -60) *
cos( Radians ) );
for (int j = 1;j<= 4;j ++) {
pMinute[(i-1)*4+j-1].x = nCenterX +
(int) ( (double) ( nCenterX -60) *
sin( DeltaRadians*((i-1)*5+j) ) );
pMinute[(i-1)*4+j-1].y = nCenterY +
(int) ( (double) ( nCenterY -60) *
cos( DeltaRadians*((i-1)*5+j) ) );
CBrush *oldBrush;
CBrush newBrush(RGB(255,0,0));
oldBrush = dcMem.SelectObject(&newBrush);
dcMem.Ellipse(pMinute[(i-1)*4+j-1].x - 1,pMinute[(i-1)*4+j-1].y - 1,pMinute[(i-1)*4+j-1].x + 1,pMinute[(i-1)*4+j-1].y + 1);
dcMem.SelectObject(oldBrush);
}
CBrush *oldBrush;
CBrush newBrush(RGB(255,0,0));
oldBrush = dcMem.SelectObject(&newBrush);
dcMem.Ellipse(pHour[i-1].x - 2,pHour[i-1].y - 2,pHour[i-1].x + 2,pHour[i-1].y + 2);
// Calculate the x coordinate. We
// use the text extent to center
// the text about a point.
x = nCenterX -
( size.cx / 2 ) +
(int) ( (double) ( nCenterX - 75 ) *
sin( Radians ) );
// Calculate the y coordinate. We
// use the text extent to center
// the text about a point.
y = nCenterY -
( size.cy / 2 ) -
(int) ( (double) ( nCenterY - 75 ) *
cos( Radians ) );
// Draw the text.
dcMem.TextOut( x, y, strDigits );
}
// Calculate the radians for the hour hand.
Radians = (double) Time.GetHour() +
(double) Time.GetMinute() / 60.0 +
(double) Time.GetSecond() / 3600.0;
Radians *= 6.28 / 12.0;
// Create a pen for the hour hand that's five
// pixels wide with a green color.
CPen HourPen( PS_SOLID, 5, RGB( 255, 255, 0 ) );
// Select the newly-created CPen object
// into the DC.
dcMem.SelectObject( &HourPen );
// Move to the center of the clock, then
// draw the hour hand line.
dcMem.MoveTo( nCenterX, nCenterY );
dcMem.LineTo(
nCenterX + (int) ( (double) ( nCenterX / 3 ) *
sin( Radians ) ),
nCenterY - (int) ( (double) ( nCenterY / 3 ) *
cos( Radians ) ) );
// Calculate the radians for the minute hand.
Radians = (double) Time.GetMinute() +
(double) Time.GetSecond() / 60.0;
Radians *= 6.28 / 60.0;
// Create a pen for the minute hand that's three
// pixels wide with a blue color.
CPen MinutePen( PS_SOLID, 3, RGB( 0, 0, 255 ) );
// Select the newly-created CPen object
// into the DC.
dcMem.SelectObject( &MinutePen );
// Move the to center of the clock, then
// draw the minute hand line.
dcMem.MoveTo( nCenterX, nCenterY );
dcMem.LineTo(
nCenterX + (int) ( (double) (
( nCenterX * 1.5 ) / 3 ) * sin( Radians ) ),
nCenterY - (int) ( (double) (
( nCenterY * 1.5 ) / 3 ) * cos( Radians ) ) );
//dcMem.LineTo(
// nCenterX + (int) ( (double)
// sin( Radians )*min(rect.Height()/2,rect.Width()/2)),
// nCenterY - (int) ( (double)
// cos( Radians )*min(rect.Height()/2,rect.Width()/2)));
// Calculate the radians for the second hand.
Radians = (double) Time.GetSecond();
Radians *= 6.28 / 60.0;
// Create a pen for the second hand that's one
// pixels wide with a cyan color.
CPen SecondPen( PS_SOLID, 1, RGB( 0, 255, 255 ) );
// Select the newly-created CPen object
// into the DC.
dcMem.SelectObject( &SecondPen );
// Move the to center of the clock, then
// draw the second hand line.
dcMem.MoveTo( nCenterX, nCenterY );
dcMem.LineTo(
nCenterX + (int) ( (double) (
( nCenterX * 3 ) / 5 ) * sin( Radians ) ),
nCenterY - (int) ( (double) (
( nCenterY * 3 ) / 5 ) * cos( Radians ) ) );
//////////////////////////////////////////////////////////////////////////
// Alarm function
//////////////////////////////////////////////////////////////////////////
int nYear,nMonth,nDay,deltaYear,deltaMonth,deltaDay;
int leap;
nYear = 2030;
nMonth = 1;
nDay = 10;
if (isleap(nYear)) {
leap = 1;
}
else leap = 0;
int iMonthDays[12] = {31,28+leap,31,30,31,30,31,31,30,31,30,31};
SYSTEMTIME curtime;
GetLocalTime(&curtime);
if(nDay - curtime.wDay < 0)
{
deltaDay = (nDay - curtime.wDay + iMonthDays[nMonth-2]);
deltaMonth = (nMonth - curtime.wMonth - 1 + 12)%12;
}
else
{
deltaDay = nDay - curtime.wDay;
deltaMonth = (nMonth - curtime.wMonth + 12)%12;
}
if(nMonth - curtime.wMonth < 0)
{
deltaYear = nYear - curtime.wYear - 1;
}
else if (nMonth - curtime.wMonth == 0 && nDay - curtime.wDay < 0) {
deltaYear = nYear - curtime.wYear - 1;
}
else deltaYear = nYear - curtime.wYear;
strDigitsNum.Format( "距%02d年%02d月%02d日还有%02d年%02d月%02d天%02d时%02d分%02d秒",
nYear,nMonth,nDay,
deltaYear,
deltaMonth,
deltaDay,
23 - Time.GetHour(),
59 - Time.GetMinute(),
60 - Time.GetSecond());
CFont Font, *pOldFont;
int nWidth = rect.Width()*0.5;
int nHeight = rect.Height()*0.15;
do{
// We may have already created
// a font in the CFont object. Here
// we make sure it's deleted.
if( Font.GetSafeHandle() != NULL )
Font.DeleteObject();
// Create the font with mostly default
// values. Use a Times New Roman font.
Font.CreateFont( nHeight, nWidth , 0, 0,
FW_DONTCARE, 0, 0, 0, ANSI_CHARSET,
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
"Times New Roman" );
// Select the newly-created CFont object into
// the DC and remember the CFont object that
// was selected out.
pOldFont = dcMem.SelectObject( &Font );
// Get the text extent so we can decide if
// this font is too large.
size =
dcMem.GetTextExtent( strDigits,
strDigitsNum.GetLength() );
// Select the old font back into the DC.
dcMem.SelectObject( pOldFont );
// If the text extent is too wide,
// reduce the font width.
if( size.cx > Rect.right )
nWidth -= 1;
// If the text extent is too high,
// reduce the font height.
if( size.cy > Rect.bottom )
nHeight -= 5;
} while( size.cx > Rect.right ||
size.cy > Rect.bottom );
// Select the final font into the
// DC and remember the CFont object
// that's selected out.
pOldFont = dcMem.SelectObject( &Font );
// Draw the text.
dcMem.TextOut( Rect.left + rect.Width()*0.2,Rect.bottom - size.cy,strDigitsNum );
// Select the old font back into the DC.
dcMem.SelectObject( pOldFont );
CDialog::OnPaint();
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,SRCCOPY); //将在内存中绘制好的图像重新显示到视图中
dcMem.SelectObject(pOldBmp);
pOldBmp->DeleteObject();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CDigClockDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDigClockDlg::OnTimer(UINT nIDEvent)
{
// The timer just causes a redraw to occur.
// In the OnDraw() function the current
// time is obtained.
CRect rect;
GetClientRect(&rect);
InvalidateRect( rect, TRUE );
//UpdateWindow();
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -