vc++课程设计实验报告

VC++课程设计报告

一、设计时间

   20##年12月 27日----12月31日

二、设计地点

    

三、设计目的

《VC++程序设计》是计算机科学与技术专业的必修专业基础课程,其实践性、应用性很强。实践教学环节是必不可少的一个重要环节。VC程序设计的设计目的是加深对理论教学内容的理解和掌握,使学生较系统地掌握程序设计及其在网络开发中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行软件开发、并在实践应用方面打下一定基础。要求学生在设计指导教师的帮助下自行完成各个操作环节,并能实现且达到举一反三的目的,完成一个项目解决一类问题。要求学生能够全面、深入理解和熟练掌握所学内容,并能够用其分析、设计和解答类似问题;对此能够较好地理解和掌握,能够进行简单分析和判断;能编写出具有良好风格的程序;掌握VC++程序设计的基本技能和面向对象的概念和方法;了解菜单、视图/文档、数据库等编程技术。同时培养学生进行分析问题、解决问题的能力;培养学生进行设计分析、设计方法、设计操作与测试、设计过程的观察、理解和归纳能力的提高。

四、设计小组成员

五、指导老师

六、设计课题

派生、多态编程

设计内容:依照书p33-40内容,创建一个应用了的窗口和应用程序派生类地完整实例。

设计要求:1)掌握虚函数的使用。2)改变窗口的背景颜色和窗口的图标。

七、基本思路及关键问题的解决方法

仔细审题理解题目要求,整理思路思考出一个系统总体开发,总体设计、总体实现的完整过程,参照书本,按思路编写程序。遇到问题先独立思考,翻阅教材或上网查找解决,实在无法自己解决的问题可以向老师或同学求助。

八、算法及流程图

九、调试过程中出现的问题及相应解决办法

问题1:missing ';' before identifier 'InvalidateRect'

解决办法:将该中文下的分号改为英文下的分号。    

问题2:LINK : fatal error LNK1168: cannot open Debug/0000.exe for writing

解决办法:将前一次的运行后的窗口关闭    

改变图标

十、课程设计心得体会

Visual C++是Microsofe公司开发的基于C和C++语言的集成开发工具,同其他的可视化编程工具一样,Visual C++6.0集代码编辑,编译,链接,调试等功能于一体,并提供多种有用的辅助开发工具。学习好VC++是广大计算机专业学生的迫切要求。

经过一个星期的VC++课程设计,我在老师和同学的共同帮助下,顺利完成该课程设计,收获很大。在《Windows程序设计》中MFC部分很重要,是需要实践内容。所以在本学期课程设计是很及时、很必要的。而且还及时、真正的做到了学以致用。主要是以下几点。

基本功要过硬。不能马虎经常犯犯小错误。提高自己找错纠错能力,通常错误总是那几种,多练习就熟练了。

要善于查找资料提高自己的资料查询能力,要善于利用网络来获得知识,获得帮助。开始着手程序设计时,有些功能感觉无从下手,都不知道要干什么。这些问题只要找到相关的资料就会得到提示从而理解所要解决问题的大致方向。有了明确的目的,就可以发挥自己的头脑来完成它了。

要善于思考。程序中有些实现难点和最初完成程序时免不了的许多不足就需要自己根据代码认真思考来解决。只有这样才能纠正程序的不足并使其更加人性化。

这次课程设计让我学到了很多,不仅是巩固了先前学的MFC程序设计知识,而且也培养了我的动手能力,更令我的创造性思维得到拓展。希望今后类似这样课程设计、类似这样的锻炼机会能更多些!

    通过这次课程设计,可以明显地感觉到它弥补了课堂教学和实验中知识的深度和广度方面的不足,也让我进一步掌握了面向过程和面向对象程序设计的基本方法和编程技巧,同时也巩固所学理论知识,虽然花费了不止一点点的时间和精力,不过那确实挺值得的,既让我认识到自己知识方面的缺陷,又培养了我独立分析问题、解决问题的能力。希望在今后的学习中我能够长久的保持这股学习热情,将理论知识化为实际编程能力,努力学好VC++,将所学知识与数据库充分结合起来,学好计算机专业课。

十一、源程序(每句话都要有详细解释)

 #include "windows.h"//头文件

//定义全局变量和函数

HINSTANCE hInst;

HINSTANCE hInstance; //表示当前应用程序实例句柄

MSG msg;

char lpszClassName[]="城院";//指出窗口类的名称

char *ShowText;

//声明消息响应函数

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);

void OnLButtonDown(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);

void OnRButtonDown(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);

void OnPaint(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);

