VC++课程设计实验报告-时钟

更新时间:2023-11-18 19:18:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

湖 南 农 业 大 学 VC++程序设计课程设计报告

时钟

学生姓名:XXX

学号:XXXXXXXXXXXX QQ:XXXXXXXXX 班级:X班

年级专业:2010级计算机

指导老师及职称:X老师 高级工程师 学院:XXXXXXXXXXXXXXX

湖南·长沙 提交日期:2010年6月

时钟

学生:XX

指导老师:XXX

(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)

1.摘要:利用MFC设计制作一个能联网调时时钟,当按下F1键时,能打开或关闭帮助,单击左

键是,能拖动窗口,双击左键时,能联网校时,滚动中轴时,能调整时间,单击右键,能随机变换背景颜色。

2.关键词:MFC;Clock;C++……

3.前言:

1.我们学习MFC,除了可以掌握一种Windows应用程序设计的基本方法之外,还可以使他们进

一步全面、深刻地理解向对象程序设计的思想。而且MFC所蕴含的程序设计思想、代码实现技巧、则是其他开发工具所不能及的。

2.我们通过制作这个时钟,可以加深对MFC的设计思想的理解。也可以加强对C++的思想的理

解。

4.正文:

4.1:窗口的创建于注册

{ public:

// Dialog Data

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected:

virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA CAboutDlg();

class CAboutDlg : public CDialog

//}}AFX_VIRTUAL

// Implementation protected: };

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { }

void CAboutDlg::DoDataExchange(CDataExchange* pDX) { }

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

//{{AFX_MSG_MAP(CAboutDlg)

// No message handlers CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP

//{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT //{{AFX_MSG(CAboutDlg) //}}AFX_MSG

DECLARE_MESSAGE_MAP()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////// // CAlarmClockDlg dialog

CAlarmClockDlg::CAlarmClockDlg(CWnd* pParent /*=NULL*/) { }

void CAlarmClockDlg::DoDataExchange(CDataExchange* pDX) { }

BEGIN_MESSAGE_MAP(CAlarmClockDlg, CDialog)

//{{AFX_MSG_MAP(CAlarmClockDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_LBUTTONDOWN() ON_WM_TIMER() ON_WM_ERASEBKGND() ON_WM_LBUTTONDBLCLK() ON_WM_RBUTTONDOWN()

CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAlarmClockDlg)

// NOTE: the ClassWizard will add DDX and DDV calls here //{{AFX_DATA_INIT(CAlarmClockDlg)

// NOTE: the ClassWizard will add member initialization here : CDialog(CAlarmClockDlg::IDD, pParent)

//}}AFX_DATA_INIT

// Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_hThread = NULL;

m_bkColor = RGB(110, 200, 255); m_bHelp = TRUE;

//}}AFX_DATA_MAP

ON_WM_MOUSEWHEEL() //}}AFX_MSG_MAP

END_MESSAGE_MAP()

///////////////////////////////////////////////////////////////////////////// // CAlarmClockDlg message handlers

void CAlarmClockDlg::OnSysCommand(UINT nID, LPARAM lParam) { }

// The system calls this to obtain the cursor to display while the user drags // the minimized window.

HCURSOR CAlarmClockDlg::OnQueryDragIcon() { }

BOOL CAlarmClockDlg::OnInitDialog() {

CDialog::OnInitDialog(); return (HCURSOR)m_hIcon;

if ((nID & 0xFFF0) == IDM_ABOUTBOX) { } else { }

CDialog::OnSysCommand(nID, lParam); CAboutDlg dlgAbout; dlgAbout.DoModal();

}

4.2:中心时间显示

