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

时间:2024.3.31

湖 南 农 业 大 学

VC++程序设计课程设计报告

 时钟 

学生姓名:XXX

学号:XXXXXXXXXXXX

QQ:XXXXXXXXX

班级:X班

年级专业:20##级计算机

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

学院:XXXXXXXXXXXXXXX

湖南·长沙

提交日期:20##年6月


时钟

                                   学生:XX

                         指导老师:XXX     

(XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)

1.摘要:利用MFC设计制作一个能联网调时时钟,当按下F1键时,能打开或关闭帮助,单击左键是,能拖动窗口,双击左键时,能联网校时,滚动中轴时,能调整时间,单击右键,能随机变换背景颜色。

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

3.前言:

   1.我们学习MFC,除了可以掌握一种Windows应用程序设计的基本方法之外,还可以使他们进一步全面、深刻地理解向对象程序设计的思想。而且MFC所蕴含的程序设计思想、代码实现技巧、则是其他开发工具所不能及的。

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

4.正文:

4.1:窗口的创建于注册

    class CAboutDlg : public CDialog

{

public:

    CAboutDlg();

// Dialog Data

    //{{AFX_DATA(CAboutDlg)

    enum { IDD = IDD_ABOUTBOX };

    //}}AFX_DATA

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CAboutDlg)

    protected:

    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

    //}}AFX_VIRTUAL

// Implementation

protected:

    //{{AFX_MSG(CAboutDlg)

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

{

    //{{AFX_DATA_INIT(CAboutDlg)

    //}}AFX_DATA_INIT

}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(CAboutDlg)

    //}}AFX_DATA_MAP

}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

    //{{AFX_MSG_MAP(CAboutDlg)

        // No message handlers

    //}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CAlarmClockDlg dialog

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

    : CDialog(CAlarmClockDlg::IDD, pParent)

{

    //{{AFX_DATA_INIT(CAlarmClockDlg)

        // NOTE: the ClassWizard will add member initialization here

    //}}AFX_DATA_INIT

    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32

    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    m_hThread = NULL;

    m_bkColor = RGB(110, 200, 255);

    m_bHelp = TRUE;

}

void CAlarmClockDlg::DoDataExchange(CDataExchange* pDX)

{

    CDialog::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(CAlarmClockDlg)

        // NOTE: the ClassWizard will add DDX and DDV calls here

    //}}AFX_DATA_MAP

}

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

    ON_WM_MOUSEWHEEL()

    //}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CAlarmClockDlg message handlers

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

{

    if ((nID & 0xFFF0) == IDM_ABOUTBOX)

    {

        CAboutDlg dlgAbout;

        dlgAbout.DoModal();

    }

    else

    {

        CDialog::OnSysCommand(nID, lParam);

    }

}

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

//  the minimized window.

HCURSOR CAlarmClockDlg::OnQueryDragIcon()

{

    return (HCURSOR)m_hIcon;

}

BOOL CAlarmClockDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.

    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);

    if (pSysMenu != NULL)

    {

        CString strAboutMenu;

        strAboutMenu.LoadString(IDS_ABOUTBOX);

        if (!strAboutMenu.IsEmpty())

        {

            pSysMenu->AppendMenu(MF_SEPARATOR);

            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

        }

    }

    // Set the icon for this dialog.  The framework does this automatically

    //  when the application's main window is not a dialog

    SetIcon(m_hIcon, TRUE);         // Set big icon

    SetIcon(m_hIcon, FALSE);        // Set small icon

   

    // TODO: Add extra initialization here

    //1. 将窗口改成正方形

    CRect rc;

    this->GetWindowRect(&rc);

    int iNewWH = min(rc.Width(), rc.Height());

    this->MoveWindow(rc.left, rc.top, iNewWH, iNewWH);

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

    {

        this->Invalidate();

    }

    else if (nIDEvent == 110)

    {

        m_bHelp = FALSE;

        this->KillTimer(110);

    }

    CDialog::OnTimer(nIDEvent);

}

// 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()

{

    CPaintDC dc(this); // device context for painting

    if (IsIconic())

    {

        SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);

        // Center icon in client rectangle

        int cxIcon = GetSystemMetrics(SM_CXICON);

        int cyIcon = GetSystemMetrics(SM_CYICON);

        CRect rect;

        GetClientRect(&rect);

        int x = (rect.Width() - cxIcon + 1) / 2;

        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon

        dc.DrawIcon(x, y, m_hIcon);

    }

    else

    {

        OnDraw(&dc);

        //CDialog::OnPaint();

    }

}

BOOL CAlarmClockDlg::OnEraseBkgnd(CDC* pDC)

{

    // TODO: Add your message handler code here and/or call default

    return TRUE;

//  return CDialog::OnEraseBkgnd(pDC);

}

void CAlarmClockDlg::OnDraw(CDC *pDC)