void OnDestory(HWND hWnd, UINT message,WPARAM wParam,LPARAM lParam);

//声明窗口类

class CFrameWnd

{

public:

HWND hWnd;

public:

    int RegisterWindow();

    void Create(LPCTSTR lpClasasName,LPCTSTR lpWindowName);

    void ShowWindow(int nCmdShow);

    void UpdateWindow();

};

//类中的函数

// RegisterWindow()设计窗口

int CFrameWnd::RegisterWindow()

{WNDCLASS wndclass;

wndclass.style=0;//窗口类型为默认类型

wndclass.lpfnWndProc=WndProc;//窗口处理函数为WndProc

wndclass.cbClsExtra=0;//窗口类无扩展

wndclass.cbWndExtra=0;//窗口实力无扩展

wndclass.hIcon=LoadIcon(NULL,IDI_QUESTION); //窗口的最小化图标为问号图标

wndclass.hCursor=LoadCursor(NULL,IDC_CROSS); //窗口采用十字光标

wndclass.hbrBackground=(HBRUSH)GetStockObject(DKGRAY_BRUSH); //窗口背景为深灰色

wndclass.lpszMenuName=NULL;//窗口中无菜单

wndclass.lpszClassName=lpszClassName;//窗口类名为“窗口示例”

//以下进行窗口类的注册

if (!RegisterClass(&wndclass))//如果注册失败则发出警告声音

{

    MessageBeep(0);

    return FALSE;

}

}

//创建窗口

void CFrameWnd::Create(LPCTSTR lpClassName,LPCTSTR lpWindowName)

{RegisterWindow();

hInst=hInstance;

hWnd=CreateWindow(lpszClassName,//窗口类名

                 lpWindowName,

                 WS_OVERLAPPEDWINDOW,//窗口的风格

                 CW_USEDEFAULT,

                 CW_USEDEFAULT,//窗口的左上角坐标为默认值

                 CW_USEDEFAULT,

                 CW_USEDEFAULT,//窗口的高和宽设为默认值

                 NULL,//此窗口无父窗口

                 NULL,//此窗口无主菜单

                 hInstance,//创建此窗口应用程序的当前句柄

                 NULL);//不使用该值

}

//显示窗口

void CFrameWnd::ShowWindow(int nCmdShow)

{::ShowWindow(hWnd,nCmdShow);

}

//注册窗口

void CFrameWnd::UpdateWindow()

{::UpdateWindow(hWnd);}

//声明应用程序类

class CWinApp

{

public:

    CFrameWnd*m_pMainWnd;

    CWinApp*m_pCurrentWnd;

public:

    CWinApp();

    ~CWinApp();

    virtual BOOL InitInstance(int nCmdShow);

    int Run();

};

//类中的函数

//构造函数

CWinApp::CWinApp()

{

    m_pCurrentWnd=this;

}

//初始化函数

BOOL CWinApp::InitInstance(int nCmdShow)

{

    m_pMainWnd=new CFrameWnd;

    m_pMainWnd->Create(NULL,"Windows 程序");

    m_pMainWnd->ShowWindow(nCmdShow);

    m_pMainWnd->UpdateWindow();

return TRUE;

}

//Run()函数

int CWinApp::Run()

{

    while(GetMessage(&msg,NULL,0,0))

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return msg.wParam;

}

//构造函数

CWinApp::~CWinApp()

{

    delete m_pMainWnd;

}

//声明窗口类CFrameWnd的派生类

class CMyWnd:public CFrameWnd

{

};

//声明窗口类CWinApp的派生类

class CMyApp:public CWinApp

{

public:

    BOOL InitInstance(int nCmdShow);

};

//实现类中的函数

CMyApp::InitInstance(int nCmdShow)

{

    CMyWnd*pMainWnd;

    pMainWnd=new CMyWnd;

pMainWnd->Create(NULL,"派生类Windows程序");

pMainWnd->ShowWindow(nCmdShow);

pMainWnd->UpdateWindow();

return TRUE;

}

//构造CMyApp类对象

CMyApp myApp;

//重写AfxGetApp()函数

CWinApp*AfxGetApp()

{

    return myApp.m_pCurrentWnd;

}

//主函数

int APIENTRY WinMain(HINSTANCE hInstance,

                     HINSTANCE hPrevInstance,

                     LPSTR lpCmdLine,

                     int nCmdShow)

{

    int rt;

    CWinApp*pApp=(CWinApp*)AfxGetApp();

    pApp->InitInstance (nCmdShow);

    rt=pApp->Run();

    return rt;

}

