用MFC做一个指针式时钟

2024-11-21 23:44:35
推荐回答(1个)
回答1:

这是做完后的程序,因为是用MFC做的,估计直接用代码的话是不行的,给个邮箱吧,我发给你!

// shejiView.cpp : implementation of the CShejiView class
//

#include "stdafx.h"
#include "sheji.h"

#include "shejiDoc.h"
#include "shejiView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include
#define PI 3.141592653589793
#include "mydialog.h"
#include "setback.h"
#include
#pragma comment(lib, "winmm.lib")
/////////////////////////////////////////////////////////////////////////////
// CShejiView

IMPLEMENT_DYNCREATE(CShejiView, CView)

BEGIN_MESSAGE_MAP(CShejiView, CView)
//{{AFX_MSG_MAP(CShejiView)
ON_COMMAND(ID_BEGIN, OnBegin)
ON_COMMAND(ID_PAUSE, OnPause)
ON_COMMAND(ID_SETBACK, OnSetback)
ON_COMMAND(ID_SETTIMER, OnSettimer)
ON_WM_TIMER()
ON_COMMAND(ID_BPCOLOR, OnBpcolor)
ON_COMMAND(ID_HOURCOLOR, OnHourcolor)
ON_COMMAND(ID_MINUTECOLOR, OnMinutecolor)
ON_COMMAND(ID_SECONDCOLOR, OnSecondcolor)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CShejiView construction/destruction

CShejiView::CShejiView()
{
// TODO: add construction code here
CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1); ///加载位图
m_brushBackground.CreatePatternBrush(&bmp); ///创建位图画刷
CTime curtime = CTime::GetCurrentTime();
m_hour = curtime.GetHour();
m_minute = curtime.GetMinute();
m_second = curtime.GetSecond();
flag=0;
flag2=1;//倒计时无效;
hour=-1;
minute=-1;
set=0;
}

CShejiView::~CShejiView()
{
}

BOOL CShejiView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs

return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CShejiView drawing