{

    // 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刷子.

    //c. 为CxxxView类增加一个成员函数void OnDrawMem(CDC &dcMem),

    //   并将你以前写在OnDraw()中的代码,移到OnDrawMem()中去即可.

    //

    /////////////////////////////////////////////////////////////////////////

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

//  ::SetClassLong(this->m_hWnd, GCL_HBRBACKGROUND, (LONG)(HBRUSH)::GetStockObject(NULL_BRUSH));

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

    //将bmp选入到dcMem中, 只有选入了位图的dcMem才有地方绘图,画到指定的bmp位图上

    CBitmap * pOldBit = dcMem.SelectObject(&bmp);

   

    //4. 先用背景色将位图清除干净,这里我用的是m_bkColor作为背景

    dcMem.FillSolidRect(0, 0, nWidth, nHeight, m_bkColor);

   

    //5. 执行真正的绘图代码, 如dcMem.MoveTo(……); dcMem.LineTo(……); 等等

    OnDrawMem(&dcMem);

    //6. 将dcMem中的图拷贝到pDC上进行显示. 关键点.

    pDC->BitBlt(0, 0, nWidth, nHeight, &dcMem, 0, 0, SRCCOPY);

   

    //7. 绘图完成后的清理

    bmp.DeleteObject();

    dcMem.DeleteDC();

}

4.2:中心时间显示

    void CAlarmClockDlg::OnDrawMem(CDC *pDC)

{

    CRect rc;

    this->GetClientRect(&rc);   //获取客户区矩形

    //1. 获取设备资源

    CPen *pOldPen = pDC->GetCurrentPen();

    CPen pen(PS_SOLID, 1, RGB(0,0,0));

    pDC->SelectObject(&pen);

   

    CBrush *pOldBrush = pDC->GetCurrentBrush();

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

    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;

    //3. 取得时, 分, 秒

    CString sTime;

    SYSTEMTIME tm;

    ::GetLocalTime(&tm);    //取得本地时间

   

    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°

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

//第一象限

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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

//第四象限

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

}

//第三象限

for(i=1;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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

//第二象限

for(i=1;i<15;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));

}

根据:

sin(PI/2+α)=cosα

cos(π/2+α)=-sinα

第四象限可以写成

for(int i=16;i<32;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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

根据:

sin(π+α)=-sinα

cos(π+α)=-cosα

第三象限可以写成:

for(int i=32;i<48;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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

根据:

sin(3π/2+α)=-cosα

cos(3π/2+α)=sinα

第二象限可以写成

for(int i=48;i<60;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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

最后统一成:

for(int i=0;i<60;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;

    SetPixel(hdc,pt0.x,pt0.y,RGB(255,0,0));

}

所以有程序代码如下:

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

   

    //4.1 画秒刻度

    pen.DeleteObject();

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

    pDC->SelectObject(&pen);

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

    {

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

    }

   

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

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

            pDC->DrawText(sHelp, &rtHelp, DT_CENTER | DT_VCENTER);

        }

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

        }

    }

    //8. 恢复现场, 释放资源

    pDC->SelectObject(pOldPen);

    pDC->SelectObject(pOldBrush);

    pen.DeleteObject();

    brush.DeleteObject();

}

//移动无标题窗口

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

{

    this->SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, 0);

    CDialog::OnLButtonDown(nFlags, point);

}

//Internet校时

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

{

    if (m_hThread) ::TerminateThread(m_hThread, -1);

    m_hThread = ::CreateThread(NULL, 0, SetInternetTimeProc, this, 0, NULL);

   

    CDialog::OnLButtonDblClk(nFlags, point);

}

//随机背景

void CAlarmClockDlg::OnRButtonDown(UINT nFlags, CPoint point)

{

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

{

    // TODO: Add your message handler code here and/or call default

    SYSTEMTIME tm;

    ::GetLocalTime(&tm);

    COleDateTime now = COleDateTime::GetCurrentTime();

    now += COleDateTimeSpan(0, 0, zDelta > 0 ? -1 : 1, 0); // 1 Minute exactly

    tm.wHour = now.GetHour();

    tm.wMinute = now.GetMinute();

    tm.wSecond = 0;//now.GetSecond();

    ::SetLocalTime(&tm);

    this->Invalidate();

    return CDialog::OnMouseWheel(nFlags, zDelta, pt);

}

//键盘控制

void CAlarmClockDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

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

{

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

}

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

DWORD CAlarmClockDlg::SetInternetTimeProc(LPVOID lpParameter)

{

    CAlarmClockDlg *pDlg = (CAlarmClockDlg *)lpParameter;

    DWORD bRet = FALSE;

    //创建TCP套接字

    SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (sock == INVALID_SOCKET)

    {

        pDlg->m_hThread = NULL;

        return FALSE;

    }

    //设置接收超时时间为2s

    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","clepsydra.dec.com",

        "time.windows.com", "5time.nist.gov", "clock.sgi.com", "tick.mit.edu",

        "210.72.145.44", "129.6.15.29", "129.6.15.28", "time.nuri.net",

    };

    //尝试连接不同的服务器

    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.wMonth = 1;       stNew.wDay = 1;

            stNew.wHour = 0;        stNew.wMinute = 0;      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

            //LARGE_INTEGER-->FILETIME-->SYSTEMTIME-->2011.6.12.

            ftNew = *(FILETIME *)&liTime;

            FileTimeToSystemTime(&ftNew, &stNew);

            //改变系统时间

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

            LONGLONG llNetDate = stNew.wYear * 10000 + stNew.wMonth * 100 + stNew.wDay;

            //LONGLONG llNetTime = stNew.wHour * 10000 + stNew.wMinute * 100 + stNew.wSecond;

            if (llNetDate > 19000101)

            {

                bRet = SetSystemTime(&stNew);

                break;

            }

        }

    }

    closesocket (sock) ;

    sock = NULL;

    pDlg->m_hThread = NULL;

    return bRet;

}