//窗口函数

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

    switch(message) //message为标示的消息

    {

    case WM_LBUTTONDOWN://放开鼠标左键时产生消息

        OnLButtonDown(hWnd,message,wParam,lParam);

        break;

    case WM_PAINT://处理重画消息

        OnPaint(hWnd,message,wParam,lParam);

        break;

    case WM_DESTROY: //退出

        PostQuitMessage(0);

        break;

    default://默认时采用系统消息默认处理函数

        return DefWindowProc(hWnd,message,wParam,lParam);

    }

    return 0;

}

//消息响应函数

//响应鼠标单击消息

void OnLButtonDown(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

    ShowText="湖南城市学院欢迎您的到来!";

    InvalidateRect(hWnd,NULL,1);

}

//刷新消息

void OnPaint(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

    PAINTSTRUCT ps;

    HDC hdc;

    hdc=BeginPaint(hWnd,&ps);

    TextOut(hdc,300,250,ShowText,25);

    EndPaint(hWnd,&ps);

}

//关闭消息

void OnDestory(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)

{

    PostQuitMessage(0);

}

运行后可得如下结果:

改变图标可得如下结果:

改变背景颜色可得如下结果:

十二、参考文献

[1] 揣锦华.面向对象程序设计与VC++实践.西安电子科技大学出版社,20##年

[2] 陈清华等。Visual  C++课程设计案例精选与编程指导。东南大学出版社   20##年

[3] 陈清华.Visual C++课程设计案例精选与编程指导.东南大学出版社,20##年

[4] 陈维兴、林小茶,《C++面向对象程序设计教程》,清华大学出版社

[5] 谭浩强,《C语言程序设计》,清华大学出版社,20##年.

[6] 孙鑫 余安萍. VC++深入详解. 电子工业出版社.20##年

[7] 刘振安、刘燕君、孙忱,《C++语言课程设计》,机械工业出版社,20##年

[8] 严华峰. Visual C++课程设计案例精编. 北京:中国水利水电出版社,20##年

[9] 魏亮, 李春葆编著.Visual C++程序设计例学与实践.清华大学出版社 .2006

[10]    郑阿奇,丁有和.Visual C++教程.北京:机械工业出版社,2006

 

第二篇:VC++课程设计实验报告-时钟

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

时钟

学生姓名:XXX

学号:XXXXXXXXXXXX

QQ:XXXXXXXXX

班级:X班

年级专业:2010级计算机

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

湖南·长沙

提交日期:20xx年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();

// 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); SetIcon(m_hIcon, FALSE); // TODO: Add extra initialization here //1. 将窗口改成正方形 CRect rc; this->GetWindowRect(&rc); int iNewWH = min(rc.Width(), rc.Height()); this->MoveWindow(rc.left, rc.top, iNewWH, iNewWH); // Set big icon // Set small icon //2. 设置绘图区域

}

this->GetWindowRect(&rc); HRGN hRgn = ::CreateEllipticRgn(rc.left, rc.top, rc.right, rc.bottom); this->SetWindowRgn(hRgn, TRUE); //3. 设置定时器 this->SetTimer(110, 7000, NULL); //110 = Help this->SetTimer(2359, 1000, NULL); //23:59 = move time //4. 主动触发鼠标双击消息 this->PostMessage(WM_LBUTTONDBLCLK); //5. 设置窗口标题 this->SetWindowText("Internet时钟"); return TRUE; // return TRUE unless you set the focus to a control

void CAlarmClockDlg::OnTimer(UINT nIDEvent) {

}

if (nIDEvent == 2359) { } else if (nIDEvent == 110) { } CDialog::OnTimer(nIDEvent); m_bHelp = FALSE; this->KillTimer(110); this->Invalidate();

// 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 CAlarmClockDlg::OnPaint()

{

}

BOOL CAlarmClockDlg::OnEraseBkgnd(CDC* pDC)

{

// TODO: Add your message handler code here and/or call default } else { } OnDraw(&dc); //CDialog::OnPaint(); // Draw the icon dc.DrawIcon(x, y, m_hIcon); // 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; CPaintDC dc(this); // device context for painting if (IsIconic()) { SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);

return TRUE;

// return CDialog::OnEraseBkgnd(pDC);

}

void CAlarmClockDlg::OnDraw(CDC *pDC)

