程序最终运行界面:
实现步骤:
1.打开VC++6.0创建一个单文档,命名为Clock
2.通过类向导在视图类CClockView中添加WM_TIMER和WM_CREATE两个消息响应。
3.在视图类CClockView的OnDraw函数中添加如下代码:(记得添加一个头文件:#include <math.h>)
void CClockView::OnDraw(CDC* pDC)
{
CClockDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect rect;
GetClientRect(&rect);//获取客户区
//计算椭圆中心位置
int CenterX = rect.right/2;
int CenterY = rect.bottom/2;
//取当前时间
CTime Time = CTime::GetCurrentTime();
CString strTime;
int i,x,y;
CSize size;
//创建一只黄色的笔用来画椭圆
CPen pen(PS_SOLID,5,RGB(255,255,0));
//设置当前画笔并记下以前的画笔
CPen *pOldPen = pDC->SelectObject(&pen);
//绘制钟面椭圆
pDC->Ellipse(5,5,rect.right-5,rect.bottom-5);
double Radians;
//设置字体颜色为红色
pDC->SetTextColor(RGB(255,0,0));
for (i = 1; i <= 12; ++i)
{
strTime.Format("%d",i);//格式化钟点值
size = pDC->GetTextExtent(strTime,strTime.GetLength());
Radians = (double)i*2*3.14/12.0;//2π:计算弧度
//计算钟点放置位置
x = CenterX - (size.cx/2) + (int)((double)(CenterX - 20) * sin(Radians));
y = CenterY - (size.cy/2) - (int)((double)(CenterY - 20) * cos(Radians));
//绘制钟点
pDC->TextOut(x,y,strTime);
}
//计算时钟指针夹角
Radians = (double)Time.GetHour() + (double)Time.GetMinute()/60.0 +(double)Time.GetSecond()/3600.0;
Radians *= (2*3.14/12.0);//计算弧度
//创建时钟画笔
CPen HourPen(PS_SOLID,5,RGB(0,0,0));
pDC->SelectObject(&HourPen);
//绘制时钟指针
pDC->MoveTo(CenterX,CenterY);
pDC->LineTo(CenterX + (int)((double)(CenterX/3)*sin(Radians)),\
CenterY - (int)((double)(CenterY/3)*cos(Radians)));
/*******************************/
//计算分钟指针夹角
Radians = (double)Time.GetMinute() +(double)Time.GetSecond()/60.0;
Radians *= (2*3.14/60.0);//计算弧度
//创建分钟画笔
CPen MinutePen(PS_SOLID,3,RGB(0,0,255));
pDC->SelectObject(&MinutePen);
//绘制分钟指针
pDC->MoveTo(CenterX,CenterY);
pDC->LineTo(CenterX + (int)((double)(CenterX*1/2)*sin(Radians)),\
CenterY - (int)((double)(CenterY*1/2)*cos(Radians)));
/*******************************/
//计算秒钟指针夹角
Radians = (double)Time.GetSecond();
Radians *= (2*3.14/60.0);//计算弧度
//创建秒钟画笔
CPen SecondPen(PS_SOLID,2,RGB(255,0,0));
pDC->SelectObject(&SecondPen);
//绘制秒钟指针
pDC->MoveTo(CenterX,CenterY);
pDC->LineTo(CenterX + (int)((double)(CenterX*7/8)*sin(Radians)),\
CenterY - (int)((double)(CenterY*7/8)*cos(Radians)));
/*****************************/
pDC->SelectObject(pOldPen);
}
4.在刚才响应的那两个消息中添加如下代码:
int CClockView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//设置定时器,1秒发送一次消息
SetTimer(1,1000,NULL);
return 0;
}
void CClockView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
InvalidateRect(NULL,TRUE);
UpdateWindow();//刷新窗口
CView::OnTimer(nIDEvent);
}
5.如果你还想美化一下界面:
1)看下面写注释哪行代码,设置窗口名字
BOOL CClockApp::InitInstance()
{
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
LoadStdProfileSettings(); // Load standard INI file options (including MRU)
// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CClockDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CClockView));
AddDocTemplate(pDocTemplate);
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
m_pMainWnd->SetWindowText("指针式时钟 V1.0");//标题栏命名
return TRUE;
}
2)看写注释的那两行代码,设置窗口宽度和高度
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.cx = 800;//界面宽度
cs.cy = 600;//界面高度
return TRUE;
}
3)看写注释的那3行代码,菜单、状态栏、工具条
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
SetMenu(NULL);//隐藏菜单
ShowControlBar(&m_wndToolBar,FALSE,FALSE);//隐藏工具条
ShowControlBar(&m_wndStatusBar,FALSE,FALSE);//隐藏状态栏
return 0;
}
6.然后,打开工程目录下面的res文件夹,将里面的Clock.ico图片用自己准备好的Logo替换掉。
附录:
中心位于点 的主轴平行于 x 轴的椭圆由如下方程指定
- .
这个椭圆可以参数化表达为
这里的 可以限制于区间 。
全部代码下载地址:链接:http://pan.baidu.com/s/1hqt9K4s 密码: ux71
转载请保留原文地址:http://blog.csdn.net/nonknown/article/details/17677723