5.结论:通过这次的课程设计的训练,深刻体会到了自己在这方面还很不足,需要加强,就像老师说的还有很大的提升空间,同时,也感觉学好C++很有用的,编出程序的那一刻还是很高兴的,因此,这次的最大的收获就是培养出了自己对C++的兴趣。我通过这次的学习,知道了,学习C++,最重要的是自己动手的能力,光靠课堂上的知识是无法编出自己的程序的,在课后,我们一定要自己多动手,这样才有可能学好C++。

参考文献

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

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

致  谢

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

更多相关推荐:
C语言程序设计实验报告——张蒙蒙

重庆邮电大学移通学院C语言程序设计实验报告学生张蒙蒙学号0214110122班级一班专业数字媒体重庆邮电大学移通学院1重庆邮电大学移通学院目录第一章基础掌握311实验目的错误未定义书签12实验要求313实验基本...

C语言课程设计实验报告模板

C语言课程设计通讯录管理系统程序设计基础课程设计报告课程设计题目通讯录管理系统指导教师李萍班级0903班学生姓名20xx100333闫晓20xx100334皇倩20xx100335翟少平20xx100336谢成...

C语言课程设计实验报告

中南大学二一三二一四学年第一学期信息科学与工程学院程序设计基础实践设计报告课程名称程序设计基础实践班级20xx级信息安全1302班学号0906130221姓名张振宇指导教师杨希二一三年十二月目录一需求分析3二总...

C语言课程设计实验报告参考

题目学生成绩管理系统学号专业姓名指导教师完成日期20xx年7月8日一目标1进一步掌握和利用C语言进行程设计的能力2进一步理解和运用结构化程设计的思想和方法3初步掌握开发一个小型实用系统的基本方法4学会调试一个较...

《C语言程序设计》课程实验报告

C语言程序设计课程实验报告学院名称建筑工程学院专业年级土木104学生姓名学号联系电话Email20xx年4月13日

c语言课程设计实验报告书

C语言课程设计报告院系信息工程系专业11级计算机科学与技术题目教小学生算术姓名许庆超学号2111714135指导教师夏学文20xx1231湖北工程学院新技术学院一实验目的1使学生更深入地理解和掌握该课程中的有关...

C语言课程设计实验报告

课程设计报告题目景点查询系统课程名称C语言课程设计专业班级信息安全二班任务书主要内容建立国内景点信息系统提供创建编辑和综合查询等基本业务管理和服务任务要求收集与阅读相关文献资料确定系统目标与范围分析系统需求确定...

C语言课程设计实验报告(万年历)

C语言课程设计一题目及功能描述题目万年历的设计利用C语言设计出万年历使其实现如下要求1输入一个年份在屏幕上输出该年的年历包括每月的天数和所对应的星期几并且在每月的左上角或右上角打印出相应的年份和月份要求输出界面...

C语言课程设计大数加减实验报告

C语言程序设计课程设计大数加减一目的因为C语言中的int类型和long类型的大小范围仅为3276732767和21474836472147483647在某些较大型计算中数据长度不能满足需要本实验目的是用C设计一...

c语言——课程设计实验报告网页未完版

中南大学C语言程序设计实践报告学生姓名木雕小象题目学生成绩管理系统指导教师学院信息科学与工程学院专业班级电气0900班完成时间20xx年7月8日系统描述功能模块结构数据结构设计主要模块的算法说明运行结果课程设计...

C语言课程设计实验报告模板 2

大学数学与信息科学学院实验报告课程名称C语言课程设计实验名称运用C语言开发小型应用软件实验类型验证性综合性设计性实验室名称数学实验室D208班级学号学生姓名任课教师成绩实验日期20xx67至20xx6261

C语言课程设计实验报告(模板)

西安科技大学C语言课程设计报告题目学生成绩管理系统班级测控技术与仪器1102班学号姓名20xx年6月C语言课程设计实验报告C语言课程设计说明书一课程设计的目的和要求1熟练掌握模块化程序设计的方法和过程2熟练掌握...

c++课程设计实验报告(33篇)