mfc时钟
MFC时钟教程

一、表盘设置模块1、设计表盘设置对话框:IDD_SET_SCALE,生成ScaleSetDlg类圆形ID:IDC_ELLIPSE;方形:IDC_RECT;菱形:IDC_RHOMBUS;三角形:IDC_TRIANGLE选择:IDC_OTHER反色:IDC_O金色:IDC_GLOD确定:IDOK;取消:IDCANCLE2、为圆形单选按钮通过类向导添加关联变量IDC_ELLIPSE:int m_type;反色IDC_O:int m_logColor为类添加一个颜色变量COLORREF m_color;3、重载Onpaint()函数:当windows或应用程序请求重画应用程序窗口的一部分时,调用该函数。
void ScaleSetDlg::OnPaint(){CPaintDC dc(this);//设备上下文环境描述符CPen penBorder(PS_SOLID, 1, RGB(255, 255, 255));//白色画笔CPen *ppenOld = dc.SelectObject(&penBorder);//将白色画笔选入设备CBrush brPoint(m_color);//刻度颜色的画刷CBrush* pbrOld = dc.SelectObject(&brPoint);//将刻度颜色的画刷选入设备CRect rectLogcolor;GetDlgItem(IDC_OTHER)->GetWindowRect(&rectLogcolor);//获取空间相对于屏幕位置ScreenToClient(rectLogcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectLogcolor.left + 5, rectLogcolor.top - 25, rectLogcolor.right - 5, rectLogcolor.bottom - 15), &brPoint);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}4 为选择按钮添加OnOther()void ScaleSetDlg::OnBnClickedOther(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;//CColorDiaDlg里面含有CHOOSECOLOR结构体,而该结构体中的rgbResult含有用户选择的颜色值dlg.m_cc.Flags |= CC_RGBINIT;//颜色对话框,CC_RGBINIT让对话框默认使用由rgbResult指定的颜色dlg.m_cc.rgbResult = m_color;//对话框属性if (IDOK == dlg.DoModal())//CColorDiaDlg::DoModal():返回值为IDOK或IDCANCLE{m_color = dlg.m_cc.rgbResult;//获取用户输入的颜色值Invalidate();}}二、表盘的绘制模块1:创建CClockScale类,添加变量:#include"DeskClock.h"#include <math.h>#define PI 3.1415926COLORREF m_color;//刻度颜色int m_logColor;CPoint m_ptMiddle;//表盘的中心点UINT m_nPointWidth;//表盘刻度之间的宽度MAJORTYPE m_style;//刻度的样式void SetScaleStyle(MAJORTYPE type);void SetScaleColor(COLORREF colorref);void SetLogColor(int color);MAJORTYPE GetScaleStyle();COLORREF GetScaleColor();int GetLogColor();在stdafx.h中定义枚举类型变量:enum MAJORTYPE{TYPE_ELLIPSE = 0,//圆形TYPE_RECT=1,//方形TYPE_RHOMBUS=2,//菱形TYPE_TRIANGLE=3//三角形};2,构造函数:m_color = 0xFF0000;m_style = TYPE_RHOMBUS;m_logColor = 0;3,为所有属性生成set 和get方法在.h中先声明方法:void CClockScale::SetScaleStyle(MAJORTYPE type){m_style = type;}void CClockScale::SetScaleColor(COLORREF colorref) {m_color = colorref;}void CClockScale::SetLogColor(int color){m_logColor = color;}MAJORTYPE CClockScale::GetScaleStyle(){return m_style;}COLORREF CClockScale::GetScaleColor(){return m_color;}int CClockScale::GetLogColor(){return m_logColor;}4,添加位图资源,IDB_LOG, IDB_LOGMASK编写表盘绘制函数void DrawScale(CDC *pDC, CPoint &ptMiddle);void CClockScale::DrawScale(CDC *pDc,CPoint &ptMiddle) {//计算钟面的中心位置m_ptMiddle.x = ptMiddle.x;m_ptMiddle.y = ptMiddle.y;if (m_ptMiddle.y < 0){m_ptMiddle.y = 0;}//计算钟面的半径UINT nRidius = min(m_ptMiddle.x,m_ptMiddle.y);//计算两个刻度之间的距离m_nPointWidth = (int)nRidius/20;// 绘制LOGCBitmap maskbmp,logbmp;maskbmp.LoadBitmap(IDB_LOGMASK);logbmp.LoadBitmap(IDB_LOG);CDC MaskDC,memDC;MaskDC.CreateCompatibleDC(pDc);MaskDC.SelectObject(&maskbmp);memDC.CreateCompatibleDC(pDc);memDC.SelectObject(&logbmp);if(m_nPointWidth > 8){if(m_logColor == 0 ){pDc->BitBlt(m_ptMiddle.x - 25 ,ptMiddle.y - nRidius * 0.7,96,96,&MaskDC,0,0,SRCAND);//该函数对指定的源设备环境区域中的像素进行位块转换,以传送到目标设备环境pDc->BitBlt(m_ptMiddle.x - 25,ptMiddle.y - nRidius * 0.7,96,96,&memDC,0,0,MERGEPAINT);}else if(m_logColor == 1 ){pDc->BitBlt(m_ptMiddle.x - 25 ,ptMiddle.y - nRidius * 0.7,96,96,&MaskDC,0,0,MERGEPAINT);pDc->BitBlt(m_ptMiddle.x - 25,ptMiddle.y - nRidius * 0.7,96,96,&memDC,0,0,SRCAND);}}if (m_nPointWidth < 2){m_nPointWidth = 2;}//保存各个刻度点的位置CPoint ptFace;//设置刻度点的颜色CBrush brPoint(m_color);CBrush* pbrOld = pDc->SelectObject(&brPoint);//刻度所在的圆半径为钟面半径的90%int nFaceLength = MulDiv(nRidius,9,10);//绘制各个刻度for (int nMin=0; nMin<60; nMin++){//bHour为假表示绘制的是分钟刻度BOOL bHour = FALSE;//计算一个刻度点的位置ptFace = ComputerFacePoint(nMin,nFaceLength);//当分钟数是5的倍数时,bHour为真表示绘制小时刻度if (nMin%5==0){bHour = true;}//绘制一个刻度点DrawFacePoint(pDc,ptFace,bHour);}pDc->SelectObject(pbrOld);return;}5,编写计算刻度函数CPoint ComputerFacePoint(UINT min, int nFaceLength)CPoint CClockScale::ComputerFacePoint(UINT min, int nFaceLength){CPoint ptCalc;//将分钟转换为角度数double fDegrees = 180+((15+min)%60)*6;//再转换为弧度数double fAngle = fDegrees/180;//计算刻度点位置ptCalc.x = m_ptMiddle.x + (int)(cos(fAngle*PI)*nFaceLength);ptCalc.y = m_ptMiddle.y + (int)(sin(fAngle*PI)*nFaceLength);//返回刻度点位置return(ptCalc);}6,编写刻度绘制函数void DrawFacePoint(CDC *pDC, const CPoint &ptFace, BOOL bMajor)void CClockScale::DrawFacePoint(CDC *pDC, const CPoint &ptFace, BOOL bMajor){CRect rectPoint(ptFace.x,ptFace.y,ptFace.x,ptFace.y);//绘制小时刻度点if (bMajor){//增加高度和宽度,使单点变为小的矩形区rectPoint.InflateRect((m_nPointWidth/2)+2,(m_nPointWidth/2)+2);DrawMajor(pDC, m_style,rectPoint);}//绘制分钟刻度点else{//只有当刻度点之间的距离足够大时才绘制if (m_nPointWidth > 2){rectPoint.InflateRect(1,1);pDC->Draw3dRect(&rectPoint,GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(CO LOR_BTNSHADOW));//COLOR_BTNHIGHLIGHT表示加亮区,COLOR_BTNSHADOW表示按钮的3d阴影}}return;}7,编写表盘小时刻度函数void DrawMajor(CDC *pDC, MAJORTYPE type, CRect rectPoint)void CClockScale::DrawMajor(CDC *pDC, MAJORTYPE type, CRect rectPoint)CPen *oldPen;CPoint ptRhombus[4] ;CPen penBorder(PS_SOLID,1,RGB(255,255,255));switch(type){case TYPE_ELLIPSE:pDC->Ellipse(rectPoint);break;case TYPE_RECT:pDC->Rectangle(&rectPoint);pDC->Draw3dRect(&rectPoint,GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(CO LOR_BTNSHADOW));break;case TYPE_RHOMBUS:oldPen = pDC->SelectObject(&penBorder);ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[1].y = rectPoint.top;ptRhombus[0].x = rectPoint.left;ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;ptRhombus[3].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[3].y = rectPoint.bottom;ptRhombus[2].x = rectPoint.right;ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;pDC->Polygon(ptRhombus,4);pDC->SelectObject(oldPen);break;case TYPE_TRIANGLE:oldPen = pDC->SelectObject(&penBorder);ptRhombus[0].x = rectPoint.left;ptRhombus[0].y = rectPoint.top + rectPoint.Height()/2;ptRhombus[1].x = rectPoint.left + rectPoint.Width()/2;ptRhombus[1].y = rectPoint.top;ptRhombus[2].x = rectPoint.right;ptRhombus[2].y = rectPoint.top + rectPoint.Height()/2;pDC->Polygon(ptRhombus,3);pDC->SelectObject(oldPen);break;}}三:表针模块的设计与实现:1设计对话框IDD_SET_HAND,生成HandSetDlg类时针边框颜色选择:IDC_HBCOLOR指针颜色:IDC_HCOLOR分针边框:IDC_MBCOLOR,指针:IDC_MCOLOR秒针:IDC_SBCOLOR2,为对话框类添加变量:COLORREF m_HbordColor; // 时针边框颜色COLORREF m_HColor;//时针实体颜色COLORREF m_MbordColor;//分针边框颜色COLORREF m_MColor;//分针实体颜色COLORREF m_SbordColor;//秒针颜色3,重载OnPaint()void HandSetDlg::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: 在此处添加消息处理程序代码// 不为绘图消息调用 CDialog::OnPaint()CPen penBorderH(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorderH);//绘制时针边框颜色CBrush brPointH(m_HbordColor);CBrush* pbrOld = dc.SelectObject(&brPointH);CRect rectHbcolor;GetDlgItem(IDC_HBCOLOR)->GetWindowRect(&rectHbcolor);//获取空间相对于屏幕位置ScreenToClient(rectHbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectHbcolor.left+5,rectHbcolor.top-25,rectHbcolor.right-5,rectHbc olor.bottom-15),&brPointH);//绘制时针实体颜色CBrush brH(m_HColor);dc.SelectObject(&brH);CRect rectHcolor;GetDlgItem(IDC_HCOLOR)->GetWindowRect(&rectHcolor);//获取空间相对于屏幕位置ScreenToClient(rectHcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectHcolor.left + 5, rectHcolor.top - 28, rectHcolor.right - 5, rectHcolor.bottom - 18), &brH);//绘制分针边框颜色CBrush brPointM(m_MbordColor);dc.SelectObject(&brPointM);CRect rectMbcolor;GetDlgItem(IDC_MBCOLOR)->GetWindowRect(&rectMbcolor);//获取空间相对于屏幕位置ScreenToClient(rectMbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectMbcolor.left + 5, rectMbcolor.top - 28, rectMbcolor.right - 5, rectMbcolor.bottom - 18), &brPointM);//绘制分针实体颜色CBrush brM(m_MColor);dc.SelectObject(&brM);CRect rectMcolor;GetDlgItem(IDC_MCOLOR)->GetWindowRect(&rectMcolor);//获取空间相对于屏幕位置ScreenToClient(rectMcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectMcolor.left + 5, rectMcolor.top - 28, rectMcolor.right - 5, rectMcolor.bottom - 18), &brM);//绘制秒针颜色CBrush brS(m_SbordColor);dc.SelectObject(&brS);CRect rectSbcolor;GetDlgItem(IDC_SBCOLOR)->GetWindowRect(&rectSbcolor);//获取空间相对于屏幕位置ScreenToClient(rectSbcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectSbcolor.left + 5, rectSbcolor.top - 28, rectSbcolor.right - 5, rectSbcolor.bottom - 18), &brM);//恢复设备对象dc.SelectObject(ppenOld);dc.SelectObject(pbrOld);}4,为颜色选择对话框添加处理函数:void HandSetDlg::OnBnClickedHbcolor(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;//颜色对话框dlg.m_cc.Flags |= CC_RGBINIT;//颜色对话框属性dlg.m_cc.rgbResult = m_HbordColor;//当前指针边框颜色显示到颜色对话框上if (IDOK == dlg.DoModal())//显示颜色对话框{m_HbordColor = dlg.m_cc.rgbResult;//获取用户选择的颜色Invalidate();//重绘界面}// TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedHcolor(){// TODO: Add your control notification handler code hereCColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_HColor;if (IDOK == dlg.DoModal()){m_HColor = dlg.m_cc.rgbResult;Invalidate();} // TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedMbcolor(){CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_MbordColor;if (IDOK == dlg.DoModal()){m_MbordColor = dlg.m_cc.rgbResult;Invalidate();} // TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedMcolor(){CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_MColor;if (IDOK == dlg.DoModal()){m_MColor = dlg.m_cc.rgbResult;Invalidate();}//TODO: 在此添加控件通知处理程序代码}void HandSetDlg::OnBnClickedSbcolor(){// TODO: 在此添加控件通知处理程序代码CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_SbordColor;if (IDOK == dlg.DoModal()){m_SbordColor = dlg.m_cc.rgbResult;Invalidate();}四:表针绘制模块:1,创建CClockHand类,添加变量和函数声明:CPoint m_ptMiddle;// 圆心UINT m_nPointWidth;//刻度之间的宽度double m_nRidius;//表盘半径COLORREF m_HbordColor;//时针边框颜色COLORREF m_HColor;//时针实体颜色COLORREF m_MbordColor;//分针边框颜色COLORREF m_MColor;//分针实体颜色COLORREF m_SbordColor;//秒针颜色void SetHandColor(COLORREF hBColor, COLORREF hColor, COLORREF mBColor, COLORREF mColor, COLORREF sColor);void GetHandColor(COLORREF &hBColor, COLORREF &hColor, COLORREF &mBColor, COLORREF &mColor, COLORREF &sColor);void GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand, CTime oTime);void DrawHand(CDC*pDC, int nValue, HANDTYPE typeHand, CPoint&ptMiddle, CTime oTime); 2,在stdAfx.h中定义HANDTYPEenum HANDTYPE{HOUR_HAND,MINUTE_HAND,SECOND_HAND};3,编写构造函数:CClockHand::CClockHand(): m_ptMiddle(0){m_HbordColor = RGB(255, 255, 255);m_HColor = RGB(128, 128, 0);m_MbordColor = RGB(255, 255, 255);m_MColor = RGB(0, 128, 128);m_SbordColor = RGB(255, 128, 128);}4,编写Set和Get方法void CClockHand::SetHandColor(COLORREF hBColor, COLORREF hColor, COLORREF mBColor, COLORREF mColor, COLORREF sColor){m_HbordColor = hBColor;m_HColor = hColor;m_MbordColor = mBColor;m_MColor = mColor;m_SbordColor = sColor;}void CClockHand::GetHandColor(COLORREF &hBColor, COLORREF &hColor, COLORREF &mBColor, COLORREF &mColor, COLORREF &sColor){hBColor = m_HbordColor;hColor = m_HColor;mBColor = m_MbordColor;mColor = m_MColor;sColor = m_SbordColor;}5根据表针类型以及时间计算对应的表针的坐标的函数注意前面加#include “CClockScale.h”void GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand,CTime oTime);void CClockHand::GetHandPoints(int nValue, HANDTYPE typeHand, CPoint *pptHand,CTime oTime) {UINT nMinute = oTime.GetMinute();CClockScale Scale;Scale.m_ptMiddle.x = m_ptMiddle.x;Scale.m_ptMiddle.y = m_ptMiddle.y;int nLength = 0;//根据指针的类型区分switch(typeHand){case HOUR_HAND://时针长为钟面半径的一半nLength = MulDiv(m_nRidius, 50, 100);//因为绘制时针按照分针进行,故需要一些变换nValue *= 5;nValue += (nMinute/12);break;case MINUTE_HAND:nLength = MulDiv(m_nRidius, 70, 100);break;case SECOND_HAND:nLength = MulDiv(m_nRidius, 80, 100);break;default:ASSERT(false);}//得到时针和分针外形的四个点if (typeHand == HOUR_HAND || typeHand == MINUTE_HAND){pptHand[0] = puterFacePoint(nValue+30,m_nPointWidth*2);pptHand[1] = puterFacePoint(nValue+15,m_nPointWidth);pptHand[2] = puterFacePoint(nValue,nLength);pptHand[3] = puterFacePoint(nValue-15,m_nPointWidth);}//得到秒针的两个端点else{pptHand[0] = m_ptMiddle;pptHand[1] = puterFacePoint(nValue,nLength);}}6、编写绘制时针指针的函数:void DrawHand(CDC *pDC,int nValue,HANDTYPE typeHand,CPoint &ptMiddle,CTime oTime);void CClockHand::DrawHand(CDC *pDC, int nValue,HANDTYPE typeHand,CPoint &ptMiddle,CTime oTime){m_ptMiddle.x = ptMiddle.x;m_ptMiddle.y = ptMiddle.y;m_nRidius = min(m_ptMiddle.x,m_ptMiddle.y);m_nPointWidth = (int)m_nRidius/20;CPoint ptHand[4];//得到指针的位置GetHandPoints(nValue,typeHand,ptHand, oTime);CBrush brHandH(m_HColor);CPen penHandH(PS_SOLID,1,m_HbordColor);CBrush brHandM(m_MColor);CPen penHandM(PS_SOLID,1,m_MbordColor);CPen penrgb(PS_SOLID,1,m_SbordColor);switch(typeHand){case HOUR_HAND://设置画刷、画笔pDC->SelectObject(&brHandH);pDC->SelectObject(&penHandH);//绘制一个四边形pDC->Polygon(ptHand,4);break;case MINUTE_HAND://设置画刷、画笔pDC->SelectObject(&brHandM);pDC->SelectObject(&penHandM);//绘制一个四边形pDC->Polygon(ptHand,4);break;case SECOND_HAND:pDC->SelectObject(&penrgb);pDC->MoveTo(ptHand[0]);pDC->LineTo(ptHand[1]);break;}}五:数字时钟设置模块:1,设计对话框IDD_SET_NUMTIME:生成NumTimeSeTDlg类表盘内:IDC_IN ;表盘外:IDC_OUT;自定义:IDC_USER;表盘内位置:IDC_COMIN;外:IDC_COMOUTX坐标:IDC_COMX;Y坐标:IDC_COMY;定制...:IDC_COLOR;隐藏:IDC_HIDE;显示:IDC_SHOW;2,添加NumTimeSetDlg类,为控件添加关联变量:IDC_COMIN 类型:CComboBox 变量名:m_comIn;IDC_COMOUT 类型:CComboBox 变量名:m_comOutIDC_COMX;int m_x;IDC_COMY:int m_y;IDC_HIDE:int m_show;IDC_IN :int m_position;IDC_CHECK1:BOOL m_bgColor;添加控制状态的变量:int m_inType;//表盘b内位置int m_outType;//表盘外位置COLORREF m_color;//字体颜色3,添加初始化函数OnInitDiaLog()CDialog::OnInitDialog();// TODO: Add extra initialization herem_comIn.InsertString(0, _T("正上方"));m_comIn.InsertString(1, _T("正下方"));m_comIn.InsertString(2, _T("正左方"));m_comIn.InsertString(3, _T("正右方"));m_comIn.SetCurSel(m_inType);m_comOut.InsertString(0, _T("左上角"));m_comOut.InsertString(1, _T("右上角"));m_comOut.InsertString(2, _T("左下角"));m_comOut.InsertString(3, _T("右下角"));m_comOut.InsertString(4, _T("上侧居中"));m_comOut.InsertString(5, _T("下侧居中"));m_comOut.InsertString(6, _T("左侧居中"));m_comOut.InsertString(7, _T("右侧居中"));m_comOut.SetCurSel(m_outType);SetPositionEnable();return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE4,编写SetPositionEnable()单选位置函数void NumTimeSetDlg::SetPositionEnable(){switch(m_position){case 0:GetDlgItem(IDC_COMIN)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(false);GetDlgItem(IDC_COMX)->EnableWindow(false);GetDlgItem(IDC_COMY)->EnableWindow(false);break;case 1:GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(true);GetDlgItem(IDC_COMX)->EnableWindow(false);GetDlgItem(IDC_COMY)->EnableWindow(false);break;case 2:GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(false);GetDlgItem(IDC_COMX)->EnableWindow(true);GetDlgItem(IDC_COMY)->EnableWindow(true);break;}}5,为控件添加处理函数(1)void NumTimeSetDlg::OnIn(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);//获取用户选中状态,UpdateData(true):将控件的值赋值给成员变量,即从窗口编辑框中读取数据,若为false,将成员变量的值赋值给相关联的控件SetPositionEnable();//使能设置}(2)void NumTimeSetDlg::OnOut(){// TODO: Add your control notification handler code hereUpdateData(true);SetPositionEnable();}(3)void NumTimeSetDlg::OnUser(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}(4)void NumTimeSetDlg::OnSelchangeComin(){// TODO: Add your control notification handler code here m_inType = m_comIn.GetCurSel();}(5)void NumTimeSetDlg::OnSelchangeComout(){// TODO: Add your control notification handler code here m_outType = m_comOut.GetCurSel();}(6)void NumTimeSetDlg::OnColor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags|=CC_RGBINIT ;dlg.m_cc.rgbResult=m_color;if(IDOK==dlg.DoModal()){m_color = dlg.m_cc.rgbResult;Invalidate();}}(7)void NumTimeSetDlg::OnHide(){// TODO: Add your control notification handler code here UpdateData(true);}(8)void NumTimeSetDlg::OnShow(){// TODO: Add your control notification handler code here UpdateData(true);}6重写OnPaint()实现将字体颜色绘制到窗体上的功能:void NumTimeSetDlg::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCPen penBorder(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorder);CBrush brPoint(m_color);CBrush* pbrOld = dc.SelectObject(&brPoint);CRect rectcolor;GetDlgItem(IDC_COLOR)->GetWindowRect(&rectcolor);//获取空间相对于屏幕位置ScreenToClient(rectcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectcolor.left + 5, rectcolor.top - 25, rectcolor.right - 5, rectcolor.bottom - 15), &brPoint);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}六,数字时钟绘制模块:1,添加CClockNum类,添加变量:public:int m_inType;//表盘内的位置int m_outType;//表盘外的位置int m_position;//数字时钟位置类型int m_pType;/int m_X;//数字时钟横坐标int m_Y;//数字时钟纵坐标COLORREF m_color;//数字时钟的字体颜色bool m_bgColor;//数字时钟字体背景色2.编写构造函数:CClockNum::CClockNum(){m_position = 0;m_inType = 1;m_outType = 5;m_color = RGB(0, 255, 0);m_bgColor = false;}3,编写数字时钟绘制函数void DrawTime(CDC *pDc,CRect rectClient,CTime oTime);//绘制函数void CClockNum::DrawTime(CDC *pDc, CRect rectClient, CTime oTime){SetPosition(rectClient);UINT nHour, nMinute, nSecond;nHour = oTime.GetHour();nMinute = oTime.GetMinute();nSecond = oTime.GetSecond();CString strTime, strHour, strMinute, strSecond;strHour.Format(_T("%d"), nHour);if (nHour <10){strHour.Format(_T("0%d"), nHour);}strMinute.Format(_T("%d"), nMinute);if (nMinute <10){strMinute.Format(_T("0%d"), nMinute);}strSecond.Format(_T("%d"), nSecond);if (nSecond <10){strSecond.Format(_T("0%d"), nSecond);}strTime.Format(_T("%s : %s : %s"), strHour, strMinute, strSecond);pDc->SetTextColor(m_color);if (!m_bgColor){int nBKMode = pDc->SetBkMode(TRANSPARENT);//CDD::SetBkMode,若参数值为OPAQUE时去掉文字背景色,为TRANSPARENT去掉文字背景色pDc->TextOut(m_X, m_Y, strTime);pDc->SetBkMode(nBKMode);}else{pDc->TextOut(m_X, m_Y, strTime);}}4,编写设置数字时钟位置的函数:void SetPosition(CRect rectClient);//设置数字时钟位置的函数void CClockNum::SetPosition(CRect rectClient){CPoint ptMiddle;ptMiddle.x = rectClient.Width() / 2;ptMiddle.y = rectClient.Height() / 2 - 15;int nRidius = min(ptMiddle.x, ptMiddle.y);if (m_position == 0){ // 内部switch (m_inType){case 0: // 上m_X = ptMiddle.x - 35;m_Y = ptMiddle.y - nRidius * 0.7;break;case 1: // 下m_X = ptMiddle.x - 35;m_Y = ptMiddle.y + nRidius * 0.7;break;case 2: // 左m_X = ptMiddle.x - nRidius * 0.8 + 25;m_Y = ptMiddle.y;break;case 3: // 右m_X = ptMiddle.x + nRidius * 0.8 - 95;m_Y = ptMiddle.y;break;}}else if (m_position == 1){ // 外部switch (m_outType){case 0: // 左上角m_X = 22;m_Y = 10;break;case 1: // 右上角m_X = rectClient.right - 100;m_Y = 10;break;case 2: // 左下角m_X = 22;m_Y = rectClient.bottom - 30;break;case 3: // 右下角m_X = rectClient.right - 96;m_Y = rectClient.bottom - 30;break;case 4: // 上侧居中m_X = ptMiddle.x - 33;m_Y = 2;break;case 5: // 下侧居中m_X = ptMiddle.x - 33;m_Y = rectClient.bottom - 30;break;case 6: // 左侧居中m_X = 10;m_Y = ptMiddle.y;break;case 7: // 右侧居中m_X = rectClient.right - 86;m_Y = ptMiddle.y;break;}}}七,数字日期模块的设置:1,创建对话框IDD_SET_DATE;生成DateSetDlg类;左右分布:IDC_LEFT;上下分布:IDC_UP;表盘内:IDC_IN;表盘外:IDC_OUT日期颜色定制:IDC_DATECOLOR;星期颜色定制:IDC_WEEKCOLOR 隐藏:IDC_HIDE;显示:IDC_SHOW;2,为控件添加关联变量:IDC_COMIN:CComboBox m_comIn;IDC_COMOUT:CComboBox m_comOut;IDC_IN :int m_in;IDC_HIDE:int m_show;IDC_UP:int m_up;在.h文件下添加其余变量:COLORREF m_dColor; // 日期颜色COLORREF m_wColor; // 星期颜色int m_inType;int m_outType;3.添加初始化函数:BOOL DateSetDlg::OnInitDialog(){CDialog::OnInitDialog();m_comIn.InsertString(0, _T("正上方"));m_comIn.InsertString(1, _T("正下方"));m_comIn.InsertString(2, _T("正左方"));m_comIn.InsertString(3, _T("正右方"));m_comIn.SetCurSel(m_inType);m_comOut.InsertString(0, _T("左上角"));m_comOut.InsertString(1, _T("右上角"));m_comOut.InsertString(2, _T("左下角"));m_comOut.InsertString(3, _T("右下角"));m_comOut.SetCurSel(m_outType);SetPositionEnable();return TRUE;}4,编写SetPositionEnable()单选位置函数void SetPositionEnable();void DateSetDlg::SetPositionEnable(){if(m_up == 0){GetDlgItem(IDC_IN)->EnableWindow(false);GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_OUT)->EnableWindow(false);GetDlgItem(IDC_COMOUT)->EnableWindow(false);return;}if(m_in == 0){GetDlgItem(IDC_IN)->EnableWindow(true);GetDlgItem(IDC_COMIN)->EnableWindow(true);GetDlgItem(IDC_OUT)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(false);}elseGetDlgItem(IDC_IN)->EnableWindow(true);GetDlgItem(IDC_COMIN)->EnableWindow(false);GetDlgItem(IDC_OUT)->EnableWindow(true);GetDlgItem(IDC_COMOUT)->EnableWindow(true);}}5,为控件添加事件处理函数void DateSetDlg::OnUp(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnLeft(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnIn(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnOut(){// TODO: Add your control notification handler code here UpdateData(true);SetPositionEnable();}void DateSetDlg::OnDatecolor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_dColor;if (IDOK == dlg.DoModal())m_dColor = dlg.m_cc.rgbResult;Invalidate();}}void DateSetDlg::OnWeekcolor(){// TODO: Add your control notification handler code here CColorDialog dlg;dlg.m_cc.Flags |= CC_RGBINIT;dlg.m_cc.rgbResult = m_wColor;if (IDOK == dlg.DoModal()){m_wColor = dlg.m_cc.rgbResult;Invalidate();}}void DateSetDlg::OnSelchangeComIn(){// TODO: Add your control notification handler code here m_inType = m_comIn.GetCurSel();}void DateSetDlg::OnSelchangeComOut(){// TODO: Add your control notification handler code here m_outType = m_comOut.GetCurSel();}void DateSetDlg::OnShow(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);SetPositionEnable();}void DateSetDlg::OnHide(){// TODO: 在此添加控件通知处理程序代码UpdateData(true);SetPositionEnable();}6,重载OnPaint()void DateSetDlg::OnPaint(){CPaintDC dc(this); // device context for paintingCPen penBorder(PS_SOLID, 1, RGB(200, 200, 200));CPen *ppenOld = dc.SelectObject(&penBorder);CBrush brPoint(m_dColor);CBrush* pbrOld = dc.SelectObject(&brPoint);CRect rectDcolor;GetDlgItem(IDC_DATECOLOR)->GetWindowRect(&rectDcolor);//获取空间相对于屏幕位置ScreenToClient(rectDcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectDcolor.left + 5, rectDcolor.top - 25, rectDcolor.right - 5, rectDcolor.bottom - 15), &brPoint);CBrush brPointw(m_wColor);dc.SelectObject(&brPointw);CRect rectWcolor;GetDlgItem(IDC_WEEKCOLOR)->GetWindowRect(&rectWcolor);//获取空间相对于屏幕位置ScreenToClient(rectWcolor);//转化为对话框的相对位置dc.FillRect(CRect(rectWcolor.left + 5, rectWcolor.top - 25, rectWcolor.right - 5, rectWcolor.bottom - 15), &brPointw);dc.SelectObject(ppenOld);//恢复设备最初的画笔dc.SelectObject(pbrOld);//恢复设备最初的画刷}八、数字日期的绘制模块1、创建CClockDate类,添加变量:int m_inType;//在表盘内部的位置int m_outType;//在表盘外部的位置int m_position;//数字日期的位置bool m_bUp;//日期与星期的位置关系(上下还是左右)int m_DX;//日期的横坐标int m_DY;//日期的纵坐标int m_WX;//星期的横坐标int m_WY;//星期的纵坐标COLORREF m_dColor;//日期的字体颜色COLORREF m_wColor;//星期的字体颜色2.编写构造函数:CClockDate::CClockDate(){m_dColor = RGB(0,255,0);m_wColor = RGB(0,255,0);m_position = 0;m_inType = 1;m_outType = 1;m_bUp = false;}3,绘制数字时钟:DrawDate()void DrawDate(CDC *pDc, CRect rectClient,CTime oTime);void CClockDate::DrawDate(CDC *pDc, CRect rectClient, CTime oTime) {SetPosition(rectClient);/*UINT nYear, nMonth, nDay, nDayOfWeek;nYear = oTime.GetYear();nMonth = oTime.GetMonth();nDay = oTime.GetDay();CString strDate, strYear, strMonth, strDay, strDayOfWeek;strYear.Format(_T("%d"), nYear);strMonth.Format(_T("%d"), nMonth);if (nMonth <10){strMonth.Format(_T("0%d"), nMonth);}strDay.Format(_T("%d"), nDay);if (nDay <10){strDay.Format(_T("0%d"), nDay);}strDate.Format(_T("%s年%s月%s日"), strYear, strMonth, strDay);strDayOfWeek = weekDay(oTime);*/CString strDate = CTime::GetCurrentTime().Format("%Y年%m月%d日");CString strDayOfWeek = weekDay(oTime);int nBKMode = pDc->SetBkMode(TRANSPARENT);pDc->SetTextColor(m_dColor);pDc->TextOut(m_DX, m_DY, strDate);pDc->SetTextColor(m_wColor);pDc->TextOut(m_WX, m_WY, strDayOfWeek);pDc->SetBkMode(nBKMode);}4,计算星期几日期的位置计算函数:SetPosition()void SetPosition(CRect rectClient);void CClockDate::SetPosition(CRect rectClient){CPoint ptMiddle;ptMiddle.x = rectClient.Width()/2;ptMiddle.y = rectClient.Height()/2 - 15;int nRidius = min(ptMiddle.x,ptMiddle.y);if(!m_bUp){m_DX = ptMiddle.x + nRidius * 0.8 - 110;m_DY = ptMiddle.y + 20 ;m_WX = ptMiddle.x - nRidius * 0.8 + 35;m_WY = ptMiddle.y + 20 ;return;}if(m_position == 0){ // 内部switch(m_inType){case 0: // 上m_DX = ptMiddle.x - 46;m_DY = ptMiddle.y - nRidius * 0.7 + 50;m_WX = ptMiddle.x - 16;m_WY = ptMiddle.y - nRidius * 0.7 + 30;break;case 1: // 下m_DX = ptMiddle.x - 46;m_DY = ptMiddle.y + nRidius * 0.7 - 50;m_WX = ptMiddle.x - 16;m_WY = ptMiddle.y + nRidius * 0.7 - 30;break;case 2: // 左m_DX = ptMiddle.x - nRidius * 0.8 + 10;m_DY = ptMiddle.y + 50;m_WX = ptMiddle.x - nRidius * 0.8 + 45;m_WY = ptMiddle.y + 30 ;。
Visual_C++基于对话框的MFC应用程序【简单时钟】

1.1创建对话框的应用程序1.使用AppWizard创建应用程序框架首先,创建一个对话框应用程序,其工程文件名为:ch1.dsp。
具体步骤如下:(1)启动Visual C++6.0,在File菜单中选择new菜单项;(2)在new对话框的Project页中选择MFC AppWizard(exe)选项,在Project name框中输入:ch1,并在Location框中指定希望的目录路径,编译系统生成的各种文件将会存放在该目录下,然后点击[OK]按钮(3)MFC AppWizard-Step1中选择Dialog based选项,MFC AppWizard-Step2到MFC AppWizard-Step4中取默认选项;(4)进入VC对话框设计界面后,选中[TODO:在这里设置对话控制。
]静态框并按del键删除该框,选中[取消]按钮并按del键删除该按钮;(5)将[确认]按钮拖曳到对话框的下方中间。
生成的对话框设计窗口(如图1-1所示)。
图1-12.向类中添加系统消息响应函数Windows应用程序的采用事件触发、消息驱动机制和大量的消息响应函数构成了应用程序的主体。
本示例需要用到两个消息响应函数OnCtlColor()和OnTimer(),前者响应窗口消息:WM_CTLCOLOR,后者响应窗口消息:WM_TIMER。
关于这两个函数的功能和用法暂且略过,留待后面小节再叙。
这里先介绍响应函数加载的方法。
在CCh1Dlg类中添加OnCtlColor()函数的操作方法如下:(1)打开类向导(MFC ClassWizard)窗口,选择Message Maps 页;(2)选择工程、类和对象标识。
在Message Maps页的Project、Class name、Object Ids框中分别选择:ch1、CCh1Dlg、CCh1Dlg;(3)添加响应函数。
在Message Maps页的Messages框中选中并双击窗口消息:WM_CTLCOLOR,此时,消息WM_CTLCOLOR 的响应函数OnCtlColor()被添加到类向导底部Member Functions框中。
MFC获取系统当前时间

} SYSTEMTIME;
typedef struct _FILETIME {
DWORD dwLowDateTime; /* low 32 bits */
DWORD dwHighDateTime; /* high 32 bits */
原型:time_t GetTime( ) const;
(3)GetYear() 获取CTime对象代表的年。
原型:int GetYear( ) const;
以下(4)至(9)函数原型与GetYear()类似。
(4)GetMonth()获取CTime对象代表的月。
(5)GetDay() 获取CTime对象代表的日期。
MessageBox("今天是周日");
break;
case 2:
MessageBox("今天是周一");
break;
1.使用CTime类
CString str; //获取系统时间
CTime tm; tm=CTime::GetCurrentTime();
str=tm.Format("现在时间是%Y年%m月%d日 %X");
MessageBox(str,NULL,MB_OK);
例2:由年、月、日得到对应的周日。
CTime m_time(2001,2,5,12,0,0);
int weekday=m_time.GetDayOfWeek();
switch(weekday)
{
case 1:
//转化为CTime
CString strTime="2008-7-2 21:59:11";
计算机图形学 MFC VC++6.0制作的简单时钟源代码

// TODO: Add your command handler code here
Timer=1;
SetTimer(1,100,NULL);
}
void CMFCFrame1View::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
{
// dቤተ መጻሕፍቲ ባይዱfault preparation
return DoPreparePrinting(pInfo);
}
void CMFCFrame1View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
// CMFCFrame1View drawing
/////////////////////////////////////////////////////////////////////////////
// CMFCFrame1View printing
BOOL CMFCFrame1View::OnPreparePrinting(CPrintInfo* pInfo)
// CMFCFrame1View
IMPLEMENT_DYNCREATE(CMFCFrame1View, CView)
BEGIN_MESSAGE_MAP(CMFCFrame1View, CView)
//{{AFX_MSG_MAP(CMFCFrame1View)
ON_WM_CREATE()
MFC时钟日历设计

mfc课程设计报告课程名称:计算机程序设计实训题目:MFC时钟日历设计说明:1、报告中的第一、二、三项由学生在课程设计开始前填写,由指导教师指导并确认签字。
2、学生成绩由指导教师根据学生的设计情况给出各项分值及总评成绩,并填写成绩评定表。
3、所有学生必须参加课程设计的答辩环节,凡不参加答辩者,其成绩一律按不及格处理。
答辩小组成员应由2人及以上教师组成。
答辩后学生根据答辩情况填写答辩记录表。
4、报告正文字数一般应不少于3000字,也可由指导教师根据本门课程设计的情况另行规定。
5、平时表现成绩低于6分的学生,取消答辩资格,其该课程设计成绩按不及格处理。
6、课程设计完成后,由指导教师根据完成情况写出总结。
7、此表格式为徐州师范大学物理与电子工程学院提供的基本格式,指导教师可根据本门课程设计的特点及内容做适当的调整。
指导教师签字:年月日目录摘要 (II)Abstract (II)目录I1 课题背景 (1)1.1 背景、目的、意义、解决的主要问题及应达到的技术要求 (1)2 设计方案简述 (2)2.1 设计方案论证 (2)2.1.1设计流程图 (2)2.1.2 主要模块 (2)3 详细设计 (3)3.1 时钟的设计 (3)3.1.1 时钟组件的绘制 (3)3.2 日历的设计 (3)3.2.1 添加日历对话框 (3)3.2.2 日期的显示 (5)4 设计结果及分析 (8)4.1 设计结果 (8)4.1.1 时钟界面的实现结果 (8)4.1.2 日历的实现结果 (9)5 总结105.1问题与调试 (10)5.2 实验感想 (10)参考文献11附录主要程序代码 (12)摘要VisuslC++6.0提供了功能强大的MFC类库(MierosoftFoundationClass),MFC是一个很大的C++类层次结构。
其中封装了大量的类及其函数,很多Windows程序所共有的标准内容可以由MFC的类来提供,MFC类为这些内容提供了用户接口的标准实现方法,程序员所要做的就是通过预定义的接口把具体应用程序特有的东西填入这个轮廓,这将简化编程工作,大大的减少程序员编写的代码数量,使编程工作变得更加轻松容易。
MFC之模拟时钟

MFC之模拟时钟最近在学习MFC,程序设计⽼师布置”画板“和”模拟时钟“作为实验来实践,由于没去上课,⽹上搜索的很多教程⼏乎都是以VC6.0为基础的,⽽⾝边⼏乎都是VS2008以上,对于初学者来说,有时仿照VC6.0的教程在VS2008或更⾼的环境上难免会出现⼀些困难,特此将模拟时钟程序在VS2008环境下的开发过程总结如下:1.新建项⽬项⽬类型选择“MFC”,模板选择“MFC应⽤程序”,名称⾃拟,这⾥命名为”Clock"。
选择好以后效果如下:2.MFC应⽤程序向导设置选择“下⼀步"这⾥有两个更改,⼀是”应⽤程序类型”选择“基于对话框”,同时取消选中“使⽤Unicode库”。
完成以上两步之后,直接单击“完成”即可。
三、核⼼部分1.⾸先打开“类视图”,选择"CClockDlg"在该类的头⽂件中,找到如下代码:紧接着后⾯添加三个变量⽤于临时保存时间的秒、分、时。
int m_Sec, m_Min, m_Hour;插⼊后的效果如下:2.⼿动添加⼀个消息映射函数,完成时间的获取和指针的绘制。
在CClockDlg类的头⽂件中找到如下代码:在其中增加⼀⾏如下:afx_msg void OnTimer(UINT nIDEvent);增加后显⽰效果如下:接着在资源管理器中找到CClockDlg类的cpp⽂件来实现刚才的函数声明需要添加的代码如下:1void CClockDlg::OnTimer(UINT nIDEvent)2 {3// TODO: Add your message handler code here and/or call default4 CTime time = CTime::GetCurrentTime(); //获得系统时间5 m_Sec = time.GetSecond();6 m_Min = time.GetMinute();7 m_Hour = time.GetHour();89 CDC* pDC = GetDC();10 CRect rect;11 GetClientRect(&rect); //获取客户区域12 CBitmap bitmap; //定义图⽚类13 bitmap.LoadBitmap(IDB_BITMAP1); //加载位图14 CDC memdc; //定义临时画布15 memdc.CreateCompatibleDC(pDC); //创建画布16 memdc.SelectObject(&bitmap); //关联图⽚1718int x = rect.Width()/2;19int y = rect.Height()/2;2021 CPen MinutePen(PS_SOLID,2,RGB(0,0,0)); //设置分针画笔22 memdc.SelectObject(&MinutePen);23 memdc.MoveTo(x,y);24//绘制分针25 memdc.LineTo(x+(long)40*cos(PI/2-2*PI*m_Min/60.0),y-(long)40*sin(PI/2-2*PI*m_Min/60.0));26 CPen HourPen(PS_SOLID,3,RGB(0,0,0)); //设置时针画笔27 memdc.SelectObject(&HourPen);28 memdc.MoveTo(x,y);29//绘制时针30 memdc.LineTo(x+(long)30*cos(PI/2-2*PI*(5*m_Hour/60.0+m_Min/12.0/60.0))31 ,y-(long)30*sin(PI/2-2*PI*(5*m_Hour/60.0+m_Min/12.0/60.0)));32 CPen SecondPen(PS_SOLID,1,RGB(255,0,0)); //设置秒针画笔33 memdc.SelectObject(&SecondPen);34 memdc.MoveTo(x,y);35 memdc.LineTo(x+(long)50*cos(PI/2-2*PI*m_Sec/60.0),y-(long)50*sin(PI/2-2*PI*m_Sec/60.0));//绘制秒针36 memdc.MoveTo(x,y);37 memdc.LineTo(x+(long)10*cos(PI/2-2*PI*(m_Sec+30)/60.0),y-(long)10*sin(PI/2-2*PI*(m_Sec+30)/60.0));//绘制秒针38 SecondPen.DeleteObject();39 MinutePen.DeleteObject();40 HourPen.DeleteObject();41 pDC->BitBlt(0,0,rect.right,rect.bottom,&memdc,0,0,SRCCOPY); //复制图⽚42 memdc.DeleteDC(); //复制临时画布到预览窗⼝43 bitmap.DeleteObject(); //删除图⽚44 ReleaseDC(pDC);45 CDialog::OnTimer(nIDEvent);46 }3.设置时钟位图打开“资源视图”在“资源视图”中添加资源资源类型选择“Bitmap",然后选择”导⼊”,把实现准备好的BMP⽂件导⼊。
CMFC中定时器的使用

CMFC中定时器的使用MFC(Microsoft Foundation Class)是一套面向Windows平台的C++类库,它简化了Windows API的使用,并提供了一些常用的界面和功能组件。
MFC中的定时器允许开发人员在应用程序中设置一定的时间间隔,以执行特定的任务或更新界面。
本文将详细介绍MFC中定时器的使用方法。
在MFC中,定时器的创建和管理是通过CWnd类来实现的。
CWnd类是MFC中所有窗口类的基类,它封装了一些与窗口有关的函数和属性。
首先,需要在窗口类的头文件中添加响应的定时器消息映射:```cppclass CMyWnd : public CWndDECLARE_MESSAGE_MAPafx_msg void OnTimer(UINT_PTR nIDEvent);};```然后,在窗口类的源文件中添加消息映射的处理函数:```cppBEGIN_MESSAGE_MAP(CMyWnd, CWnd)ON_WM_TIMEREND_MESSAGE_MAPvoid CMyWnd::OnTimer(UINT_PTR nIDEvent)switch (nIDEvent)case 1://处理定时器1的逻辑break;case 2://处理定时器2的逻辑break;default:break;}CWnd::OnTimer(nIDEvent);```在窗口类的构造函数中,可以通过调用CWnd类的SetTimer函数来创建定时器:```cppCMyWnd::CMyWndSetTimer(1, 1000, NULL); // 创建ID为1的定时器,时间间隔为1000msSetTimer(2, 2000, NULL); // 创建ID为2的定时器,时间间隔为2000ms```在窗口类的析构函数中,需要调用CWnd类的KillTimer函数来销毁定时器:```cppCMyWnd::~CMyWndKillTimer(1); // 销毁ID为1的定时器KillTimer(2); // 销毁ID为2的定时器```通过上述代码,我们可以在窗口类中创建和管理多个定时器,并且可以在OnTimer函数中根据定时器的ID来处理相应的逻辑。
基于MFC的大屏幕数字时钟审批稿

基于M F C的大屏幕数字时钟YKK standardization office【 YKK5AB- YKK08- YKK2C- YKK18】大屏幕显示数字时钟设计姓名:谭X 指导教师:XXX专业:XXXXXXXXX 年级:20XX级摘要本设计基于MFC,M FC是提供的一条类库,是一种应用程序框架,随微软Visual C++开发工具发布,以C++类的形式封装了Windows的API,并且包含一个框架,以减少人员的工作量。
其中包含的类包含大量Windows句柄封装类和很多Windows的内建和组件的封装类。
MFC:微软基础类(Microsoft Foundation Classes),同VCL类似,是一种应用程序框架,随微软Visual C++开发工具发布。
目前最新版本为,并且发布了中文版。
该类库提供一组通用的可重用的类库供开发人员使用,大部分类均从CObject 直接或间接派生,只有少部分类例外。
MFC应用程序的总体结构通常由开发人员从MFC类派生的几个类和一个CWinApp类(应用程序对象)组成。
MFC 提供了MFC 自动生成框架。
Windows 应用程序中,MFC 的主包含文件为。
此外MFC的部分类为MFC/ 通用,可以在Win32 应用程序中单独包含并使用这些类。
由于它的易用性,初学者常误认为开发必须使用MFC,这种想法是错误的。
作为Application Framework,MFC的使用只能提高某些情况下的开发效率,只起到辅助作用,而不能替代整个Win32 程序设计。
关键字:MFC;大屏显示幕数字时钟;C++。
Large screen display digital clock designName:Chen Tan Tutor:Jijie BiMajor:Electronics and Communications Engineering Grade: 2013AbstractThis design is based on the MFC, MFC is Microsoft provides aclass library,is a kind of application framework,along with the Microsoft Visual c++development tools, in the form of c++class encapsulates the Windows API, and contains an application framework, in order to reduce the workload application to the class contains a large number of Windows which contains wrapper class and many Windows built-in controls and component wrapper class.MFC: Microsoft Foundation Classes (Microsoft Foundation Classes), with the VCL, is a kind of application framework, along with the Microsoft Visual c++development the latest version is , and release the Chinese class library provides a set of generic reusable class library for developers, most of the classification are directly or indirectly derived from CObject, only a few exceptions.The overall structure of the MFC applications usually derived by the developer from MFC class several classes and class a CWinApp object (the application object).MFC provides a MFC AppWizard framework automatically generated.Windows application, MFC master include file for .Also part of the MFC class for MFC/ATL general, can separate in the Win32 application contains and use these classes.Because of its ease of use, often mistaken for beginners vc++ evelopment must use MFC, this idea is an Application Framework, the use of MFC can only improve the efficiency of the development of some cases, only play a supplementary role, and does not replace the Win32 programming.Key words:MFC;Screen display digital clock;C++.第1章绪论MFC简介M FC(Microsoft Foundation Classes),是提供的一条类库(class libraries),以C++类的形式封装了Windows的API,并且包含一个框架,以减少人员的工作量。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我们可以从CStatic类(静态控件类)派生出类CClockEx来实 现时钟控件类,这样,就可以继承MFC静态控件的很多已经 具备的功能和特点。在建立新类的对话框中,按下图输入。
按Ctrl+W调出Class Wizard,在class name中选择刚才建立的新类CClockEx,然后 重载虚函数PreSubClassWindow,对时钟控件的基本初始化工作将在该函数中进行。 添加消息响应WM_PAINT,我们必须用自己完成时钟的绘制工作。 添加消息响应WM_SIZE,重载该消息响应以便我们的时钟控件能够自动适应其大小的变化。 为了时钟能够走动,我们得定时刷新时钟控件让它走动,还得添加WM_TIMER的消息响应。最终效果如下图所 示。
下面逐步实现各个类,首先实现各个组成类的基类—— CClockElement。同样,在ClassView的工程名上面点右 键,选择New Class,在ClassType里面选择Genenric Class,类CClockElement不需要从其它类派生,所以 Base Class可以不填,效果如下图所示。
续上页:
void CClockElement::SetTime(const CTime &tmCur) { m_tmCur = tmCur; } void CClockElement::SetColor(COLORREF crMain, COLORREF crOther) { m_crMain = crMain; m_crOther = crOther; }
应用程序框架设计过程(仅供参考)
打开VC++6.0,新建一个MFC工程,输入工程名,选 择“MFC AppWizard”如图所示,然后点击OK。
为简单起见,这里选择“Dialog based”程序,然 后可以直接选择finish了。
在类视图的工程名上右键单击,选择New Class(如 下图所示)来建立一个新类。
综合刚才这几点,CClockElement的实现的头文件代码如下:
#include <MATH.H> #define PI 3.1415926535 class CClockElement { public: void SetColor(COLORREF crMain, COLORREF crOther); void SetTime(const CTime &tmCur); void SetRegion(LPRECT lprcRect); virtual void Draw(CDC *pDC) = 0; CClockElement(); virtual ~CClockElement(); protected: COLORREF m_crMain; //主要颜色 COLORREF m_crOther; //辅助的其他颜色 CTime m_tmCur; //当前时刻 CRect m_rcRegion; //绘图区域 int m_nRadius; //时钟半径
到目前为止,时钟控件的轮廓和已经有了,下面考虑时钟绘 制的具体实现。 一个时钟大致可由时钟背景、时针、分针、秒针四个部分构 成。 以上的时钟四个部分可是看作四个不同的对象,可以考虑建 立类CClockBackground(背景)CClockHourHand(时针)、 CClockMinHand(分针)、CClockSecHand(秒针)来分别实 现。(此处为了意义明确,类名都比较长) 这四个类有它们的共同点,譬如都有自己的绘图函数,如果 要具体能够设置颜色,它们都应该有自己的绘图颜色,同样 应该有颜色设置函数,此外都有绘图区域和区域设置函数等 等。因此,可以为它们的共性建立一个基类,此处命名为 CClockElement(时钟元素)。
试 • 验三 面向对象程序设计实验
——一个简单的可复用时钟控件
本实验的开发环境
使用C++语言实现 使用VC++6.0集成开发环境开发 使用MFC应用程序开发框架
MFC版本简介
MFC全称Microsoft Foundation Classes. 1989年微软公司成立Application Framework技术团队, 开发C++面向对象工具给Windows应用程序开发人员 使用。这个小组即AFX小组,就是他们,开始了MFC的 开发历程。 微软公司于1992年4月推出C/C++7.0产品时,初次向 世人介绍了MFC 1.0,其32位版本也在1992年7月随着 Win32 SDK推出。 Visual C++1.0(也就是C/C++8.0)搭配MFC 2.0于 1993年3月推出。同年8月推出在Windows NT上的 Visual C++1.1 for Windows NT,搭配的是MFC 2.1。
CClockBackground只需实现基类的虚函数 Draw即可,因此这里重载基类的虚函数 Draw,其头文件实现代码如下:
#include "ClockElement.h" class CClockBackground : public CClockElement { public: CClockBackground(); virtual ~CClockBackground(); };
CClockBackground源文件代码如下:
CClockBackground源文件代码如下(续上页): //绘制60个小圆点,表示分针和秒针的刻度
CPoint ptCenter = m_rcRegion.CenterPoint(); int nRadius = m_nRadius - 8; for(int i=0; i<60; i++) { CPoint ptEnd = ptCenter; ptEnd.Offset((int)(nRadius * sin(2 * PI * (i % 60) / 60)), (int)(-nRadius * cos(2 * PI * (i % 60) / 60))); CRect rcDot(-2, -2, 2, 2); rcDot.OffsetRect(ptEnd); pDC->Ellipse(rcDot); } //绘制12个小方框,表示12个正点 pDC->SelectObject(&penMain); pOldBrush = pDC->SelectObject(&brOther); for(i=0; i<12; i++) { CPoint ptEnd = ptCenter; double fRadian = 2 * PI * (i % 12) / 12; ptEnd.Offset((int)(nRadius * sin(fRadian)), (int)(-nRadius * cos(fRadian))); CRect rcDot(-3, -3, 3, 3); rcDot.OffsetRect(ptEnd); pDC->Rectangle(rcDot); } //还原设备环境 pDC->SelectObject(pOldPen); pDC->SelectObject(pOldBrush);
试验设计目标
完成一个可重用的C++类,可以通过该类实现一个 简单的模拟时钟 编写一个简单的MFC程序测试验证这个时钟控件类 关于这个时钟控件,如果按照课件继续完善下去,请 将他做得更好更强大。比如说:可以考虑为时钟控件 的各项设置(如颜色)提供外部接口,供CClockEx的 使用者调用,可以考虑丰富背景绘制,加入背景图片 设置,在刻度上标上数字,为指针加上阴影效果,在 时钟上显示日期等。有兴趣的同学有空不妨试试。 Nhomakorabea
下面对类CClockElement的源代码进行编写。 因为在后面的绘图中需要用到sin和cos这两个数 学计算公式,因此需包含头文件<MATH.H>以便使 用数学函数库。为后面计算使用,还需定义数学 常量PI(3.1415926535)。 时钟的每个组成部分都有绘图区域区域,因此, 可在基类中定义绘图区域变量。同理,可以定义 颜色变量,为了是颜色不显得单调,这里为每个 控件设置两种颜色(如果想使程序更加绚丽,可 以设置更多颜色)。 对应的,这些变量需增加接口函数来进行访问。 对于每个组成部分都应该有的Draw函数,当然也 需在基类中定义,但是,该函数对于基类来说是 无需函数实现的,因此可定义为纯虚函数。
//设置颜色 //设置当前时间 //设置绘图区域 //绘图函数
CClockElement::CClockElement() { m_nRadius = 0; m_crMain = RGB(255, 255, 255); m_crOther = RGB(128, 128, 128); } CClockElement::~CClockElement() { }
微软在1993年12月又推出了16为的Visual C++ 1.5, 搭配 的是MFC 2.5。 1994年9月,微软推出Visual C++ 2.0,搭配MFC 3.0。 1995年1月,微软推在增加了MAPI和WinSock支持的基础上, 推出MFC 3.1。 1995年7月,MFC有了3.2版,这是一个小的改版。 然后就是1995年9月的32位版MFC 4.0。这个版本有了相当 大的改进。 1996年上半年又有了MFC4.1…… 时至今日MFC在Visual C++ 7.0中已经到了7.0版本。 我们常用的Visual C++6.0使用的是MFC 4.2版本。 微软正不断地为“为什么要使用MFC”加上各式各样地强 烈你有,并强烈导引它成为Windows程序设计的C++标准 界面。正如我们所看到的,越来越多的MFC程序出现了并 继续在产生。
CClockElement的实现的源文件关键代码如下: