为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

毕业设计-多时区时钟软件的设计与实现-论文

2018-11-05 50页 doc 475KB 12阅读

用户头像

is_633808

暂无简介

举报
毕业设计-多时区时钟软件的设计与实现-论文毕业设计-多时区时钟软件的设计与实现-论文 毕业设计(论文) 多时区时钟软件的设计与实现 论文作者姓名: 申请学位专业: 申请学位类别: 指导教师姓名,职称,: 论文提交日期: 多时区时钟软件的设计与实现 摘 要 进入21世纪以来,电脑用户数迅速增长,网上的跨国交流也越见频繁,由于时差的关系,不同国家的作息不同,因此需要经常进行时间的切换。 本系统主要论述如何利用VC++6.0应用程序开发环境和微软基础类库(MFC),设计与实现一个基于对话框的多时区时钟软件。该软件主要包括时钟显示,闹钟报时以及计时器功能...
毕业设计-多时区时钟软件的设计与实现-论文
毕业设计-多时区时钟软件的设计与实现-论文 毕业设计(论文) 多时区时钟软件的设计与实现 论文作者姓名: 申请学位专业: 申请学位类别: 指导教师姓名,职称,: 论文提交日期: 多时区时钟软件的设计与实现 摘 要 进入21世纪以来,电脑用户数迅速增长,网上的跨国交流也越见频繁,由于时差的关系,不同国家的作息不同,因此需要经常进行时间的切换。 本系统主要论述如何利用VC++6.0应用程序开发环境和微软基础类库(MFC),设计与实现一个基于对话框的多时区时钟软件。该软件主要包括时钟显示,闹钟报时以及计时器功能。其中,时钟显示包含单时区时钟显示和多时区时钟显示,计时器可实现倒计时与正常计时。利用MFC中与定时器相关的函数,实现计时和时钟的定时刷新;运用模运算实现不同时区的时间转换;采用多线程技术使三个时钟同时运行。 关键词:VC++;MFC;时钟;多线程 The design and realization of Multi_ time_ zone Clock Abstract stSince the 21Century, the number of computer users has increased quickly,the communication among different countries on Internet becomes more and more frequent. Because of the time difference, every country has its own timetable, you need to switch the time frequently. This system has discussed how to design and realize a clock with Visual C++6.0 and Microsoft Foundation Class. This software principally contains these functions: the display of clocks, alarm clock and timer. The function of clock display contains the displays of single time zone clocks and multi time zone clocks. The timer can realize functions of countdown and clock. Take use of the functions related to the timer in Microsoft Foundation Class library to implement time and regular update of the clocks; the time conversion of different time zone could use modular arithmetic to realize; and taking advantage of multithreading could make three clocks run at the same time. Key words: Visual C++; MFC; clock; multithreading 目 录 论文总页数:27页 1 引 言 ........................................................................................................................................... 1 1.1课题背景及意义 ..................................................................................................................... 1 1.2 课题的研究方法 .................................................................................................................... 1 2 程序功能描述 ............................................................................................................................. 1 2.1 时钟显示 ................................................................................................................................ 1 2.1.1 单时钟显示 ..................................................................................................................... 1 2.1.2 多时钟显示 ..................................................................................................................... 1 2.2闹钟功能 ................................................................................................................................. 1 2.3计时器 ..................................................................................................................................... 2 2.3.1 倒计时 ............................................................................................................................. 2 2.3.2 正常计时 ......................................................................................................................... 2 2.4 开发环境 ................................................................................................................................ 2 2.4.1 开发环境 ......................................................................................................................... 2 2.4.2 Visual C++ 6.0简介 ........................................................................................................ 2 3 主要开发技术 ............................................................................................................................. 3 3.1 MFC简介 ............................................................................................................................... 3 3.2 MFC的线程 ........................................................................................................................... 3 3.2.1多线程概述 ...................................................................................................................... 3 3.2.2 MFC的线程 .................................................................................................................... 4 4 程序功能实现 ............................................................................................................................. 5 4.1单时钟显示 ............................................................................................................................. 5 4.2多时钟显示 ........................................................................................................................... 10 4.3闹钟报时 ............................................................................................................................... 13 4.4计时器 ................................................................................................................................... 17 4.4.1倒计时 ............................................................................................................................ 17 4.4.2正常计时 ........................................................................................................................ 20 结 论 ......................................................................................................................................... 22 参考文献 ......................................................................................................................................... 23 附 录 ......................................................................................................................................... 24 致 谢 ......................................................................................................................................... 26 声 明 ......................................................................................................................................... 27 1 引 言 1.1课题背景及意义 随着社会的发展,进入21世纪,个人电脑已经进入千家万户,人们已习惯于以互联网的方式交流,学习和娱乐。网上跨国交流也越见频繁,由于时差的关系,人们在浏览国外新闻时经常需要进行时间的换算。不同地区作息时间的不同也影响到人们的交流。因此,一种能显示多个时区时间的时钟程序,将给人们的生活与交流带来极大地方便。 1.2 课题的研究方法 通过对VC++可视化编程的学习以及各地区时间差的查询,本文主要采用MFC控件和多线程编程技术,以及三个与时间有关的函数SetTimer()、OnTimer()和KillTimer(),设计实现一个包含计时器功能和闹钟功能的多时区时钟程序。 2 程序功能描述 软件主要实现三个功能:时钟显示,闹钟以及计时器。具体功能如下 2.1 时钟显示 2.1.1 单时钟显示 实现三个时区时钟(北京时间,纽约时间,伦敦时间)的单独显示。在程序的主界面上,有一个日历,一个指针式时钟,一个时间显示框,一个确定按钮和一个取消按钮。 时钟切换:单击菜单[时钟显示],>[单时钟]->北京时间/纽约时间/伦敦时间。 整点报时:当时间为整点时,扬声器响相应次数。 日期显示:在日历控件上显示相应地区的当前日期。 单击[关闭]按钮,关闭主程序。 2.1.2 多时钟显示 实现三个时区时钟的同时显示及运行。 在主界面上,单击菜单[时钟显示],>[多时钟],弹出[多时钟显示]对话框。此对话框上有三个时钟同时运行,每个时钟有一个相对应的数字时间显示。 单击{关闭}按钮,将关闭此对话框。 2.2闹钟功能 实现三个时区时钟的闹钟设置。 在主界面上单击{闹钟}菜单,将弹出[闹钟]对话框,此对话框有三个单选按钮,分别选择北京时间,纽约时间和伦敦时间,系统默认为北京时间,右边的指针式时钟以及数字时间随单选按钮而改变。在报时设置框中设置时间后,点击[确 定],则闹钟设置完成。 点击[取消],可取消报时。 2.3计时器 实现以秒为单位的倒计时和正常计时功能。 2.3.1 倒计时 在主界面上单击菜单[计时器]->[倒计时],将弹出[倒计时]对话框,在编辑框中输入计时长度,单击[开始计时],编辑框置成不可用状态,倒计时开始。在[剩余时间]栏,将显示剩余时间。单击[重新计时],可取消倒计时,编辑框恢复可编辑状态。 2.3.2 正常计时 在主界面上单击菜单[计时器]->[正常计时],将弹出[正常计时]对话框,点击[开始计时]按钮,在流逝的时间栏将显示时间数,[开始计时]按钮呈不可用状态,而[重新计时]可用。点击[重新计时],取消计时,并将时间设为零秒,[开始计时]可用。 2.4 开发环境 2.4.1 开发环境 Visual C++ 6.0, Windows 2000/XP 2.4.2 Visual C++ 6.0简介 Visual C++是Microsoft公司推出的功能最强大、最复杂的语言产品之一,它是目前为止在W环境下进行大型软件开发的首选。其具有如下特点。 , Visual C++的语法符合ANSI C++,并在此基础上针对性W操作系统增 加了一些语句。 , 集成了MFC(Microsoft Foundation Class)类库,MFC封装了Windows API函数 和消息,使程序员可以使用MFC高效率地开发各种应用程序。 , 提供了MFC AppWizard,可方便地生成程序框架。 , 提供了基于MFC的ClassWizard,通过它可以轻松地完成对各种MFC类的使 用与维护。 Visual C++6.0作为Visual Studio家族中的一员,是微软公司推出的以C++语言为基础,开发Win32应用程序(Windows 95/98/2000/XP/NT)的、面向对象的可视化集成工具。它的最大优点就是提供了功能强大的MFC类库,MFC是一个很大的C++类层次结构,其中封装了大量的类及其函数,很多Windows程序所共有的标准可以由MFC的类来提供,MFC类为这些内容提供了用户接 口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓,这将简化编程工作,大大的减少程序员编写的代码数量,使编程工作变得更加轻松容。 3 主要开发技术 程序主要采用MFC控件和多线程技术实现。 3.1 MFC简介 MFC,微软基础类(Microsoft Foundation Classes),是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个输助软件开发包,MFC类是微软为VC++专配的。 MFC是Win API与C++的结合,API,即微软提供的WinOS下应用程序的编程语言接口,是一种软件编程的规范,但不是程序开发语言本身,可以允许用户使用各种各样的第三方的编程语言来进行对Win OS下应用程序的开发,使这些被开发出来的应用程序能在WinOS下运行,比如VB,VC++,Java,Dehpi编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在WinOS的消息机制里。 MFC 是一个很大的、扩展了的 C++ 类层次结构,它能使开发 Windows应用程序变得更加容易。MFC 是在整个 Windows 家族中都是兼容的,也就是说,无论是 Windows3.x、Windows95 还是 Windows NT,所使用的 MFC 是兼容的。每当新的 Windows 版本出现时,MFC 也会得到修改以便使旧的编译器和代码能在新的系统中工作。MFC 也会得到扩展,添加新的特性、变得更加容易建立应用程序。 3.2 MFC的线程 3.2.1多线程概述 进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程终止了,进程也就随之终止。每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空 间、全局变量和系统资源,所以线程间的通讯非常方便,多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,好像这些线程都在同时运行。 3.2.2 MFC的线程 MFC明确区分两种线程:用户界面线程(User interface thread)和工作者线程(Worker thread)。用户界面线程一般用于处理用户输入并对用户产生的事件和消息作出应答。工作者线程用于完成不要求用户输入的任务,如耗时计算。 线程的创建 1)创建用户界面线程 通过以下步骤创建一个用户界面线程: , 从CWinThread派生一个有动态创建能力的类。使用DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE宏来支持动态创建。 , 覆盖CWinThread的一些虚拟函数,其中,函数InitInstance是必须覆盖 的,ExitInstance通常是要覆盖的。 , 使用AfxBeginThread创建MFC线程对象和Win32线程对象。如果创建线 程时没有指定CREATE_SUSPENDED,则开始执行线程。 , 如果创建线程是指定了CREATE_SUSPENDED,则在适当的地方调用函数 ResumeThread开始执行线程。 2)创建工作者线程 程序员不必从CWinThread派生新的线程类,只需要提供一个控制函数,由线程启动后执行该函数。然后,使用AfxBeginThread创建MFC线程对象和Win32线程对象。如果创建线程时没有指定CREATE_SUSPENDED(创建后挂起),则创建的新线程开始执行。如果创建线程是指定了CREATE_SUSPENDED,则在适当的地方调用函数ResumeThread开始执行线程。虽然没有从CWinThread派生类,但是MFC给工作者线程提供了缺省的CWinThread对象。 线程的结束 AfxEndThread用来结束调用它的线程:它将清理本线程创建的MFC对象和释放线程局部存储分配的内存空间;调用CWinThread的虚拟函数Delete;调用“C”的结束线程函数_endthreadex释放分配给线程的资源,但是不关闭线程句柄。CWinThread::Delete的缺省实现是:如果本线程的成员函数m_bDelete为TRUE,则调用“C”运算符号delete销毁MFC线程对象自身(delete this),这将导致线程对象的析构函数被调用。若析构函数线程句柄非空则调用CloseHandle关闭它。 3.3 定时器 在程序中我们经常要使用定时刷新的功能, MFC提供了定时器来完成这个功能。 在MFC中和定时器相关的有三个函数: UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)( HWND, UINT, UINT, DWORD) ); afx_msg void OnTimer( UINT nIDEvent ); BOOL KillTimer( int nIDEvent ); 函数功能: SetTimer用来定义一个定时器的属性,如改定时器的ID,刷新时间,处理函数。 OnTimer实际时系统定义消息用来响应WM_TIMER消息,在这里可以实现对多定时器中的各个定时器分别响应,这里才时定时程序大展宏图的地方。 KillTimer用来结束一个定时器。 4 程序功能实现 4.1单时钟显示 创建一个基于对话框的工程MultiClock。 1.在对话框上添加控件资源并设置属性(如图4-1,4-1) 图4-1 程序主对话框(单时钟界面)设计 表4-1 对话框资源IDD_MULTICLOCK_DIALOG控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 日历控件 IDC_MONTHCALENDAR1 无 分组框 IDC_STATIC1 北京时间 按钮1 IDCANCEL 关闭 静态文本框 IDC_STATIC2 static 分隔线(Picture控件) IDC_STATIC 类型Frame,颜色Black 2.添加菜单资源并导入对话框(如图4-2,图4-3) 图4-2 菜单界面设计1 图4-3 菜单界面设计2 表4-2 菜单项属性设置 ID Caption Pop-up 时钟显示 ? 单时钟 ? 计时器 ? ID_MCLOCK 多时钟 ID_BKTIME 北京时间 ID_NYTIME 纽约时间 ID_LDTIME 伦敦时间 ID_NAOZHONG 闹钟 ID_DAOJISHI 倒计时 ID_ZHENJI 正常计时 ID_HELP 帮助 3.使用MFC类向导添加消息响应函数和成员变量(表4-3,4-4) 表4-3 向对话框类CMultiClockDlg添加消息响应函数 Object IDs Messages 消息的描述 函数名 CMultiClockDlg WM_TIMER 时间触发消息 OnTimer ID_MCLOCK COMMAND 菜单消息 OnMclock ID_NAOZHONG COMMAND 菜单消息 OnNaozhong ID_DAOJISHI COMMAND 菜单消息 OnDaojishi ID_ZHENJI COMMAND 菜单消息 OnZhenji ID_HELP COMMAND 菜单消息 OnHelp 表4-4 向对话框类CMultiClockDlg添加控件对应的成员变量 Object IDs 变量名 变量种类 变量类型 IDC_MONTHCALENDAR1 m_monthcal Control CMonthCalCtrl IDC_STATIC1 m_spot Control CButton IDC_STATIC2 m_str Value CString 4.添加代码(粗体字部分为添加代码) (1)在MultiClock.h文件中添加函数声明 绘制时钟外观函数 // void DrawClockFace(HDC hdc); //绘制时钟指针函数 void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor); (2)在MultiClock.cpp文件中添加: #include DrawClockFace.函数体 DrawHand 函数体 (函数体见附录) (3)在MultiClockDlg.h文件中添加CMultiClockDlg类成员变量和函数 public: SYSTEMTIME time,tm; int minute,hour,second; private: afx_msg void OnSingleClock(WORD nID);//声明单时钟菜单消息处理函数 (4)在MultiClockDlg.cpp文件中添加功能代码: //单时钟消息映射 ON_COMMAND_RANGE(ID_BKTIME,ID_LDTIME,OnSingleClock) //初始化时间变量,设置定时器 BOOL CMultiClockDlg::OnInitDialog() { // TODO: Add extra initialization here ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); return TRUE; // return TRUE unless you set the focus to a control } //单时钟菜单响应函数 void CMultiClockDlg::OnSingleClock(WORD nID) {KillTimer(1); m_nsclock=nID-ID_BKTIME; switch(m_nsclock) { case 0: ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); m_spot.SetWindowText("北京时间"); break; case 1: ::GetLocalTime(&time); hour=(time.wHour-13+24)%24; minute=time.wMinute; second=time.wSecond; if((time.wHour-13)<0)//日历设置 { CTime tm1(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm1); m_monthcal.SetToday(&tm1); } SetTimer(1,1000,NULL); m_spot.SetWindowText("纽约时间"); break; case 2: ::GetLocalTime(&time); hour=(time.wHour-8+24)%24; minute=time.wMinute; second=time.wSecond; if((time.wHour-8)<0)//日历设置 { CTime tm2(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm2); m_monthcal.SetToday(&tm2); } SetTimer(1,1000,NULL); m_spot.SetWindowText("伦敦时间"); break; } } //定时刷新,使指针运行 void CMultiClockDlg::OnTimer(UINT nIDEvent) { //绘制单时钟 CClientDC dc(this); dc.SetMapMode(MM_ISOTROPIC); dc.SetViewportOrg(380,100); COLORREF crf=RGB(255,255,255); ::GetLocalTime(&time); DrawClockFace(dc); if(time.wMinute!=minute) {DrawHand(dc,60,8,hour*30+minute/2,crf); DrawHand(dc,90,6,minute*6,crf); if(m_nsclock==0) hour=time.wHour; if(m_nsclock==1) {hour=(time.wHour-13+24)%24; if((time.wHour-13)<0) //日历设置 { CTime tm1(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm1); m_monthcal.SetToday(&tm1); } } if(m_nsclock==2) {hour=(time.wHour-8+24)%24; if((time.wHour-8)<0)//日历设置 { CTime tm2(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm2); m_monthcal.SetToday(&tm2); } } minute=time.wMinute; } if(time.wSecond!=second) {DrawHand(dc,120,1,second*6,crf); DrawHand(dc,120,1,time.wSecond*6,RGB(255,0,0)); DrawHand(dc,90,6,time.wMinute*6,RGB(0,255,0)); DrawHand(dc,60,8,hour*30+minute/2,RGB(0,0,255)); second=time.wSecond; } m_str.Format("%.2d:%.2d:%.2d",hour,minute,second); UpdateData(false); if(minute==0&&second<=hour) //整点报时 { ::Beep(1000,500); } } 编译后运行,单时钟效果(如图4-4) 4.2多时钟显示 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_MCLOCK,新建一个CDialog的派生类CMULCLOCK。 2. 在对话框上添加控件资源并设置属性(如图4-5,表4-5) 3.使用MFC类向导添加消息响应函数和成员变量(表4-6) 图4-4 单时钟运行效果 表4-5 对话框资源IDD_MULCLOCK控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 北京时间 分组框2 IDC_STATIC 纽约时间 分组框3 IDC_STATIC 伦敦时间 按钮 IDCANCEL 关闭 分隔线(Picture控件) IDC_STATIC 类型Frame,颜色Black 图4-5 多时钟界面设计 表4-6 向对话框类CMULClOCK添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CMULCLOCK WM_INITDIALOG 窗口初始化 OnInitDialog 4.添加代码(粗体字部分) (1)在 MULCLOCK.h文件 中添加声明 void drawclock1(HWND hwnd,SYSTEMTIME time,int hour,int minute,int second,int xpos,int ypos); void drawclock2(…); void drawclock3(…); UINT ThreadProc1(LPVOID pParam); UINT ThreadProc2(LPVOID pParam); UINT ThreadProc3(LPVOID pParam); static HWND hWnd; static SYSTEMTIME t1,t2,t3; static int h1,m1,s1,h2,m2,s2,h3,m3,s3; static BOOL m_b0=false,m_b1=false,m_b2=false; (2)在 MULCLOCK.cpp文件 中添加代码(粗体字部分) 添加上述声明函数的的函数体. //开启多时钟线程 BOOL CMULCLOCK::OnInitDialog() { // TODO: Add extra initialization here hWnd=CMULCLOCK::GetSafeHwnd(); AfxBeginThread(ThreadProc1,this); AfxBeginThread(ThreadProc2,this); AfxBeginThread(ThreadProc3,this); return TRUE; } (3)在MultiClockDlg.cpp文件中添加 #include "MULCLOCK.h" //打开多时钟显示对话框 void CMultiClockDlg::OnMclock() { // TODO: Add your command handler code here CMULCLOCK MCLOCK; MCLOCK.DoModal(); } 编译后运行,多时钟效果为(图4-6) 图4-6 多时钟运行效果 4.3闹钟报时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对话框,ID为IDD_NAOZHONG,新建一个CDialog的派生类CNAOZHONG。 2. 在对话框上添加控件资源并设置性(图4-7,表4-7) 3.使用MFC类向导添加消息响应函数和成员变量(表4-8,4-9) 图4-7 闹钟界面设计 表4-7 对话框资源IDD_NAOZHONG控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 单选按钮1 IDC_RADIO1 北京时间 单选按钮2 IDC_RADIO2 纽约时间 单选按钮3 IDC_RADIO3 伦敦时间 分组框 IDC_STATIC1 北京时间 静态文本框1 IDC_STATIC2 static 静态文本框2 IDC_STATIC 定时设置: 日期控件 IDC_DATETIMEPICKER2 无,格式Time|spin 按钮1 IDC_ENTER 确定 按钮2 IDC_CLEAR 取消 表4-8 向对话框类CNAOZHONG添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CNAOZHONG WM_INITDIALOG 窗口初始化 OnInitDialog IDC_RADIO1 BN_CLICKED 单击控件 OnRadio1 IDC_RADIO2 BN_CLICKED 单击控件 OnRadio2 IDC_RADIO3 BN_CLICKED 单击控件 OnRadio3 IDC_ENTER BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-9 向对话框类CNAOZHONG添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_DATETIMEPICKER2 m_time Control CDateTimeCtrl IDC_STATIC1 m_address Control CButton IDC_STATIC2 m_str Value CString 4.添加代码(粗体字部分) (1)在 NAOZHONG.h文件 中添加CNAOZHONG类成员变量 public: SYSTEMTIME time; int hour,minute,second; (2)在 NAOZHONG.cpp文件中添加(粗体字部分) static BOOL m_b=false; static int m_rad1; BOOL CNAOZHONG::OnInitDialog() { // TODO: Add extra initialization here CheckRadioButton(IDC_RADIO1,IDC_RADIO3,IDC_RADIO1); m_rad1=0; CString formatstr=_T("HH:mm:ss"); m_time.SetFormat(formatstr); ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); return TRUE; } void CNAOZHONG::OnTimer(UINT nIDEvent) { CClientDC dc(this); dc.SetMapMode(MM_ISOTROPIC); dc.SetViewportOrg(170,100); COLORREF crf=::GetSysColor(COLOR_3DFACE); ::GetLocalTime(&time); DrawClockFace(dc); if(time.wMinute!=minute) {DrawHand(dc,60,8,hour*30+minute/2,crf); DrawHand(dc,90,6,minute*6,crf); if(m_rad1==0) hour=time.wHour; if(m_rad1==1) hour=(time.wHour-13+24)%24; if(m_rad1==2) hour=(time.wHour-8+24)%24; minute=time.wMinute; } if(time.wSecond!=second) {DrawHand(dc,120,1,second*6,crf); DrawHand(dc,120,1,time.wSecond*6,RGB(255,0,0)); DrawHand(dc,90,6,time.wMinute*6,RGB(0,255,0)); DrawHand(dc,60,8,hour*30+minute/2,RGB(0,0,255)); second=time.wSecond; } m_str.Format("%.2d:%.2d:%.2d",hour,minute,second); UpdateData(FALSE); if(m_b) { m_time.GetTime(t1);; if(hour==t1.GetHour()) { if(minute==t1.GetMinute()) if(second>=t1.GetSecond()) {m_b=false; ::Beep(1000,500); AfxMessageBox("时间到"); } } } } void CNAOZHONG::OnRadio1()//选择北京时区 {KillTimer(1); m_rad1=0; m_address.SetWindowText("北京时间"); ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } void CNAOZHONG::OnRadio2()//选择纽约时区 {KillTimer(1); m_rad1=1; m_address.SetWindowText("纽约时间"); ::GetLocalTime(&time); hour=(time.wHour-13+24)%24; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } void CNAOZHONG::OnRadio3()//选择伦敦时区 {KillTimer(1); m_rad1=2; m_address.SetWindowText("伦敦时间"); ::GetLocalTime(&time); hour=(time.wHour-8+24)%24; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } (3)在MultiClockDlg.cpp文件中添加 #include "NAOZHONG.h" //打开闹钟对话框 void CMultiClockDlg::OnNaozhong() { // TODO: Add your command handler code here CNAOZHONG NAOZHONG; NAOZHONG.DoModal(); } 编译后运行效果(如图4-8) 4.4计时器 4.4.1倒计时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_DAOJISHI,新建一个CDialog的派生类CDAOJISHI. 2. 在对话框上添加控件资源并设置性(如图4-9,表4-10) 3.使用MFC类向导添加消息响应函数和成员变量(表4-11,4-12) 图4-8 闹钟运行效果 图4-9 倒计时界面设计 表4-10 对话框资源IDD_DAOJISHI控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 请输入计时长度 分组框2 IDC_STATIC 剩余时间 静态文本框1 IDC_STATIC1 static 静态文本框2 IDC_STATIC 分 静态文本框3 IDC_STATIC 秒 文本编辑框1 IDC_EDIT1 无 文本编辑框2 IDC_EDIT2 无 按钮1 IDC_START 开始计时 按钮2 IDC_CLEAR 重新计时 表4-11 向对话框类CDAOJISHI添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CDAOJISHI WM_TIMER 时间触发消息 OnTimer IDC_START BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-12 向对话框类CDAOJISHI添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_EDIT1 m_min Value UINT IDC_EDIT2 m_sec Value UINT IDC_STATIC1 m_str Value CString 4.添加代码(粗体字部分) (1)在 DAOJISHI.h文件 中添加CDAOJISHI类成员变量 int m_totaltime; (2)在 DAOJISHI.cpp文件中添加如下代码(粗体字部分) void CDAOJISHI::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(m_totaltime>=0) {m_str.Format("%d分%d秒", (int)(m_totaltime/60),m_totaltime-((int)(m_totaltime/60))*60); m_totaltime--; UpdateData(FALSE); } else { KillTimer(1); ::Beep(1000,500); } } void CDAOJISHI::OnStart()//开始计时 { UpdateData(true); m_totaltime=m_min*60+m_sec; GetDlgItem(IDC_EDIT1)->EnableWindow(false); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_START)->EnableWindow(false); GetDlgItem(IDC_CLEAR)->EnableWindow(true); SetTimer(1,1000,NULL); } void CDAOJISHI::OnClear()//重新计时 {KillTimer(1); GetDlgItem(IDC_CLEAR)->EnableWindow(FALSE); GetDlgItem(IDC_START)->EnableWindow(true); GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); m_str=_T(""); UpdateData(false); } (3)在MultiClockDlg.cpp文件中添加 #include "DAOJISHI.h" //打开倒计时对话框 void CMultiClockDlg::OnDaojishi() { CDAOJISHI DAO; DAO.DoModal(); } 编译后运行效果(如图4-10) 图4-10 倒计时运行效果 4.4.2正常计时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_ZHENJISHI,新建一个CDialog的派生类CZHENJISHI. 2. 在对话框上添加控件资源并设置性(如图4-11,表4-13) 3.使用MFC类向导添加消息响应函数和成员变量(表4-14,4-15) 图4-11 正常计时界面设计 表4-13 对话框资源IDD_ZHENJISHI控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 流逝的时间 静态文本框1 IDC_STATIC 正常计时: 静态文本框2 IDC_STATIC1 static 按钮1 IDC_START 开始计时 按钮2 IDC_CLEAR 重新计时 表4-14 向对话框类CZHENJISHI添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CZHENJISHI WM_TIMER 时间触发消息 OnTimer IDC_START BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-15 向对话框类CZHENJISHI添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_STATIC1 m_str Value CString 4.添加代码(粗体字部分) (1)在 ZHENJISHI.h文件 中添加CZHENJISHI类成员变量 int m_time; (2)在 ZHENJISHI.cpp文件中添加如下代码 //开始计时 void CZHENJISHI::OnStart() { // TODO: Add your control notification handler code here m_time=0; GetDlgItem(IDC_START)->EnableWindow(false); GetDlgItem(IDC_CLEAR)->EnableWindow(true); SetTimer(1,1000,NULL); } void CZHENJISHI::OnClear()//重新计时 {KillTimer(1); m_time=0; m_str.Format("%d分%d秒",0,0); GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_CLEAR)->EnableWindow(FALSE); UpdateData(false); } void CZHENJISHI::OnTimer(UINT nIDEvent) //计时实现 { m_time++; m_str.Format("%d分%d秒", (int)(m_time/60),m_time-((int)(m_time/60))*60); UpdateData(FALSE); } (3)在MultiClockDlg.cpp文件中添加 #include "ZHENJISHI.h" //打开正常计时对话框 void CMultiClockDlg::OnZhenji() { // TODO: Add your command handler code here CZHENJISHI ZHEN; ZHEN.DoModal(); } 编译后运行效果(如图4-12) 图4-12 正常计时运行效果 至此一个多时区时钟程序完成了。 结 论 基于本次课题的研究和设计实现,可以发现,时钟的设计与实现的主要问题在于对MFC控件的使用和消息机制的理解,以及多线程设计中全局函数的编写。其中,窗口类指针的调用,是一大难点,大多数错误发生的原因都因为指针的错误调用。 本次设计实现了一个显示三个不同时区时间的时钟和相应的闹钟以及一个以秒为计时单位的计时器。程序除指针式时钟显示外,还有相应的数字时间显示, 主界面的日历也与显示时区的日期相对应。计时器可完成正常计时和倒计时功能。在此基础上,通过添加、修改控件和代码,还可以添加更多新的功能,使界面显得更美观,使其更方便,发挥的作用更大。 参考文献 [1] 黄维通.Visual C++ 面向对象与可视化程序设计[M].北京:清华大学出版社,2003。 [2] 郑莉,董渊.C++语言程序设计[M].北京:清华大学出版社,2001。 [3] 古槿.新手学Visual C++30例[M].北京:人民邮电出版社,2004。 [4] Charles Petzold. Windows程序设计[M].北京: 北京大学出版社,1999。 [5]胡峪,刘静.Visual C++编程技巧与与示例[M].西安: 西安电子科技大学出版社,2000。 [6]东方人华,李秀敏,凌宇欣.Visual C++ 6.0 范例入门与提高[M].北京:清华大学出版 社,2003。 [7]梁普选.Visual C++程序设计与实践[M].北京:清华大学出版社&北京交通大学出版 社,2005。 附 录 世界重要城市时差表 国 名 城 市 与北京时差 美 国 旧 金 山 -16 墨 西 哥 墨西哥城 -15 美 国 纽 约 -13 巴 拿 马 巴拿马城 -13 加 拿 大 蒙特利亚 -13 古 巴 哈 瓦 那 -13 法 国 巴 黎 -8 英 国 伦 敦 -8 意 大 利 罗 马 -7 东 德 柏 林 -7 波 兰 华 沙 -7 瑞 士 日 内 瓦 -7 捷 克 布 拉 格 -7 匈 牙 利 布达佩斯 -7 罗马尼亚 布加勒斯特 -6 埃 及 开 罗 -6 俄 罗 斯 莫 斯 科 -5 斯里兰卡 科 伦 城 -2.30 印 尼 雅 加 达 -0.30 马来西亚 吉 隆 坡 -0.30 菲 律 宾 马 尼 拉 -0.30 朝 鲜 平 壤 +1 日 本 东 京 +1 //MultiClock.cpp //绘制时钟外观函数 void DrawClockFace(HDC hdc) { const int SQUARESIZE=8; static POINT pt[]= {0,140, 70,122, 122,70, 140,0, 122,-70, 70,-122, 0,-140, -70,-122, -122,-70, -140,0, -122,70, -70,122 }; ::GetStockObject(WHITE_BRUSH); Ellipse(hdc,-155,155,155,-155); SelectObject(hdc,GetStockObject(BLACK_BRUSH)); for(int i=0;i<12;i++) { Ellipse(hdc,pt[i].x-SQUARESIZE,pt[i].y+SQUARESIZE, pt[i].x+SQUARESIZE,pt[i].y-SQUARESIZE); } } //绘制时钟指针函数 void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor) { double nRadians=(double)nDegrees*0.0174533; POINT pt[2]; pt[0].x=(int)(nLength*sin(nRadians)); pt[0].y=(int)(nLength*cos(nRadians)); pt[1].x=-pt[0].x/5; pt[1].y=-pt[0].y/5; HPEN hPen=CreatePen(PS_SOLID,nWidth,clrColor); HPEN hOldPen=(HPEN)SelectObject(hdc,hPen); MoveToEx(hdc,pt[0].x,pt[0].y,NULL); LineTo(hdc,pt[1].x,pt[1].y); SelectObject(hdc,hOldPen); DeleteObject(hPen);} 致 谢 本文是在王永丽老师的热情关心和指导下完成的,她渊博的知识和严谨的治学作风使我受益匪浅,对顺利完成本课题起到了极大的作用。在此向她表示我最衷心的感谢~ 在论文完成过程中,本人还得到了吴春旺老师和张雨同学的热心帮助,本人向他们表示深深的谢意~ 最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢~ 作者简介: 姓 名: 敬小平 性别: 男 出生年月: 1984-10 民族: 汉 E-mail:jingdong_888@163.com 声 明 本论文的工作是 2007年2 月至2007年6 月在成都信息工程学院网络工程系完成的。文中除了特别加以标注地方外,不包含他人已经发表或撰写过的研究成果,也不包含为获得成都信息工程学院或其他教学机构的学位或证书而使用过的材料。除非另有说明,本文的工作是原始性工作。 关于学位论文使用权和研究成果知识产权的说明: 本人完全了解成都信息工程学院有关保管使用学位论文的规定,其中包括: (1)学校有权保管并向有关部门递交学位论文的原件与复印件。 (2)学校可以采用影印、缩印或其他复制方式保存学位论文。 (3)学校可以学术交流为目的复制、赠送和交换学位论文。 (4)学校可允许学位论文被查阅或借阅。 (5)学校可以公布学位论文的全部或部分内容(保密学位论文在解密后遵守此规定)。 除非另有科研合同和其他法律文书的制约,本论文的科研成果属于成都信息工程学院。 特此声明~ 毕业设计(论文) 多时区时钟软件的设计与实现 论文作者姓名: 申请学位专业: 申请学位类别: 指导教师姓名,职称,: 论文提交日期: 多时区时钟软件的设计与实现 摘 要 进入21世纪以来,电脑用户数迅速增长,网上的跨国交流也越见频繁,由于时差的关系,不同国家的作息不同,因此需要经常进行时间的切换。 本系统主要论述如何利用VC++6.0应用程序开发环境和微软基础类库(MFC),设计与实现一个基于对话框的多时区时钟软件。该软件主要包括时钟显示,闹钟报时以及计时器功能。其中,时钟显示包含单时区时钟显示和多时区时钟显示,计时器可实现倒计时与正常计时。利用MFC中与定时器相关的函数,实现计时和时钟的定时刷新;运用模运算实现不同时区的时间转换;采用多线程技术使三个时钟同时运行。 关键词:VC++;MFC;时钟;多线程 The design and realization of Multi_ time_ zone Clock Abstract stSince the 21Century, the number of computer users has increased quickly,the communication among different countries on Internet becomes more and more frequent. Because of the time difference, every country has its own timetable, you need to switch the time frequently. This system has discussed how to design and realize a clock with Visual C++6.0 and Microsoft Foundation Class. This software principally contains these functions: the display of clocks, alarm clock and timer. The function of clock display contains the displays of single time zone clocks and multi time zone clocks. The timer can realize functions of countdown and clock. Take use of the functions related to the timer in Microsoft Foundation Class library to implement time and regular update of the clocks; the time conversion of different time zone could use modular arithmetic to realize; and taking advantage of multithreading could make three clocks run at the same time. Key words: Visual C++; MFC; clock; multithreading 目 录 论文总页数:27页 1 引 言........................................................................................................................................... 1 1.1课题背景及意义 ..................................................................................................................... 1 1.2 课题的研究方法 .................................................................................................................... 1 2 程序功能描述 ............................................................................................................................. 1 2.1 时钟显示................................................................................................................................ 1 2.1.1 单时钟显示 ..................................................................................................................... 1 2.1.2 多时钟显示 ..................................................................................................................... 1 2.2闹钟功能................................................................................................................................. 1 2.3计时器..................................................................................................................................... 2 2.3.1 倒计时............................................................................................................................. 2 2.3.2 正常计时 ......................................................................................................................... 2 2.4 开发环境................................................................................................................................ 2 2.4.1 开发环境 ......................................................................................................................... 2 2.4.2 Visual C++ 6.0简介 ........................................................................................................ 2 3 主要开发技术 ............................................................................................................................. 3 3.1 MFC简介 ............................................................................................................................... 3 3.2 MFC的线程 ........................................................................................................................... 3 3.2.1多线程概述 ...................................................................................................................... 3 3.2.2 MFC的线程 .................................................................................................................... 4 4 程序功能实现 ............................................................................................................................. 5 4.1单时钟显示 ............................................................................................................................. 5 4.2多时钟显示 ........................................................................................................................... 10 4.3闹钟报时............................................................................................................................... 13 4.4计时器................................................................................................................................... 17 4.4.1倒计时............................................................................................................................ 17 4.4.2正常计时 ........................................................................................................................ 20 结 论......................................................................................................................................... 22 参考文献......................................................................................................................................... 23 附 录......................................................................................................................................... 24 致 谢......................................................................................................................................... 26 声 明......................................................................................................................................... 27 1 引 言 1.1课题背景及意义 随着社会的发展,进入21世纪,个人电脑已经进入千家万户,人们已习惯于以互联网的方式交流,学习和娱乐。网上跨国交流也越见频繁,由于时差的关系,人们在浏览国外新闻时经常需要进行时间的换算。不同地区作息时间的不同也影响到人们的交流。因此,一种能显示多个时区时间的时钟程序,将给人们的生活与交流带来极大地方便。 1.2 课题的研究方法 通过对VC++可视化编程的学习以及各地区时间差的查询,本文主要采用MFC控件和多线程编程技术,以及三个与时间有关的函数SetTimer()、OnTimer()和KillTimer(),设计实现一个包含计时器功能和闹钟功能的多时区时钟程序。 2 程序功能描述 软件主要实现三个功能:时钟显示,闹钟以及计时器。具体功能如下 2.1 时钟显示 2.1.1 单时钟显示 实现三个时区时钟(北京时间,纽约时间,伦敦时间)的单独显示。在程序的主界面上,有一个日历,一个指针式时钟,一个时间显示框,一个确定按钮和一个取消按钮。 时钟切换:单击菜单[时钟显示],>[单时钟]->北京时间/纽约时间/伦敦时间。 整点报时:当时间为整点时,扬声器响相应次数。 日期显示:在日历控件上显示相应地区的当前日期。 单击[关闭]按钮,关闭主程序。 2.1.2 多时钟显示 实现三个时区时钟的同时显示及运行。 在主界面上,单击菜单[时钟显示],>[多时钟],弹出[多时钟显示]对话框。此对话框上有三个时钟同时运行,每个时钟有一个相对应的数字时间显示。 单击{关闭}按钮,将关闭此对话框。 2.2闹钟功能 实现三个时区时钟的闹钟设置。 在主界面上单击{闹钟}菜单,将弹出[闹钟]对话框,此对话框有三个单选按钮,分别选择北京时间,纽约时间和伦敦时间,系统默认为北京时间,右边的指针式时钟以及数字时间随单选按钮而改变。在报时设置框中设置时间后,点击[确 定],则闹钟设置完成。 点击[取消],可取消报时。 2.3计时器 实现以秒为单位的倒计时和正常计时功能。 2.3.1 倒计时 在主界面上单击菜单[计时器]->[倒计时],将弹出[倒计时]对话框,在编辑框中输入计时长度,单击[开始计时],编辑框置成不可用状态,倒计时开始。在[剩余时间]栏,将显示剩余时间。单击[重新计时],可取消倒计时,编辑框恢复可编辑状态。 2.3.2 正常计时 在主界面上单击菜单[计时器]->[正常计时],将弹出[正常计时]对话框,点击[开始计时]按钮,在流逝的时间栏将显示时间数,[开始计时]按钮呈不可用状态,而[重新计时]可用。点击[重新计时],取消计时,并将时间设为零秒,[开始计时]可用。 2.4 开发环境 2.4.1 开发环境 Visual C++ 6.0, Windows 2000/XP 2.4.2 Visual C++ 6.0简介 Visual C++是Microsoft公司推出的功能最强大、最复杂的语言产品之一,它是目前为止在W环境下进行大型软件开发的首选。其具有如下特点。 , Visual C++的语法符合ANSI C++标准,并在此基础上针对性W操作系统增 加了一些语句。 , 集成了MFC(Microsoft Foundation Class)类库,MFC封装了Windows API函数 和消息,使程序员可以使用MFC高效率地开发各种应用程序。 , 提供了MFC AppWizard,可方便地生成程序框架。 , 提供了基于MFC的ClassWizard,通过它可以轻松地完成对各种MFC类的使 用与维护。 Visual C++6.0作为Visual Studio家族中的一员,是微软公司推出的以C++语言为基础,开发Win32应用程序(Windows 95/98/2000/XP/NT)的、面向对象的可视化集成工具。它的最大优点就是提供了功能强大的MFC类库,MFC是一个很大的C++类层次结构,其中封装了大量的类及其函数,很多Windows程序所共有的标准内容可以由MFC的类来提供,MFC类为这些内容提供了用户接 口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓,这将简化编程工作,大大的减少程序员编写的代码数量,使编程工作变得更加轻松容。 5 主要开发技术 程序主要采用MFC控件和多线程技术实现。 3.1 MFC简介 MFC,微软基础类(Microsoft Foundation Classes),是微软提供的,用于在C++环境下编写应用程序的一个框架和引擎,VC++是WinOS下开发人员使用的专业C++ SDK(SDK,Standard SoftWare Develop Kit,专业软件开发平台),MFC就是挂在它之上的一个输助软件开发包,MFC类是微软为VC++专配的。 MFC是Win API与C++的结合,API,即微软提供的WinOS下应用程序的编程语言接口,是一种软件编程的规范,但不是程序开发语言本身,可以允许用户使用各种各样的第三方的编程语言来进行对Win OS下应用程序的开发,使这些被开发出来的应用程序能在WinOS下运行,比如VB,VC++,Java,Dehpi编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在WinOS的消息机制里。 MFC 是一个很大的、扩展了的 C++ 类层次结构,它能使开发 Windows应用程序变得更加容易。MFC 是在整个 Windows 家族中都是兼容的,也就是说,无论是 Windows3.x、Windows95 还是 Windows NT,所使用的 MFC 是兼容的。每当新的 Windows 版本出现时,MFC 也会得到修改以便使旧的编译器和代码能在新的系统中工作。MFC 也会得到扩展,添加新的特性、变得更加容易建立应用程序。 3.2 MFC的线程 3.2.1多线程概述 进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程终止了,进程也就随之终止。每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空 间、全局变量和系统资源,所以线程间的通讯非常方便,多线程可以实现并行处理,避免了某项任务长时间占用CPU时间。目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,好像这些线程都在同时运行。 3.2.2 MFC的线程 MFC明确区分两种线程:用户界面线程(User interface thread)和工作者线程(Worker thread)。用户界面线程一般用于处理用户输入并对用户产生的事件和消息作出应答。工作者线程用于完成不要求用户输入的任务,如耗时计算。 线程的创建 1)创建用户界面线程 通过以下步骤创建一个用户界面线程: , 从CWinThread派生一个有动态创建能力的类。使用DECLARE_DYNCREATE 和IMPLEMENT_DYNCREATE宏来支持动态创建。 , 覆盖CWinThread的一些虚拟函数,其中,函数InitInstance是必须覆盖 的,ExitInstance通常是要覆盖的。 , 使用AfxBeginThread创建MFC线程对象和Win32线程对象。如果创建线 程时没有指定CREATE_SUSPENDED,则开始执行线程。 , 如果创建线程是指定了CREATE_SUSPENDED,则在适当的地方调用函数 ResumeThread开始执行线程。 2)创建工作者线程 程序员不必从CWinThread派生新的线程类,只需要提供一个控制函数,由线程启动后执行该函数。然后,使用AfxBeginThread创建MFC线程对象和Win32线程对象。如果创建线程时没有指定CREATE_SUSPENDED(创建后挂起),则创建的新线程开始执行。如果创建线程是指定了CREATE_SUSPENDED,则在适当的地方调用函数ResumeThread开始执行线程。虽然没有从CWinThread派生类,但是MFC给工作者线程提供了缺省的CWinThread对象。 线程的结束 AfxEndThread用来结束调用它的线程:它将清理本线程创建的MFC对象和释放线程局部存储分配的内存空间;调用CWinThread的虚拟函数Delete;调用“C”的结束线程函数_endthreadex释放分配给线程的资源,但是不关闭线程句柄。CWinThread::Delete的缺省实现是:如果本线程的成员函数m_bDelete为TRUE,则调用“C”运算符号delete销毁MFC线程对象自身(delete this),这将导致线程对象的析构函数被调用。若析构函数检测线程句柄非空则调用CloseHandle关闭它。 3.3 定时器 在程序中我们经常要使用定时刷新的功能, MFC提供了定时器来完成这个功能。 在MFC中和定时器相关的有三个函数: UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)( HWND, UINT, UINT, DWORD) ); afx_msg void OnTimer( UINT nIDEvent ); BOOL KillTimer( int nIDEvent ); 函数功能: ,刷新时间,处理SetTimer用来定义一个定时器的属性,如改定时器的ID 函数。 OnTimer实际时系统定义消息用来响应WM_TIMER消息,在这里可以实现对多定时器中的各个定时器分别响应,这里才时定时程序大展宏图的地方。 KillTimer用来结束一个定时器。 6 程序功能实现 4.1单时钟显示 创建一个基于对话框的工程MultiClock。 1.在对话框上添加控件资源并设置属性(如图4-1,表4-1) 图4-1 程序主对话框(单时钟界面)设计 表4-1 对话框资源IDD_MULTICLOCK_DIALOG控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 日历控件 IDC_MONTHCALENDAR1 无 分组框 IDC_STATIC1 北京时间 按钮1 IDCANCEL 关闭 静态文本框 IDC_STATIC2 static 分隔线(Picture控件) IDC_STATIC 类型Frame,颜色Black 2.添加菜单资源并导入对话框(如图4-2,图4-3) 图4-2 菜单界面设计1 图4-3 菜单界面设计2 表4-2 菜单项属性设置 ID Caption Pop-up 时钟显示 ? 单时钟 ? 计时器 ? ID_MCLOCK 多时钟 ID_BKTIME 北京时间 ID_NYTIME 纽约时间 ID_LDTIME 伦敦时间 ID_NAOZHONG 闹钟 ID_DAOJISHI 倒计时 ID_ZHENJI 正常计时 ID_HELP 帮助 3.使用MFC类向导添加消息响应函数和成员变量(表4-3,4-4) 表4-3 向对话框类CMultiClockDlg添加消息响应函数 Object IDs Messages 消息的描述 函数名 CMultiClockDlg WM_TIMER 时间触发消息 OnTimer ID_MCLOCK COMMAND 菜单消息 OnMclock ID_NAOZHONG COMMAND 菜单消息 OnNaozhong ID_DAOJISHI COMMAND 菜单消息 OnDaojishi ID_ZHENJI COMMAND 菜单消息 OnZhenji ID_HELP COMMAND 菜单消息 OnHelp 表4-4 向对话框类CMultiClockDlg添加控件对应的成员变量 Object IDs 变量名 变量种类 变量类型 IDC_MONTHCALENDAR1 m_monthcal Control CMonthCalCtrl IDC_STATIC1 m_spot Control CButton IDC_STATIC2 m_str Value CString 4.添加代码(粗体字部分为添加代码) (1)在MultiClock.h文件中添加函数声明 绘制时钟外观函数 // void DrawClockFace(HDC hdc); //绘制时钟指针函数 void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor); (2)在MultiClock.cpp文件中添加: #include DrawClockFace.函数体 DrawHand 函数体 (函数体见附录) (3)在MultiClockDlg.h文件中添加CMultiClockDlg类成员变量和函数 public: SYSTEMTIME time,tm; int minute,hour,second; private: afx_msg void OnSingleClock(WORD nID);//声明单时钟菜单消息处理函数 (4)在MultiClockDlg.cpp文件中添加功能代码: //单时钟消息映射 ON_COMMAND_RANGE(ID_BKTIME,ID_LDTIME,OnSingleClock) //初始化时间变量,设置定时器 BOOL CMultiClockDlg::OnInitDialog() { // TODO: Add extra initialization here ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); return TRUE; // return TRUE unless you set the focus to a control } //单时钟菜单响应函数 void CMultiClockDlg::OnSingleClock(WORD nID) {KillTimer(1); m_nsclock=nID-ID_BKTIME; switch(m_nsclock) { case 0: ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); m_spot.SetWindowText("北京时间"); break; case 1: ::GetLocalTime(&time); hour=(time.wHour-13+24)%24; minute=time.wMinute; second=time.wSecond; if((time.wHour-13)<0)//日历设置 { CTime tm1(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm1); m_monthcal.SetToday(&tm1); } SetTimer(1,1000,NULL); m_spot.SetWindowText("纽约时间"); break; case 2: ::GetLocalTime(&time); hour=(time.wHour-8+24)%24; minute=time.wMinute; second=time.wSecond; if((time.wHour-8)<0)//日历设置 { CTime tm2(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm2); m_monthcal.SetToday(&tm2); } SetTimer(1,1000,NULL); m_spot.SetWindowText("伦敦时间"); break; } } //定时刷新,使指针运行 void CMultiClockDlg::OnTimer(UINT nIDEvent) { //绘制单时钟 CClientDC dc(this); dc.SetMapMode(MM_ISOTROPIC); dc.SetViewportOrg(380,100); COLORREF crf=RGB(255,255,255); ::GetLocalTime(&time); DrawClockFace(dc); if(time.wMinute!=minute) {DrawHand(dc,60,8,hour*30+minute/2,crf); DrawHand(dc,90,6,minute*6,crf); if(m_nsclock==0) hour=time.wHour; if(m_nsclock==1) {hour=(time.wHour-13+24)%24; if((time.wHour-13)<0) //日历设置 { CTime tm1(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm1); m_monthcal.SetToday(&tm1); } } if(m_nsclock==2) {hour=(time.wHour-8+24)%24; if((time.wHour-8)<0)//日历设置 { CTime tm2(time.wYear,time.wMonth,time.wDay-1,0,0,0); m_monthcal.SetCurSel(tm2); m_monthcal.SetToday(&tm2); } } minute=time.wMinute; } if(time.wSecond!=second) {DrawHand(dc,120,1,second*6,crf); DrawHand(dc,120,1,time.wSecond*6,RGB(255,0,0)); DrawHand(dc,90,6,time.wMinute*6,RGB(0,255,0)); DrawHand(dc,60,8,hour*30+minute/2,RGB(0,0,255)); second=time.wSecond; } m_str.Format("%.2d:%.2d:%.2d",hour,minute,second); UpdateData(false); if(minute==0&&second<=hour) //整点报时 { ::Beep(1000,500); } } 编译后运行,单时钟效果(如图4-4) 4.2多时钟显示 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_MCLOCK,新建一个CDialog的派生类CMULCLOCK。 2. 在对话框上添加控件资源并设置属性(如图4-5,表4-5) 3.使用MFC类向导添加消息响应函数和成员变量(表4-6) 图4-4 单时钟运行效果 表4-5 对话框资源IDD_MULCLOCK控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 北京时间 分组框2 IDC_STATIC 纽约时间 分组框3 IDC_STATIC 伦敦时间 按钮 IDCANCEL 关闭 分隔线(Picture控件) IDC_STATIC 类型Frame,颜色Black 图4-5 多时钟界面设计 表4-6 向对话框类CMULClOCK添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CMULCLOCK WM_INITDIALOG 窗口初始化 OnInitDialog 4.添加代码(粗体字部分) (1)在 MULCLOCK.h文件 中添加声明 void drawclock1(HWND hwnd,SYSTEMTIME time,int hour,int minute,int second,int xpos,int ypos); void drawclock2(…); void drawclock3(…); UINT ThreadProc1(LPVOID pParam); UINT ThreadProc2(LPVOID pParam); UINT ThreadProc3(LPVOID pParam); static HWND hWnd; static SYSTEMTIME t1,t2,t3; static int h1,m1,s1,h2,m2,s2,h3,m3,s3; static BOOL m_b0=false,m_b1=false,m_b2=false; (2)在 MULCLOCK.cpp文件 中添加代码(粗体字部分) 添加上述声明函数的的函数体. //开启多时钟线程 BOOL CMULCLOCK::OnInitDialog() { // TODO: Add extra initialization here hWnd=CMULCLOCK::GetSafeHwnd(); AfxBeginThread(ThreadProc1,this); AfxBeginThread(ThreadProc2,this); AfxBeginThread(ThreadProc3,this); return TRUE; } (3)在MultiClockDlg.cpp文件中添加 #include "MULCLOCK.h" //打开多时钟显示对话框 void CMultiClockDlg::OnMclock() { // TODO: Add your command handler code here CMULCLOCK MCLOCK; MCLOCK.DoModal(); } 编译后运行,多时钟效果为(图4-6) 图4-6 多时钟运行效果 4.3闹钟报时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对话框,ID为IDD_NAOZHONG,新建一个CDialog的派生类CNAOZHONG。 2. 在对话框上添加控件资源并设置性(图4-7,表4-7) 3.使用MFC类向导添加消息响应函数和成员变量(表4-8,4-9) 图4-7 闹钟界面设计 表4-7 对话框资源IDD_NAOZHONG控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 单选按钮1 IDC_RADIO1 北京时间 单选按钮2 IDC_RADIO2 纽约时间 单选按钮3 IDC_RADIO3 伦敦时间 分组框 IDC_STATIC1 北京时间 静态文本框1 IDC_STATIC2 static 静态文本框2 IDC_STATIC 定时设置: 日期控件 IDC_DATETIMEPICKER2 无,格式Time|spin 按钮1 IDC_ENTER 确定 按钮2 IDC_CLEAR 取消 表4-8 向对话框类CNAOZHONG添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CNAOZHONG WM_INITDIALOG 窗口初始化 OnInitDialog IDC_RADIO1 BN_CLICKED 单击控件 OnRadio1 IDC_RADIO2 BN_CLICKED 单击控件 OnRadio2 IDC_RADIO3 BN_CLICKED 单击控件 OnRadio3 IDC_ENTER BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-9 向对话框类CNAOZHONG添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_DATETIMEPICKER2 m_time Control CDateTimeCtrl IDC_STATIC1 m_address Control CButton IDC_STATIC2 m_str Value CString 4.添加代码(粗体字部分) (1)在 NAOZHONG.h文件 中添加CNAOZHONG类成员变量 public: SYSTEMTIME time; int hour,minute,second; (2)在 NAOZHONG.cpp文件中添加(粗体字部分) static BOOL m_b=false; static int m_rad1; BOOL CNAOZHONG::OnInitDialog() { // TODO: Add extra initialization here CheckRadioButton(IDC_RADIO1,IDC_RADIO3,IDC_RADIO1); m_rad1=0; CString formatstr=_T("HH:mm:ss"); m_time.SetFormat(formatstr); ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); return TRUE; } void CNAOZHONG::OnTimer(UINT nIDEvent) { CClientDC dc(this); dc.SetMapMode(MM_ISOTROPIC); dc.SetViewportOrg(170,100); COLORREF crf=::GetSysColor(COLOR_3DFACE); ::GetLocalTime(&time); DrawClockFace(dc); if(time.wMinute!=minute) {DrawHand(dc,60,8,hour*30+minute/2,crf); DrawHand(dc,90,6,minute*6,crf); if(m_rad1==0) hour=time.wHour; if(m_rad1==1) hour=(time.wHour-13+24)%24; if(m_rad1==2) hour=(time.wHour-8+24)%24; minute=time.wMinute; } if(time.wSecond!=second) {DrawHand(dc,120,1,second*6,crf); DrawHand(dc,120,1,time.wSecond*6,RGB(255,0,0)); DrawHand(dc,90,6,time.wMinute*6,RGB(0,255,0)); DrawHand(dc,60,8,hour*30+minute/2,RGB(0,0,255)); second=time.wSecond; } m_str.Format("%.2d:%.2d:%.2d",hour,minute,second); UpdateData(FALSE); if(m_b) { m_time.GetTime(t1);; if(hour==t1.GetHour()) { if(minute==t1.GetMinute()) if(second>=t1.GetSecond()) {m_b=false; ::Beep(1000,500); AfxMessageBox("时间到"); } } } } void CNAOZHONG::OnRadio1()//选择北京时区 {KillTimer(1); m_rad1=0; m_address.SetWindowText("北京时间"); ::GetLocalTime(&time); hour=time.wHour; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } void CNAOZHONG::OnRadio2()//选择纽约时区 {KillTimer(1); m_rad1=1; m_address.SetWindowText("纽约时间"); ::GetLocalTime(&time); hour=(time.wHour-13+24)%24; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } void CNAOZHONG::OnRadio3()//选择伦敦时区 {KillTimer(1); m_rad1=2; m_address.SetWindowText("伦敦时间"); ::GetLocalTime(&time); hour=(time.wHour-8+24)%24; minute=time.wMinute; second=time.wSecond; SetTimer(1,1000,NULL); } (3)在MultiClockDlg.cpp文件中添加 #include "NAOZHONG.h" //打开闹钟对话框 void CMultiClockDlg::OnNaozhong() { // TODO: Add your command handler code here CNAOZHONG NAOZHONG; NAOZHONG.DoModal(); } 编译后运行效果(如图4-8) 4.4计时器 4.4.1倒计时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_DAOJISHI,新建一个CDialog的派生类CDAOJISHI. 2. 在对话框上添加控件资源并设置性(如图4-9,表4-10) 3.使用MFC类向导添加消息响应函数和成员变量(表4-11,4-12) 图4-8 闹钟运行效果 图4-9 倒计时界面设计 表4-10 对话框资源IDD_DAOJISHI控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 请输入计时长度 分组框2 IDC_STATIC 剩余时间 静态文本框1 IDC_STATIC1 static 静态文本框2 IDC_STATIC 分 静态文本框3 IDC_STATIC 秒 文本编辑框1 IDC_EDIT1 无 文本编辑框2 IDC_EDIT2 无 按钮1 IDC_START 开始计时 按钮2 IDC_CLEAR 重新计时 表4-11 向对话框类CDAOJISHI添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CDAOJISHI WM_TIMER 时间触发消息 OnTimer IDC_START BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-12 向对话框类CDAOJISHI添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_EDIT1 m_min Value UINT IDC_EDIT2 m_sec Value UINT IDC_STATIC1 m_str Value CString 4.添加代码(粗体字部分) (1)在 DAOJISHI.h文件 中添加CDAOJISHI类成员变量 int m_totaltime; (2)在 DAOJISHI.cpp文件中添加如下代码(粗体字部分) void CDAOJISHI::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(m_totaltime>=0) {m_str.Format("%d分%d秒", (int)(m_totaltime/60),m_totaltime-((int)(m_totaltime/60))*60); m_totaltime--; UpdateData(FALSE); } else { KillTimer(1); ::Beep(1000,500); } } void CDAOJISHI::OnStart()//开始计时 { UpdateData(true); m_totaltime=m_min*60+m_sec; GetDlgItem(IDC_EDIT1)->EnableWindow(false); GetDlgItem(IDC_EDIT2)->EnableWindow(FALSE); GetDlgItem(IDC_START)->EnableWindow(false); GetDlgItem(IDC_CLEAR)->EnableWindow(true); SetTimer(1,1000,NULL); } void CDAOJISHI::OnClear()//重新计时 {KillTimer(1); GetDlgItem(IDC_CLEAR)->EnableWindow(FALSE); GetDlgItem(IDC_START)->EnableWindow(true); GetDlgItem(IDC_EDIT1)->EnableWindow(TRUE); GetDlgItem(IDC_EDIT2)->EnableWindow(TRUE); m_str=_T(""); UpdateData(false); } (3)在MultiClockDlg.cpp文件中添加 #include "DAOJISHI.h" //打开倒计时对话框 void CMultiClockDlg::OnDaojishi() { CDAOJISHI DAO; DAO.DoModal(); } 编译后运行效果(如图4-10) 图4-10 倒计时运行效果 4.4.2正常计时 1.在Resource View 中右键单击文件夹,选择Insert Dialog,插入一个对 话框,ID为IDD_ZHENJISHI,新建一个CDialog的派生类CZHENJISHI. 2. 在对话框上添加控件资源并设置性(如图4-11,表4-13) 3.使用MFC类向导添加消息响应函数和成员变量(表4-14,4-15) 图4-11 正常计时界面设计 表4-13 对话框资源IDD_ZHENJISHI控件ID及说明文字修改 对话框资源 修改后的ID 说明文字 分组框1 IDC_STATIC 流逝的时间 静态文本框1 IDC_STATIC 正常计时: 静态文本框2 IDC_STATIC1 static 按钮1 IDC_START 开始计时 按钮2 IDC_CLEAR 重新计时 表4-14 向对话框类CZHENJISHI添加消息响应函数 ObjectIDs Messages 消息的描述 函数名 CZHENJISHI WM_TIMER 时间触发消息 OnTimer IDC_START BN_CLICKED 单击控件 OnEnter IDC_CLEAR BN_CLICKED 单击控件 OnClear 表4-15 向对话框类CZHENJISHI添加成员变量 ControlIDs 变量名 变量种类 变量类型 IDC_STATIC1 m_str Value CString 4.添加代码(粗体字部分) (1)在 ZHENJISHI.h文件 中添加CZHENJISHI类成员变量 int m_time; (2)在 ZHENJISHI.cpp文件中添加如下代码 //开始计时 void CZHENJISHI::OnStart() { // TODO: Add your control notification handler code here m_time=0; GetDlgItem(IDC_START)->EnableWindow(false); GetDlgItem(IDC_CLEAR)->EnableWindow(true); SetTimer(1,1000,NULL); } void CZHENJISHI::OnClear()//重新计时 {KillTimer(1); m_time=0; m_str.Format("%d分%d秒",0,0); GetDlgItem(IDC_START)->EnableWindow(TRUE); GetDlgItem(IDC_CLEAR)->EnableWindow(FALSE); UpdateData(false); } void CZHENJISHI::OnTimer(UINT nIDEvent) //计时实现 { m_time++; m_str.Format("%d分%d秒", (int)(m_time/60),m_time-((int)(m_time/60))*60); UpdateData(FALSE); } (3)在MultiClockDlg.cpp文件中添加 #include "ZHENJISHI.h" //打开正常计时对话框 void CMultiClockDlg::OnZhenji() { // TODO: Add your command handler code here CZHENJISHI ZHEN; ZHEN.DoModal(); } 编译后运行效果(如图4-12) 图4-12 正常计时运行效果 至此一个多时区时钟程序完成了。 结 论 基于本次课题的研究和设计实现,可以发现,时钟的设计与实现的主要问题在于对MFC控件的使用和消息机制的理解,以及多线程设计中全局函数的编写。其中,窗口类指针的调用,是一大难点,大多数错误发生的原因都因为指针的错误调用。 本次设计实现了一个显示三个不同时区时间的时钟和相应的闹钟以及一个以秒为计时单位的计时器。程序除指针式时钟显示外,还有相应的数字时间显示, 主界面的日历也与显示时区的日期相对应。计时器可完成正常计时和倒计时功能。在此基础上,通过添加、修改控件和代码,还可以添加更多新的功能,使界面显得更美观,使其更方便,发挥的作用更大。 参考文献 [1] 黄维通.Visual C++ 面向对象与可视化程序设计[M].北京:清华大学出版社,2003。 [2] 郑莉,董渊.C++语言程序设计[M].北京:清华大学出版社,2001。 [3] 古槿.新手学Visual C++30例[M].北京:人民邮电出版社,2004。 [4] Charles Petzold. Windows程序设计[M].北京: 北京大学出版社,1999。 [5]胡峪,刘静.Visual C++编程技巧与与示例[M].西安: 西安电子科技大学出版社,2000。 [6]东方人华,李秀敏,凌宇欣.Visual C++ 6.0 范例入门与提高[M].北京:清华大学出版 社,2003。 [7]梁普选.Visual C++程序设计与实践[M].北京:清华大学出版社&北京交通大学出版 社,2005。 附 录 世界重要城市时差表 国 名 城 市 与北京时差 美 国 旧 金 山 -16 墨 西 哥 墨西哥城 -15 美 国 纽 约 -13 巴 拿 马 巴拿马城 -13 加 拿 大 蒙特利亚 -13 古 巴 哈 瓦 那 -13 法 国 巴 黎 -8 英 国 伦 敦 -8 意 大 利 罗 马 -7 东 德 柏 林 -7 波 兰 华 沙 -7 瑞 士 日 内 瓦 -7 捷 克 布 拉 格 -7 匈 牙 利 布达佩斯 -7 罗马尼亚 布加勒斯特 -6 埃 及 开 罗 -6 俄 罗 斯 莫 斯 科 -5 斯里兰卡 科 伦 城 -2.30 印 尼 雅 加 达 -0.30 马来西亚 吉 隆 坡 -0.30 菲 律 宾 马 尼 拉 -0.30 朝 鲜 平 壤 +1 日 本 东 京 +1 //MultiClock.cpp //绘制时钟外观函数 void DrawClockFace(HDC hdc) { const int SQUARESIZE=8; static POINT pt[]= {0,140, 70,122, 122,70, 140,0, 122,-70, 70,-122, 0,-140, -70,-122, -122,-70, -140,0, -122,70, -70,122 }; ::GetStockObject(WHITE_BRUSH); Ellipse(hdc,-155,155,155,-155); SelectObject(hdc,GetStockObject(BLACK_BRUSH)); for(int i=0;i<12;i++) { Ellipse(hdc,pt[i].x-SQUARESIZE,pt[i].y+SQUARESIZE, pt[i].x+SQUARESIZE,pt[i].y-SQUARESIZE); } } //绘制时钟指针函数 void DrawHand(HDC hdc,int nLength,int nWidth,int nDegrees,COLORREF clrColor) { double nRadians=(double)nDegrees*0.0174533; POINT pt[2]; pt[0].x=(int)(nLength*sin(nRadians)); pt[0].y=(int)(nLength*cos(nRadians)); pt[1].x=-pt[0].x/5; pt[1].y=-pt[0].y/5; HPEN hPen=CreatePen(PS_SOLID,nWidth,clrColor); HPEN hOldPen=(HPEN)SelectObject(hdc,hPen); MoveToEx(hdc,pt[0].x,pt[0].y,NULL); LineTo(hdc,pt[1].x,pt[1].y); SelectObject(hdc,hOldPen); DeleteObject(hPen);} 致 谢 本文是在王永丽老师的热情关心和指导下完成的,她渊博的知识和严谨的治学作风使我受益匪浅,对顺利完成本课题起到了极大的作用。在此向她表示我最衷心的感谢~ 在论文完成过程中,本人还得到了吴春旺老师和张雨同学的热心帮助,本人向他们表示深深的谢意~ 最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢~ 作者简介: 姓 名: 敬小平 性别: 男 出生年月: 1984-10 民族: 汉 E-mail:jingdong_888@163.com 声 明 本论文的工作是 2007年2 月至2007年6 月在成都信息工程学院网络工程系完成的。文中除了特别加以标注地方外,不包含他人已经发表或撰写过的研究成果,也不包含为获得成都信息工程学院或其他教学机构的学位或证书而使用过的材料。除非另有说明,本文的工作是原始性工作。 关于学位论文使用权和研究成果知识产权的说明: 本人完全了解成都信息工程学院有关保管使用学位论文的规定,其中包括: (1)学校有权保管并向有关部门递交学位论文的原件与复印件。 (2)学校可以采用影印、缩印或其他复制方式保存学位论文。 (3)学校可以学术交流为目的复制、赠送和交换学位论文。 (4)学校可允许学位论文被查阅或借阅。 (5)学校可以公布学位论文的全部或部分内容(保密学位论文在解密后遵守此规定)。 除非另有科研合同和其他法律文书的制约,本论文的科研成果属于成都信息工程学院。 特此声明~ lists." "Really?" I said, trying not to sound jubilant. "I found out they wear this red scarf thing on their arm. It covers up Sitting Bull's horse." "That is a problem," I said. "Well, that's not all. My docent told me about your lunch. Did Grandma Karen really tell you you were right?" "Yes." "Gosh! I didn't believe that part. Well, anyway, my docent said you wouldn't listen to her about how great menstruating is, that you all kept talking about the negative aspects of it, like bloating and cramps and crabbiness, and I said, 'What are cramps?' and she said, 'Menstrual bleeding frequently causes headaches and depression,' and I said, 'Bleeding!? Nobody ever said anything about bleeding!' Why didn't you tell me there was blood involved, Mother?" I had, but I felt it wiser to keep silent. "And you didn't say a word about its being painful. An uget. It was impossible to keep secrets when seven people lived in such a confined space. She knew for a fact, for instance, that what the Polo sisters did behind the closed doors of their adjoining rooms was still illegal in Alabama. They had all bounced around a lot, especially in the early months of the voyage. Gene was the only married crew member, and he had taken care to announce quite early that he and his wife had an arrangement about such matters. Still, he had slept alone for a long time because the Polos had each other, Gaby didn't seem to care about sex at all, and Cirocco had been irresistibly drawn to Calvin Greene. Her persistence was such that Calvin eventually went to bed with her, not just once, but three times. It didn't get any better, so before he could sense her disappointment she had cooled the relationship and let him pursue Gaby, the woman he had been drawn to from the first. Calvin was a general surgeon trained by NASA to be competent as ship's biologist and ecologist as well. He was black, but attached little importance to it, having been born and raised in O'Neil One. He was also the only crew member who was taller than sirocco. She didn't think that had much to do with his appeal; she had learned early to be indifferent to a man's height, since she like a big, soft asteroid. The analogy pleased her. Extending it, she watched the terminator line crawl around her to bring the hills and valleys of her front into sunlight. Cirocco liked space, reading, and sex, not necessarily in that order. She had never been able to satisfactorily combine all three, but two was not bad. New games were possible in free-fall, like the one they had been playing, "no hands." They could use feet, mouths, knees, or shoulders to position each other. One had to be gentle and careful, but with slow bites and nips anything could be done, and in such an interesting way. All of them came to the hydroponics room from time to time. Ringmaster had seven private rooms, and they were as necessary as oxygen. But even Cirocco's cabin was crowded when two people were in it, and it *as at the bottom of the carousel. It took one act of love in free-fall to make a bed seem as limiting as the back scat of a Chevrolet. 'Why don't you turn this way a little?" Bill asked. "Can you give me a good reason?" He showed her one, and she gave him a little more than he had asked for. Then she found herself with a little more than she had .asked for, but as usual, he kne would be easy to move it." Cirocco frowned. "Just how big is it, then?" The Polo--August, she was almost sure it was August- looked at her with that calm, strangely unsettling face. "I should say about two or three kilometers. Possibly less." "Is that all?" Gene grinned. "You give me the numbers, I'll land on it." "What do you mean, 'Is that all'?" Gaby said. "It couldn't have been very much bigger, not to have been sighted by the Lunar scopes. We would have known about it thirty years ago." "All right. But you interrupted my bath for a damn pebble. It hardly seems worth it." Gaby looked smug. "Maybe not to you, but if it was a tenth that size, I'd still get to name it. Discovering a comet or an asteroid is one thing but only a couple people each century get to name a moon." Cirocco released her toehold on the holo tank strut and twisted toward the corridor entr The gunner fired the second harpoon. The whale gave a convulsive shudder. His life was nearly over. A life that had begun thirty years ago as a tiny calf in the sparkling Indian Ocean. At the age of five he had left his mother and joined other young males in a bachelor group. When his blubber thickened, he migrated to colder waters where food was more plentiful. At 25 he became master of a "pod" of twelve cows which remained with their calves in tropical seas. Although he was dwarfed by the hundred-foot blue whale, could not sing like the sweet-voiced humpback whale--both of which fed on plankton--his sort were the largest of the toothed whales, the same majestic breed as Moby Dick. Each year he made the long journey back from the Antarctic to mate. But not this year. For three decades, the bull had eluded harpoons. Now he died, spouting thick blood. The gunner nodded with satisfaction. Soon the vast corpse was winched alongside. Then, swinging slowly, the catcher boat chugged towards the factory ship whose stern gaped open like a mouth to swallow the whale. Once inside, it was hauled up a ramp. The whale was efficiently disposed of. Its domed head yielded fifteen barrels of spermaceti oil for use in cosmetics; its body, oil for lubricants and leather softening; its belly, ambergris (the residue of squids' beaks) for perfume. Other products would later include crayons, candles, soap, pet food, fertiliser, glue. All these could be obtained from vegetable sources. But as long as unscrupulous people paid, whalers would go on breaking the law. Sadly, as he saw the mighty animal disappear, the medical officer walked away. Behind him a helicopter lifted off with a swish and swirl of blades. Whale-spotting? He wondered, not for the first time, what was really happening aboard the factory ship. Whaling was bad enough--but he suspected something still more sinister. However, he had learned that it wasn't wise to ask too many questions round here. In the Antarctic, you could vanish without trace. Far, far to the north, off the coast of Norway, an oil-tanker crawled through fog. Usually the captain loathed such conditions. But today he was pleased--for the clammy cloud would conceal his activities. Leaning forward on the bridge, he gave orders to wash out the ship's tanks. Within minutes a sticky stinking stream of brown liquid was gurgling into the sea. Even when unloaded, a tanker retains about 2,000 tons of oil at the bottom of its tanks. That sludge has to be removed before a new cargo is taken on. Why pay to have the tanks cleaned in port if you could do it for nothing yourself? The captain's action was irresponsible, illegal and punishable with a heavy fine. But who can arrest an invisible culprit? He blessed the fog as the ship stole away from the scene of the crime. Hours later a violent storm blew up, clearing the fog. Buffeted by wind, sea-birds sought refuge on the calmest water--which was those patches slicked with oil. Not long after, the first grease-caked casualties started to stagger ashore. Guillemots, gannets, puffins, razor-bills, little auks, kittiwakes. The final death toll would be fifty thousand. News of the pollution spread fast. People gathered on the beaches, but they were unable to help the birds--except by putting them out of their misery. As a naturalist explained to a tearful woman onlooker, oil often blinded birds. It burnt their skin, stomachs and livers. It also removed the waterproofing from their feathers, which insulated them against cold and wet, so they couldn't float properly or catch fish. And if the birds weren't poisoned by swallowing oil after preening, they would probably die of pneumonia. Singly or in small groups the bedraggled creatures stumbled to land. A three-foot gannet, normally brilliant white, pecked feverishly at its ruined plumage until a rifle-shot rang out. By nightfall a two-ton pile of dead sea-birds had been collec ad all those things, and more. Part of it was thickly wooded. There was a swimming hole. The stationary apparatus was combined with dazzling light sculptures that darted in and out of reality. There were animals too: pygmy rhinoceros and elegant gazelles no taller than your knee. They seemed unnaturally gentle and unafraid. But most of all, the playground had children. Ian liked children. He sat on a wooden park bench at the edge of the trees, in the shadows, and watched them. They came in all colors and all sizes, in both sexes. There were black ones like animated licorice jellybeans and white ones like bunny rabbits, and brown ones with curly hair and more brown ones with slanted eyes and straight black hair and some who had been white but were now toasted browner than some of the brown ones. Ian concentrated on the girls. He had tried with boys before, long ago, but it had not worked out. He watched one black child for a time, trying to estimate her age. He thought it was around eight or nine. Too young. Another one was more like thirteen, judging from her shirt. A possibility, but he'd prefer something younger. Somebody less sophisticated, less suspicious. Finally he found a girl he liked. She was brown, but with startling blond hair. Ten? Possibly eleven. Young enough, at any rate. He concentrated on her and did the strange thing he did when he had selected the right one. He didn't know what it was, but it usually worked. Mostly it was just a matter of looking at her, keeping his eyes fixed on her no matter where she went or what she did, not allowing himself to be distracted by anything. And sure enough, in a few minutes she looked up, looked around, and her eyes locked with his. She held his gaze for a moment, then went back to her play. He relaxed. Possibly what he did was nothing at all. He had noticed, with adult women, that if one really caught his eye so he found himself staring at her, she would usually look up from what she was doing and catch him. It never seemed to fail. Talking to other men, he had found it to be a common experience. It was almost as if they could feel his gaze. Women had told him it was nonsense, or if not, it was just reaction to things seen peripherally by people trained to alertness for sexual signal's. Merely an unconscious observation penetrating to the awareness; nothing mysterious, like ESP. Perhaps. Still, Ian was very good at this sort of eye contact. Several times he had noticed the girls rubbing the backs of their necks while he observed them, or hunching their shoulders. Maybe they'd developed some kind of ESP and just didn't recognize it as such. Now he merely watched her. He was smiling, so that every time she looked up to see him-which she did with increasing frequency-she saw a friendly, slightly graying man with a broken nose and powerful shoulders. His hands were strong too. He kept them clasped in his lap. Presently she began to wander in his direction. No one watching her would have thought she was coming toward him. She probably didn't know it herself. On her way, she found reasons to stop and tumble, jump on the soft rubber mats, or chase a flock of noisy geese. But she was coming toward him, and she would end up on the park bench beside him. He glanced around quickly. As before, there were few adults in this playground. It had surprised him when he arrived. Apparently the new conditioning techniques had reduced the numbers of the violent and twisted to the point that parents felt it safe to allow their children to run without supervision. The adults present were involved with each other. No one had given him a second glance when he arrived. That was fine with Ian. It made what he planned to do much easier. He had his excuses ready, of course, but it could be embarrassing to be confronted with the questions representatives of the law ask single, middle-aged men who hang around playgrounds. For a moment he considered, with real concern, how the parents of these children could feel so confident, even with mental conditioning. After all, no one was conditioned until he had first done something. New maniacs were presumably being produced every day. Typically, they looked just like everyone else until they proved their difference by some demented act. Somebody ought to give those parents a stern lecture, he thought. "Who are you?" Ian frowned. Not eleven, surely, not seen up this close. Maybe not even ten. She might be as young as eight. Would eight be all right? He tasted the idea with his usual caution, looked around again for curious eyes. He saw none. "My name is Ian. What's yours?" "No. Not your name. Who are you?" "You mean what do I do?" "Yes." "I'm a pusher." She thought that over, then smiled. She had her permanent teeth, crowded into a small jaw. "You give away pills?" He laughed. "Very good," he said. "You must do a lot of reading." She said nothing, but her manner indicated she was pleased. "No," he said. "That's an old kind of pusher. I'm the other kind. But you knew that, didn't you?" When he smiled, she broke into giggles. She was doing the pointless things with her hands that little girls do. He thought she had a pretty good idea of how cute she was, but no inkling of her forbidden eroticism. She was a ripe seed with sexuality ready to burst to the surface. Her body was a bony sketch, a framework on which to build a woman. "How old are you?" he asked. "That's a secret. What happened to your nose?" "I broke it a long time ago. I'll bet you're twelve." She giggled, then nodded. Eleven, then. And just barely. "Do you want some candy?" He reached into his pocket and pulled out the pink-and-white-striped paper bag. She shook her head solemnly. "My mother says not to take candy from strangers." "But we're not strangers. I'm Ian, the pusher." She thought that over. While she hesitated, he reached into the bag and picked out a chocolate thing so thick and gooey it was almost obscene. He bit into it, forcing himself to chew. He hated sweets. "Okay," she said, and reached toward the bag. He pulled it away. She looked at him in innocent surprise. "I just thought of something," he said. "I don't know your name. So I guess we are strangers." She caught on to the game when she saw the twinkle in his eye. He'd practiced that. It was a good twinkle. "My name is Radiant. Radiant Shining star Smith." "A very fancy name," he said, thinking how names had changed. "For a very pretty girl." He paused, and cocked his head. "No. I don't think so. You're Radiant . . . Starr. With two r's. . . . Captain Radiant Starr, of the Star Patrol." She was dubious for a moment. He wondered if he'd judged her wrong. Perhaps she was really Miz Radiant Fainting heart Belle, or Mrs. Radiant Motherhood. But her fingernails were a bit dirty for that. She pointed a finger at him and made a Donald Duck sound as her thumb worked back and forth. He put his hand to his heart and fell over sideways, and she dissolved in laughter. She was careful, however, to keep her weapon firmly trained on him. "And you'd better give me that candy or I'll shoot you again." The playground was darker now, and not so crowded. She sat beside him on the bench, swinging her legs. Her bare feet did not quite touch the dirt. She was going to be quite beautiful. He could see it clearly in her face. As for the body . . . who could tell? Not that he really gave a damn. She was dressed in a little of this and a little of that, worn here and there without much regard for his concepts of modesty. Many of the children wore nothing. It had been something of a shock when he arrived. Now he was almost used to it, but he still thought it incautious on the part of her parents. Did they really think the world was that safe, to let an eleven year-old girl go practically naked in a public place? He sat there listening to her prattle about her friends-the ones she hated and the one or two she simply adored-with only part of his att IDAY TRANSCRIBED BY Graham (hepburn@unforgettable.com) (A newsreel begins:) --PARAMOUNT NEWS-- NEWS FLASH (A commentator describes the newsreel showing Princess Ann at several ceremonies in various European locations.) NEWSREEL Paramount News brings you a special coverage of Princess Ann's visit to London, the first stop on her much publicised goodwill tour of European capitals. She gets a royal welcome from the British as thousands cheer the gracious young member of one of Europe's oldest ruling families. After three days of continuous activity and a visit to Buckingham Palace, Ann flew to Amsterdam where Her Royal Highness dedicated the new International Aid Building and christened an ocean liner. Then went to Paris where she attended many official functions designed to cement trade relations between her country and the Western European nations. And so to Rome, the eternal city, where the Princess' visit was marked by a spectacular military parade highlighted by the band of the crack Piersa Yeri Regiment. The smiling young Princess showed no sign of the strain of the week's continuous public appearances. And at her country's embassy that evening, a formal reception and ball in her honor was given by her country's ambassador to Italy. -------------------------------------------------------------------------------- (The Embassy ballroom. People fill the floor of the room. A fanfare sounds. The Master of Ceremonies appears and the people clear a path down the middle of the hall in front of him. The Master of Ceremonies announces "Her Royal Highness"--first in Italian, then in English.) (The orchestra starts playing as the Master of Ceremonies walks down the newly-formed aisle. Princess Ann, resplendent in her ballgown, diamond tiara, and necklace, appears at the door accompanied by the Ambassador in formal military dress. Behind them follow together the Countess Vereberg and General Provno, and others. As the company walks slowly down the aisle, Princess Ann smiles and nods her head to acknowledge the guests who line their path. They bow as the Princess walks past them.) (As they reach the front, the Princess and the others step onto the dais as the orchestra finishes playing. The dais is furnished with chairs--a large one in the center. The Princess and the others stand, facing the guests. Princess Ann is about to sit when the Ambassador discreetly stops her with a hand on her arm.) (As they stand waiting, the guests form in a line in front. The Master of Ceremonies announces them as they walk forward to greet her, in turn.) MASTER OF CEREMONIES His Excellency, the Papal Nuntius, Monsignor Altomonto. (Ann greets him warmly in Italian, shaking his hand; he replies, in Italian.) MASTER OF CEREMONIES Sir Hugo Macy de Farmington. ANN (he bows to her) Good evening, Sir Hugo. SIR HUGO (shaking her hand) Good evening, Your Royal Highness. MASTER OF CEREMONIES His Highness, The Maharajah of Kalipur; and The Rajkumari. ANN (shaking the Rajkumari's hand) I'm so glad that you could come. THE RAJKUMARI Thank you. THE MAHARAJA (shaking Ann's hand) Thank you, madame. (The Master of Ceremonies announes the next couple, in German.) ANN (hidden beneath her dress, she takes her right foot out of its shoe and stretches it) Guten Abend. MASTER OF CEREMONIES (as Ann puts her foot back) Prince Istvan Barossy Nagyavaros. ANN How do you do? as she curtsies) Guten Abend. (She greets the man as he kisses her hand.) (The Master of Ceremonies announces the next couple. As she greets them, Ann rubs her tired right foot against her leg.) (Much later on and Ann is still greeting the guests.) miles back as she regathers herself. The Ambassador looks down in disappointment at her error. Th (the man kisses her hand.) (The Master of Ceremonies announces the next guest as Ann pushes her shoe again in an effort to right it.) ANN (as the man bends, gesturing with his hand in greeting) How do you do? (As the last guest moves back Ann looks around anxiously, trying again to right her shoe, resulting in her pushing it further away. The Ambassador then motions her to sit down. As she sits back into the chair with the Ambassador and the Countess on either side her dress pulls back, revealing the shoe.) (The orchestra starts playing a waltz. Ann tries as inconspicuously as possible to drag her shoe back with her foot. The General, standing behind her frowning, motions to the Countess to look at the shoe. She looks down at it and closes her eyes in horror. The Princess stirs in her seat trying to get her shoe back, fiddling with her gloves as cover. A man standing behind the Ambassador motions to him and he shrugs and gets up, bowing and presenting his arm to the Princess. The Princess rises and, pausing for time to regather her shoe, is lead onto the ballroom floor by the Ambassador. Taking her up to dance he looks at the area in front of the eat and, relieved that the shoe isn't to be seen, continues dancing with her as the other guests watch. ) (Later on and the dance floor is filled people. Princess Ann dances with a short, lively gentleman who rattles off rapid Spanish phrases to her. She listens, nodding and smiling politely. Still later and she dances with a short, elderly gentlemen. They smile and nod to each other silently. Later again and Ann dances with a somewhat remote gentlemen. She almost speaks so as to strike up a conversation, but thinks better of it.) -------------------------------------------------------------------------------- (Later that (Just) the top half. (The Countess takes off her glasses, shocked, then walks over to the window. Ann pulls the covers over her, sitting up) Did you know there are people who sleep with absolutely (nothing) on at all? COUNTESSance. just before she left she glanced back at the two tiny dots still flashing on the screen overhead.
/
本文档为【毕业设计-多时区时钟软件的设计与实现-论文】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索