MemDC.h

  1. #ifndef _MEMDC_H_
  2. #define _MEMDC_H_
  3. //////////////////////////////////////////////////
  4. // CMemDC - memory DC
  5. //
  6. // Author: Keith Rule
  7. // Email:  keithr@europa.com
  8. // Copyright 1996-1999, Keith Rule
  9. //
  10. // You may freely use or modify this code provided this
  11. // Copyright is included in all derived versions.
  12. //
  13. // History - 10/3/97 Fixed scrolling bug.
  14. //                   Added print support. - KR
  15. //
  16. //           11/3/99 Fixed most common complaint. Added
  17. //                   background color fill. - KR
  18. //
  19. //           11/3/99 Added support for mapping modes other than
  20. //                   MM_TEXT as suggested by Lee Sang Hun. - KR
  21. //
  22. // This class implements a memory Device Context which allows
  23. // flicker free drawing.
  24. class CMemDC : public CDC {
  25. protected:
  26.    CBitmap  m_bitmap;       // Offscreen bitmap
  27.    CBitmap* m_oldBitmap;    // bitmap originally found in CMemDC
  28.    CDC*     m_pDC;          // Saves CDC passed in constructor
  29.    CRect    m_rect;         // Rectangle of drawing area.
  30.    BOOL     m_bMemDC;       // TRUE if CDC really is a Memory DC.
  31.     
  32.    void Construct(CDC* pDC)
  33.    {
  34.         ASSERT(pDC != NULL); 
  35.         // Some initialization
  36.         m_pDC = pDC;
  37.         m_oldBitmap = NULL;
  38.         m_bMemDC = !pDC->IsPrinting();
  39.         if (m_bMemDC) {
  40.             // Create a Memory DC
  41.             CreateCompatibleDC(pDC);
  42.             pDC->LPtoDP(&m_rect);
  43.             m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
  44.             m_oldBitmap = SelectObject(&m_bitmap);
  45.             
  46.             SetMapMode(pDC->GetMapMode());
  47.             pDC->DPtoLP(&m_rect);
  48.             SetWindowOrg(m_rect.left, m_rect.top);
  49.         } else {
  50.             // Make a copy of the relevent parts of the current DC for printing
  51.             m_bPrinting = pDC->m_bPrinting;
  52.             m_hDC       = pDC->m_hDC;
  53.             m_hAttribDC = pDC->m_hAttribDC;
  54.         }
  55.         // Fill background 
  56.         FillSolidRect(m_rect, pDC->GetBkColor());
  57.     }
  58. // TRK begin
  59. public:
  60.    CMemDC(CDC* pDC                  ) : CDC() { pDC->GetClipBox(&m_rect); Construct(pDC); }
  61.    CMemDC(CDC* pDC, const RECT& rect) : CDC() { m_rect = rect           ; Construct(pDC); }
  62. // TRK end
  63.     
  64.    virtual ~CMemDC()
  65.    {        
  66.         if (m_bMemDC) {
  67.             // Copy the offscreen bitmap onto the screen.
  68.             m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
  69.                 this, m_rect.left, m_rect.top, SRCCOPY);            
  70.             
  71.             //Swap back the original bitmap.
  72.             SelectObject(m_oldBitmap);        
  73.         } else {
  74.             // All we need to do is replace the DC with an illegal value,
  75.             // this keeps us from accidently deleting the handles associated with
  76.             // the CDC that was passed to the constructor.            
  77.             m_hDC = m_hAttribDC = NULL;
  78.         }    
  79.     }
  80.     
  81.     // Allow usage as a pointer    
  82.     CMemDC* operator->() 
  83.     {
  84.         return this;
  85.     }    
  86.     // Allow usage as a pointer    
  87.     operator CMemDC*() 
  88.     {
  89.         return this;
  90.     }
  91. };
  92. #endif

 

先用普通DC构造一个memDC,然后把绘图操作作用在memDC上,当memDC析构时,自动把结果写到普通DC上。

void CCountdownCtrl::OnPaint() { // 双缓冲绘图 CPaintDC dc(this); CDC memDC; memDC.CreateCompatibleDC(&dc); CRect rect; GetClientRect(&rect); CBitmap memBitmap; memBitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); memDC.SelectObject(&memBitmap); //--- 原有背景绘制 ---// // 绘制圆形背景(假设已存在) // ... [假设这里已有圆形背景绘制代码] ... //--- 新增部分:中央矩形绘制 ---// // 创建透明背景(防止文字闪烁) memDC.FillSolidRect(rect, m_bgColor); // m_bgColor需在类中定义 // 绘制中央矩形(占圆形区域的60%) CRect circleRect(10, 10, rect.Width()-10, rect.Height()-10); CRect timeRect = circleRect; timeRect.DeflateRect(circleRect.Width()*0.2, circleRect.Height()*0.2); // 绘制带圆角的矩形背景 CBrush brush(m_rectBgColor); // m_rectBgColor需在类中定义 CBrush* pOldBrush = memDC.SelectObject(&brush); memDC.RoundRect(timeRect, CPoint(15, 15)); // 15像素圆角 //--- 时间计算 ---// int h = 0, m = 0, s = 0; GetHMS(h, m, s); // 需实现GetHMS函数 //--- 字体设置 ---// CFont fontTime, fontLabel; fontTime.CreatePointFont(240, _T("Segoe UI")); // 时间数字字体 fontLabel.CreatePointFont(80, _T("Microsoft YaHei")); // 标签字体 // 主时间显示(动态布局) CString strTime; if(h > 0) { strTime.Format(_T("%02d:%02d:%02d"), h, m, s); } else { strTime.Format(_T("%02d:%02d"), m, s); } //--- 时间文本绘制 ---// CFont* pOldFont = memDC.SelectObject(&fontTime); memDC.SetTextColor(m_textColor); // m_textColor需在类中定义 memDC.SetBkMode(TRANSPARENT); // 自动调整文本大小 CRect textRect = timeRect; textRect.DeflateRect(10, 15); // 内边距 memDC.DrawText(strTime, textRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); //--- 底部标签 ---// memDC.SelectObject(&fontLabel); CRect labelRect = timeRect; labelRect.top = labelRect.bottom - 25; // 底部留出标签位置 memDC.DrawText(h > 0 ? _T("时:分:秒") : _T("分:秒"), labelRect, DT_CENTER | DT_VCENTER); //--- 资源清理 ---// memDC.SelectObject(pOldFont); memDC.SelectObject(pOldBrush); // 将内存DC复制到屏幕 dc.BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); }补充这里未提供的代码
最新发布
03-30
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值