{

子.

// //1. 改变当前View窗口的背景为空刷子

// ::SetClassLong(this->m_hWnd, GCL_HBRBACKGROUND, (LONG)(HBRUSH)::GetStockObject(NULL_BRUSH)); //c. 为CxxxView类增加一个成员函数void OnDrawMem(CDC &dcMem), // 并将你以前写在OnDraw()中的代码,移到OnDrawMem()中去即可. // ///////////////////////////////////////////////////////////////////////// // TODO: add draw code for native data here ///////////////////////////////////////////////////////////////////////// // //如下的做法能避免绘图闪烁, 强烈推荐使用. KouConghua. // //主要思想是将以前直接画在pDC上的图,改画到一个内存DC(如dcMem)中去, //然后使用BitBlt函数,将dcMem这个内存中的图复制到当前屏幕即pDC中去. // //具体步骤如下, 其中a 和b 选择一步即可, 不可二者都做: //a. 直接在OnDraw()中增加如下语句, 以改变窗口背景为透明色: // ::SetClassLong(this->m_hWnd, GCL_HBRBACKGROUND, // (LONG)(HBRUSH)::GetStockObject(NULL_BRUSH)); //b. 在CxxxView类中增加OnEraseBkgnd()消息响应函数, // 将其中的代码改为: return TRUE; // 直接返回TRUE表示告诉系统绘图时不再绘制背景,相当于设置窗口背景为NULL刷

//6. 将dcMem中的图拷贝到pDC上进行显示. 关键点. pDC->BitBlt(0, 0, nWidth, nHeight, &dcMem, 0, 0, SRCCOPY); //7. 绘图完成后的清理 bmp.DeleteObject(); dcMem.DeleteDC(); CBitmap * pOldBit = dcMem.SelectObject(&bmp); //4. 先用背景色将位图清除干净,这里我用的是m_bkColor作为背景 dcMem.FillSolidRect(0, 0, nWidth, nHeight, m_bkColor); //5. 执行真正的绘图代码, 如dcMem.MoveTo(……); dcMem.LineTo(……); 等等 OnDrawMem(&dcMem); //将bmp选入到dcMem中, 只有选入了位图的dcMem才有地方绘图,画到指定的bmp位图//2. 获取当前绘图区的宽度和高度 CRect rcClient; this->GetClientRect(&rcClient); int nWidth = rcClient.Width(); int nHeight= rcClient.Height(); //3. 创建一个和pDC兼容的内存DC: dcMem CDC dcMem; dcMem.CreateCompatibleDC(pDC); //pDC换成NULL也可以,指定为显示器 //创建一个位图对象, 其宽度和高度就用当前绘图区的nWidth 和nHeight CBitmap bmp; bmp.CreateCompatibleBitmap(pDC, nWidth, nHeight);

} 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("%.2d:%.2d:%.2d", tm.wHour, tm.wMinute, tm.wSecond); pDC->DrawText(sTime, &rtO, DT_CENTER);

4.3:画时钟

算法:时钟的秒刻度分为60个刻度,每个刻度是6°

四个象限的刻度尺的算法如下:

//第一象限

VC课程设计实验报告时钟

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);

if (j == 0) j = 12; CString sTime; sTime.Format("%d", j); POINT ptN; ptN.x = ptO.x + iR * sin( PI/30 * i) * 0.87f; ptN.y = ptO.y - iR * cos( PI/30 * i) * 0.87f; } CRect rtN(ptN.x - 10, ptN.y - 10, ptN.x + 10, ptN.y + 10); pDC->DrawText(sTime, &rtN, DT_CENTER | DT_VCENTER); //5. 画秒针 60s = 2*PI, 1s = PI / 30 pen.DeleteObject(); pen.CreatePen(PS_SOLID, 1, RGB(0,0,255)); pDC->SelectObject(&pen); POINT ptSecond; ptSecond.x = ptO.x + iR * sin( PI/30 * fSecond) * 0.94f; ptSecond.y = ptO.y - iR * cos( PI/30 * fSecond) * 0.94f; pDC->MoveTo(ptO.x, ptO.y); pDC->LineTo(ptSecond.x, ptSecond.y); //6. 画分针 60m = 2*PI, 1m = PI / 30 pen.DeleteObject(); pen.CreatePen(PS_SOLID, 2, RGB(255,0,0)); pDC->SelectObject(&pen); POINT ptMinute; ptMinute.x = ptO.x +iR * sin( PI/30 * fMinute) * 0.84f; ptMinute.y = ptO.y - iR * cos( PI/30 * fMinute) * 0.84f; pDC->MoveTo(ptO.x, ptO.y);

pDC->LineTo(ptMinute.x, ptMinute.y); //7. 画时针 12h = 2*PI, 1h = PI / 6 pen.DeleteObject(); pen.CreatePen(PS_SOLID, 3, RGB(255,0,255)); pDC->SelectObject(&pen); POINT ptHour; ptHour.x = ptO.x + iR * sin( PI/6 * fHour) * 0.71f; ptHour.y = ptO.y - iR * cos( PI/6 * fHour) * 0.71f; pDC->MoveTo(ptO.x, ptO.y); pDC->LineTo(ptHour.x, ptHour.y);