void CShejiView::OnDraw(CDC* pDC)
{
CShejiDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect rect;
GetClientRect(rect);///取得客户区域
pDC->FillRect(rect,&m_brushBackground); ///用背景画刷填充区域,而我们在mbrushbackground里加载了位图,所以理所当然就变成了我们设置的图片
//画表盘,标注刻度
CRect client;
GetClientRect(&client);

int centerX = client.Width()/2;
int centerY = client.Height()/2;

int clockRadius = centerX > centerY ? centerY : centerX;//用较小的一个作为钟表的半径,避免半径太大矩形放不开
clockRadius = clockRadius * 0.9;
int keduDRadius = clockRadius * 0.85;
int keduXRadius = clockRadius * 0.95;
int hourRadius = clockRadius * 0.3;//时针半径
int minuteRadius = clockRadius * 0.5;//分针半径
int secondRadius = clockRadius * 0.7;//秒针半径

//CPen clockPen(PS_SOLID, 2, RGB(0,0,255));
CPen clockPen(PS_SOLID, 2, bpcolor);//配合下面的执行代码,使用自己定义的画笔来设置表盘的颜色
CPen * oldPen = pDC->SelectObject(&clockPen);//恢复到原来的画笔

//标注刻度
for(int i = 0; i< 12; i++)
{
pDC->MoveTo(centerX + keduDRadius * cos(i * 30 * PI / 180),
centerY + keduDRadius * sin(i * 30 * PI / 180));
pDC->LineTo(centerX + clockRadius * cos(i * 30 * PI / 180),
centerY + clockRadius * sin(i * 30 * PI / 180));
}

for(int j = 0; j< 60; j++)
{
pDC->MoveTo(centerX + keduXRadius * cos(j * 6 * PI / 180),//keduxradius是0.95,更加接近圆周,所以比起时针当然理所当然的更短
centerY + keduXRadius * sin(j * 6 * PI / 180));
pDC->LineTo(centerX + clockRadius * cos(j * 6 * PI / 180),
centerY + clockRadius * sin(j * 6 * PI / 180));
}
pDC->SelectObject(oldPen);

//调节时,分,秒针角度显示的关系
double secondRadians = m_second * 2 * PI / 60; //一个圆周是2pi,共有60秒,所以一秒是左边这个表达式,用的是弧度值
double minuteRadians = m_minute * 2 * PI / 60 + secondRadians / 60;//秒针每动一格,其效果等同于分针动1/60格
double hourRadians = m_hour * 2 * PI / 12 + minuteRadians*5 / 60;

//依照所计算的角度画出时,分,秒针
//CPen secondPen(PS_SOLID, 2, RGB(0,255,0));
CPen secondPen(PS_SOLID,2,secondcolor);
oldPen = pDC->SelectObject(&secondPen);
pDC->MoveTo(centerX , centerY);//时针的起点在中心
pDC->LineTo(centerX + double(secondRadius) * sin(secondRadians),
centerY - double(secondRadius) * cos(secondRadians));
pDC->SelectObject(oldPen);

//CPen minutePen(PS_SOLID, 4, RGB(255,255,0));
CPen minutePen(PS_SOLID, 4, minutecolor);
oldPen = pDC->SelectObject(&minutePen);
pDC->MoveTo(centerX , centerY);
pDC->LineTo(centerX + double(minuteRadius) * sin(minuteRadians),
centerY - double(minuteRadius) * cos(minuteRadians));
pDC->SelectObject(oldPen);

//CPen hourPen(PS_SOLID, 8, RGB(255,0,255));
CPen hourPen(PS_SOLID,8,hourcolor);
oldPen = pDC->SelectObject(&hourPen);
pDC->MoveTo(centerX , centerY);
pDC->LineTo(centerX + double(hourRadius) * sin(hourRadians),
centerY - double(hourRadius) * cos(hourRadians));
pDC->SelectObject(oldPen);

//画表盘中心
CBrush abrush(RGB(255,0,0));
CBrush * oldbrush = pDC->SelectObject(&abrush);
pDC->Ellipse(centerX - 8, centerY - 8 , centerX +8, centerY +8);//最左是圆心减8,最右是圆心加8
pDC->SelectObject(oldbrush);

//定义数字时钟的位置,显示当前时间
CRect dianzibiao(centerX-52,centerY*6/15, centerX+52,centerY);
CString shijian;
char temp1[3], temp2[3], temp3[3];
itoa(m_hour, temp1, 10);
itoa(m_minute, temp2, 10);//ITOA功能,把一整书转换为字符串,10进制
itoa(m_second, temp3, 10);
shijian.Insert(0, temp1);//temp1用来保存小时,temp2用来保存分钟,temp3用来保存秒

shijian += ":";//时和分之间的帽号
if(m_minute < 10)
{
shijian += "0";//如果分钟小于10,则在前面加上字符“0”,以用来显示 “07”、“08”之类的形式
}
shijian += temp2;
shijian += ":";
if(m_second < 10)
{
shijian += "0";//同理
}
shijian += temp3;

//完成数字时钟显示当前时间
pDC->SetBkMode (TRANSPARENT);
pDC->SetTextColor(RGB(255,0,0));
pDC->DrawText(shijian,&dianzibiao,DT_CENTER);//dianzibiao是一个矩形,shijian是我们转换后的cstring类型
//设置文本的字体大小,颜色
CString b("指针式时钟--赵建");
CFont abc;
abc.CreateFont(15, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_ULTRABOLD, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
b); // lpszFacename
CFont * oldFont = pDC->SelectObject(&abc);
pDC->SetTextColor(RGB(255,0,0));

CRect rectText1(centerX-52,centerY*3/2, centerX+52,centerY*2);
pDC->DrawText(b, &rectText1, DT_CENTER);

CString c("12");
CRect rectText2(centerX-8,centerY-keduDRadius*10/9+10, centerX+8,centerY-(keduDRadius*10/9-14)+10);
pDC->SetTextColor(RGB(255,0,0));
pDC->DrawText(c, &rectText2, DT_CENTER);

CString d("6");
CRect rectText3(centerX-5,centerY+(keduDRadius*10/9-14-10), centerX+5,centerY+keduDRadius*10/9-10);
pDC->DrawText(d, &rectText3, DT_CENTER);

CString e("9");
CRect rectText4(centerX-(keduDRadius*10/9-14)+10,centerY-7, centerX-keduDRadius*10/9+10,centerY+7);
pDC->DrawText(e, &rectText4, DT_CENTER);

CString f("3");
CRect rectText5(centerX+(keduDRadius*10/9-14)-10,centerY-7, centerX+keduDRadius*10/9-10,centerY+7);
pDC->DrawText(f, &rectText5, DT_CENTER);
pDC->SelectObject(oldFont);
//若定时时间到则提醒“时间到”
if((m_hour==hour)&&(m_minute==minute)&&(set==0))
{

PlaySound((LPCTSTR)IDR_WAVE1, AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC);
set=1;

}

//如果要求时钟暂停,则不调用OnTimer函数
if(flag&&flag2)
return;
//调用OnTimer函数
SetTimer(1,1000,NULL);//每1000毫秒产生一个消息,让ontimer响应
}

/////////////////////////////////////////////////////////////////////////////
// CShejiView printing