{

//3. 取得时, 分, 秒 CString sTime; SYSTEMTIME tm; ::GetLocalTime(&tm);

//取得本地时间

//1. 获取设备资源

CPen *pOldPen = pDC->GetCurrentPen(); CPen pen(PS_SOLID, 1, RGB(0,0,0)); pDC->SelectObject(&pen);

CBrush *pOldBrush = pDC->GetCurrentBrush(); CBrush brush;

//使圆背景透明,不至于遮挡住圆心处显示的时间文本

CRect rc;

this->GetClientRect(&rc); //获取客户区矩形 void CAlarmClockDlg::OnDrawMem(CDC *pDC)

brush.CreateStockObject(NULL_BRUSH); pDC->SelectObject(&brush);

pDC->SetBkMode(TRANSPARENT);

//设置文本背景为透明

//设置文本颜色

pDC->SetTextColor(RGB(128, 0, 128));

//2. 获取圆心和半径 POINT ptO; //圆心

int iR = min(rc.right - rc.left, rc.bottom-rc.top) / 2; iR = iR - 10; //半径

ptO.x = (rc.right + rc.left) / 2; ptO.y = (rc.bottom + rc.top) / 2;

float fSecond = tm.wSecond;

float fMinute = tm.wMinute + fSecond / 60.0f; float fHour = tm.wHour % 12 + fMinute / 60.0f;

//在圆心附近显示时间

// CRect rtO(ptO.x - 40, ptO.y + 2, ptO.x + 40, ptO.y + 22);

CRect rtO(ptO.x - iR, ptO.y + 2, ptO.x + iR, ptO.y + iR); sTime.Format(\pDC->DrawText(sTime, &rtO, DT_CENTER);

4.3:画时钟

算法:时钟的秒刻度分为60个刻度,每个刻度是6° 四个象限的刻度尺的算法如下: //第一象限

for(int i=0;i<16;i++) {

POINT pt0;

pt0.x = ptOrigin.x + iR * sin( PI/180 * 6*i) *

0.95f;

pt0.y = ptOrigin.y - iR * cos( PI/180 * 6*i) *

0.95f; }

//第四象限 for(i=1;i<16;i++) { }

POINT pt0;

pt0.x = ptOrigin.x + iR * cos( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y + iR * sin( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0)); SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

//第三象限 for(i=1;i<16;i++) { }

//第二象限 for(i=1;i<15;i++) { } 根据:

sin(PI/2+α)=cosα cos(π/2+α)=-sinα 第四象限可以写成 for(int i=16;i<32;i++) { } 根据:

sin(π+α)=-sinα cos(π+α)=-cosα 第三象限可以写成:

POINT pt0;

pt0.x = ptOrigin.x + iR * sin( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y - iR * cos( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0)); POINT pt0;

pt0.x = ptOrigin.x - iR * cos( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y - iR * sin( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0)); POINT pt0;

pt0.x = ptOrigin.x - iR * sin( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y + iR * cos( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

for(int i=32;i<48;i++) { } 根据:

sin(3π/2+α)=-cosα cos(3π/2+α)=sinα 第二象限可以写成 for(int i=48;i<60;i++) { }

最后统一成:

for(int i=0;i<60;i++) { }

所以有程序代码如下:

// pDC->Ellipse(ptO.x - iR, ptO.y - iR, ptO.x + iR, ptO.y + iR);

//4.1 画秒刻度 POINT pt0;

pt0.x = ptOrigin.x + iR * sin( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y - iR * cos( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0)); POINT pt0;

pt0.x = ptOrigin.x + iR * sin( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y - iR * cos( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0)); POINT pt0;

pt0.x = ptOrigin.x + iR * sin( PI/180 * 6*i) * 0.95f; pt0.y = ptOrigin.y - iR * cos( PI/180 * 6*i) * 0.95f; SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

pen.DeleteObject();

pen.CreatePen(PS_SOLID, 1, RGB(0,0,0));

pDC->SelectObject(&pen); for (int i = 0; i < 60; i++) { }

//4.2 画小时刻度 pen.DeleteObject();

pen.CreatePen(PS_SOLID, 2, RGB(0,0,0)); pDC->SelectObject(&pen); for (i = 0; i < 60; i = i + 5) {

POINT ptA, ptB;

ptA.x = ptO.x + iR * sin( PI/30 * i) * 0.95f; ptA.y = ptO.y - iR * cos( PI/30 * i) * 0.95f; ptB.x = ptO.x + iR * sin( PI/30 * i) * 1.00f; ptB.y = ptO.y - iR * cos( PI/30 * i) * 1.00f; pDC->MoveTo(ptA.x, ptA.y); pDC->LineTo(ptB.x, ptB.y);

//写出小时数字 int j = i/5; POINT ptA, ptB;

ptA.x = ptO.x + iR * sin( PI/30 * i) * 0.98f; ptA.y = ptO.y - iR * cos( PI/30 * i) * 0.98f; ptB.x = ptO.x + iR * sin( PI/30 * i) * 1.00f; ptB.y = ptO.y - iR * cos( PI/30 * i) * 1.00f; pDC->MoveTo(ptA.x, ptA.y); pDC->LineTo(ptB.x, ptB.y);

}

//帮助信息

void CAlarmClockDlg::WinHelp(DWORD dwData, UINT nCmd) { }

//将当前系统时间设置为从Internet取得的标准时间

DWORD CAlarmClockDlg::SetInternetTimeProc(LPVOID lpParameter) {

//设置接收超时时间为2s //创建TCP套接字

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET) { }

pDlg->m_hThread = NULL; return FALSE;

CAlarmClockDlg *pDlg = (CAlarmClockDlg *)lpParameter; DWORD bRet = FALSE;

// TODO: Add your specialized code here and/or call the base class m_bHelp = !m_bHelp; if (m_bHelp)

this->SetTimer(110, 7000, NULL);

else

this->KillTimer(110);

this->Invalidate();

//CDialog::WinHelp(dwData, nCmd);

int nTimeout = 2000;

::setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&nTimeout, sizeof(nTimeout));

//时间服务器IP地址 char *szServer[] = { };

\\\

\\

\\

//尝试连接不同的服务器 BOOL bConnect = FALSE;

for (int i = 0; i < dim(szServer); i++) {

SOCKADDR_IN sa;

sa.sin_family = AF_INET ;

sa.sin_port = htons(IPPORT_TIMESERVER);

sa.sin_addr.S_un.S_addr = inet_addr(szServer[i]) ; //

sa.sin_addr.S_un.S_addr = inet_addr (\

}

if (0 == connect(sock, (SOCKADDR *)&sa, sizeof(sa))) { }

bConnect = TRUE;

TRACE(\break;

if (!bConnect) { }

closesocket(sock) ; pDlg->m_hThread = NULL; return FALSE;

while (TRUE) {

::Sleep(1); ULONG ulTime = 0;

int iBytesRecv = recv(sock, (char *)&ulTime, sizeof(ulTime), 0); if (iBytesRecv > 0) {

ulTime = ntohl(ulTime);

//ulTime += 8*60*60;

//加8小时,就是北京时

//ulTime = Now - 1900.1.1 00:00:00 此时的ulTime是自1900.1.1子夜到现在时

间之间的秒数 !!!!!!!!!!

// 1900.1.1-->SYSTEMTIME-->FILETIME-->LARGE_INTEGER SYSTEMTIME stNew; stNew.wYear = 1900; stNew.wHour = 0;

stNew.wMonth = 1; stNew.wMinute = 0;

stNew.wDay = 1; stNew.wSecond

=

0

;

stNew.wMilliseconds = 0;

FILETIME ftNew;

SystemTimeToFileTime(&stNew, &ftNew);

LARGE_INTEGER liTime = *(LARGE_INTEGER *)&ftNew;

//用64位大整数表示

1900.1.1

//加上从服务器获取的秒数: ulTime

liTime.QuadPart += (LONGLONG)10000000 * ulTime;

//1900.1.1 + ulTime

//改变系统时间

// 将当前的Internet时间转化为 20080101 和 235959 这种数字型格式

LONGLONG llNetDate = stNew.wYear * 10000 + stNew.wMonth * 100 + stNew.wDay; //LONGLONG llNetTime = stNew.wHour * 10000 + stNew.wMinute * 100 +

//LARGE_INTEGER-->FILETIME-->SYSTEMTIME-->2011.6.12. ftNew = *(FILETIME *)&liTime; FileTimeToSystemTime(&ftNew, &stNew);

stNew.wSecond; }

return bRet;

pDlg->m_hThread = NULL; }

closesocket (sock) ; sock = NULL;

}

if (llNetDate > 19000101) { }

bRet = SetSystemTime(&stNew); break;

5.结论:通过这次的课程设计的训练,深刻体会到了自己在这方面还很不足,需要加强,就像

老师说的还有很大的提升空间,同时,也感觉学好C++很有用的,编出程序的那一刻还是很高兴的,因此,这次的最大的收获就是培养出了自己对C++的兴趣。我通过这次的学习,知道了,学习C++,最重要的是自己动手的能力,光靠课堂上的知识是无法编出自己的程序的,在课后,我们一定要自己多动手,这样才有可能学好C++。

参考文献

[1] 任哲等编著《MFC Windows应用程序设计(第二版)》,出版年:2007年9月,卷(期):第

二版。

[2] 课堂上提供的程序代码。

致 谢

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

本文来源:https://www.bwwdw.com/article/ln5v.html

Top