⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 digclockdlg.cpp

📁 很好的一个用MFC实现的数字时钟程序
💻 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 + -