BOOL CShejiView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void CShejiView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void CShejiView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CShejiView diagnostics

#ifdef _DEBUG
void CShejiView::AssertValid() const
{
CView::AssertValid();
}

void CShejiView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

CShejiDoc* CShejiView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CShejiDoc)));
return (CShejiDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CShejiView message handlers

void CShejiView::OnBegin()
{
// TODO: Add your command handler code here
flag=0;//0为正常,表示时钟正常运行
flag2=1;//1为不正常,表示此时倒计时不工作
Invalidate();
}

void CShejiView::OnPause()
{
// TODO: Add your command handler code here
flag=1;
flag2=1;
KillTimer(1);//KillTimer:移除定时器函数的声明:移除先前用SetTimer设置的定时器。在定时器使用完毕后移除定时器时使用
Invalidate();
}

void CShejiView::OnSetback()
{
// TODO: Add your command handler code here
Csetback dia;
if(dia.DoModal()==IDOK)//如果点击"确认“(IDOK)之后,用输入的时间来代替系统本来的时间
{
m_hour=dia.m_hour;
m_minute=dia.m_minute;
m_second=dia.m_second;
flag2=0;

}
flag=1;
Invalidate();

}

void CShejiView::OnSettimer()
{
// TODO: Add your command handler code here
Cmydialog md;
md.m_shour=hour;
md.m_sminute=minute;
UpdateData(false);

if(md.DoModal()==IDOK)//如果Updatedata(TRUE),将控件的值赋值给成员变量;Updatedata(FALSE),将成员变量的值赋值给控件;
{
UpdateData(true);
hour=md.m_shour;
minute=md.m_sminute;
set=0;
}

}

void CShejiView::OnTimer(UINT nIDEvent) //OnTimer()函数是响应用SetTimer()函数设定的时钟发送的时钟消息的
//为类添加WM_TIMER消息响应,会看到类中多了个OnTimer(UINT nIDEvent)。
//然后用SetTimer(1,1000,NULL)就行了。第一个参数是ID,第二个是间隔时间,单位是毫秒,第3个是响应函数,因为要在OnTimer(UINT nIDEvent)里面做响应操作,所以此处给个NULL就行了
{
// TODO: Add your message handler code here and/or call default
//若为时钟状态则获取系统当前时间
if(flag==0)
{
CTime curtime = CTime::GetCurrentTime();
m_hour = curtime.GetHour();
m_minute = curtime.GetMinute();
m_second = curtime.GetSecond();
}
//若为倒计时状态则判断是否倒计时结束
if(flag2==0)
{
if(m_second||m_minute||m_hour)//如果时、分、秒不同时为零,则进行倒计时
{

if(m_second==0)//如果在时分秒不同时为零的情况下,秒为零,那么秒向分借60秒,如果此时分也恰好为零,则同时向时借60分,因为被秒借去60秒,所以分为59,hour减1
{ m_second=60;

if(m_minute==0)
{
m_minute=59;
m_hour--;
}
else
m_minute--;

}

m_second--;
}
else
{
AfxMessageBox("倒计时时间到");
flag2=1;
KillTimer(1);
}

}

Invalidate();
CView::OnTimer(nIDEvent);
}
void CShejiView::OnBpcolor()
{
// TODO: Add your command handler code here

CColorDialog ColorDlg; //创建调色板对象

ColorDlg.m_cc.Flags|=CC_FULLOPEN;

if(IDOK == ColorDlg.DoModal()) //将调色板实例化

{

bpcolor= ColorDlg.GetColor(); //获取选中的颜色

}
}

void CShejiView::OnHourcolor()
{
// TODO: Add your command handler code here
CColorDialog ColorDlg; //创建调色板对象

ColorDlg.m_cc.Flags|=CC_FULLOPEN;

if(IDOK == ColorDlg.DoModal()) //将调色板实例化

{

hourcolor= ColorDlg.GetColor(); //获取选中的颜色

}
}

void CShejiView::OnMinutecolor()
{
// TODO: Add your command handler code here
CColorDialog ColorDlg; //创建调色板对象

ColorDlg.m_cc.Flags|=CC_FULLOPEN;

if(IDOK == ColorDlg.DoModal()) //将调色板实例化

{

minutecolor= ColorDlg.GetColor(); //获取选中的颜色

}
}

void CShejiView::OnSecondcolor()
{
// TODO: Add your command handler code here
CColorDialog ColorDlg; //创建调色板对象

ColorDlg.m_cc.Flags|=CC_FULLOPEN;

if(IDOK == ColorDlg.DoModal()) //将调色板实例化

{

secondcolor= ColorDlg.GetColor(); //获取选中的颜色

}
}