基于MFC画时钟防闪烁通用

来源:互联网 发布:织梦 资讯新闻类 模板 编辑:程序博客网 时间:2024/06/07 18:16

先了解双缓冲理论防闪烁,可以参考此文:http://blog.csdn.net/skykingf/article/details/20632125  

基于单文档的

修改CChildView.h和CChildView.cpp即可

CChildView.h

// ChildView.h : CChildView 类的接口//#pragma once// CChildView 窗口class CChildView : public CWnd{// 构造public:CChildView();// 属性public:// 操作public:// 重写protected:virtual BOOL PreCreateWindow(CREATESTRUCT& cs);// 实现public:virtual ~CChildView();CDCm_memDC;CBitmap     m_memBmp;CRectm_rtClient;    // 生成的消息映射函数protected:afx_msg void OnPaint();DECLARE_MESSAGE_MAP()public:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnTimer(UINT_PTR nIDEvent);afx_msg void OnSize(UINT nType, int cx, int cy);afx_msg BOOL OnEraseBkgnd(CDC* pDC);};


CChildView.cpp

// ChildView.cpp : CChildView 类的实现//#include "stdafx.h"#include "DoClock.h"#include "ChildView.h"#include <math.h>#ifdef _DEBUG#define new DEBUG_NEW#endif// CChildViewCChildView::CChildView(){}CChildView::~CChildView(){}BEGIN_MESSAGE_MAP(CChildView, CWnd)ON_WM_PAINT()ON_WM_CREATE()ON_WM_TIMER()ON_WM_SIZE()ON_WM_ERASEBKGND()END_MESSAGE_MAP()// CChildView 消息处理程序BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) {if (!CWnd::PreCreateWindow(cs))return FALSE;cs.dwExStyle |= WS_EX_CLIENTEDGE;cs.style &= ~WS_BORDER;cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);return TRUE;}void CChildView::OnPaint() {CPaintDC dc(this); // 用于绘制的设备上下文// TODO: 在此处添加消息处理程序代码// 不要为绘制消息而调用 CWnd::OnPaint()m_memDC.FillSolidRect(m_rtClient,RGB(255,255,255));    //填充背景色//1.画圆部分      CPen CirclePen(PS_SOLID, 1, RGB(0,255,0));   CPen * pOldPen   = m_memDC.SelectObject(&CirclePen);   CRect rtCircle;   GetClientRect(&rtCircle);   int nWidth       = min(rtCircle.Width(),rtCircle.Height());   //获取最小宽度   int nRadius      = nWidth/2; //获取最小半径   CPoint ptCenter  = rtCircle.CenterPoint();   rtCircle.left    = ptCenter.x - nRadius;                      //获取左上顶点x   rtCircle.top     = ptCenter.y - nRadius;                      //获取左上顶点y   rtCircle.right   = rtCircle.left + nWidth;                    //获取右下角x   rtCircle.bottom  = rtCircle.top + nWidth; //获取右下角y    m_memDC.Ellipse(rtCircle);   // 2.刻度部分   CPoint ptBig, ptSmall;   double fpi_6     = 3.1415926 * 2 / 12;       double fpi_60    = 3.1415926 * 2 / 60;   for(int i = 0; i < 12; i++)   {   ptBig.x   = ptCenter.x + (int)((double)nRadius * cos(fpi_6 * i));   ptBig.y   = ptCenter.y + (int)((double)nRadius * sin(fpi_6 * i));      ptSmall.x = ptCenter.x + (int)((double)0.8f * nRadius * cos(fpi_6 * i));   ptSmall.y = ptCenter.y + (int)((double)0.8f * nRadius * sin(fpi_6 * i));   m_memDC.MoveTo(ptSmall);   m_memDC.LineTo(ptBig);   }   for(int i = 0; i < 60; i++)   {   ptBig.x   = ptCenter.x + (int)((double)nRadius * cos(fpi_60 * i));   ptBig.y   = ptCenter.y + (int)((double)nRadius * sin(fpi_60 * i));   ptSmall.x = ptCenter.x + (int)((double)0.9f * nRadius * cos(fpi_60 * i));   ptSmall.y = ptCenter.y + (int)((double)0.9f * nRadius * sin(fpi_60 * i));   m_memDC.MoveTo(ptSmall);   m_memDC.LineTo(ptBig);   }      //3.钟表指针部分        CTime Time = CTime::GetCurrentTime();           //获取当前时间CString strTime;        //计算时间走动角度        double fpi_h = (double)Time.GetHour() + (double)Time.GetMinute()/60.0 +(double)Time.GetSecond()/3600.0;         fpi_h *= (2*3.1415926 / 12.0);CPen HourPen(PS_SOLID,5,RGB(0,0,0));m_memDC.SelectObject(&HourPen);//绘画时钟指针CPoint ptHour;ptHour.x = ptCenter.x + (int)((double)nRadius * 0.6 * sin(fpi_h));ptHour.y = ptCenter.y - (int)((double)nRadius * 0.6 * cos(fpi_h));m_memDC.MoveTo(ptCenter);m_memDC.LineTo(ptHour);//分针指针走动 double fpi_m = (double)Time.GetMinute() + (double)Time.GetSecond()/60.0;fpi_m *= (2*3.1415926 / 60.0);CPen MinutePen(PS_SOLID,3,RGB(125,125,125));m_memDC.SelectObject(&MinutePen);//绘画分针指针CPoint ptMinute;ptMinute.x = ptCenter.x + (int)((double)nRadius * 3/4 * sin(fpi_m));ptMinute.y = ptCenter.y - (int)((double)nRadius * 3/4 * cos(fpi_m));m_memDC.MoveTo(ptCenter);m_memDC.LineTo(ptMinute);//计算秒针走动double fpi_s = (double)Time.GetSecond();fpi_s *= (2*3.1415926 / 60.0);CPen SecondPen(PS_SOLID,1,RGB(0,168,120));m_memDC.SelectObject(&SecondPen);        //绘画分针指针CPoint ptSecond;ptSecond.x = ptCenter.x + (int)((double)nRadius* 7/8 * sin(fpi_s));ptSecond.y = ptCenter.y - (int)((double)nRadius* 7/8 * cos(fpi_s));m_memDC.MoveTo(ptCenter);m_memDC.LineTo(ptSecond);        //该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。dc.BitBlt(0,0,m_rtClient.Width(),m_rtClient.Height(),&m_memDC,0,0,SRCCOPY);  }int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CWnd::OnCreate(lpCreateStruct) == -1)return -1;// TODO:  Add your specialized creation code hereGetClientRect(&m_rtClient);CPaintDC dc(this); // 用于绘制的设备上下文//该函数创建一个与指定设备兼容的内存设备上下文环境(DC)。//通过GetDc()获取的HDC直接与相关设备沟通,而本函数创建的DC,//则是与内存中的一个表面相关联m_memDC.CreateCompatibleDC(&dc);//函数功能:该函数创建与指定的设备环境相关的设备兼容的位图。m_memBmp.CreateCompatibleBitmap(&dc,m_rtClient.Width(),m_rtClient.Height());m_memDC.SelectObject(&m_memBmp);    SetTimer(10,1000,NULL);return 0;}void CChildView::OnTimer(UINT_PTR nIDEvent){// TODO: Add your message handler code here and/or call default        CWnd::OnTimer(nIDEvent);Invalidate(TRUE);}void CChildView::OnSize(UINT nType, int cx, int cy){CWnd::OnSize(nType, cx, cy);// TODO: Add your message handler code hereCPaintDC dc(this);  //用于绘制的设备上下文GetClientRect(&m_rtClient);if (m_memBmp.m_hObject){m_memBmp.DeleteObject();}m_memBmp.CreateCompatibleBitmap(&dc,m_rtClient.Width(),m_rtClient.Height());m_memDC.SelectObject(&m_memBmp);}BOOL CChildView::OnEraseBkgnd(CDC* pDC){// TODO: Add your message handler code here and/or call defaultreturn(FALSE);    //防闪烁代码return CWnd::OnEraseBkgnd(pDC);}

感谢张治国老师的认真指导!


0 0
原创粉丝点击