4.4:显示帮助信息及其相关操作

//帮助信息, 显示7s后关闭 if (m_bHelp) { CString sHelp; sHelp += "按下F1键: 帮助开关\r\n"; sHelp += "单击左键: 拖动窗口\r\n"; sHelp += "双击左键: 联网校时\r\n"; sHelp += "滚动中轴: 调整时间\r\n"; sHelp += "单击右键: 随机背景\r\n"; sHelp += "按Esc 键: 退出程序\r\n"; if (int(fHour) % 12 >= 3 && (int)fHour % 12 < 9) { CRect rtHelp(ptO.x - iR, ptO.y - iR * 7 / 10, ptO.x + iR, ptO.y + iR * 3 /

10);

} else { CRect rtHelp(ptO.x - iR, ptO.y + iR / 5, ptO.x + iR, ptO.y + iR * 4 / 5); pDC->DrawText(sHelp, &rtHelp, DT_CENTER | DT_VCENTER);

}

} } pDC->DrawText(sHelp, &rtHelp, DT_CENTER | DT_VCENTER); //8. 恢复现场, 释放资源 pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush); pen.DeleteObject(); brush.DeleteObject();

//移动无标题窗口

void CAlarmClockDlg::OnLButtonDown(UINT nFlags, CPoint point) {

}

//Internet校时

void CAlarmClockDlg::OnLButtonDblClk(UINT nFlags, CPoint point) {

}

//随机背景

void CAlarmClockDlg::OnRButtonDown(UINT nFlags, CPoint point) { if (m_hThread) ::TerminateThread(m_hThread, -1); m_hThread = ::CreateThread(NULL, 0, SetInternetTimeProc, this, 0, NULL); CDialog::OnLButtonDblClk(nFlags, point); CDialog::OnLButtonDown(nFlags, point); this->SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);

}

// TODO: Add your message handler code here and/or call default ::srand(::GetTickCount()); m_bkColor = RGB(rand() * 100 % 255, rand() * 100 % 255, rand() * 100 % 255); this->Invalidate(); CDialog::OnRButtonDown(nFlags, point);

//调整时间

BOOL CAlarmClockDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) {

}

//键盘控制

void CAlarmClockDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { return CDialog::OnMouseWheel(nFlags, zDelta, pt); this->Invalidate(); tm.wHour = now.GetHour(); tm.wMinute = now.GetMinute(); tm.wSecond = 0;//now.GetSecond(); ::SetLocalTime(&tm); now += COleDateTimeSpan(0, 0, zDelta > 0 ? -1 : 1, 0); // 1 Minute exactly // TODO: Add your message handler code here and/or call default SYSTEMTIME tm; ::GetLocalTime(&tm); COleDateTime now = COleDateTime::GetCurrentTime();

// TODO: Add your message handler code here and/or call default switch (nChar) { case VK_ESCAPE: CDialog::OnOK(); break; case VK_HOME: this->SendMessage(WM_LBUTTONDBLCLK); break; case VK_END: SYSTEMTIME tm; ::GetLocalTime(&tm); tm.wHour = 0; tm.wMinute = 0; tm.wSecond = 0; ::SetLocalTime(&tm); this->Invalidate(); break; case VK_DOWN: case VK_RIGHT: case VK_NEXT: OnMouseWheel(0, -1, 0); break; case VK_UP: case VK_LEFT: case VK_PRIOR: } OnMouseWheel(0, 1, 0); break; //CDialog::OnKeyDown(nChar, nRepCnt, nFlags);

}

//帮助信息

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[] = { }; "128.138.140.44", "132.163.4.101", "132.163.4.102", "132.163.4.103", "192.43.244.18", "131.107.1.10", "66.243.43.21", "216.200.93.8", "208.184.49.9", "207.126.98.204", "207.200.81.113", "205.188.185.33", "216.218.254.202", "209.81.9.7", "time.stdtime.gov.tw","time-a.nist.gov","", "", "5time.nist.gov", "", "tick.mit.edu", "210.72.145.44", "129.6.15.29", "129.6.15.28", "", //尝试连接不同的服务器 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 ("132.163.4.101") ; } if (0 == connect(sock, (SOCKADDR *)&sa, sizeof(sa))) { } bConnect = TRUE; TRACE("\r\nOK: %s\r\n\r\n", szServer[i]); 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应用程序设计(第二版)》,出版年:20xx年9月,卷(期):第

二版。

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

致 谢

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

相关推荐